使用Core Audio實現對聲卡輸出的捕捉


涉及的接口有:

  • 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 這個軟件


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM