ALSA库

一.声音参数基本概念:

声音是连续模拟量,计算机将它离散化之后用数字表示,就有了以下几个名词术语。

样本长度(sample)样本是记录音频数据最基本的单位,计算机对每个通道采样量化时数字比特位数,常见的有8位和16位。

通道数(channel)该参数为1表示单声道,2则是立体声。

(frame)帧记录了一个声音单元,其长度为样本长度与通道数的乘积,一段音频数据就是由苦干帧组成的。

采样率(rate)每秒钟采样次数,该次数是针对帧而言,常用的采样率如8KHz的人声,44.1KHz的mp3音乐, 96Khz的蓝光音频。

周期(period)音频设备一次处理所需要的桢数,对于音频设备的数据访问以及音频数据的存储,都是以此为单位。

交错模式(interleaved)是一种音频数据的记录方式

在交错模式下,数据以连续桢的形式存放,即首先记录完桢1的左声道样本和右声道样本(假设为立体声格式),再开始桢2的记录。

而在非交错模式下,首先记录的是一个周期内所有桢的左声道样本,再记录右声道样本,数据是以连续通道的方式存储。

不过多数情况下,我们只需要使用交错模式就可以了。

period(周期):硬件中中断间的间隔时间。它表示输入延时。

比特率(Bits

Per Second):比特率表示每秒的比特数,比特率=采样率×通道数×样本长度

二.ALSA介绍

1.ALSA简介

ALSA表示高级Linux声音体系结构(Advanced Linux Sound Architecture)。ALSA是一个完全开放源代码的音频驱动程序集,除了像OSS那样提供了一组内核驱动程序模块之外,ALSA还专门为简化应用程序的编写提供了相应的函数库,与OSS提供的基于ioctl的原始编程接口相比,ALSA函数库使用起来要更加方便一些。利用该函数库,开发人员可以方便快捷的开发出自己的应用程序,细节则留给函数库内部处理。当然ALSA也提供了类似于OSS的系统接口,不过ALSA的开发者建议应用程序开发者使用音频函数库而不是驱动程序的API。

2.ALSA版本支持

Linux内核2.5在开发过程中,ALSA被合并到了官方的源码树中。在发布内核2.6后,ALSA已经内建在稳定的内核版本中并将广泛地使用。在内核设备驱动层,ALSA提供了alsa-driver,同时在应用层,ALSA为我们提供了alsa-lib,应用程序只要调用alsa-lib提供的API,即可以完成对底层音频硬件的控制。

3.ALSA基础

ALSA由许多声卡的声卡驱动程序组成,同时它也提供一个称为libasound的API库。应用程序开发者应该使用libasound而不是内核中的ALSA接口。因为libasound提供最高级并且编程方便的编程接口。并且提供一个设备逻辑命名功能,这样开发者甚至不需要知道类似设备文件这样的低层接口。

用户空间的alsa-lib对应用程序提供统一的API接口,这样可以隐藏了驱动层的实现细节,简化了应用程序的实现难度。内核空间中,alsa-soc其实是对alsa-driver的进一步封装,他针对嵌入式设备提供了一些列增强的功能。

4.ALSA体系结构:

ALSA API可以分解成以下几个主要的接口:

1控制接口:提供管理声卡注册和请求可用设备的通用功能

2 PCM接口:管理数字音频回放(playback)和录音(capture)的接口。它是开发数字音频程序最常用到的接口。

3 Raw MIDI接口:支持MIDI(Musical Instrument Digital Interface),标准的电子乐器。这些API提供对声卡上MIDI总线的访问。这个原始接口基于MIDI事件工作,由程序员负责管理协议以及时间处理。

4定时器(Timer)接口:为同步音频事件提供对声卡上时间处理硬件的访问。

5时序器(Sequencer)接口

6混音器(Mixer)接口设备命名API库使用逻辑设备名而不是设备文件。

5.伪代码

一个典型的声音程序使用PCM的程序通常类似下面的伪代码:

1.打开回放或录音接口

2.设置硬件参数(访问模式,数据格式,信道数,采样率,等等)

2.while有数据要被处理:读PCM数据(录音)或写PCM数据(回放)

3.关闭接口

三.ALSA编译安装

1.ALSA相关库下载

官方主页http://www.alsa-project.org/

主要跟编程相关是

·alsa-lib. ALSA应用库(最常用)

·ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.0.22.tar.bz2

·alsa-driver一些常见芯片的ALSA驱动代码,一般内核会集成.

·ftp://ftp.alsa-project.org/pub/driver/alsa-driver-1.0.22.1.tar.bz2

·alsa-firmware一些DSP或ASIC的专用的微码(运在芯片之上,启动时由LINUX装入到硬件中).

·ftp://ftp.alsa-project.org/pub/firmware/alsa-firmware-1.0.20.tar.bz2

·alsa-utils一般ALSA小的测试工具.如aplay/arecord播放和录音小程序.

·ftp://ftp.alsa-project.org/pub/utils/alsa-utils-1.0.22.tar.bz2

·alsa-oss用alsa接口模拟旧的oss接口.

·ftp://ftp.alsa-project.org/pub/oss-lib/alsa-oss-1.0.17.tar.bz2

其中alsa-driver,alsa-firwware是内核开发者所接触的东西,对于已经正常运行硬件,通常意味着这一部分已经整合到内核当中,无需修改.

而alsa-utils主要是测试一些小工具.

因此对于一个应用程序开发者,或者嵌入式应用开发者,接触到主要是alsa-lib编译出来的库libasound.

2.ALSA驱动测试

cat

/proc/asound/devices驱动测试

ls -l/dev/snd设备测试

aplay –h工具alsa-utils测试

3.嵌入式linuxALSA移植

·ALSA driver移植

·ALSA lib移植.

解压tar xvjf alsa-lib-1.0.22.tar.bz2

cd alsa-lib-1.0.22

生成Makefile

./configure --host=arm-linux  --prefix=$PWD/../../output/arm-linux --enable-static --enable-shared   --disable-python  --with-configdir=/usr/local/share  --with-plugindir=/usr/local/lib/alsa_lib

在这里要注意--with--configdir的选项.它将影响include/config.h中的ALSA_CONFIG_DIR目录.

它默认是你的--prefix目录.这样在嵌入式交叉编译将是一个桌面机的路径,在libasoud.so运行.会提示,如果出来这个提示,一般都是ALSA_CONFIG_DIR路径错误造成的.

ALSA  lib pcm.c:2145:(snd_pcm_open_noupdate) Unknown PCM default

aplay:  main:546: audio open error: No such file or directory

--with-plugindir也是同样道理了.它是设为ALSA_PLUGIN_DIR宏.

编译make

安装make install

开发板发布注意:

在开发板上发布alsa库.除了libasound.so库以外,必须还要把alsa.conf发布到板上--with-configdir所指向目录下的alsa目录,否则还是会报"audio open error: No such file ordirectory".

这个文件可以在make install后在你安装目录下的share找到alsa目录,把这个目录整个拷贝到开发板即可.

·ALSA utils移植

解压:tar xvjf alsa-utils-1.0.22.tar.bz2

cdalsa-utils-1.0.22

生成Makefile

./configure --host=arm-linux  --prefix=$PWD/../../output/arm-linux --enable-static  --enable-shared    --with-configdir=/usr/local/share  --with-libiconv-prefix=$PWD/../../output/arm-linux  CFLAGS="-I$PWD/../../output/arm-linux/include"  LDFLAGS="-L$PWD/../../output/arm-linux/lib -lasound -liconv"   --disable-alsamixer --disable-xmlto

注意这里LDFLAGS是必须,否则会找不到libasound.另外alsamixer是一个ncurses程序,基本上在嵌入式终端上很难移植.所以这里取消掉.--disable-xmlto也是因为找不到库.

编译make

安装make install

四.ALSA录音demo

#include

#include

#include

main (int argc, char *argv[])

{

int i;

int err;

short buf[128];

snd_pcm_t *capture_handle; // PCM设备句柄

snd_pcm_hw_params_t *hw_params;//硬件信息和PCM流配置

//1.打开PCM,最后一个参数0为标准配置

if ((err = snd_pcm_open (&capture_handle,argv[1], SND_PCM_STREAM_CAPTURE, 0)) < 0) {

fprintf (stderr, "cannot open audiodevice %s (%s)\n",

argv[1],

snd_strerror (err));

exit (1);

}

//2.分配snd_pcm_hw_params_t结构体

if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {

fprintf (stderr, "cannot allocatehardware parameter structure (%s)\n",

snd_strerror (err));

exit (1);

}

//3.初始化hw_paraws

if ((err = snd_pcm_hw_params_any (capture_handle,hw_params)) < 0) {

fprintf (stderr, "cannot initializehardware parameter structure (%s)\n",

snd_strerror (err));

exit (1);

}

//4.初始化访问权限

if ((err = snd_pcm_hw_params_set_access(capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {

fprintf (stderr, "cannot set accesstype (%s)\n",

snd_strerror (err));

exit (1);

}

//5.初始化采样格式SND_PCM_FORMAT_U8,16位

if ((err = snd_pcm_hw_params_set_format(capture_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {

fprintf (stderr, "cannot set sampleformat (%s)\n",

snd_strerror (err));

exit (1);

}

1.//6.设置采样率,如果硬件不支持我们设置的采样率,将使用最接近的

2.//val = 44100,有些录音采样频率固定为8KHz

if ((err = snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, 44100, 0)) < 0) {

fprintf (stderr, "cannot set samplerate (%s)\n",

snd_strerror (err));

exit (1);

}

//7.设置通道数量

if ((err = snd_pcm_hw_params_set_channels(capture_handle, hw_params, 2)) < 0) {

fprintf (stderr, "cannot set channelcount (%s)\n",

snd_strerror (err));

exit (1);

}

//8.设置hw_params

if ((err = snd_pcm_hw_params (capture_handle,hw_params)) < 0) {

fprintf (stderr, "cannot setparameters (%s)\n",

snd_strerror (err));

exit (1);

}

snd_pcm_hw_params_free (hw_params);

if ((err = snd_pcm_prepare (capture_handle)) <0) {

fprintf (stderr, "cannot prepareaudio interface for use (%s)\n",

snd_strerror (err));

exit (1);

}

//读取数据

for (i = 0; i < 10; ++i) {

if ((err = snd_pcm_readi (capture_handle,buf, 128)) != 128) {

fprintf (stderr, "read fromaudio interface failed (%s)\n",

snd_strerror (err));

exit (1);

}

}

//10.关闭PCM设备句柄

snd_pcm_close (capture_handle);

exit (0);

}

Alsa编译安装:http://blog.csdn.net/liu_chunhai/article/details/6582090

http://blog.csdn.net/shui1025701856/article/details/7646197

http://www.cnblogs.com/cslunatic/p/3677729.html

http://blog.csdn.net/zd394071264/article/details/8300045

http://blog.csdn.net/ropenyuan/article/details/9344299

slsa编译

http://blog.chinaunix.net/uid-23065002-id-3884658.html

https://www.oschina.net/news/72059/alsa-lib-1-1-1

http://www.360doc.com/content/11/0613/13/168576_126609790.shtml

你可能感兴趣的:(ALSA库)