【TinyALSA全解析(一)】TinyALSA简介

/*****************************************************************************************************************/

声明: 本博客内容均由https://blog.csdn.net/weixin_47702410原创,转载or引用请注明出处,谢谢!

创作不易,如果文章对你有帮助,麻烦点赞 收藏支持~感谢

/*****************************************************************************************************************/

一、TinyALSA概述

1.1 TinyALSA背景与作用

TinyALSA是AOSP(Android Open Source Project)的一部分,它是一个与 Linux 内核中的 ALSA 交互的小型库,主要提供比ALSA Lib更小、更精简的接口,目前已经被广泛运用在嵌入式领域。

1.2 TinyALSA主要内容

TinyALSA包括两个主要的组件:

  • 一个库,提供了一组API用于直接与ALSA驱动进行交互
  • 一组工具,包括用来播放和录制音频的命令行工具

TinyALSA的主要优势在于其代码非常精简,易于阅读和理解。这使得它在资源有限的嵌入式系统中是一种理想的音频解决方案,例如Android设备会广泛使用TinyALSA。

1.3 TinyALSA与Android的关系

TinyALSA在安卓官方文档的描述:

HAL
HAL 定义了音频服务会调用且您必须实现才能使音频硬件正常运行的标准接口。如需了解详情,请参阅音频 HAL 接口并查看相应 HAL 版本目录的 *.hal 文件中的注释。

内核驱动程序
音频驱动程序用于同您的硬件和 HAL 实现进行交互。您可以使用高级 Linux 声音架构 (ALSA)、开放声音系统 (OSS) 或自定义驱动程序(HAL 与驱动程序无关)。
注意:如果您使用的是 ALSA,建议将 external/tinyalsa 用于驱动程序的用户部分,因为它具有兼容的许可(标准的用户模式库已获得 GPL 许可)。

TinyALSA在安卓系统的层次为安卓HAL层与Linux Kernel的中间交互层。TinyALSA向安卓HAL提供API接口,并操作Linux kernel 去完成硬件相关操作。

小总结:

  1. ALSA是位于Linux Kernel层面的音频系统。TinyALSA是AOSP(Android Open Source Project)的一部分。

  2. TinyALSA与ALSA的关系:TinyALSA位于Linux用户层,可以简单理解为应用程序的库。ALSA是Advanced Linux Sound Architecture的缩写,即高级Linux声音架构的简称,位于Linux Kernel层(不包括ALSA Lib)。TinyALSA跟ALSA是调用的关系,TinyALSA使用了一些系统调用(如 open(), ioctl(), mmap(), close() 等)与ALSA 进行交互

  3. TinyALSA与ALSA Lib的关系:两者都是API库,都位于用户层,但两者独立,没有直接的调用关系。ALSA Lib有更多功能(混音、重采样等),TinyALSA更精简(减少内存占用和CPU使用)。

二、TinyALSA具体有哪些内容

2.1 libtinyalsa.so 库

这个库提供了与音频硬件进行交互的功能。具体文件包括以下:

  • pcm.c和pcm.h:这些文件提供了PCM(脉冲编码调制)的操作,包括录音和播放。PCM是一种常见的数字音频格式。加载这些文件将提供类似于打开、关闭、读写PCM设备的基本功能。
  • mixer.c和mixer.h:这些文件为ALSA混音器提供支持。混音器用来控制音频设备上各个音频通道的音量和路由。加载这些文件将提供控制混音器的功能。

2.2 一组工具

这些工具包括了在命令行环境中使用TinyALSA的最基本用法。主要且常用的文件包括以下:

  • tinycap:这是个从音频设备中捕获音频的工具。它的源代码是tinycap.c。
  • tinyplay:这是个播放音频的工具。它的源代码是tinyplay.c。
  • tinymix:这是个修改混音器设置的工具。它的源代码是tinymix.c。

三、TinyALSA完整目录分析

以安卓12为例,tinyalsa的目录可见:
安卓官方代码库

其包含的文件如下:

Files and Directories

include/
Android.bp
METADATA
MODULE_LICENSE_BSD
NOTICE
OWNERS
README
mixer.c
mixer_hw.c
mixer_io.h
mixer_plugin.c
pcm.c
pcm_hw.c
pcm_io.h
pcm_plugin.c
snd_utils.c
snd_utils.h
tinycap.c
tinyplay.c
tinyhostless.c
tinymix.c
tinypcminfo.c

可以将上面的这些文件分成三个类别:

  • 核心库

    • pcm.c,pcm_hw.c:这些文件都包含了处理PCM(脉冲编码调制)音频数据的逻辑。
    • mixer.c,mixer_hw.c:这些文件都包含了处理混音器的逻辑。
  • 命令行工具

    • tinycap.c:用于从音频设备录音。
    • tinyplay.c:用于将音频播放到音频设备。
    • tinymix.c:用于修改混音器的设置。

    • 上面三个工具是常用的,注意这三个工具是可以直接用cmd进行操作的,其可以绕过Android HAL层和Android Framework层次,直接对Linux Kernel进行操作
      如果在HAL层有相关的算法存在,为了检测与HAL交互的数据,一般使用这些工具进行读取或者播放数据。
      另外一般为了解决Android APP层不能播放声音或者不能录音的问题,一般也用这些工具检测底层的驱动是否已经正确。
  • 其它

    • Android.bp:Android构建系统的配置文件
    • METADATA, MODULE_LICENSE_BSD, NOTICE, OWNERS, README:这些文件通常用于描述项目信息、版权通知、许可证信息等。
    • pcm_io.h,mixer_io.h,和 snd_utils.h 是头文件,在那些C源文件中被include。

四、TinyALSA的编译方法和使用方法

4.1 TinyALSA编译方法

以安卓系统为例,介绍一下TinyALSA全编译方法和针对某个工具进行编译的方法

区别在于全编译方法会编译整个TinyALSA,包括库和各种工具都会编译到,但是缺点也很明显,就是编译时间会比较长。

而针对某个工具的编译方法,编译时间比较短,针对性强,推荐修改了某个文件后,用这种方法,而在修改较多的情况下用TinyALSA全编译方法。

4.1.1 TinyALSA全编译方法

  • 先配置编译环境
先配置编译环境:
source build/envsetup.sh && export OUT_DIR=out && lunch xxx
或者
source ./build/envsetup.sh && lunch xxx
具体是什么命令,跟你设备的编译环境有很大关系

再使用 mmm 命令进行编译:
mmm external/tinyalsa
  • 使用ADB push文件编译产物到设备中
(如是64位系统则目录为:/system/lib64/)
adb push libtinyalsa.so /system/lib/ 
adb push tinyplay /system/bin/
adb push tinycap /system/bin/
adb push tinymix /system/bin/

4.1.2 针对某个工具进行编译

以编译tinyplay为例:

./prebuilts/build-tools/linux-x86/bin/ninja -f out/combined*.ninja tinyplay

4.2 TinyALSA使用方法

4.2.1 使用TinyALSA特别注意事项

  1. 在安卓12中,tinyplay只能播放.wav格式的音乐,tinycap录音出来的文件格式是.wav格式

  2. 如果有用到DAPM去控制电源开关,需要先使用tinymix操作相关控件后再进行tinycap or tinyplay

  3. Tip:查看音频节点的方法:cat /proc/asound/pcm

4.2.2 tinyplay使用方法

用法:tinyplay file.wav [-D card] [-d device] [-p period_size] [-n n_periods]
参数说明:
file.wav:你要播放的WAV音频文件的路径。
-D :声卡编号,它可以让你选择要使用哪个声卡进行音频播放。
-d :设备编号,它可以让你选择特定的音频设备进行音频播放。
-P : 周期,在 ALSA 系统中做音频处理(例如,播放或录制)的过程就是将数据从应用程序的缓冲区转移到硬件缓冲区(或相反),并且这个过程都是以周期为单位进行的
-n : 周期数量,定义了硬件缓冲区的大小。如果你选择了更大的周期数量,缓冲区会更大,可以存储更多的数据,这有助于防止缓冲区溢出和音频的中断。但是,更多的周期可能会带来更大的延迟,因为需要更多的时间来填满缓冲区。

通常情况下,-p和-n一般不指定,使用默认参数就可以了。
默认参数见external/tinyalsa/tinyplay.c中main函数的如下内容:
unsigned int period_size = 1024;
unsigned int period_count = 4;

举例:

如果音频节点0-0可以播放音乐,
使用音频节点“0-0”播放sdcard目录下的test.wav文件,命令如下:
tinyplay -D 0 -d 0 /sdcard/test.wav

4.2.3 tinycap的使用方法

用法:tinycap file.wav file.wav [-D card] [-d device] [-c channels] [-r rate] [-b bits] [-p period_size] [-n n_periods] [-T capture time]
参数说明:
file.wav:这是你要捕获音频数据并要保存成WAV格式的文件的路径。
-D:声卡编号,它可以让你选择要使用哪个声卡进行音频捕获。
-d:设备编号,它可以让你选择特定的音频设备进行音频捕获。
-c:声道数,它可以指定录音的声道数,通常是1(单声道)或2(立体声)。
-r:采样率,它可以指定音频的采样率,常见值包括4410048000等。
-b:位深度,这个参数可以指定每一个样本的位数,通常有162432等。
-p:周期大小,即在ALSA系统中,数据从应用程序的缓冲区转移到硬件缓冲区(或相反)的过程是以周期单位进行的。
-n:周期数量,它定义了硬件缓冲区的大小。选择较大的周期数量会有较大的缓冲区,这对于防止缓冲区溢出和音频中断是有益的,但可能会导致更大的延迟,因为需要更多的时间来填满缓冲区。
-T:捕获时间,单位是秒,它定义了你希望录音的时间长度。

通常情况下,-p、-n和-T一般不指定,使用默认参数就可以了,不需要录音的时候,ctrl+C停止录音。
默认参数见external/tinyalsa/tinycap.c中main函数的如下内容:
unsigned int card = 0;
unsigned int device = 0;
unsigned int channels = 2;
unsigned int rate = 44100;
unsigned int bits = 16;
unsigned int frames;
unsigned int period_size = 1024;
unsigned int period_count = 4;
unsigned int cap_time = 0;

举例:

如果音频节点0-1可以录音,
举例使用音频节点“0-1”录音,并保存在sdcard目录下的capture.wav文件,
录音格式为48K 16bit 2ch:
则可用如下的命令录音:
tinycap sdcard/capture.wav -D 0 -d 1 -c 2 -r 48000 -b 16 
  • 22
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
TinyAlsa是一个基于Linux ALSA(Advanced Linux Sound Architecture)的轻量级音频库,可用于在嵌入式系统上进行音频处理和播放。下面是一些使用TinyAlsa的基本步骤: 1. 安装TinyAlsa库 可以使用以下命令在Linux系统上安装TinyAlsa库: ``` sudo apt-get install libtinyalsa-dev ``` 2. 打开音频设备 使用TinyAlsa打开音频设备需要先创建一个TinyAlsa设备对象并打开设备,例如: ```c #include <tinyalsa/asoundlib.h> struct pcm_config config; struct pcm *pcm; config.channels = 2; config.rate = 44100; config.period_size = 1024; config.period_count = 2; config.format = PCM_FORMAT_S16_LE; pcm = pcm_open(0, 0, PCM_OUT, &config); if (!pcm || !pcm_is_ready(pcm)) { printf("Failed to open PCM device (%s)\n", pcm_get_error(pcm)); return -1; } ``` 上述代码中,`pcm_config`结构体用于设置音频设备的配置参数,`pcm_open()`函数用于打开一个PCM设备,其中第一个参数是设备的卡号,第二个参数是设备的设备号,第三个参数是设备的方向(输入或输出),第四个参数是设备的配置参数。 3. 写入或读取音频数据 打开音频设备后,可以使用`pcm_write()`函数将音频数据写入设备,例如: ```c void *data_buf; int data_size; // 将音频数据存储在data_buf中,data_size为数据大小 int ret = pcm_write(pcm, data_buf, data_size); if (ret != data_size) { printf("Failed to write PCM data (%s)\n", pcm_get_error(pcm)); } ``` 类似地,可以使用`pcm_read()`函数从音频设备中读取音频数据。 4. 关闭音频设备 使用完毕后,需要关闭音频设备并释放资源,例如: ```c pcm_close(pcm); ``` 上述代码中,`pcm_close()`函数用于关闭PCM设备。 以上是使用TinyAlsa的基本步骤,具体的实现方式要根据实际需求进行调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

芯心智库

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

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

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

打赏作者

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

抵扣说明:

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

余额充值