如果我使用十六进制eitor打开捕获的PCM数据,它们只是00和FF字节的组合,似乎只能捕获笔记本电脑和PC上的静态噪声。在我的PC上,录音设备(立体声混音-Realtek高Definiton Audio),在笔记本电脑上,我使用录音设备Stereo Mix(Realtek Audio)。我可以修改WAVEFORMATEX并更改驱动程序格式,但仍然只能听到不同种类的大声静态噪声或根本没有声音...如果我使用Audacity捕获,它可以正常工作,所以问题一定在我的代码上。
HRESULT InitAudio() {
HRESULT hr = E_FAIL;
REFERENCE_TIME hnsRequestedDuration;
REFERENCE_TIME hnsActualDuration;
UINT32 bufferFrameCount;
IMMDeviceEnumerator *pEnumerator = NULL;
IMMDeviceCollection* pIMMDeviceCollection = NULL;
IMMDevice *pDevice = NULL;
_AudioSamplesReadyEvent = CreateEventEx(NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE);
_ShutdownEvent = CreateEventEx(NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE);
WAVEFORMATEX wfx =
{WAVE_FORMAT_PCM, wavFile.num_channels, wavFile.sample_rate, wavFile.byte_rate, wavFile.sample_alignment, wavFile.bit_depth, 0};
hr = CoCreateInstance(
CLSID_MMDeviceEnumerator, NULL,
CLSCTX_ALL, IID_IMMDeviceEnumerator,
(void**)&pEnumerator);
hr = pEnumerator->EnumAudioEndpoints(eCapture,DEVICE_STATE_ACTIVE,&pIMMDeviceCollection);
hr = pIMMDeviceCollection->Item(0, &pDevice);
hr = pDevice->Activate(
IID_IAudioClient, CLSCTX_ALL,
NULL, (void**)&pAudioClient);
hr = pAudioClient->GetDevicePeriod(NULL, &hnsRequestedDuration);
hr = pAudioClient->Initialize(
AUDCLNT_SHAREMODE_SHARED,
AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
hnsRequestedDuration,
0,
&wfx,
NULL);
hr = pAudioClient->SetEventHandle(_AudioSamplesReadyEvent);
if (FAILED(hr)) MessageBox(NULL,TEXT("Unable to set event handle!"), TEXT("Error"), MB_OK);
hr = pAudioClient->GetService(
IID_IAudioCaptureClient,
(void**)&pCaptureClient);
ProcessSoundThread = CreateThread(NULL, 0, ProcessSound, 0, 0, NULL);
hr = pAudioClient->Start(); // Start recording.
return hr;
}
以及用于处理数据的功能
DWORD WINAPI ProcessSound(void* arg) {
UINT32 numFramesAvailable;
UINT32 packetLength = 0;
UINT32 dataSize = 0;
BYTE *pData;
DWORD flags;
HRESULT hr;
UINT dwDataWrote;
HANDLE waitArray[2] = { _AudioSamplesReadyEvent, _ShutdownEvent};
HANDLE mmcssHandle = NULL;
DWORD mmcssTaskIndex = 0;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hr)) MessageBox(NULL,TEXT("Unable to initialize COM in render thread!"), TEXT("Error"), MB_OK);
mmcssHandle = AvSetMmThreadCharacteristics("Audio", &mmcssTaskIndex);
if(mmcssHandle == NULL) MessageBox(NULL,TEXT("Unable to enable MMCSS on capture thread!"), TEXT("Error"), MB_OK);
while(captureSound) {
DWORD waitResult = WaitForMultipleObjects(2, waitArray, FALSE, INFINITE);
switch (waitResult)
{
case WAIT_OBJECT_0 + 0:
hr = pCaptureClient->GetBuffer(&pData,&numFramesAvailable,&flags,NULL,NULL);
if(hr != AUDCLNT_S_BUFFER_EMPTY) {
dataSize = numFramesAvailable * wavFile.sample_alignment; // wavFile.sample_alignment = frameSize = num_channels * (pWav->bit_depth)/8
if (FAILED( addWavData(&wavFile, pData, dataSize, &dwDataWrote)))
MessageBox(NULL,TEXT("Error writting the data!"), TEXT("Error"), MB_OK);
totalData += dataSize;
}
pCaptureClient->ReleaseBuffer(numFramesAvailable);
break;
case WAIT_OBJECT_0 + 1:
captureSound = false;
break;
}`
}
return 0;
}