音频是我们最常用到的功能,音频也是 linux 和安卓的重点应用场合。I.MX6ULL 带有 SAI接口,正点原子的 I.MX6ULL ALPHA 开发板通过此接口外接了一个 WM8960 音频 DAC 芯片,本章我们就来学习一下如何使能 WM8960 驱动,并且通过 WM8960 芯片来完成音乐播放与录音。
1.音频接口简介
1.1 为什么需要音频解码
处理器要想“听到”外界的声音必须要把外界的声音转化为自己能够理解的“语言”,处理器能理解的就是 0 和 1,也就是二进制数据。所以我们需要先把外界的声音转换为处理器能理解的 0 和 1,在信号处理领域,外界的声音是模拟信号,处理器能理解的是数字信号,因此这里就涉及到一个模拟信号转换为数字信号的过程,而完成这个功能的就是 ADC 芯片。
同理,如果处理器要向外界传达自己的“心声”,也就是放音,那么就涉及到将处理器能理解的 0 和 1 转化为外界能理解的连续变化的声音,这个过程就是将数字信号转化为模拟信号,而完成这个功能的是 DAC 芯片。
现在我们知道了,处理器如果既想“听到”外界的声音,又想向外界传达自己的“心声”,那么就需要同时用到 DAC 和 ADC 这两款芯片。那是不是买两颗 DAC 和 ADC 芯片就行了呢?答案肯定是可以的,但是音频不单单是能出声、能听到就行。我们往往需要听到的声音动听、录进去的语音贴近真实、可以调节音效、对声音能够进行一些处理(需要 DSP 单元)、拥有统一的标准接口,方便开发等等。将这些针对声音的各种要求全部叠加到 DAC 和 ADC 芯片上,那么就会得到一个专门用于音频的芯片,也就是音频编解码芯片,英文名字就是 Audio CODEC,所以我们在手机或者电脑的介绍中看到“CODEC”这个词语,一般说的都是音频编解码。
既然音频 CODEC 的本质是 ADC 和 DAC,那么采样率和采样位数就是衡量一款音频CODEC 最重要的指标。比如常见音频采样率有 8K、44.1K、48K、192K 甚至 384K 和 768K,采样位数常见的有 8 位、16 位、24 位、32 位。采样率和采样位数越高,那么音频 CODEC 越能真实的还原声音,也就是大家说的 HIFI。因此大家会看到高端的音频播放器都会有很高的采样率和采样位数,同样的价格也会越高。当然了,实际的效果还与其他部分有关,采样率和采样位数只是其中重要的指标之一。
1.2 WM8960
WM8960 是一颗由 wolfson(欧胜)公司出品的音频编解码芯片,是一颗低功耗、高质量的立体声音频 CODEC。集成 D 类喇叭功放,每个通道可以驱动一个 1W 喇叭(8Ω)。内部集成 3 个立体声输入源,可以灵活配置,拥有一路完整的麦克风接口。WM8960 内部 ADC 和 DAC 都为24 位,WM8960 主要特性如下所示
①、DAC 的 SNR(信噪比)为 98dB,3.3V、48KHz 下 THD(谐波失真)为-84dB。
②、ADC 的 SNR(信噪比)为 94dB,3.3V、48KHz 下 THD(谐波失真)为-82dB。
③、3D 增强。
④、立体声 D 类功放,可以直接外接喇叭,8Ω负载下每通道 1W。
⑤、集成耳机接口。
⑥、集成麦克风接口。
⑦、采样率支持 8K、11.025K、12K、16K、22.05K、24K、32K、44.1K 和 48K。
①、此部分是 WM8960 提供的输入接口,作为立体声音频输入源,一共提供了三路,分别为 LINPUT1/RINPUT1、LINPUT2/RINPUT2、LINPUT3/RINPUT3。麦克风或线路输入就连接到此接口上,这部分是需要硬件工程师重点关心的,因为音频选择从哪一路进入需要在画 PCB 的时候就应该定好。
②、此部分是 WM8960 的输出接口,比如输出给耳机或喇叭,SPK_LP/SPK_LN 用于连接左声道的喇叭,支持 1W 的 8Ω喇叭。SPK_RP/SPK_RN 用于连接右声道的喇叭,同样支持 1W的 8Ω喇叭,最后就是 HP_L/HP_R,用于连接耳机。
③、此部分是数字音频接口,用于和主控制器连接,有 5 根线,用于主控制器和 WM8960之间进行数据“沟通”。主控制器向 WM8960 的 DAC 发送的数据,WM8960 的 ADC 向主控制传递的数据都是通过此音频接口来完成的。这个接口非常重要,是我们驱动开发人员重点关注的,此接口支持 I2S 格式。此接口 5 根线的作用如下:
ADCDAT:ADC 数据输出引脚,采集到的音频数据转换为数字信号以后通过此引脚传输给主控制器。
ADCLRC:ADC 数据对齐时钟,也就是帧时钟(LRCK),用于切换左右声道数据,此信号的频率就是采样率。此引脚可以配置为 GPIO 功能,配置为 GPIO 以后 ADC 就会使用 DACLRC引脚作为帧时钟。
DACDAT:DAC 数据输入引脚,主控器通过此引脚将数字信号输入给 WM8960 的 DAC。
DACLRC:DAC 数据对齐时钟,功能和 ADCLRC 一样,都是帧时钟(LRCK),用于切换左右声道数据,此信号的频率等于采样率。
BCLK:位时钟,用于同步。
MCLK:主时钟,WM8960 工作的时候还需要一路主时钟,此时钟由 I.MX6ULL 提供,MCLK 频率等于采样率的 256 或 384 倍,因此大家在 WM8960 的数据手册里面常看到MCLK=256fs 或 MCLK=384fs。
④、此部分为控制接口,是一个标准的 I2C 接口,WM8960 要想工作必须对其进行配置,这个 I2C 接口就是用于配置 WM8960
1.3 I2S总线
I2S 总线用于主控制器和音频 CODEC 芯片之间传输音频数据。因此,要想使用 I2S 协议,主控制器和音频 CODEC 都得支持 I2S 协议,I.MX6ULL 的 SAI 外设就支持 I2S 协议,WM8960 同样也支持 I2S,所以本章实验就是使用 I2S 协议来完成的。I2S 接口需要 3 根信号线(如果需要实现收和发,那么就要 4根信号线,收和发分别使用一根信号线):
另外,有时候为了使音频 CODEC 芯片与主控制器之间能够更好的同步,会引入另外一个叫做 MCLK 的信号,也叫做主时钟或系统时钟,一般是采样率的 256 倍或 384 倍。
1.4 SAI简介
STM32 中就是通过 SAI 接口来连接音频CODEC,I.MX6ULL 的 SAI 是一个全双工、支持帧同步的串行接口,支持 I2S、AC97、TDM 和音频DSP,SAI 主要特性如下:
①、帧最大为 32 个字。
②、字大小可选择 8bit 或 32bit。
③、每个接收和发送通道拥有 32×32bit 的 FIFO。
④、FIFO 错误以后支持平滑重启。
2.音频驱动使能
2.1 设备树
2.2 使能内核的WM8960
3.alsa-lib和alsa-utils
alsa-utils 是 ALSA 的一些小工具集合,我们可以通过这些小工具还测试我们的声卡。将 alsautils-1.2.2.tar.bz2 复制到 ubuntu 中并解压,命令如下