音頻的相關知識咱們從AudioRecord的構造傳參看起:html
RecorderHelper.getInstance().initRecoder(
this,
MediaRecorder.AudioSource.MIC, //麥克風數據
16000, //採樣率16k
AudioFormat.CHANNEL_CONFIGURATION_MONO, //單聲道
AudioFormat.ENCODING_PCM_16BIT);// 16bit的採樣精度複製代碼
上面一個初始化麥克風的調用,涉及到了不少知識,大概是大學時數字信號處理課程或者是信號與系統學的。相關以爲有必要科普一下,否則你們永遠是在複製代碼,遇到相關問題的時候若是不瞭解會一頭霧水,優化效果更提不上了。java
這篇文章不是用來介紹API的,介紹AndroidRecord API很簡單,無非初始化而後讀取。若是隻是這麼簡單的需求,甚至這個類都用不到,直接用MediaRecorder
便可錄音等。本文主要介紹相關的參數是什麼意思。好比什麼是16Bit採樣,什麼是44100採樣率。android
Google API地址
developer.android.google.cn/reference/a…git
從網頁的右上角咱們能夠看到,這是從API3等級開始就有的類。AndroidRecord
是一個比MediaRecorder
更加底層的類,根據谷歌介紹,有點至關因而直接從音頻設備拉數據的意思,而且咱們拿到的也直接是PCM流。github
從API23開始 多了個AudioRecord.Builder
類來幫助咱們初始化AndroidRecord
,惋惜這個類還不如不用,用了我23如下的還得用老方法初始化,這不只沒優化代碼,還冗餘了代碼。算法
AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)複製代碼
參數 | 介紹 |
---|---|
audioSource | MediaRecorder.AudioSource類裏面的各類類型,有MIC 、VOICE_CALL 等 |
sampleRateInHz | 採樣率,44100Hz是惟一能夠工做於全部手機上的採樣率,22050, 16000, and 11025 可能只有部分機型能工做,我以前就由於設置的採樣率爲16000致使在個人手機上工做正常,而在努比亞手機上Buffer滿的時間變短致使了些問題。 |
channelConfig | CHANNEL_IN_MONO 和 CHANNEL_IN_STEREO.即單聲道和立體聲也叫雙聲道,雙聲道能夠有保證的做於全部手機上 |
audioFormat | ENCODING_PCM_8BIT, ENCODING_PCM_16BIT, and ENCODING_PCM_FLOAT. 有8bit,16bit,32bit的採樣精度 |
bufferSizeInBytes | Record的內部記錄緩衝區大小,能夠經過getMinBufferSize(int, int, int) 方法獲得。 |
脈衝編碼調製(Pulse Code Modulation,PCM),這是在信號與系統裏面接觸過的編碼格式,脈衝編碼調製是數字通訊的編碼方式之一。主要過程是將話音、圖像等模擬信號每隔必定時間進行取樣,使其離散化,同時將抽樣值按分層單位四捨五入取整量化,同時將抽樣值按一組二進制碼來表示抽樣脈衝的幅值。優化
PCM經過抽樣、量化、編碼三個步驟將連續變化的模擬信號轉換爲數字編碼
ui
採樣率又叫抽樣,因爲聲音實際上是一種能量波,所以也有頻率和振幅的特徵,頻率對應於時間軸線,振幅對應於電平軸線。波是無限光滑的,絃線能夠當作由無數點組成,因爲存儲空間是相對有限的,數字編碼過程當中,必須對絃線的點進行採樣。採樣的過程就是抽取某點的頻率值,很顯然,在一秒中內抽取的點越多,獲取得頻率信息更豐富,爲了復原波形,一次振動中,必須有2個點的採樣,人耳可以感受到的最高頻率爲20kHz,所以要知足人耳的聽覺要求,則須要至少每秒進行40k次採樣,用40kHz表達,這個40kHz就是採樣率。咱們常見的CD,採樣率爲44.1kHz。this
44.1kHz意味着什麼呢?假設咱們有2段正弦波信號,分別爲20Hz和20KHz,長度均爲一秒鐘,以對應咱們能聽到的最低頻和最高頻,分別對這兩段信號進行 40KHz的採樣,咱們能夠獲得一個什麼樣的結果呢?結果是:20Hz的信號每次振動被採樣了40K/20=2000次,而20K的信號每次振動只有2次採樣。顯然,在相同的採樣率下,記錄低頻的信息遠比高頻的詳細。這也是爲何有些音響發燒友指責CD有數碼聲不夠真實的緣由,CD的44.1KHz採樣也沒法保證高頻信號被較好記錄。要較好的記錄高頻信號,看來須要更高的採樣率,因而有些朋友在捕捉CD音軌的時候使用48KHz的採樣率,這是不可取的!這其實對音質沒有任何好處,對抓軌軟件來講,保持和CD提供的44.1KHz同樣的採樣率纔是最佳音質的保證之一,而不是去提升它。較高的採樣率只有相對模擬信號的時候纔有用,若是被採樣的信號是數字的,請不要去嘗試提升採樣率。google
經常使用的採樣率爲:44.1KHz與48KHz
1 字節(也就是8bit) 只能記錄 256 個數, 也就是隻能將振幅劃分紅 256 個等級;
2 字節(也就是16bit) 能夠細到 65536 個數, 這已經是 CD 標準了;
4 字節(也就是32bit) 能把振幅細分到 4294967296 個等級, 實在是不必了.
若是是雙聲道(stereo), 採樣就是雙份的, 文件也差很少要大一倍.
咱們來看一張圖就能明白:
上述的模擬數據模擬就比如人的聲音是有振幅有頻率的波,假設上面的模擬數據時長爲1秒。
那麼採樣,能夠看到咱們採樣了10根線,那採樣率就是10Hz。(44100Hz是多高本身體會)
再看量化,分爲了8個等級,也就是採樣進度是3bit。(能夠想象16bit是多麼精確了)
最後1秒鐘的數據,被編碼成了3bit×10 即30個二進制數據。
若是是8bit的採樣,對於單聲道聲音文件,採樣數據爲八位的短整數(short int 00H-FFH);
而對於雙聲道立體聲聲音文件,每次採樣數據爲一個16位的整數(int),高八位(左聲道)和低八位(右聲道)分別表明兩個聲道。
算一個PCM音頻流的碼率是一件很輕鬆的事情,採樣率值×採樣大小值×聲道數bps。一個採樣率爲44.1KHz,採樣大小爲16bit,雙聲道的PCM編碼的WAV文件,它的數據速率則爲 44.1K×16×2 =1411.2 Kbps。咱們常說128K的MP3,對應的WAV的參數,就是這個1411.2 Kbps,這個參數也被稱爲數據帶寬,它和ADSL中的帶寬是一個概念。將碼率除以8,就能夠獲得這個WAV的數據速率,即176.4KB/s。這表示存儲一秒鐘採樣率爲44.1KHz,採樣大小爲16bit,雙聲道的PCM編碼的音頻信號,須要176.4KB的空間,1分鐘則約爲10.34M,這對大部分用戶是不可接受的,尤爲是喜歡在電腦上聽音樂的朋友,要下降磁盤佔用,只有2種方法,下降採樣指標或者壓縮。下降指標是不可取的,所以專家們研發了各類壓縮方案。
碼率的不一樣帶來的是音頻品質的不一樣,咱們的音樂軟件裏面有音樂的品質其實就是這些,正常咱們聽的固然是有損壓縮的歌曲,好比QQ音樂裏面聽歌有SQ無損品質,就是無損壓縮的音頻。
PCM流咱們能夠直接保存爲文件,可是這就是PCM格式了,正常播放器都沒有播放pcm的功能,咱們能夠把PCM轉成WAV。WAV文件是一種一種無損的音頻文件格式,裏面仍是PCM的編碼,只不過是在咱們原有的pcm文件上加上一個WAV規定的協議頭而已。這個頭是44個byte大小。因此一個0bit的pcm文件轉成wav大小是44B。
由於WAV並無進行壓縮,因此WAV佔用的空間是最大的。所以爲了傳輸以及存儲的需求後來人們設計了不少的音頻壓縮格式,mp3就是一種有損的壓縮音頻,至於怎麼壓縮的那是各類壓縮算法的事情了。
本文做者:Anderson/Jerey_Jobs
博客地址 : jerey.cn/
簡書地址 : Anderson大碼渣
github地址 : github.com/Jerey-Jobs