Arduino經過MAX9814實現錄音

若是經過Arduino進行錄音不是單純地接一個駐極電容MIC就能夠的,由於天然界中的聲音很是複雜,波形極其複雜,一般咱們採用的是脈衝代碼調製編碼。即PCM編碼。PCM經過抽樣、量化、編碼三個步驟將連續變化的模擬信號轉換爲數字編碼。在開始動手以前咱們須要先了解一些關於數字編碼的基礎知識。git

採樣-採樣率

在音頻採集中叫作採樣率。github

因爲聲音實際上是一種能量波,所以也有頻率和振幅的特徵,頻率對應於時間軸線,振幅對應於電平軸線。波是無限光滑的,絃線能夠當作由無數點組成,因爲存儲空間是相對有限的,數字編碼過程當中,必須對絃線的點進行採樣。採樣的過程就是抽取某點的頻率值,很顯然,在一秒中內抽取的點越多,獲取得頻率信息更豐富,爲了復原波形,一次振動中,必須有2個點的採樣,人耳可以感受到的最高頻率爲20kHz,所以要知足人耳的聽覺要求,則須要至少每秒進行40k次採樣,用40kHz表達,這個40kHz就是採樣率。 咱們常見的CD,採樣率爲44.1kHz。編程

量化-採樣大小

光有頻率信息是不夠的,咱們還必須得到該頻率的能量值並量化,用於表示信號強度。採樣大小就是量化的過程,將該頻率的能量值並量化,用於表示信號強度。網絡

量化電平數爲 2的整數次冪,咱們常見的CD位16bit的採樣大小,即2的16次方。oop

採樣大小相對採樣率更難理解,由於要顯得抽象點,舉個簡單例子:假設對一個波進行8次採樣,採樣點分別對應的能量值分別爲A1-A8,但咱們只使用 2bit的採樣大小,結果咱們只能保留A1-A8中4個點的值而捨棄另外4個。若是咱們進行3bit的採樣大小,則恰好記錄下8個點的全部信息。採樣率和 採樣大小的值越大,記錄的波形更接近原始信號。學習

採樣率和採樣大小/比特率

採樣率和比特率就像是座標軸上的橫縱座標。ui

橫座標的採樣率表示了每秒鐘的採樣次數。 縱座標的比特率表示了用數字量來量化模擬量的時候的精度。編碼

採樣率相似於動態影像的幀數,好比電影的採樣率是24赫茲,PAL制式的採樣率是25赫茲,NTSC制式的採樣率是30赫茲。當咱們把採樣到的一個個靜止畫面再以採樣率一樣的速度回放時,看到的就是連續的畫面。一樣的道理,把以44.1kHZ採樣率記錄的CD以一樣的速率播放時,就能聽到連續的聲音。顯然,這個採樣率越高,聽到的聲音和看到的圖像就越連貫。固然,人的聽覺和視覺器官能分辨的採樣率是有限的,基本上高於44.1kHZ採樣的聲音,絕大部分人已經覺察不到其中的分別了。翻譯

而聲音的位數就至關於畫面的顏色數,表示每一個取樣的數據量,固然數據量越大,回放的聲音越準確,不至於把開水壺的叫聲和火車的鳴笛混淆。一樣的道理,對於畫面來講就是更清晰和準確,不至於把血和西紅柿醬混淆。不過受人的器官的機能限制,16位的聲音和24位的畫面基本已是普通人類的極限了,更高位數就只能靠儀器才能分辨出來了。好比電話就是3kHZ取樣的7位聲音,而CD是44.1kHZ取樣的16位聲音,因此CD就比電話更清楚。code

當你理解了以上這兩個概念,比特率就很容易理解了。以電話爲例,每秒3000次取樣,每一個取樣是7比特,那麼電話的比特率是21000。而CD是每秒 44100次取樣,兩個聲道,每一個取樣是13位PCM編碼,因此CD的比特率是44100213=1146600,也就是說CD每秒的數據量大約是 144KB,而一張CD的容量是74分等於4440秒,就是639360KB=640MB。

比特率這個詞有多種翻譯,好比碼率等,表示通過編碼(壓縮)後的音頻數據每秒鐘須要用多少個比特來表示,而比特就是二進制裏面最少的單位,要麼是 0,要麼是1。比特率與音頻壓縮的關係簡單的說就是比特率越高音質就越好,但編碼後的文件就越大;若是比特率越少則狀況恰好翻轉。

編碼

根據採樣率和採樣大小能夠得知,相對天然界的信號,音頻編碼最多隻能作到無限接近,至少目前的技術只能這樣了,相對天然界的信號,任何數字音頻編碼方案都是有損的,由於沒法徹底還原。在計算機應用中,可以達到最高保真水平的就是PCM編碼,被普遍用於素材保存及音樂欣賞,CD、DVD以及咱們常見的WAV文件中均有應用。所以,PCM約定俗成了無損編碼,由於PCM表明了數字音頻中最佳的保真水準,並不意味着PCM就可以確保信號絕對保真,PCM也只能作到 最大程度的無限接近。咱們而習慣性的把MP3列入有損音頻編碼範疇,是相對PCM編碼的。強調編碼的相對性的有損和無損,是爲了告訴你們,要作到真正的無損是困難的,就像用數字去表達圓周率,無論精度多高,也只是無限接近,而不是真正等於圓周率的值

爲何要使用音頻壓縮技術

要算一個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種方法,下降採樣指標或者壓縮。下降指標是不可取的,所以專家們研發了各類壓縮方案。因爲用途和針對的目標市場不同,各類音頻壓縮編碼所達到的音質和壓縮比都不同,在後面的文章中咱們都會一一提到。有一點是能夠確定的,他們都壓縮過。

頻率與採樣率的關係

採樣率表示了每秒對原始信號採樣的次數,咱們常見到的音頻文件採樣率多爲44.1KHz,這意味着什麼呢?假設咱們有2段正弦波信號,分別爲20Hz和 20KHz,長度均爲一秒鐘,以對應咱們能聽到的最低頻和最高頻,分別對這兩段信號進行40KHz的採樣,咱們能夠獲得一個什麼樣的結果呢?結果是:20Hz的信號每次振動被採樣了40K/20=2000次,而20K的信號每次振動只有2次採樣。顯然,在相同的採樣率下,記錄低頻的信息遠比高頻的詳細。這也是爲何有些音響發燒友指責CD有數碼聲但不夠真實的緣由,CD的44.1KHz採樣也沒法保證高頻信號被較好記錄。要較好的記錄高頻信號,看來須要更高的採樣率,因而有些朋友在捕捉CD音軌的時候使用48KHz的採樣率,這是不可取的!這其實對音質沒有任何好處,對抓軌軟件來講,保持和CD提供的44.1KHz同樣的採樣率纔是最佳音質的保證之一,而不是去提升它。較高的採樣率只有相對模擬信號的時候纔有用,若是被採樣的信號是數字的,請不要去嘗試提升採樣率。

流特徵

隨着網絡的發展,人們對在線收聽音樂提出了要求,所以也要求音頻文件可以一邊讀一邊播放,而不須要把這個文件所有讀出後而後回放,這樣就能夠作到不用下載就能夠實現收聽了。也能夠作到一邊編碼一邊播放,正是這種特徵,能夠實如今線的直播,架設本身的數字廣播電臺成爲了現實。

像這麼一個曲線,就能夠用來描述振膜隨時間變化的關係了。可是想要描述這樣的一個曲線,咱們並無辦法來描述它,除非咱們這樣說:「呃,這個曲線它上來了,而後又下去了,再上來,再下去...」顯然這麼描述是不可能的。那麼怎麼辦?人們想了這麼一個辦法:

每隔一個小小的時間間隔,去用尺子量一下這個點的位置在哪裏。那麼只要這個間隔是必定的,咱們就能夠把這個曲線描述成:{9,11,12,13,14,14,15,15,15,14,14,13,12,10,9,7...}這樣描述是否是比剛纔的方法要精確多了?並且更美妙的是,若是咱們把這個時間間隔取得更小,拿的尺子越精確,那麼測量獲得的,用來描述這個曲線的數字也能夠作到更加地精確。用專業的術語來講,咱們每兩次測一下位置的時間間隔,就是所謂的採樣率。採樣率等於多少,就意味着咱們每秒鐘進行了多少次這樣的測量。

假設你用萬用表去量一秒鐘麥克風傳來的模擬電信號,量的次數越多,越能反映聲音的真實狀況,量的數值編程二進制就成了數字信號

採樣率(sampling rate)高,就能保真原信號中越高頻的成份。可是,頻率高過必定值的聲音人耳是分辨不出的,所以採樣率過高沒有必要。採樣率的單位是Hz或S/s(samples per second),這兩個單位是同樣的。平時所說的16-bit和24-bit不是採樣率,而是分辨率(resolution)。它是指聲音的連續強度被數字化以後分爲多少級。N-bit的意思聲音的強度被均分爲2^N級。16-bit的話,就是65535級。這是一個很大的數了,人可能也分辨不出六萬五千五百三十五分之一的音強差異。也就是說,採樣率針對的是信號的時間(頻率)特性,而分辨率針對的是信號的強度特性,這是兩個不同的概念。

好了,講了一大堆的理論也是時候講講應該如何來實現了,本文是基於Arduino來實現這個功能,而Arduino是沒有PCM解碼模塊的但架不住它便宜學習曲線又低。費話很少說了先來看看本文的主角吧:

MAX9814

MAX9814是個錄音放大模塊,本文會使用它與Arduino鏈接將錄音生成一個wav文件保存到SD上,固然也能夠進行直接的播放。咱們的目標是使用它進行聲音的採樣。

另外,若是用ESP8266能夠不使用SD卡模塊直接將文件存到雲。

BOM

  • MAX9814 模塊
  • MicroSDCard 模塊
  • Arduino Uno

線路圖

代碼

這裏我使用了一個叫TMRpcm的庫,這個庫在Arduino上很是好用,它原本是作軟DAC用的,能夠用來擴展Arduino進行直接的聲音解碼播放。

注: TMRpcm裏面有一個用於錄音的方法,源碼中是被註釋掉的,在安裝該庫以後須要打開源碼庫中的pcmConfig.h文件將如下的行取消註釋,不然會編譯不經過:

#define buffSize 128. May need to increase.
#define ENABLE_RECORDING 
#define BLOCK_COUNT 10000UL

如下是 Arduino 代碼:

#include <SD.h>
#include <SPI.h>
#include <TMRpcm.h>

#define SD_ChipSelectPin 10  // 若是使用 arduino nano 328 可以使用Pin4

TMRpcm audio;   

void setup() {
  
  audio.speakerPin = 4; 

  Serial.begin(115200);
  
  if (!SD.begin(SD_ChipSelectPin)) {  
    Serial.println("SD Fail");
    return;
  }else{
    Serial.println("SD OK"); 
  }
  audio.CSPin = SD_ChipSelectPin;
}


void loop() {
    if(Serial.available()){                          
      char c = Serial.read();
      Serial.println(c);
      switch(c){
        case 'r': audio.startRecording("test.wav",16000,A0); break;    //以16khz的採樣率開始錄音
        case 'R': audio.startRecording("test.wav",16000,A0,1); break;  //錄音並直接進行回放
        case 't': audio.startRecording("test.wav",16000,A0,2); break;  //將錄音直接進行回放
        case 's': audio.stopRecording("test.wav"); break;                  //中止錄音
        case 'p': audio.play("test.wav"); break;                                 //回放錄音
        case '=': audio.volume(1); break;                                          //增長音量
        case '-': audio.volume(0); break;                                         //減少音量
        case 'S': audio.stopPlayback(); break;                                  //中止全部的回放
        
      }
    }
}

將以上代碼寫入Arduino後須要打開串口監視器運行,因爲以上代碼是一個互操做代碼因此你須要經過串口監視器向Arduino發送文字指令。

參考

相關文章
相關標籤/搜索