📄 usbaudiodevice.cpp
字号:
// USBAudioDevice.cpp: implementation of the CUSBAudioDevice class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "USBAudioDevice.h"
#include "math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CUSBAudioDevice::CUSBAudioDevice()
{
//Initialize the critical section variable used for exclusivity
InitializeCriticalSection(&gWaveCriticalSection);
//Make the handles NULL to begin with
m_USBAudioAudioHandle = NULL;
m_USBAudioDataHandle = NULL;
m_SoundCardHandle = NULL;
//Set the input buffer pointers to NULL, and size to 0
m_pEndpoint0ReportBuffer = NULL;
m_pEndpoint1ReportBuffer = NULL;
m_pEndpoint2ReportBuffer = NULL;
m_Endpoint0ReportBufferSize = 0;
m_Endpoint1ReportBufferSize = 0;
m_Endpoint2ReportBufferSize = 0;
//The device is not streaming or tuning initially
m_Streaming = false;
m_Tuning = false;
// m_RDSCleared = false;
//The current block starts at zero, and all blocks are initially free
m_CurrentBlock = 0;
m_FreeBlock = 0;
gWaveFreeBlockCount = BLOCK_COUNT;
//Allocate memory for the blocks of audio data to stream
m_OutputHeader = AllocateBlocks(BLOCK_SIZE, BLOCK_COUNT);
m_WaveformBuffer = (char*)malloc(BLOCK_SIZE);
m_InputHeader.lpData = m_WaveformBuffer;
m_InputHeader.dwBufferLength = BLOCK_SIZE;
m_InputHeader.dwFlags = 0;
}
CUSBAudioDevice::~CUSBAudioDevice()
{
//Free all allocated memory when destroyed
FreeBlocks(m_OutputHeader);
free(m_WaveformBuffer);
}
BYTE CUSBAudioDevice::OpenUSBAudio(AudioData* audioData)
{
BYTE status = STATUS_ERROR;
//Check that audiodata is not NULL
if (audioData)
{
//Open the USB audio input device
if (OpenUSBAudioAudio())
{
//Open the sound card
if (OpenSoundCard())
{
status = STATUS_OK;
}
else
{
status = STATUS_OUTPUTAUDIO_ERROR;
}
}
else
{
status = STATUS_USBAudioAUDIO_ERROR;
}
}
return status;
}
bool CUSBAudioDevice::CloseUSBAudio()
{
bool status = false;
//Close all pipes
CloseUSBAudioAudio();
CloseSoundCard();
CloseUSBAudioData();
status = true;
return status;
}
bool CUSBAudioDevice::OpenUSBAudioAudio()
{
bool status = false;
WAVEINCAPS waveInputCapabilities;
WAVEFORMATEX USBAudioWaveFormat;
//Setup the wave format based on our defined audio data
USBAudioWaveFormat.wFormatTag = WAVE_FORMAT_PCM;
USBAudioWaveFormat.nSamplesPerSec = SAMPLES_PER_SECOND;
USBAudioWaveFormat.wBitsPerSample = BITS_PER_SAMPLE;
USBAudioWaveFormat.nChannels = CHANNELS;
//Obtain the number of input devices on the system
DWORD numWaveInputDevices = waveInGetNumDevs();
//Scan through each input device to see if we can find our device
for (DWORD i = 0; i < numWaveInputDevices; i++)
{
//Get the device capabilities of the currently indexed device
if (waveInGetDevCaps(i, &waveInputCapabilities, sizeof(waveInputCapabilities)) == MMSYSERR_NOERROR)
{
//Compare the name of the device to see if it is the correct device
if (!strcmp(waveInputCapabilities.szPname, "TONE GENERATOR") || !strcmp(waveInputCapabilities.szPname, "USB Audio Device"))
{
//When the device is found, open a handle to the device
if (waveInOpen(&m_USBAudioAudioHandle, i, &USBAudioWaveFormat, 0, 0, CALLBACK_NULL) == MMSYSERR_NOERROR)
{
//Set i to the last item to kill the loop once the device is found
i = numWaveInputDevices;
status = true;
}
}
}
}
return status;
}
bool CUSBAudioDevice::OpenSoundCard()
{
bool status = false;
WAVEFORMATEX soundCardWaveFormat;
//Setup the wave format based on our defined audio data
soundCardWaveFormat.wFormatTag = WAVE_FORMAT_PCM;
soundCardWaveFormat.nSamplesPerSec = SAMPLES_PER_SECOND;
soundCardWaveFormat.wBitsPerSample = BITS_PER_SAMPLE;
soundCardWaveFormat.nChannels = CHANNELS;
//Open a handle to the default wave output device (sound card)
if (waveOutOpen(&m_SoundCardHandle, WAVE_MAPPER, &soundCardWaveFormat, (DWORD)waveOutProc, (DWORD)&gWaveFreeBlockCount, CALLBACK_FUNCTION | WAVE_ALLOWSYNC) == MMSYSERR_NOERROR)
{
status = true;
}
return status;
}
void CUSBAudioDevice::InitializeStream()
{
waveInStart(m_USBAudioAudioHandle);
//Fill the audio buffer to initialize the stream
while (gWaveFreeBlockCount > BUFFER_PADDING)
{
StreamAudioIn();
Sleep(50);
}
//Set streaming to true
m_Streaming = true;
}
void CUSBAudioDevice::StreamAudio()
{
if (!m_Streaming)
{
In_Count = 0;
Out_Count = 0;
InitializeStream();
}
//Check that the handles arent NULL
if ((m_USBAudioAudioHandle) && (m_SoundCardHandle))
{
//If there are any free blocks, then stream audio in
if (gWaveFreeBlockCount)
{
if (StreamAudioIn())
{
In_Count++;
TRACE(_T("StreamIn Success\n"));
}
}
//If there are any blocks ready for output, then stream audio out
if (gWaveFreeBlockCount < BLOCK_COUNT)
if (StreamAudioOut())
{
Out_Count++;
TRACE(_T("StreamOut Success\n"));
}
}
}
bool CUSBAudioDevice::IsStreaming()
{
return m_Streaming;
}
bool CUSBAudioDevice::StreamAudioIn()
{
bool status = false;
//Prepare the header for streaming in
if (waveInPrepareHeader(m_USBAudioAudioHandle, &m_OutputHeader[m_FreeBlock], sizeof(m_InputHeader)) == MMSYSERR_NOERROR)
{
//Get the buffer of audio in the input header
if (waveInAddBuffer(m_USBAudioAudioHandle, &m_OutputHeader[m_FreeBlock], sizeof(m_InputHeader)) == MMSYSERR_NOERROR)
{
//Enter the critical section to decrement the free block count
EnterCriticalSection(&gWaveCriticalSection);
gWaveFreeBlockCount--;
LeaveCriticalSection(&gWaveCriticalSection);
//Increment the free block index, and scale it
m_FreeBlock++;
m_FreeBlock %= BLOCK_COUNT;
status = true;
}
}
else
TRACE(_T("Could not prepare header\n"));
return status;
}
static void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
if (uMsg == WOM_DONE)
{
EnterCriticalSection(&gWaveCriticalSection);
int* freeBlockCounter = (int*)dwInstance;
(*freeBlockCounter)++;
LeaveCriticalSection(&gWaveCriticalSection);
}
}
bool CUSBAudioDevice::StreamAudioOut()
{
bool status = false;
//Prepare the header for streaming out
if (waveOutPrepareHeader(m_SoundCardHandle, &m_OutputHeader[m_CurrentBlock], sizeof(WAVEHDR)) == MMSYSERR_NOERROR)
{
//Write the sound to the sound card
if (waveOutWrite(m_SoundCardHandle, &m_OutputHeader[m_CurrentBlock], sizeof(WAVEHDR)) == MMSYSERR_NOERROR)
{
//waveOutProc callback function will get called, and free block counter gets incremented
//Increment the index of the current block to be played
m_CurrentBlock++;
m_CurrentBlock %= BLOCK_COUNT;
status = true;
}
}
return status;
}
UINT CUSBAudioDevice::GetCurrentBlock(void)
{
return m_CurrentBlock;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -