使用WASAPI捕获蓝牙音频数据

问题描述

我正在做一个小项目,我需要混合来自内部麦克风和蓝牙耳机(Bose)的传入数据。我以为我会使用WASAPI。但是,虽然我可以轻松读出内置麦克风,但蓝牙耳机却不是这样。 我几乎沿用了Docs给出的示例,但是我做了一个小小的改动,可以使用给出的ID选择自己的“输入设备”(内部麦克风或头戴式耳机)。

以下是方法:

HRESULT RecordAudioStreamBLE(MyAudioSink *pMySink,LPWSTR pwszID)
{

    HRESULT hr;
    REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
    REFERENCE_TIME hnsActualDuration;
    UINT32 bufferFrameCount;
    UINT32 numFramesAvailable;
    IMMDeviceEnumerator *pEnumerator = NULL;
    IMMDevice *pDevice = NULL;
    IAudioClient *pAudioClient = NULL;
    IAudioCaptureClient *pCaptureClient = NULL;
    WAVEFORMATEX *pwfx = NULL;
    UINT32 packetLength = 0;
    BOOL bDone = FALSE;
    BYTE *pData;
    DWORD flags;

    hr = CoInitialize(0);

    hr = CoCreateInstance(
           CLSID_MMDeviceEnumerator,NULL,CLSCTX_ALL,IID_IMMDeviceEnumerator,(void**)&pEnumerator);
    EXIT_ON_ERROR(hr)

    hr = pEnumerator->GetDevice(pwszID,&pDevice);
    EXIT_ON_ERROR(hr)

    hr = pDevice->Activate(IID_IAudioClient,(void**)&pAudioClient);
    EXIT_ON_ERROR(hr)

    hr = pAudioClient->GetMixFormat(&pwfx);
    EXIT_ON_ERROR(hr)

    hr = pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED,hnsRequestedDuration,pwfx,NULL);
    EXIT_ON_ERROR(hr)

    // Get the size of the allocated buffer.
    hr = pAudioClient->GetBufferSize(&bufferFrameCount);
    EXIT_ON_ERROR(hr)

    hr = pAudioClient->GetService(IID_IAudioCaptureClient,(void**)&pCaptureClient);
    EXIT_ON_ERROR(hr)

    // Notify the audio sink which format to use.
    hr = pMySink->SetFormat(pwfx);
    EXIT_ON_ERROR(hr)

    // Calculate the actual duration of the allocated buffer.
    hnsActualDuration = (double)REFTIMES_PER_SEC * bufferFrameCount / pwfx->nSamplesPerSec;

    hr = pAudioClient->Start();  // Start recording.
    EXIT_ON_ERROR(hr)

    // Each loop fills about half of the shared buffer.
    while (bDone == FALSE)
    {
        // Sleep for half the buffer duration.
        Sleep(hnsActualDuration/REFTIMES_PER_MILLISEC/2);

        hr = pCaptureClient->GetNextPacketSize(&packetLength);
        EXIT_ON_ERROR(hr)

        printf("packet size = %d\n",packetLength);
        while (packetLength != 0)
        {
            // Get the available data in the shared buffer.
            hr = pCaptureClient->GetBuffer( &pData,&numFramesAvailable,&flags,NULL);
            EXIT_ON_ERROR(hr)

            if (flags & AUDCLNT_BUFFERFLAGS_SILENT)
            {
                pData = NULL;  // Tell CopyData to write silence.
            }

            // Copy the available capture data to the audio sink.
            hr = pMySink->CopyData(pData,numFramesAvailable,&bDone);
            EXIT_ON_ERROR(hr)

            hr = pCaptureClient->ReleaseBuffer(numFramesAvailable);
            EXIT_ON_ERROR(hr)

            hr = pCaptureClient->GetNextPacketSize(&packetLength);
            EXIT_ON_ERROR(hr)
        }
    }

    hr = pAudioClient->Stop();  // Stop recording.
    EXIT_ON_ERROR(hr)

Exit:
    printf("%s\n",hr);
    CoTaskMemFree(pwfx);
    SAFE_RELEASE(pEnumerator)
    SAFE_RELEASE(pDevice)
    SAFE_RELEASE(pAudioClient)
    SAFE_RELEASE(pCaptureClient)

    return hr;
}

使用内部麦克风的ID进行操作时,一切正常。但是,如果使用了蓝牙设备的ID,则会得到以下输出:(我首先列出所有活动的设备,然后在终端中选择ID:

Endpoint 0: "S24D330 (Intel(R) Display Audio)" ({0.0.0.00000000}.{0f483f83-6e29-482e-94b5-fb9cc257a03d})
Endpoint 1: "Hoofdtelefoon (LE-My headphone Hands-Free AG Audio)" ({0.0.0.00000000}.{75c8e0c3-2e44-4538-940d-f8c2ae6424ca})
Endpoint 2: "Hoofdtelefoon (My headphone Stereo)" ({0.0.0.00000000}.{849b4cc2-ed72-4d40-9725-d1ce6b4abfa0})
Endpoint 3: "Luidsprekers (2- High Definition Audio Device)" ({0.0.0.00000000}.{cb8d7625-257e-4fd0-84b8-26de6aeb1e1b})
Endpoint 4: "Microfoon (2- High Definition Audio Device)" ({0.0.1.00000000}.{5edec961-7a46-4554-bdcd-43fb7d9a9d9a})
Endpoint 5: "Hoofdtelefoon (LE-My headphone Hands-Free AG Audio)" ({0.0.1.00000000}.{f937a0fa-1475-495b-81be-7aec0c1c7ea5})
Which input would you like?5
samples per second 16000
packet size = 0
packet size = 0
packet size = 0
packet size = 0
packet size = 0
packet size = 0
packet size = 0
packet size = 0
packet size = 0
^C

按上述方法在循环中打印数据包大小。显示每次的数据包大小仅为0。 有谁知道如何解决这个问题,只是从中获取“常规”数据? 是否可能需要使用其他API?速度是关键。

此致

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)