【音频应用】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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tVm5tcyU-1682084270719)(image/Linux之ALSA声卡应用驱动/1681615020116.png)]

​ alsa-libs 为一套 Linux 应用层的 C 语言函数库, 为音频应用程序开发提供了一套统一、标准
的接口,应用程序只需调用这一套 API 即可完成对底层声卡设备的操控 。

二、alsa-libs移植

首先需要在ALSA的官网上下载官网http://www.alsa-project.org下载alsa-lib和alsa-utils。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K9o1Fqhz-1682084270721)(image/Linux之ALSA声卡应用驱动/1681615443264.png)]

具体步骤参考:

alsa-lib和alsa-utils移植_移植alsa-utils库_风雨兼程8023的博客-CSDN博客

三、ALSA设备文件结构

/dev/snd

在 Linux 内核设备驱动层、基于 ALSA 音频驱动框架注册的 sound 设备会在/dev/snd 目录下生成相应的
设备节点文件 。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BWnihaaV-1682084270721)(image/Linux之ALSA声卡应用驱动/1681616247600.png)]

我们可以看到以下设备文件:

  • 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中,定义了以下设备类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bQ2NTLKT-1682084270722)(image/Linux之ALSA声卡应用驱动/1681616672104.png)]

通常,我们更关心的是pcm和control这两种设备。

/proc/asound

在 Linux 系统的/proc/asound 目录下,有很多的文件,这些文件记录了系统中声卡相关的信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zP8ZdmXX-1682084270723)(image/Linux之ALSA声卡应用驱动/1681617091453.png)]

  • 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文件越大

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HplWZx9E-1682084270724)(image/Linux之ALSA声卡应用驱动/1682049469753.png)]

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)

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Linux ALSA-Lib库是用于读取和处理音频的开源库。它提供了一套API,可以让开发者通过 C/C++ 编程语言访问 Linux 系统中的音频设备。 ALSA-Lib 可以实现多种音频设备的读写,包括内置音频硬件,外部 USB 音频设备以及蓝牙音频ALSA-Lib 提供了一个叫做alsa-lib.h的头文件,这个头文件包含了常用的 ALSA-Lib API 函数。开发者可以根据具体需求来选择合适的函数,最常用的是snd_pcm_open()、snd_pcm_hw_params_set_xxx()、snd_pcm_writei()和snd_pcm_close(),这些函数分别用于打开、设置参数、写数据和关闭音频设备。 ALSA-Lib 提供的多种API函数使得开发者可以对音频进行多种高级操作。比如,开发者可以通过snd_pcm_drop()中止当前播放操作,通过snd_pcm_pause()暂停播放,通过snd_pcm_prepare()准备播放,还可以通过调用snd_pcm_avail_update()获取当前音频设备的缓冲区状态。 读取音频数据可以通过snd_pcm_readi()函数实现,这个函数会一次性从设备中读取指定数量的音频采样,并将其存储在一个指定的缓冲区中。开发者还可以选择使用snd_pcm_mmap_readi()和snd_pcm_mmap_begin()来读取音频采样,这两个函数可以实现更高效的读取。 在开发 Linux 音频应用程序时,ALSA-Lib 是非常重要的组件。通过掌握 ALSA-Lib 的 API 函数,开发者可以实现快速、高效地读取和处理音频数据。因此,熟悉 ALSA-Lib 是 Linux 音频开发工程师的必备技能之一。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ssq不是上上签

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值