現在移動端已不僅僅局限于文本、圖片這些 pc 平臺上的常見信息類型,語音的使用愈見頻繁,于是前段時間萌生了個想法:如果在移動端對語音內容做處理,提取特征出來構建關鍵詞庫是否可以對這些語音進行分類、搜索,于是花了一段時間研究 android,本文從音頻的錄制、處理來記錄總結,識別下篇放上。
一、?音頻系統的架構
安卓系統里的音頻模塊可劃分為幾層:硬件、驅動、硬件抽象層、硬件與 java 庫之間的 “中介”、Framework(供 app 調用的接口都封裝在這層)、實際用戶可視的 app。
二、?語音錄制
處理語音錄制的類主要 4 個:?AudioTrack、AudioRecorder、MediaPlayer 和 MediaRecorder,都在 android.media 包下,MediaRecorder 的使用相對簡單,不過相對的是無法處理一些底層的操作,例如無法對音頻進行處理。
除了上面的類庫實現外,音頻系統實際調用了更為底層的服務來實現音頻的采集,這就是 AudioFlinger 和 AudioPolicyService 。
AudioRecord 使用:
1、?創建 AudioRecord 對象
1 2 3 4 5 6 7 8 9 10 11 |
AudioRecord( int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes) |
參數說明
AudioSource?音頻采集來源
SampleRateInHz??錄制頻率
channelConfig 錄制通道
AudioFormat 錄制編碼格式
BufferSize 錄制緩沖大小,可以通過 getMinBufferSize 來獲取
getMinBufferSize 這個接口返回了要成功創建一個 AudioRecord?object 所需的最小 buffer?size。
2、監聽用戶界面操作
1 |
public void setOnClickListener (View.onClickListener l) |
3、讀
1 2 3 4 5 6 7 |
public int read ( byte[] audioData, int offsetInBytes, int sizeInBytes) |
audioData 是一個用來存儲音頻的字節數組
4、寫
寫操作主要涉及幾個類:
java.io.File;
java.io.FileInputStream;
java.io.FileOutputStream;
使用:
1 2 3 |
FileOutputStream fos = null; fos.write(audiodata); //將上一步得到的字節數組寫入到文件中 |
二、音頻處理
一般信號處理技術采用快速傅立葉變換,卷積變換和逆傅立葉變換來實現音頻處理。
音頻處理大致兩類:變頻、變速、變調。我們錄到的聲音為時域信號,需要利用信號處理技術將時域轉成頻域(指在對函數或信號進行分析時,分析其和頻率有關部份,而不是和時間有關的部份),然后用頻譜遷移技術來對信號處理,最后再將頻域信號轉換回時域。
對于每個音頻片段,傅里葉變換將音頻波形分解為它的成分音符并且保存下來,從而代替存儲原始波形。語音識別就是基于此,將一段話分成塊,與已有詞庫進行比較。
“函數或信號可以透過一對數學的運算子在時域及頻域之間轉換。例如傅里葉變換可以將一個時域信號轉換成在不同頻率下對應的振幅及相位,其頻譜就是時域信號在頻域下的表現,而反傅里葉變換可以將頻譜再轉換回時域的信號?!?/p>
雖說音頻處理令人為之一亮,但涉及的技術較為復雜,因此現在市場上提供了相關產品直接提供開發者使用,例如 soundtouch,IIR?。