【音频应用】Linux之ALSA音频应用编程
使用alsa-libs和alsa-utils实现.wav格式文件的播放与录制,了解Linux中声卡的应用层设备节点。介绍了使用alsa-libs应用编程步骤。
Linux之ALSA音频应用编程
上文: 【音频驱动】Linux之ALSA声卡、WAV文件相关概念
Linux之ALSA音频应用编程
使用alsa-libs和alsa-utils实现.wav格式文件的播放与录制,了解Linux中声卡的应用层设备节点。介绍了使用alsa-libs应用编程步骤。
一、ALSA架构
高级Linux声音体系结构(ALSA)为Linux操作系统提供音频和MIDI功能。
ALSA具有以下显著特征:
-
高效支持所有类型的音频接口,从消费类声卡到专业多通道音频接口。
-
完全模块化的声音驱动程序。
-
SMP和线程安全设计。
-
用户空间库(alsa-lib),以简化应用程序编程并提供高级功能。
-
支持旧的开放声音系统(OSS) API,为大多数OSS程序提供二进制兼容性。
ALSA系统包括7个子项目:
-
驱动包alsa-driver
-
开发包alsa-libs
-
开发包插件alsa-libplugins
-
设置管理工具包alsa-utils
-
OSS接口兼容模拟层工具alsa-oss
-
特殊音频固件支持包alsa-finnware
-
其他声音相关处理小程序包alsa-tools
alsa-libs 为一套 Linux 应用层的 C 语言函数库, 为音频应用程序开发提供了一套统一、标准
的接口,应用程序只需调用这一套 API 即可完成对底层声卡设备的操控 。
二、alsa-libs移植
首先需要在ALSA的官网上下载官网http://www.alsa-project.org下载alsa-lib和alsa-utils。
具体步骤参考:
alsa-lib和alsa-utils移植_移植alsa-utils库_风雨兼程8023的博客-CSDN博客
三、ALSA设备文件结构
/dev/snd
在 Linux 内核设备驱动层、基于 ALSA 音频驱动框架注册的 sound 设备会在/dev/snd 目录下生成相应的
设备节点文件 。
我们可以看到以下设备文件:
- controlC0 :用于声卡的控制,例如通道选择,混音,麦克风的控制等
- midiC0D0 :用于播放midi音频
- pcmC0D0c :用于录音的pcm设备
- pcmC0D0p :用于播放的pcm设备
- pcmC0D1p :用于播放的pcm设备
- seq :音序器
- timer :定时器
C0D0代表的是声卡0中的设备0, pcmC0D0c最后一个c代表capture, pcmC0D0p最后一个p代表
playback,这些都是alsa-driver中的命名规则。 从上面的列表可以看出,我的声卡下挂了7个设备,根据声卡的实际能力,驱动实际上可以挂上更多种类的设备,在include/sound/core.h中,定义了以下设备类型
通常,我们更关心的是pcm和control这两种设备。
/proc/asound
在 Linux 系统的/proc/asound 目录下,有很多的文件,这些文件记录了系统中声卡相关的信息
-
cards : 查看 cards 文件的内容,可列出系统中可用的、注册的声卡
-
devices : 列出系统中所有声卡注册的设备,
-
pcm : 列出系统中的所有 PCM 设备
-
timers : 定时器设备选型
-
version : ALSA驱动版本
-
card0 :记录了声卡 0 相关的信息,譬如声卡的名字以及声卡注册的 PCM 设备
四、alsa-utils的测试工具
alsa-utils的测试工具
-
aplay
-
arecord
-
alsamixer
-
amixer
-
alsactl
-
alsaloop
aplay
aplay 是一个用于测试音频播放功能程序,可以使用 aplay 播放 wav 格式的音频文件。
常用命令:
aplay xxx.wav
arecord
arecord 工具是一个用于录音测试的应用程序
常用命令:
arecord -r 20000 -f S16_LE -c 1 -d 10 -D hw:0,1 6.wav
-r 表示采样频率(最小为8000);
-f 表示采样格式,这里指 16 bit little endian(一般为S16_LE、S32_LE);
-c 表示通道数量(1或2);
-d 表示录音时间;
-D 表示使用哪个录音设备(hw:0,1:hw插件,第一个参数表示声卡号,第二个参数表示设备号);
采样频率越高,声音越清晰,.wav文件越大
alsaloop
alsaloop用于回环测试,边录音边播放。
常用命令:
alsaloop -C hw:0,1 -t 100
五、编写ALSA应用程序
基于alsa-lib编写
API和例子参考官网 ALSA project - the C library reference: Index, Preamble and License (alsa-project.org)
1、打开PCM设备
int snd_pcm_open(snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode)
2、设置硬件参数
实例化 snd_pcm_hw_params_t 对象
int snd_pcm_hw_params_malloc(snd_pcm_hw_params_t **ptr);
初始化 snd_pcm_hw_params_t 对象
int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
设置 access 访问类型
int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t _access);
设置数据格式
int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val);
设置声道数
int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
设置采样率大小
int snd_pcm_hw_params_set_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
设置周期大小
int snd_pcm_hw_params_set_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir);
设置 buffer 大小
int snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val);
或
int snd_pcm_hw_params_set_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,unsigned int val,int dir)
安装/加载硬件配置参数
int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
3、读/写数据
snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
4、释放资源
int snd_pcm_close(snd_pcm_t *pcm);
void snd_pcm_hw_params_free(snd_pcm_hw_params_t *obj)
5、异步接口
int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm,
snd_async_callback_t callback, void *private_data);
int snd_pcm_poll_descriptors(snd_pcm_t *pcm,struct pollfd *pfds,unsigned int space);
参考资料
正点原子文档
ALSA project - the C library reference: Index, Preamble and License (alsa-project.org)
更多推荐
所有评论(0)