目录
一、音频接口简介
1、音频编解码芯片
2、 WM8960
3、I2S总线接口
二、硬件原理图
三、音频驱动使能
三、使能内核的 WM8960 驱动
1、取消 ALSA 模拟 OSS API
2、使能 I.MX6ULL 的 WM8960 驱动
验证
四、alsa-lib 和 alsa-utils 移植
1、alsa-utils 移植
②、安装alsa-lib
③、拷贝文件
2、 alsa-utils 移植
五、声卡设置与测试
1、使用 amixer 设置声卡
①、测试声卡
②、使用 arecord 录制音频
2、LINE IN 录音测试
使用 arecord 录制音频
六、开机自动配置声卡
1、使用 alsactl 保存声卡设置
2、开机启动
I.MX6ULL 带有 SAI接口,开发板通过此接口外接了一个 WM8960 音频 DAC 芯片,通过使能NXP官方的WM8960 驱动,并且通过 WM8960 芯片来完成音乐播放与录音。
一、音频接口简介
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。因此大家会看到高端的音频播放器都会有很高的采样率和采样位数,同样的价格也会越高。当然,实际的效果还与其他部分有关,采样率和采样位数只是其中重要的指标之一。
2、 WM8960
WM8960 是一颗由 wolfson(欧胜)公司出品的音频编解码芯片,是一颗低功耗、高质量的立体声音频 CODEC。采样率支持 8K、 11.025K、 12K、 16K、 22.05K、 24K、 32K、 44.1K 和48K。WM8960 内部 ADC 和 DAC 都为24 位。 WM8960的控制接口是一个标准的 I2C接口WM8960 要想工作必须对其进行配置,这个 I2C 接口就是用于配置 WM8960 的。
3、I2S总线接口
I2S(Inter-IC Sound)总线有时候也写作 IIS, I2S 是飞利浦公司提出的一种用于数字音频设备之间进行音频数据传输的总线。和 I2C、 SPI 这些常见的通信协议一样, I2S 总线用于主控制器和音频 CODEC 芯片之间传输音频数据。因此,要想使用 I2S 协议, 主控制器和音频 CODEC 都得支持 I2S 协议, I.MX6ULL 的 SAI 外设就支持 I2S 协议, WM8960 同样也支持 I2S,所以本章实验就是使用 I2S 协议来完成的。 I2S 接口需要 3 根信号线(如果需要实现收和发,那么就要 4根信号线,收和发分别使用一根信号线):
SCK: 串行时钟信号,也叫做位时钟(BCLK),音频数据的每一位数据都对应一个 SCK,立体声都是双声道的,因此 SCK=2×采样率×采样位数。比如采样率为 44.1KHz、 16 位的立体声音频,那么 SCK=2× 44100× 16=1411200Hz=1.4112MHz。
WS: 字段(声道)选择信号,也叫做 LRCK,也叫做帧时钟,用于切换左右声道数据, WS 为
“1”表示正在传输左声道的数据, WS 为“0”表示正在传输右声道的数据。 WS 的频率等于采样率,比如采样率为 44.1KHz 的音频, WS=44.1KHz。
SD: 串行数据信号,也就是我们实际的音频数据,如果要同时实现放音和录音,那么就需要 2 根数据线,比如 WM8960 的 ADCDAT 和 DACDAT,就是分别用于录音和放音。不管音频数据是多少位的,数据的最高位都是最先传输的。数据的最高位总是出现在一帧开始后(LRCK变化)的第 2 个 SCK 脉冲处。
另外,有时候为了使音频 CODEC 芯片与主控制器之间能够更好的同步,会引入另外一个叫做 MCLK 的信号,也叫做主时钟或系统时钟,一般是采样率的 256 倍或 384 倍。
I.MX6ULL SAI :音频 CODEC 支持 I2S 协议,那么主控制器也必须支持 I2S 协议,I.MX6ULL 也提供了一叫做 SAI 的外设,全称为 Synchronous Audio Interface,翻译过来就是同步音频接口。I.MX6ULL 的 SAI 是一个全双工、支持帧同步的串行接口,支持 I2S、 AC97、 TDM 和音频DSP
二、硬件原理图
开发板音频原理图接口如图
SAI 接口一共用到了 6 根数据线,这 6 根数据线用于 I.MX6ULL 与 WM8960 之间的音频数据收发
WM8960 在使用的时候需要进行配置,配置接口为 I2C,连接到了 I.MX6ULL 的 I2C2上
三、音频驱动使能
根据原理图我们知道 WM8960 连接到了 I.MX6ULL 的 I2C2 接口上,因此在设备树中的“i2c2”节点下需要添加 wm8960 信息。NXP 官方 I.MX6ULL EVK 开发板使用的也是 WM8960,因此在设备树中添加设备节点这些工作 NXP 已经帮我们做了。打开 imx6ull-alientek-emmc.dts,找到名为“i2c2”的节点,此节点下都是连接到 I2C2 总线上的设备,其中就包括了 wm8960, wm8960 节点信息
看设备树的绑定手册,打开 Documentation/devicetree/bindings/sound/wm8960.txt,compatible:兼容属性,属性值要设置为“wlf,wm8960”,linux 内核里面全局搜索“wlf,wm8960”的话就会找到WM8960的I2C驱动文件,此文件为sound/soc/codecs/wm8960.c
reg: 设置 WM8960 的 I2C 地址,开发板中 WM8960 的 I2C 地址为0X1A。
wlf,shared-lrclk: 这是一个 bool 类型的属性,如果添加了此属性, WM8960 的 R24 寄存器的 LRCM 位(bit2)就会置 1。
在 imx6ull.dtsi 文件中会有关于 SAI 相关接口的描述,这部分是 NXP 原厂编写的,我们不需要做任何修改, SAI2 的设备子节点内容如下所示:
修改名为“sound”的子节点,如下,将这两行屏蔽
三、使能内核的 WM8960 驱动
在linux内核源码目录下输入下面命令打开 linux 内核的图形化配置界面:
make menuconfig
1、取消 ALSA 模拟 OSS API
如下路径:
-> Device Drivers
-> Sound card support (SOUND [=y])
-> Advanced Linux Sound Architecture (SND [=y])
-> <> OSS Mixer API //不选择
-> <> OSS PCM (digital audio) API //不选择
如下图
2、使能 I.MX6ULL 的 WM8960 驱动
进入如下路径:
-> Device Drivers
-> Sound card support (SOUND [=y])
-> Advanced Linux Sound Architecture (SND [=y])
-> ALSA for SoC audio support (SND_SOC [=y])
-> SoC Audio for Freescale CPUs
-> <*> Asynchronous Sample Rate Converter (ASRC) module support //选中
-> <*> SoC Audio support for i.MX boards with wm8960 //选中
如下图
验证
重新编译 linux 内核,编译完成以后使用新的 zImage 和.dtb 文件启动
系统启动过程中就会打印信息,如下两图
进入系统以后查看一下/dev/snd 目录看看
controlC0:用于声卡控制, C0 表示声卡 0。
pcmC0D0c 和 pcmC0D1c: 用于录音的 pcm 设备,其中的“COD0”和“C0D1”分别表示声卡 0 中的设备 0 和设备 1,最后面的“c”是 capture 的缩写,表示录音。
pcmC0D0p 和 pcmC0D1p:用于播放的 pcm 设备,其中的“COD0”和“C0D1”分别表示声卡 0 中的设备 0 和设备 1,最后面的“p”是 playback 的缩写,表示放音。
timer: 定时器
音频驱动使能以后还不能直接播放音乐或录音,我们还需要移植 alsa-lib 和 alsa-utils
四、alsa-lib 和 alsa-utils 移植
1、alsa-utils 移植
①、开发板和uabntu都创建一个/usr/share/arm-alsa 目录
ubantu
cd /usr/share/
sudo mkdir arm-alsa
开发板
mkdir /usr/share/arm-alsa -p
②、安装alsa-lib
由于 alsa-utils 要用到 alsa-lib 库,因此要先编译 alsa-lib 库,解压命令如下
tar -vxjf alsa-lib-1.2.2.tar.bz2
进入alsa-lib-1.2.2根目录下 ,输入下面命令
./configure --host=arm-linux-gnueabihf --prefix=/home/ubantu22/alsa-lib/alsa-lib --with-configdir=/usr/share/arm-alsa
目录/home/ubantu22/alsa-lib/alsa-lib保存编译结果和安装,“--with-configdir”用于设置 alsa-lib 编译出来的配置文件存放位置,这里设置为前面创建的“/usr/share/arm-alsa”目录。
编译成功如下
安装命令
sudo -s //切换到 root 用户
source /etc/profile //执行/etc/profile
make install //安装,此时已经工作在 root 下,因此不需要加“sudo”su 用户名 //切换回原来的用户
如果出现“error: version mismatch. This is Automake 1.16.5”或者“Makefile:357:Makefile.in”错误
按以下顺序用root用户执行这5条命令,没问题的跳过这步
autoscan
aclocal
autoconf
automake --add-missing
make install
查看安装
③、拷贝文件
拷贝文件到开发板根文件系统
cd alsa-lib //进入 alsa-lib
sudo cp lib/* /home/ubantu22nfs/rootfs/lib/ -af
cd /usr/share/arm-alsa //进入 arm-alsa 目录,拷贝配置文件
sudo cp * /home/ubantu22/nfs/rootfs/usr/share/arm-alsa/ -raf
2、 alsa-utils 移植
和移植alsa-lib同理,解压alsa-utils 之后进入根目录下,分别·输入下面命令
./configure --host=arm-linux-gnueabihf --prefix=/home/ubantu22/alsa-utils/alsa-utils --with-alsa-inc-prefix=/home/ubantu22/alsa-lib/alsa-lib/include/ --with-alsa-prefix=/home/ubantu22/alsa-lib/alsa-lib/lib/ --disable-alsamixer --disable-xmlto
make
sudo make install
编译完成以后就会在前面创建的“alsa-utils”目录下生成 bin、 sbin 和 share 三个文件夹
bin、 sbin 和 share 这三个目录中的所有文件分别拷贝到开发板根目录下的/bin、 /sbin 和/usr/share/alsa 目录下,命令如下
cd alsa-utils
sudo cp bin/* /home/uabntu22/nfs/rootfs/bin/ -rfa
sudo cp sbin/* /home/uabntu22/nfs/rootfs/sbin/ -rfa
sudo cp share/* /home/uabntu22/nfs/rootfs/usr/share/ -rfa
打开开发板根文件系统中的/etc/profile 文件,在里面加入如下所示内容:
export ALSA_CONFIG_PATH=/usr/share/arm-alsa/alsa.conf
ALSA_CONFIG_PATH 用于指定 alsa 的配置文件,这个配置文件是 alsa-lib 编译出来的
五、声卡设置与测试
1、使用 amixer 设置声卡
第一次使用声卡录音之前要先使用 amixer 设置一下声卡,这里为了方便,我们在开发板根文件系统的/music 目录(自行创建)下创建一个名为“mic_in_config.sh”的 shell 脚本,然后在里面输入声卡的设置命令。 mic_in_config.sh 脚本内容如下所示:
#!/bin/sh
#设置捕获的音量
amixer cset name='Capture Volume' 90,90
PCM
amixer sset 'PCM Playback' on
amixer sset 'Playback' 256
amixer sset 'Right Output Mixer PCM' on
amixer sset 'Left Output Mixer PCM' on
#ADC PCM
amixer sset 'ADC PCM' 200
#耳机/喇叭(扬声器)设置播放音量,直流/交流
#Turn on Headphone
amixer sset 'Headphone Playback ZC' on
#Set the volume of your headphones(98% volume, 127 is the MaxVolume)
amixer sset Headphone 125,125
#Turn on the speaker
amixer sset 'Speaker Playback ZC' on
#Set the volume of your Speaker(98% volume, 127 is the MaxVolume)
amixer sset Speaker 125,125
#Set the volume of your Speaker AC(80% volume, 100 is the MaxVolume)
amixer sset 'Speaker AC' 4
#Set the volume of your Speaker AC(80% volume, 5 is the MaxVolume)
amixer sset 'Speaker DC' 4
#音频输入,左声道管理
#Turn on Left Input Mixer Boost
amixer sset 'Left Input Mixer Boost' off
amixer sset 'Left Boost Mixer LINPUT1' off
amixer sset 'Left Input Boost Mixer LINPUT1' 0
amixer sset 'Left Boost Mixer LINPUT2' off
amixer sset 'Left Input Boost Mixer LINPUT2' 0
#Turn off Left Boost Mixer LINPUT3
amixer sset 'Left Boost Mixer LINPUT3' off
amixer sset 'Left Input Boost Mixer LINPUT3' 0
#音频输入,右声道管理,全部关闭
#Turn on Right Input Mixer Boost
amixer sset 'Right Input Mixer Boost' on
amixer sset 'Right Boost Mixer RINPUT1' off
amixer sset 'Right Input Boost Mixer RINPUT2' 0
amixer sset 'Right Boost Mixer RINPUT2' on
amixer sset 'Right Input Boost Mixer RINPUT2' 127
amixer sset 'Right Boost Mixer RINPUT3' off
amixer sset 'Right Input Boost Mixer RINPUT3' 0
最后,给予 mic_in_config.sh 可执行权限并运行,命令如下:
chmod 777 mic_in_config.sh //给予可执行权限
./ mic_in_config.sh //运行
①、测试声卡
在开发板根文件系统下创建一个名为“music”的目录来存放音频文件,然后找一首 wav 格式的音乐放到开发板根文件系统中,可以使用 aplay 软件播放 wav 格式的音乐测试一下, aplay 也是 alsa-utils提供的
aplay y1215.wav //播放歌曲
如果一切设置正常的话就会开始播放音乐,因为 ALPHA 开发板支持喇叭和耳机自动切换,因此如果不插耳机的话默认从喇叭播放音乐。插上耳机以后喇叭就会停止播放音乐,改为耳机播放音乐
②、使用 arecord 录制音频
使用 arecord 来录制一段 10 秒中的音频, arecord 也是 alsa-utils 编译出来的,输入如下命令:
arecord -f cd -d 10 record.wav
-f 是设置录音质量,“-f cd”表示录音质量为 cd 级别。 -d 是指定录音时间,单位是 s,这条指令就是录制一段 cd 级别 10s 的 wav 音频,音频名字为 record.wav(这里开发板的 MIC 只接了左声道,因此录出来的音频只有左声道有数据)
2、LINE IN 录音测试
Line in 测试,也就是线路输入测试,使用一根 3.5mm 公对公音频线,一头连接到手机或者电脑,另外一头连接到开发板 Line in 接口上
同样新建一个名为“line_in_config.sh”的 shell 脚本,在此脚本里面输入如下内容:
#!/bin/sh
#设置捕获的音量
amixer cset name='Capture Volume' 100,100
#PCM
amixer sset 'PCM Playback' on
amixer sset 'Playback' 256
amixer sset 'Right Output Mixer PCM' on
amixer sset 'Left Output Mixer PCM' on
#ADC PCM
amixer sset 'ADC PCM' 200
#录音前应该设置耳机或者扬声器的音量为 0(下面并没有设置)防止干扰
#耳机/喇叭(扬声器)设置播放音量,直流/交流
#Turn on Headphone
amixer sset 'Headphone Playback ZC' on
#Set the volume of your headphones(98% volume, 127 is the MaxVolume)
amixer sset Headphone 125,125
#Turn on the speaker
amixer sset 'Speaker Playback ZC' on
#Set the volume of your Speaker(98% volume, 127 is the MaxVolume)
amixer sset Speaker 125,125
#Set the volume of your Speaker AC(80% volume, 100 is the MaxVolume)
amixer sset 'Speaker AC' 4
#Set the volume of your Speaker AC(80% volume, 5 is the MaxVolume)
amixer sset 'Speaker DC' 4
#音频输入,左声道管理
#Turn off Left Input Mixer Boost
amixer sset 'Left Input Mixer Boost' on
#关闭其他通道输入
amixer sset 'Left Boost Mixer LINPUT1' off
amixer sset 'Left Input Boost Mixer LINPUT1' 0
#关闭麦克风左声道输入
amixer sset 'Left Boost Mixer LINPUT2' on
amixer sset 'Left Input Boost Mixer LINPUT2' 127
#Line_in 右声道输入关闭
amixer sset 'Left Boost Mixer LINPUT3' off
amixer sset 'Left Input Boost Mixer LINPUT3' 0
#音频输入,右声道管理
#Turn on Right Input Mixer Boost
amixer sset 'Right Input Mixer Boost' on
amixer sset 'Right Boost Mixer RINPUT1' off
amixer sset 'Right Input Boost Mixer RINPUT1' 0
amixer sset 'Right Boost Mixer RINPUT2' off
amixer sset 'Right Input Boost Mixer RINPUT2' 0
#要想设置成音频输入, 请打开 RINPUT3,看原理图可知
#其他的声道通过上面的配置可关闭,这样是为了避免干扰,需要的时候就打开
#RINPUT3 打开(关键点)
amixer sset 'Right Boost Mixer RINPUT3' on
amixer sset 'Right Input Boost Mixer RINPUT3' 127
最后,给予 line_in_config.sh 可执行权限并运行,命令如下:
chmod 777 line_in_config.sh //给予可执行权限
./line_in_config.sh //运行
使用 arecord 录制音频
使用 arecord 来录制一段 10 秒中的音频,输入如下命令:
arecord -f cd -d 10 record.wav
录制完成以后使用 aplay 播放刚刚录制的音频,由于 开发板上 LINE IN 是接了左右双声道,因此录制出来的音频是立体声的,不像 MIC 录出来的只有左声道。
六、开机自动配置声卡
1、使用 alsactl 保存声卡设置
开发板重启以后声卡的所有设置都会消失,必须重新设置声卡,让配置保存
首先在开发板根文件系统下创建/var/lib/alsa目录,命令如下
mkdir /var/lib/alsa -p
在新建的目录下创建文件asound.state
cd /var/lib/alsa
touch asound.state
使用 amixer 设置声卡,然后输入如下命令保存声卡设置
alsactl -f asound.state store
-f 指定声卡配置文件, store 表示保存。
2、开机启动
打开/etc/init.d/rcS 文件,在最后面追加如下内容:
if [ -f "/var/lib/alsa/asound.state" ]; then
echo "ALSA: Restoring mixer setting......"
/sbin/alsactl -f /var/lib/alsa/asound.state restore &
fi
如下
设置完成以后重启开发板,开发板开机就会自动设置声卡,直接使用 aplay 播放音乐测试声卡开机自动配置是否正确