Linux音频编程(一)ALSA介绍
Linux下的音频编程中有OSS和ALSA,本篇文章将对ALSA进行相关介绍。ALSA提供一系列基于命令行的工具集,比如混音器(mixer),音频文件播放器(aplay),以及控制特定声卡特定属性的工具。 一、ALSA的?API主要分为以下几种接口: (Pulse Code Modulation(脉冲编码调制)。这个词描述了一种用数字化形式表示模拟信号的方法。这种方法几乎被所有的计算机音卡所使用,它在ALSA?API中用“audio”来简称。) 二、 1、pcm用来描述alsa中数字音频流。Alsa音频的播放/录制可通过pcm来实现的。 2、在内核设备驱动层,ALSA提供了alsa-driver,同时在应用层,ALSA为我们提供了alsa-lib,应用程序只要调用alsa-lib提供的API,即可以完成对底层音频硬件的控制。 3、alsa驱动实际上可分为两层,比如s3c24xx-iis.c或s3c24xx-ac97.c之类,主要是音频总线与硬件初始化(iis/ac97,GPIO,dma等),另一层才是wm8987.c之类的芯片驱动,主要是提供寄存器读写接口(i2c等),创建mixer设备之类。 三、PCM介绍 (一)简单介绍 1、根据ALSA写一简单的PCM应用程序,我们首先需要为PCM设备打开一个句柄(Handle),然后指定PCM流的方向是playback。 2、pcm下面有一个playback和capture stream,playback和capture下面各自有一个substream。 (1)playback如何把用户空间的应用程序发过来的PCM数据,转化为人耳可以辨别的模拟音频。 (2)capture把mic拾取到得模拟信号,经过采样、量化,转换为PCM信号送回给用户空间的应用程序。 (二)相关程序 (1)此部分程序可以参考: 可参考链接:https://blog.csdn.net/orz415678659/article/details/8995163。 ? 其中: snd_card 表示一个声卡实例,包含多个声卡设备; snd_device 表示一个声卡设备部件: snd_pcm 表示一个PCM设备,声卡设备的一种,用于播放和录音 ; snd_control 表示Control设备,用于控制声卡; snd_pcm_str 表示PCM流,分为playback和capture; snd_pcm_substream PCM子流,用于音频的播放或录制 ; snd_pcm_ops PCM流操作集。 具体可参考链接: https://www.cnblogs.com/hzl6255/p/9979377.html (2)对于pcm.c程序可参考以下链接: https://github.com/tinyalsa/tinyalsa/blob/master/src/pcm.c 1、合理的pcm_config可以做到更好的低时延和功耗。 struct pcm_config { unsigned int channels; unsigned int rate; unsigned int period_size; unsigned int period_count; enum pcm_format format; unsigned int start_threshold; unsigned int stop_threshold; unsigned int silence_threshold; int avail_min; }; (1)结构中的每个参数的单位都是frame(1帧 = 通道*采样位深): period_size. 每次传输的数据长度。值越小,时延越小,cpu占用就越高。 (2)period_count. 缓之冲区period的个数。缓冲区越大,发生XRUN的机会就越少。 (3)format. 定义数据格式,如采样位深,大小端。 (4)start_threshold. 缓冲区的数据超过该值时,硬件开始启动数据传输。如果太大, 从开始播放到声音出来时延太长,甚至可导致太短促的声音根本播不出来;如果太小, 又可能容易导致XRUN. (5)stop_threshold. 缓冲区空闲区大于该值时,硬件停止传输。默认情况下,这个数 为整个缓冲区的大小,即整个缓冲区空了,就停止传输。但偶尔的原因导致缓冲区空, 如CPU忙,增大该值,继续播放缓冲区的历史数据,而不关闭再启动硬件传输(一般此 时有明显的声音卡顿),可以达到更好的体验。 (6)silence_threshold. 这个值本来是配合stop_threshold使用,往缓冲区填充静音 数据,这样就不会重播历史数据了。但如果没有设定silence_size, (7)avail_min. 缓冲区空闲区大于该值时,pcm_mmap_write()才往缓冲写数据。这个 值越大,往缓冲区写入数据的次数就越少,面临XRUN的机会就越大。Android samsung tuna 设备在screen_off时增大该值以减小功耗,在screen_on时减小该 值以减小XRUN的机会。 在不同的场景下,合理的参数就是在性能、时延、功耗等之间达到较好的平衡。 (8)struct pcm pcm_open(unsigned int card,unsigned int device,unsinged int flags,struct pcm_config config)。 2、从pcm_open这个接口可以看到,它通过几个参数获得了一个句柄,之后所有的操作都通过这个句柄来完成。这些参数里面,card代表第几块声卡,device就是上面提到的device index,它跟驱动中配置的DAI link的次序有关,flags参数中会指明这个设备是capture类型还是playback类型。通过这3个参数,就可以找到对应的PCM设备文件。 3、一个pcm设备包含播 放/录制两个流,每个流有若干个substream.一个substream只能被一个进程占用。其中snd_pcm_substream可实现音频的播放或录制。如下:? struct snd_pcm_substream {? ? 四、补充: alsa驱动的设备文件可在Linux系统中的/dev/snd?里查看。 其中:C0D0代表的是声卡0中的设备0,pcmC0D0c最后一个c代表capture,pcmC0D0p最后一个p代表playback。 controlC0:用于声卡的控制,例如通道选择,混音,麦克风的控制等; midiC0D0:用于播放midi音频; pcmC0D0c :?用于录音的pcm设备; pcmC0D0p :用于播放的pcm设备; seq?:音序器; timer :定时器; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |