Android Tinyalsa

tinyalsa位于Android源码的external/tinyalsa位置。

关于tinyalsa,tinyalsa是Google在Android 4.0之后推的基于alsa内核的用户层音频接口。在Android 4.0之前还一直是使用这alsa-lib接口。Google之所以推出tinyalsa,我认为有可能是因为alsa使用了GPL许可证的缘故,也有可能是因为alsa-lib的库过于复杂繁琐大部分功能在Android平台没有实际实用意义却依然占用屈指可数的内存空间。

关于alsa在Android中,在Android 4.0及之后只要你愿意还是可以使用原版alsa的,因为内核中依然是使用alsa的驱动,只需要把alsa的用户层接口alsa-lib移植到源码中即可。

tinyalsa中主要的头文件和数据结构如下,通过ioctrl和内核的alsa驱动交互。

pcm设备,通过阅读tinyalsa的代码和查看Android下的音频设备节点,可知在Android中一个pcm设备最多可有一个mixer设备"/dev/snd/controlC%u"(一般是controlC0)和32个/dev/snd/pcmC%uD%uc(一般是pcmC0D0c)、/dev/snd/pcmC%uD%u%p(一般是pcmC0D0p),pcm设备中的C代表card,D代表device,c代表capture,p代表playback。当我们新增一个pcm声卡C的值会+1,D还是从0开始,可能只有c(pcmC1D0c
例如麦克风),可能只有p(pcmC1D0p 例如音响),可能同时存在c和p(pcmC1D0c  pcmC1D0p )。

tinyalsa的对外提供的头文件就我上图提到的一个"asoundlib.h",提供最基础的pcm和mixer操作。实现文件为pcm.c(实现pcm api)和mixer.c(实现mixer api)。根据asoundlib.h编写了四个小工具tinypcminfo
tinyplay tinycap tinymix,这四个小工具作为系统命令存放在系统中,可以很方便的使用。tinyasla作为精简版的alsa-lib可能会有人想把它移植到Linux使用,tinyasla依赖的库有libcutils && libutils,如果能把依赖的这两个库的一些方法使用Linux接口实现那么剩下的问题应该不大了吧,这个仅仅是我的猜想。

tinypcminfo的实现文件tinypcminfo.c (查看pcm设备能力)

tinyplay的实现文件tinyplay.c(使用pcm设备播放wav格式的音频文件)

tinycap的实现文件tinycap.c(使用pcm设备采集pcm格式的码流,并保存为wav格式的文件)

tinymix的实现文件tinymix.c(对pcm设备的控制,包括音量调节、设备切换)

这几个命令使用时可以先使用tinypcminfo查看pcm设备的能力,要不当我们使用其他三个命令时使用了不合理的配置会出现parameter invalid的错误。

PCM API


/* 对pcm设备节点的操作 */

struct pcm *pcm_open(unsigned int card, unsigned int device, unsigned int flags, struct pcm_config *config);

int pcm_close(struct pcm *pcm);

int pcm_is_ready(struct pcm *pcm);

 

/* 获取pcm设备的能力 */

struct pcm_params *pcm_params_get(unsigned int card, unsigned int device, unsigned int flags);

void pcm_params_free(struct pcm_params *pcm_params);

unsigned int pcm_params_get_min(struct pcm_params *pcm_params, enum pcm_param param);

unsigned int pcm_params_get_max(struct pcm_params *pcm_params, enum pcm_param param);

 

/* 配置pcm设备capture和playback的规格 */

int pcm_get_config(struct pcm *pcm, struct pcm_config *config);

int pcm_set_config(struct pcm *pcm, struct pcm_config *config);

 

/* 返回调用tinyalsa最后的错误信息 */

const char *pcm_get_error(struct pcm *pcm);

 

/* 设置pcm设备采集和播放的位数,位数越高越接近真实声音 */

unsigned int pcm_format_to_bits(enum pcm_format format);

 

/* pcm设备的内置缓冲之间大小、帧数、时间的转换 */

unsigned int pcm_get_buffer_size(struct pcm *pcm);

unsigned int pcm_frames_to_bytes(struct pcm *pcm, unsigned int frames);

unsigned int pcm_bytes_to_frames(struct pcm *pcm, unsigned int bytes);

unsigned int pcm_get_latency(struct pcm *pcm); // in ms

 

/* 返回下一帧的有效帧指针和该帧时间戳,时间戳有CLOCK_MONOTONIC和CLOCK_REALTIME可选,里面使用的是CLOCK_REALTIME */

/* 我认为应该需要两个时间戳,一个用于播放的时间戳(CLOCK_MONOTONIC)不受系统时间的影响,一个用于记录当前音频采集的时间戳(CLOCK_REALTIME) */

int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail, struct timespec *tstamp);

 

/* 通过FIFO把数据写入硬件用于playback或者从硬件中读取capture数据 */

int pcm_write(struct pcm *pcm, const void *data, unsigned int count);

int pcm_read(struct pcm *pcm, void *data, unsigned int count);

 

/* 这是一个可选的和hardware通信的方式。 */

int pcm_mmap_write(struct pcm *pcm, const void *data, unsigned int count);

int pcm_mmap_read(struct pcm *pcm, void *data, unsigned int count);

int pcm_mmap_begin(struct pcm *pcm, void **areas, unsigned int *offset, unsigned int *frames);

int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames);

int pcm_start(struct pcm *pcm);

int pcm_stop(struct pcm *pcm);

int pcm_wait(struct pcm *pcm, int timeout);

int pcm_set_avail_min(struct pcm *pcm, int avail_min);

对于pcm设备的操作只需要注意所操作的设备是否存在,以及设备的能力问题不要设置设备所不能及的能力设备就可以正常工作了,其实就是需要注意channels、rate、format、period_size和period_count。

MIXER API


/* 对mixer设备的操作 */

struct mixer *mixer_open(unsigned int card);

void mixer_close(struct mixer *mixer);

 

/* 获取mixer设备信息name */

const char *mixer_get_name(struct mixer *mixer);

 

/* 获取mixer设备的控制句柄 struct mixer_ctl */

unsigned int mixer_get_num_ctls(struct mixer *mixer);

struct mixer_ctl *mixer_get_ctl(struct mixer *mixer, unsigned int id);

struct mixer_ctl *mixer_get_ctl_by_name(struct mixer *mixer, const char *name);

 

/* 取mixer设备的控制信息 */

const char *mixer_ctl_get_name(struct mixer_ctl *ctl);

enum mixer_ctl_type mixer_ctl_get_type(struct mixer_ctl *ctl);

const char *mixer_ctl_get_type_string(struct mixer_ctl *ctl);

unsigned int mixer_ctl_get_num_values(struct mixer_ctl *ctl);

unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl);

const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl, unsigned int enum_id);

 

/* Some sound cards update their controls due to external events,

 * such as HDMI EDID byte data changing when an HDMI cable is

 * connected. This API allows the count of elements to be updated.

 */

void mixer_ctl_update(struct mixer_ctl *ctl);

 

/* 设置和获取可控制的信息,方式有比例、数组、范围、固定值 */

/* id通过mixer_get_num_ctls获得 */

int mixer_ctl_get_percent(struct mixer_ctl *ctl, unsigned int id);

int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent);

 

int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id);

int mixer_ctl_get_array(struct mixer_ctl *ctl, void *array, size_t count);

int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value);

int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count);

int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string);

 

int mixer_ctl_get_range_min(struct mixer_ctl *ctl);

int mixer_ctl_get_range_max(struct mixer_ctl *ctl);

扩展:

1. 什么是pcm

http://en.wikipedia.org/wiki/Pulse-code_modulation

2. 音频采样

http://baike.baidu.com/link?url=b9CLvaPgU4A0e0X3y5cLU4ADOI0eBuUeCys05m5unE7G-0eR2sQMBVhNxkCEvOf-Ot2CLAw2wWX5ZLhqi3D2t_#1

时间: 2024-10-05 05:57:38

Android Tinyalsa的相关文章

Android音频底层调试-基于tinyalsa

由于Android中默认并没有使用标准alsa,而是使用的是tinyalsa,所以就算基于命令行的测试也要使用libtinyalsa.Android系统在上层Audio千变万化的时候,可以能这些个工具实时查看到,比如音频通道的切换等等. 1.编译tinyalsa配套工具 $ mmm external/tinyalsa/ 编译完后会产生tinyplay/tinymix/tinycap等等工具. tinymix: 查看配置混音器 tinyplay: 播放音频 tinycap: 录音 2.查看当前系统

Android平台上的Aplay与TinyAlsa移植使用

ALSA是高级Linux声音架构.提供了一系列音频的逻辑接口,包括PCM.CONTROL等.这些,不影响它的使用,了解一下就可以. 在Android设备上,2.x的版本,要控制录制播放音频,要使用alsa-lib和alsa-utils编译出aplay播放器.使用你的交叉编译工具,经过一系列编译后移植使用. 而在3.x的版本往后,已经使用TinyAlsa来替代这些了.tinyalsa的使用,与aplay相比,大大降低了编译和使用难度. 过程今天记录了,明天更. TODO:aplay交叉编译过程&t

[转]Android音频底层调试-基于tinyalsa

http://blog.csdn.net/kangear/article/details/38139669 [-] 编译tinyalsa配套工具 查看当前系统的声卡 tinymix查看混响器 使用tinyplay播放wav音乐 tinycap使用 由于Android中默认并没有使用标准alsa,而是使用的是tinyalsa,所以就算基于命令行的测试也要使用libtinyalsa.Android系统在上层Audio千变万化的时候,可以能这些个工具实时查看到,比如音频通道的切换等等. 1.编译tin

linux中的alsa工具与Android中的tinyalsa工具【转】

本文转载自:http://blog.csdn.net/luckywang1103/article/details/48053015 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 由于Android中默认并没有使用标准alsa,而是使用的是tinyalsa,所以就算基于命令行的测试也要使用libtinyalsa.Android系统在上层Audio千变万化的时候,可以能这些个工具实时查看到,比如音频通道的切换等等. 1.编译tinyalsa配套工具 $ mmm extern

Android底层开发之Audio HAL

http://blog.csdn.net/kangear/article/details/44939429 Android底层开发之Audio HAL 在Android音频底层调试-基于tinyalsa中以「抛开Android的天生复杂,回归嵌入式Linux的本质」的方式介绍如何调试Linux内核中的音频驱动. 这里向上再伸展一下进入HAL层,看是如何将tinyalsa封装给Frameworks使用的. 基于4.2.2版本源码进行讨论.Android官方教程是Audio Implementing

Android音频系统之音频框架

http://blog.csdn.net/xuesen_lin/article/details/8796492 我们可以结合目前已有的知识,想一下每一个层次都会包含哪些模块(先不考虑蓝牙音频部分)? ·        APP 这是整个音频体系的最上层,因而并不是Android系统实现的重点.比如厂商根据特定需求自己写的一个音乐播放器,游戏中使用到声音,或者调节音频的一类软件等等. ·        Framework 相信大家可以马上想到MediaPlayer和MediaRecorder,因为这

Android 4.4 Kitkat 音频实现及简要分析

在 Android 4.4 上实现录放音 背景 Android 自 ICS 开始,音频系统就有了很大的变化,先是抛弃了 alsalib,然后是采用了 AIO,各级框架上,都有了自己的特色,与 Linux 的音频应用渐行渐远,形成了自己独特的音频管理和音频配置功能.总的来说改进还是非常大,至少在用户体验上已经大大的超越了之前的版本.我们就从 4.4 的音频实现上来分析其中的一些变化和实现机制. 要求 首先是硬件功能正常,这个不表. Linux 支持 alsa 驱动,生成 alsa 子系统,最好是能

Android音频系统之音频框架(转http://blog.csdn.net/uiop78uiop78/article/details/8796492)

1.1 音频框架 转载请注明,From LXS, http://blog.csdn.net/uiop78uiop78/article/details/8796492 Android的音频系统在很长一段时间内都是外界诟病的焦点.的确,早期的Android系统在音频处理上相比于IOS有一定的差距,这也是很多专业的 音乐播放软件开发商没有推出Android平台产品的一个重要原因.但这并不代表它的音频框架一无是处,相反,基于Linux系统的Android平台有 很多值得我们学习的地方. 1.1.1 Li

Android repo 学习参考

/*************************************************************************** * Android repo 学习参考 * 说明: * 首先是由于源代码拷贝的问题,将原来的repo源码丢失了,顺便看一下作为使用 * 者,对repo需要掌握到哪些东西. * * 2017-2-6 深圳 南山平山村 曾剑锋 *************************************************************