Audio
本章节对V853音频相关模块的架构、开发和使用进行介绍。
V853 芯片提供了 AudioCodec(芯片内置音频接口) x1、I2S/PCM(数字音频接口) x2、DMIC(外置数字 MIC 接口) x1,可以满足各类音频需求。
在官方提供的V853 开发板板中,贴了两个板载麦克风、一个Line-in接口和一个speaker接口,可以进行音频相关模块的开发和调试。
*注:左侧 UART0 旁的 3.5mm 耳机接口是 GPS 使用的 UART 接口,不是耳机接口
Audio规格简介
AudioCodec
* 支持多种采样率格式
* 播放:8~192KHz
* 录音:8~48KHz
* 支持多通道播放和录音
* 播放:1(支持 mono 模式,最高支持 2 通道)
* 录音:1~2
* 支持 16bit/24bit/32bit 数据精度(硬件支持16/20bit)
* 支持硬件 HPF、DRC 算法
* 支持的物理接口(均支持差分和单端模式)
* INPUT : mic
* OUTPUT: lineout
* 支持同时 playback 和 capture (全双工模式)
* 支持多声卡同源输出
* 支持多声卡同步录音
I2S/PCM
* 支持多种采样率格式
* 播放:8~192KHz
* 录音:8~192KHz
* 支持多通道播放和录音
* 播放:1~16
* 录音:1~16
* 支持 16bit/20bit/24bit/32bit 数据精度(硬件支持8/12/16/20/24/28/32bit)
* 支持 5 种 TDM 模式
* I2S standard mode
* Left-justified mode
* Right-justified mode
* DSP-A mode (short frame PCM mode)
* DSP-B mode (long frame PCM mode)
* 支持 loopback 回环模式
* 支持同时 playback 和 capture (全双工模式)
* 支持多声卡同源输出
* 支持多声卡同步录音
DMIC
* 支持多种采样率格式
* 8~48KHz
* 支持多通道录音
* channels:1~8
* 支持 16bit/24bit 数据精度(硬件支持16/24bit)
* 支持硬件 HPF 算法
* 支持多声卡同步录音
播放和录音
开发板板载了2路麦克风,使用这两个麦克风可以进行【录音】操作,录制双声道音频。
同时开发板也带有一路音频输出扬声器,可以进行【播放】等相关操作。
录音
V853 开发板板载的两个麦克风,位于 LINE-IN接口附近。
我们可以使用下面这行命令录制音频,其命令的含义在后文中有讲解,这里先不用考虑,先测试一下
amixer -D hw:audiocodec cset name='MIC1 Input Select' 0 && \
amixer -D hw:audiocodec cset name='MIC2 Input Select' 0 && \
amixer -D hw:audiocodec cset name='MIC1 Switch' 1 && \
amixer -D hw:audiocodec cset name='MIC2 Switch' 1 && \
amixer -D hw:audiocodec cset name='MIC1 gain volume' 30 && \
amixer -D hw:audiocodec cset name='MIC2 gain volume' 30 && \
arecord -D hw:audiocodec -f S16_LE -t wav -c2 -r 16000 -d 3 t.wav
可以看到,录音结束后生成了 t.wav
音频文件
我们也可以用 adb
把录音上传到电脑上查看。
可以看到刚才录制的双声道音频
这就是刚刚录取到的声音。
播放
再试试播放刚才的录音,先接入扬声器。
然后使用命令播放音频
amixer -D hw:audiocodec cset name='LINEOUT Switch' 1 && \
amixer -D hw:audiocodec cset name='LINEOUT Switch' 1 && \
amixer -D hw:audiocodec cset name='LINEOUT volume' 25 && \
aplay -D hw:audiocodec t.wav
此时喇叭中就会播放刚刚录取的声音。
音频驱动框架简介
在 Tina Linux 中,音频软件框架使用ASoC( ALSA System on Chip ),它是在 ALSA 驱动程序上封装的一层。ASoC 框架更好地支持嵌入式处理器和移动设备中的音频 Codec 的一套软件体系,并将音频系统分为 3 部分:Machine,Platform 和 Codec。
Codec驱动
所有的Codec驱动都要提供以下特性:
(1)Codec DAI (Digital Audio Interface) 和 PCM的配置信息;
(2)Codec 的 IO 控制方式(I2C等);
(3)Mixer 和其他的音频控件;
(4)Codec 的 ALSA 音频操作接口;
必要时,也可以提供以下功能:
(5)DAPM描述信息;
(6)DAPM事件处理程序;
(7)DAC数字静音控制;
ASoC 中的一个重要设计原则就是要求 Codec 驱动是平台无关的,它包含了一些音频的控件(Controls)、音频接口、DAMP(动态音频电源管理)的定义和某些 Codec IO 功能。
为了保证硬件无关性,任何特定于平台和机器的代码都要移到 Platform 和 Machine 驱动中。
Platform驱动
它包含了该 SoC 平台的音频 DMA 和音频接口的配置和控制(I2S,PCM等等),但一般不包含与板子或 Codec 相关的代码。
Machine驱动
单独的 Platform 和 Codec 驱动是不能工作的,它必须由 Machine 驱动把它们结合在一起才能完成整个设备的音频处理工作,并且一般是在 Machine 驱动中实现了底层硬件设备的驱动。
音频框架的使用
由于在 Tina Linux 中使用的是标准的 ALSA API,所以使用音频的功能可以使用标准的 alsa-utils
。它提供了 amixer
、aplay
、arecord
等工具。可以在 make menuconfig
内的 Sound
选项中启用。
驱动调控:amixer
amixer是命令行的 ALSA 声卡驱动调节工具,用于启用、关闭各声卡,设置各声卡的音量。使用 amixer
命令列出当前注册的音频设备。
amixer
- 常用选项
选项 功能
-D,--device 指定声卡设备,默认使用default
- 常用命令
命令 功能
controls 列出指定声卡的所有控件
contents 列出指定声卡的所有控件的具体信息
cget 获取指定控件的信息
cset 设定指定控件的值
选择 MIC1 输入
amixer -D hw:audiocodec cset name='MIC1 Input Select' 0
选择 MIC2 输入
amixer -D hw:audiocodec cset name='MIC2 Input Select' 0
开启 MIC1
amixer -D hw:audiocodec cset name='MIC1 Switch' 1
开启 MIC2
amixer -D hw:audiocodec cset name='MIC2 Switch' 1
设置 MIC1 音量
amixer -D hw:audiocodec cset name='MIC1 gain volume' 30
设置 MIC2 音量
amixer -D hw:audiocodec cset name='MIC2 gain volume' 30
开启 LINEOUT 输出功能
amixer -D hw:audiocodec cset name='LINEOUT Output Select' 1
开启 LINEOUT 通路
amixer -D hw:audiocodec cset name='LINEOUT Switch' 1
设置输出音量
amixer -D hw:audiocodec cset name='LINEOUT volume' 25
录音工具:arecord
arecord 是命令行的 ALSA 声卡驱动的录音工具,用于录音功能。
选项 功能
-D,--device 指定声卡设备,默认使用default
-l,--list-device` 列出当前所有声卡
-t,--file-type 指定播放文件的格式,如voc,wav,raw,不指定的情况下会去读取文件头部作识别
-c,--channels 指定通道数
-f,--format 指定采样格式
-r,--rate 采样率
-d,--duration 指定播放的时间
--period-size 指定period size
--buffer-siz` 指定buffer size
查看录音设备
可以使用 arecord -l
命令查看开发板提供的录音设备。
arecord -l
麦克风录音
在录音之前,首先需要使用 amixer 打开音频通路,配置内部 MIC1,MIC2 录制双通道音频。
amixer -D hw:audiocodec cset name='MIC1 Input Select' 0 && \
amixer -D hw:audiocodec cset name='MIC2 Input Select' 0 && \
amixer -D hw:audiocodec cset name='MIC1 Switch' 1 && \
amixer -D hw:audiocodec cset name='MIC2 Switch' 1 && \
amixer -D hw:audiocodec cset name='MIC1 gain volume' 30 && \
amixer -D hw:audiocodec cset name='MIC2 gain volume' 30
使用 arecord
命令,使用板载的两个麦克风进行录音。
arecord -D hw:audiocodec -f S16_LE -t wav -c2 -r 16000 -d 3 t.wav
播放工具:aplay
aplay 是命令行的 ALSA 声卡驱动的播放工具,用于播放功能。
选项 功能
-D,--device 指定声卡设备,默认使用default
-l,--list-devices 列出当前所有声卡
-t,--file-type 指定播放文件的格式,如voc,wav,raw,不指定的情况下会去读取文件头部作识别
-c,--channels 指定通道数
-f,--format 指定采样格式
-r,--rate 采样率
-d,--duration 指定播放的时间
--period-size 指定period size
--buffer-size 指定buffer size
查看播放设备
使用 aplay -l
查看播放设备
aplay -l
扬声器播放音频
在播放之前,首先需要打开音频通路,配置扬声器播放音频,具体可以参照 amixer 配置。
amixer -D hw:audiocodec cset name='LINEOUT Switch' 1 && \
amixer -D hw:audiocodec cset name='LINEOUT Switch' 1 && \
amixer -D hw:audiocodec cset name='LINEOUT volume' 25
使用 aplay
通过外接扬声器播放刚才录制的音频。
aplay -D hw:audiocodec t.wav
修改音量:alsamixer
使用 alsamixer
提供的图形化界面调整音量。
alasmixer
配置文件:alsaconf
alsaconf 指的是 ALSA configuration file,使用 alsa-lib 打开声卡,操作 pcm, mixer 时,会加载相关位置上的配置文件,用于指导操作pcm,mixer
设备。
alsaconf 配置文件位于 openwrt/target/v853/v853-vision/busybox-init-base-files/etc/asound.conf
这些配置文件可以设定defaut声卡,自定义pcm设备,alsa插件等功能,具体可以参考:
https://www.alsa-project.org/alsa-doc/alsa-lib/conf.html
https://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html
这里给出一份示例配置文件
pcm.!default {
type asym
playback.pcm "hw:{CARD=audiocodec, DEV=0}"
capture.pcm "hw:0,0"
}
pcm.PlaybackRateDmix {
type plug
slave {
pcm {
type dmix
ipc_key 1111
ipc_perm 0666
slave {
pcm "hw:0,0"
format S16_LE
rate 16000
channels 1
period_size 1024
periods 8
}
}
}
rate_converter "linear"
}
#pcm.resample rely on alsa-plugin and libspeexdsp. Select them in menuconfig if we want to use plugin pcm.resample.
pcm.resample {
type plug
slave {
pcm "hw:0,0"
format S16_LE
rate 16000
channels 1
}
rate_converter "speexrate"
}
pcm.CaptureMic {
type hooks
slave.pcm "hw:0,0"
hooks.0 {
type ctl_elems
hook_args [
{
name "MIC1 Switch"
preserve true
optional true
value 1
}
]
}
}
pcm.eq {
type awequal
slave.pcm "hw:0,0"
config_file "/etc/awequal.conf"
tuning_support true
verbose true
}
tinyalsa-utils
tinyalsa是alsa-lib的一个简化版。它提供了pcm和control的基本接口;没有太多太复杂的操作、功能。可以按需使用接口。
tinyalsa-utils是基于tinyalsa的一些工具,下面对几个常用的工具作介绍。
tinymix
与amixer作用类似,用于操作 mixer control。
常用选项
选项 功能
-D,--card 指定声卡设备,默认使用card0
常用命令
命令 功能
controls 列出指定声卡的所有控件
contents 列出指定声卡的所有控件的具体信息
get 获取指定控件的信息
set 设定指定控件的值
举例:
获取card0的所有控件名
tinymix -D 0 controls
获取card0当前硬件音量
tinymix -D 0 get 'LINEOUT volume'
设置card0当前硬件音量
tinymix -D 0 set 'LINEOUT volume' 25
tinycap
与arecord作用类似,用于操作声卡进行录音功能
常用选项
选项 功能
-D,--device 指定声卡设备,默认使用card0
-p,--period-size 指定period大小,单位为帧
-c,--channels 指定通道数
-r,--rate 指定采样率
-b,--bits 指定采样精度
这里我们可以测试录制使用,设置录制通道数为2, 采样率为16000, 采样精度为16bit, 保存为wav文件
首先开启录制通路
tinymix -D hw:audiocodec set 'MIC1 Input Select' 0 && \
tinymix -D hw:audiocodec set 'MIC2 Input Select' 0 && \
tinymix -D hw:audiocodec set 'MIC1 Switch' 1 && \
tinymix -D hw:audiocodec set 'MIC2 Switch' 1 && \
tinymix -D hw:audiocodec set 'MIC1 gain volume' 30 && \
tinymix -D hw:audiocodec set 'MIC2 gain volume' 30
tinycap -D 0 -b 16 -r 16000 -c 2 test.wav
如果希望结束录音需要 Ctrl + C
退出。
tinyplay
与aplay作用类似,用于操作声卡设备进行播放
常用选项
选项 功能
-D,--card 指定声卡设备,默认使用card0
-p,--period-size 指定period大小,单位为帧
-c,--channels 指定通道数
-r,--rate 指定采样率
-b,--bits 指定采样精度
如果播放的是 wav 文件,可以解析头部,识别通道数,采样率等参数
播放之前先开启音频通路
tinymix set 'LINEOUT Switch' 1 && \
tinymix set 'SPK Switch' 1 && \
tinymix set 'LINEOUT volume' 31
然后播放音频
tinyplay -D 0 temp.wav
开发实战
配置开机音乐
V853 开发板默认已经启用了开机音乐,是一个自启动脚本位于:
openwrt/target/v853/v853-vision/busybox-init-base-files/etc/init.d/S03audio
脚本源码:
#!/bin/sh
#
# Start audio
#
start() {
printf "Starting audio: " # 开机启动音乐播放
if [ -d "/home/res/audio" ];then # 检查是否存在音频文件
if [ -f "/usr/bin/tinyplay" ];then # 检查是否启用了tinyalsa
tinymix set 'LINEOUT Switch' 1 # 设置各类包
tinymix set 'SPK Switch' 1
tinymix set 'LINEOUT volume' 31
tinyplay /home/res/audio/startup.wav &
else
echo "no tinyplay tool" # 没有配置tinyals,输出提示
fi
echo "Successfully play boot music"
else
echo "no /home/res/audio director" # 没有找到开机音乐,输出提示
fi
}
stop() {
printf "Stopping audio: "
if [ -d "/home/res/audio" ];then
if [ -f "/usr/bin/tinyplay" ];then
tinymix set 'LINEOUT Switch' 1
tinymix set 'SPK Switch' 1
tinymix set 'LINEOUT volume' 31
tinyplay /home/res/audio/shutdown.wav
else
echo "no tinyplay tool"
fi
echo "Successfully play shutdown music"
else
echo "no /home/res/audio director"
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
stop
start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit $?
这样,在开关机的时候就会播放响应的提示音了。同时,在logo中也会看到对应的log打印提示。