1. 程式人生 > >PortAudio採集和播放音訊,實現一個雙路混音器

PortAudio採集和播放音訊,實現一個雙路混音器

混音,顧名思義,就是把多個音源混合的過程,是一個很常見的應用。這兩天我也做了一個雙路混音器,當然,我沒有做多麼專業的音訊訊號處理,只是一個簡單的混音,調節各路音量,並實現了一些音效處理。主要功能有:採集硬體裝置,讀取wav檔案,播放,混音,音量調節,音訊節奏、音調的調節,wav檔案輸出。這麼多功能,我們不需要一個一個全部自己實現,有時候,藉助開源專案,尤其是比較成熟的開源專案,不但可以大大節省開發時間,還能使程式更加穩定。即便不能直接在自己的專案中使用,也能有借鑑意義。這個專案中我就使用了PortAudio,PortAudio是一個開源的、跨平臺的音訊IO庫,它主要提供了音訊採集和播放的介面,而且API非常簡單。大家可以嘗試一下。

  下圖就是該專案產品截圖:

  所有的功能呢,在介面上是一目瞭然了,其中有三個子視窗,是音訊資料經FFT(快速傅立葉)變換後顯示的頻譜圖,左右兩個分別是兩路音訊的,中間則是混音後的。這裡我和大家分享一下這個混音器的設計思路以及PortAudio的使用,希望有需求的朋友能夠有所借鑑。

首先是程式的邏輯架構圖

  

  PortAudio在專案中主要負責採集硬體裝置和播放記憶體中的音訊Sample,其實在Windows上實現這種功能可以有多種方法,之前我也基於DirectShow做過,這次使用PortAudio主要也是想熟悉一下,將來如果要做其他平臺的應用時,可以直接拿來使用了。

  • AudioInput的主要功能是封裝一下音訊的輸入,包括硬體採集和檔案讀取
  • AudioMixer管理AudioInput,並進行音量和各種音效處理
  • 鑑於檔案操作比較費時,FileWritter的操作其實是放在單獨的執行緒中進行的。

PortAudio的封裝和使用

  PortAudio的API非常的簡單,基本上完成採集或播放的功能,只需要呼叫三個介面就可以了:Pa_OpenStreamPa_StartStreamPa_CloseStream。它們的原型如下

    

  首先,我們需要呼叫Pa_Initialize來進行PortAudio的初始化,然後設定好Pa_OpenStream

的各項引數,然後就可以使用它了。呼叫Pa_StartStream之後,如果是採集,就可以從PortAudio讀取資料了,如果是播放,則只需要不斷的把要播放的音訊資料交給PortAudio就行了。而PortAudio和你的程式之間的資料的互動,其實是有兩種方式的,一種就是上面原型中提到的設定回撥函式的形式,另一種就是呼叫Pa_ReadStreamPa_WriteStream這兩個函式,我推薦還是通過回撥的形式,簡單嘛,這個最重要了:)。回撥函式的原型也比較簡單,採集和播放都是一樣的。

  我們只需要在回撥函式中操作inputBuffer或者outputBuffer即可,下面是我啟動前進行設定的程式碼:

1. PortAudio的採集

2. PortAudio的播放

  有一點需要注意的是,framesPerBuffer的值,也就是在Pa_OpenStream中設定的引數值,這個數值就是outputBuffer或inputBuffer中音訊幀的個數,我這裡設定成了512,當然你也可以設定成其他的數值,不過不宜過小,否則會造成大量的非同步回撥,cpu是處理不過來的。這個數值再乘以你之前這隻的音訊幀Sample格式(我這裡是paFloat32)和音軌個數,就可以計算出outputBuffer或inputBuffer的大小,然後就可以操作音訊資料了,例如在採集的回撥函式中這樣使用。

memcpy(audio_data, inputBuffer, framesPerBuffer * sizeof(float)*2);

混音演算法

  實話實說,這個混音演算法是我從網上找到的,不過效果還是挺不錯的,公式就是

C = A + B - (A * B >> 0x10)

  A和B就是兩路不同的音訊資料,C就是混音後的音訊資料,當然,處理後,還需要對C進行防止資料溢位的處理,否則,可能會有爆音。

如果是16bit音訊資料,就是:

if (C > 32767) C = 32767;
else if (C < -32768) C = -32768;

如果是float音訊資料,就是:

if (C > 1) C = 1;
else if (C < -1) C = -1;

  這個演算法針對的是16bit的音訊取樣資料,我實驗的結果是:對float音訊取樣資料,同樣有不錯的效果。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  haibindev.cnblogs.com,合作請聯絡QQ。(轉載請註明作者和出處)

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++