涉及的接口有:
- IMMDeviceEnumerator
- IMMDevice
- IAudioClient
- IAudioCaptureClient
主要過程:
- 創建多媒體設備枚舉器(IMMDeviceEnumerator)
- 通過多媒體設備枚舉器獲取聲卡接口(IMMDevice)
- 通過聲卡接口獲取聲卡客戶端接口(IAudioClient)
- 通過聲卡客戶端接口(IAudioClient)可獲取聲卡輸出的音頻參數、初始化聲卡、獲取聲卡輸出緩沖區的大小、開啟/停止對聲卡輸出的采集
- 通過聲卡采集客戶端接口(IAudioCaptureClient)可獲取采集的聲卡輸出數據,並對內部緩沖區進行控制
- 通過聲卡輸出客戶端接口(IAudioRenderClient)可將采集的聲音數據寫入聲音輸出設備的緩存單元,輸出設備可以通過IAudioClient::GetService函數獲取 IAudioRenderClient 接口。
代碼示例:
//首先枚舉你的音頻設備,你可以在這個時候獲取到你機器上所有可用的設備,並指定你需要用到的那個設備
hr = CoCreateInstance(
CLSID_MMDeviceEnumerator, NULL,
CLSCTX_ALL, IID_IMMDeviceEnumerator,
(void**)&pEnumerator);
EXIT_ON_ERROR(hr)
hr = pEnumerator->GetDefaultAudioEndpoint(
eCapture, eConsole, &pDevice);
EXIT_ON_ERROR(hr)
//創建一個管理對象,通過它可以獲取到你需要的一切數據
hr = pDevice->Activate(
IID_IAudioClient, CLSCTX_ALL,
NULL, (void**)&pAudioClient);
EXIT_ON_ERROR(hr)
hr = pAudioClient->GetMixFormat(&pwfx);
EXIT_ON_ERROR(hr)
//初始化管理對象,在這里,你可以指定它的最大緩沖區長度,這個很重要,應用程序控制數據塊的大小以及延時長短都靠這里的初始化,具體參數大家看看文檔解釋
hr = pAudioClient->Initialize(
AUDCLNT_SHAREMODE_SHARED,
0,
hnsRequestedDuration,
0,
pwfx,
NULL);
EXIT_ON_ERROR(hr)
//這個buffersize,指的是緩沖區最多可以存放多少幀的數據量
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(hnsActualDuration/REFTIMES_PER_MILLISEC/2);
hr = pCaptureClient->GetNextPacketSize(&packetLength);
EXIT_ON_ERROR(hr)
while (packetLength != 0)
{
//鎖定緩沖區,獲取數據
hr = pCaptureClient->GetBuffer(
&pData,
&numFramesAvailable,
&flags, NULL, NULL);
EXIT_ON_ERROR(hr)
if (flags & AUDCLNT_BUFFERFLAGS_SILENT)
{
pData = NULL;
}
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();
EXIT_ON_ERROR(hr)
查看錄制的音頻可以用 audacity 這個軟件