標籤:android blog io ar os sp for 檔案 資料
簡介
PortAudio 是一個跨平台採集和播放音訊開源庫,不過尚未支援Android平台,筆者決定讓PortAudio支援Android。
Android上,處理音訊庫是OpenSL ES,從API 9開始支援的技術,通過這個標準,Android已經完全可以在native層採集和播放音頻。
換句話說,PortAudio支援Android,也就是支援OpenSL ES。
詳情Opensl es
penSL ES 是無授權費、跨平台、針對嵌入式系統精心最佳化的硬體音頻加速API。它為嵌入式移動多媒體裝置上的本地應用程式開發人員提供標準化, 高效能,低回應時間的音頻
功能實現方法,並實現軟/硬體音頻效能的直接跨平台部署,降低執行難度,促進進階音頻市場的發展。
實現
Android Opensl es 實現可以直接通過官方的Demo瞭解。官方的demo提供了音頻採集、音頻緩衝播放、音頻url播放、音頻檔案播放、調整混合音效等等功能。
函數如下:
////////////////////////////////////////音頻播放器操作static int CreateAudioPlayer(SLObjectItf *playerObject, SLEngineItf engine, SLObjectItf mix, int numChannels, double sampleRate, PaSampleFormat sampleFormat );//建立音頻static int OpenAudioPlayer(PaOpenSLESStream* stream,unsigned long framesPerBuffer,PaSampleFormat outputSampleFormat);//開啟音頻播放器static int SetAudioPlayerVolum(PaOpenSLESStream* stream,int millibel); //設定音頻聲量static int PushAudioPlayerQueue(PaOpenSLESStream* stream);//向音頻播放器輸入資料static int StartAudioPlayer(PaOpenSLESStream* stream);//開始音頻static int CloseAudioPlayer(PaOpenSLESStream* stream);//關閉音頻static int SetAudioPlayerMuteSolo(PaOpenSLESStream* stream,int chan,int muteSolo);//操作MuteSolo///////////////////////////////////////麥克風操作static int CreateAudioRecorder(SLObjectItf *recorderObject, SLEngineItf engine,int numChannels, double sampleRate, PaSampleFormat sampleFormat);static int OpenAudioRecorder(PaOpenSLESStream* stream,unsigned long framesPerBuffer,PaSampleFormat inputSampleFormat);//開啟麥克風static int CloseAudioRecorder(PaOpenSLESStream* stream);//關閉麥克風static int StartAudioRecorder(PaOpenSLESStream* stream);//開始麥克風static int PopAudioRecorderQueue(PaOpenSLESStream* stream);//向音頻播放器取出資料
PortAudio Opensl es實現
實現機制如下--------音頻採集緩衝、音頻播放緩衝然後回調實現資料處理便可。
代碼按源碼pa_hostapi_skeleton.c模版實現便可。
回調如下:
static int c_callback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer,const PaStreamCallbackTimeInfo* outTime, const PaStreamCallbackFlags statusFlags, void *userData)
音頻元素涉及音訊元素挺多,記錄如下:
OpenSLES 中typedef struct SLDataFormat_PCM_ {SLuint32 formatType;資料格式定義 SL_DATAFORMAT_PCMSLuint32 numChannels;聲道個數(跟channelMask 一致)SLuint32 samplesPerSec;每秒採集頻率 hzSLuint32 bitsPerSample;採樣位元(採樣格式)SLuint32 containerSize;包含大小SLuint32 channelMask;通道面具//立體聲、左聲道、右聲道SLuint32endianness;塊的位元組順序 從16--32位} SLDataFormat_PCM;GUID-----SL_IID_VOLUME 音量SL_IID_PLAY 播放控制SL_IID_BUFFERQUEUE 緩衝介面SL_IID_EFFECTSEND 音效SL_IID_MUTESOLO 靜音SL_IID_RECORD 錄音介面SL_IID_PLAYBACKRATE 採樣率控制SL_IID_EQUALIZER 均衡器SL_IID_PRESETREVERB 預設混響SL_IID_ENVIRONMENTALREVERB 環境混響SL_IID_3DLOCATION 3D定位SL_IID_3DDOPPLER 多普勒效應SL_IID_BASSBOOST 低音增強SL_IID_PITCH 升降調SL_IID_VIRTUALIZER 虛擬化……
採集頻率:音訊採樣頻率,每秒鐘能夠採樣的次數,採樣率越高,音質越高。給出的執行個體是44100、22050、11025但不限於這幾個參數。例如要採集低品質的音頻就可以使
用4000、8000等。
量化位元(資料位元數):採樣值或取樣值,用來衡量聲音波動變化的一個參數,也可以說是音效卡的解析度。
1 位元組(也就是8bit) 只能記錄 256 個數, 也就是只能將振幅劃分成 256 個等級;
2 位元組(也就是16bit) 可以細到 65536 個數, 這已是 CD 標準了;
4 位元組(也就是32bit) 能把振幅細分到 4294967296 個等級, 實在是沒必要了。
位元速率:它描述了單位時間長度的媒體內容需要空間。每秒的傳輸速率。
聲道:聲音的通道的數目。常有單聲道和立體聲之分。
幀:單位時間內媒體幀的個數,其長度為樣本長度(採樣位元)和通道數的乘積。
資料量:採集資料需要的緩衝區的大小
資料量(位元組每秒) = 採集頻率 * 量化位元 * 聲道數 / 8(位元組) = 幀 * 位元組
周期:音訊裝置一次處理所需要的幀數,對於音訊裝置的資料訪問以及音頻資料的儲存,都是以此為單位。
交錯模式:數字音頻訊號儲存的方式。資料以連續幀的方式存放,即首先記錄幀1的左聲道樣本和右聲道樣本,再開始幀2的記錄...,
非交錯模式:首先記錄的是一個周期內所有幀的左聲道樣本,再記錄所有右聲道樣本。
總結
PortAudio支援Android,為Raknet實現語音通話提供了方便。
Android RakNet 系列之三 移植Portaudio