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发送文字指令。

参考

相关文章
相关标签/搜索