ALSA库

作者: cs1001 | 来源:发表于2017-06-19 19:23 被阅读0次

    一.声音参数基本概念:

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

    样本长度(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库

          本文链接:https://www.haomeiwen.com/subject/tlrnqxtx.html