android底层对PCM节点读写操作的实现

来源:互联网 发布:c语言里n次方 编辑:程序博客网 时间:2024/06/05 08:52

实现PCM读写操作之前,首先要引入系统对PCM操作已经封装好了的头文件(asoundlib.h)和实现文件pcm.c。

参考tinyalsa 系统代码位于external/tinyalsa/中,tinycap.c和tinyplay.c是对PCM节点操作的一个很好的例子。不过tinycap是以文件的方式来存储录音数据,tinyplay是播放现有的.wav文件,而项目中是要处理实时性的音频流,需要在理解tinyalsa上对代码进行修改。操作音频数据前,要理解音频的基础参数如下:

样本长度(sample):样本是记录音频数据最基本的单位,计算机对每个通道采样量化时数字比特位数,常见的有8位和16位。
通道数(channel):该参数为1表示单声道,2则是立体声。
帧(frame):帧记录了一个声音单元,其长度为样本长度与通道数的乘积,一段音频数据就是由苦干帧组成的。
采样率(rate):每秒钟采样次数,该次数是针对帧而言,常用的采样率如8KHz的人声, 44.1KHz的mp3音乐, 96Khz的蓝光音频。
周期(period):音频设备一次处理所需要的桢数,对于音频设备的数据访问以及音频数据的存储,都是以此为单位。
交错模式(interleaved):是一种音频数据的记录方式在交错模式下,数据以连续桢的形式存放,即首先记录完桢1的左声道样本和右声道样本(假设为立体声格式),再开始桢2的记录。而在非交错模式下,首先记录的是一个周期内所有桢的左声道样本,再记录右声道样本,数据是以连续通道的方式存储。不过多数情况下,我们只需要使用交错模式就可以了。
period(周期): 硬件中中断间的间隔时间。它表示输入延时。
比特率(Bits Per Second):比特率表示每秒的比特数,比特率=采样率×通道数×样本长度

card和device两个参数可以确定具体要操作的pcm节点,相关资料可以自行搜索。


处理音频的数据是以buffer的形式写入到pcm。函数pcm_write()实现写数据和pcm_read()实现读数据。结合以上的知识参数看下实现代码:

从PCM读取数据:


其中pcm_audio_data_ind是将采集到的buffer传到项目中进行特定处理。pcm_read中size的长度可以自己随便定义,不定义使用默认长度。

往PCM写取数据:


这里注意,不同于pcm_read(),对pcm最好是分开处理。分三步:打开pcm函数open_pcm_write(),写函数play_sample(),和关闭pcm函数close_pcm_write()。因为不同于处理.wav文件的方法。项目中对流数据读的方式一般是用while循环的方法,如果所有操作放在一个函数里面,while就会不停的open和close设备,会导致流数据来不及处理。

还有,play_sample(unsigned char *record_buf,int count),里的参数count是record_buf的长度,传进来时最好是1024长度左右,太小太大会导致音频效果不好。原因不明,实践出来的。


0 0
原创粉丝点击