音频PCM数据的采集和播放
2021-09-26 09:00 dreamboy2000 阅读(1190) 评论(0) 编辑 收藏 举报在 Android 平台使用 AudioRecord 和 AudioTrack API 完成音频 PCM 数据的采集和播放,并实现读写音频 wav 文件。
音频基础知识
声道数(通道数)
即声音的通道的数目。很好理解,有单声道和立体声之分,单声道的声音只能使用一个喇叭发声(有的也处理成两个喇叭输出同一个声道的声音),立体声的PCM可以使两个喇叭都发声(一般左右声道有分工) ,更能感受到空间效果。
采样位数
即 采样值或取样值(就是将采样样本幅度量化)。它是用来衡量声音波动变化的一个参数,也可以说是声卡的分辨率。它的数值越大,分辨率也就越高,所发出声音的能力越强。
在计算机中采样位数一般有8位和16位之分,但有一点请大家注意,8位不是说把纵坐标分成8份,而是分成2的8次方即256份; 同理16位是把纵坐标分成2的16次方65536份。
采样频率
即取样频率,指 每秒钟取得声音样本的次数。采样频率越高,声音的质量也就越好,声音的还原也就越真实,但同时它占的资源比较多。由于人耳的分辨率很有限,太高的频率并不能分辨出来。在16位声卡中有22KHz、44KHz等几级,其中,22KHz相当于普通FM广播的音质,44KHz已相当于CD音质了,目前的常用采样频率都不超过48KHz。
既然知道了以上三个概念,就可以由下边的公式得出PCM文件所占容量:
存储量= (采样频率 * 采样位数 * 声道 * 时间)/8 (单位:字节数)。
PCM 介绍
目前我们在计算机上进行音频播放都需要依赖于音频文件,音频文件的生成过程是将声音信息采样、量化和编码产生的数字信号的过程,人耳所能听到的声音,最低的频率是从20Hz起一直到最高频率20KHZ,因此音频文件格式的最大带宽是20KHZ。根据奈奎斯特的理论,只有采样频率高于声音信号最高频率的两倍时,才能把数字信号表示的声音还原成为原来的声音,所以音频文件的采样率一般在40~50KHZ,比如最常见的CD音质采样率44.1KHZ。
对声音进行采样、量化过程被称为脉冲编码调制(Pulse Code Modulation),简称PCM。PCM数据是最原始的音频数据完全无损,所以PCM数据虽然音质优秀但体积庞大,为了解决这个问题先后诞生了一系列的音频格式,这些音频格式运用不同的方法对音频数据进行压缩,其中有无损压缩(ALAC、APE、FLAC)和有损压缩(MP3、AAC、OGG、WMA)两种。
WAV
Waveform Audio File Format(WAVE,又或者是因为扩展名而被大众所知的WAV),是微软与IBM公司所开发在个人电脑存储音频流的编码格式,在Windows平台的应用软件受到广泛的支持,地位上类似于麦金塔电脑里的AIFF。 此格式属于资源交换档案格式(RIFF)的应用之一,通常会将采用脉冲编码调制的音频资存储在区块中。也是其音乐发烧友中常用的指定规格之一。由于此音频格式未经过压缩,所以在音质方面不会出现失真的情况,但档案的体积因而在众多音频格式中较为大。
所有的WAV都有一个文件头,这个文件头音频流的编码参数。WAV对音频流的编码没有硬性规定,除了PCM之外,还有几乎所有支持ACM规范的编码都可以为WAV的音频流进行编码。WAV也可以使用多种音频编码来压缩其音频流,不过我们常见的都是音频流被PCM编码处理的WAV,但这不表示WAV只能使用PCM编码,MP3编码同样也可以运用在WAV中,和AVI一样,只要安装好了相应的Decode,就可以欣赏这些WAV了。
在Windows平台下,基于PCM编码的WAV是被支持得最好的音频格式,所有音频软件都能完美支持,由于本身可以达到较高的音质的要求,因此,WAV也是音乐编辑创作的首选格式,适合保存音乐素材。因此,基于PCM编码的WAV被作为了一种中介的格式,常常使用在其他编码的相互转换之中,例如MP3转换成WMA。
wav文件格式
在文件的前44字节放置标头(header),使播放器或编辑器能够简单掌握文件的基本信息,其内容以区块(chunk)为最小单位,每一区块长度为4字节。
起始位址 | 区块名称 | 区块大小 | 端序 | 区块内容 | 备注 |
---|---|---|---|---|---|
0 | 区块编号 | 4 | 大 | “RIFF” | |
4 | 总区块大小 | 4 | 小 | = N+36 | N:音频数据的总字节数;36:从下一个地址开始到头文件尾的总字节数 |
8 | 档案格式 | 4 | 大 | “WAVE” | |
12 | 子区块1标识 | 4 | 大 | “fmt ” (最后有一个空格) | |
16 | 子区块1大小 | 4 | 小 | 16 | |
20 | 音频格式 | 2 | 小 | 1(PCM) | |
22 | 声道数量 | 2 | 小 | 1(单声道)2(立体声) | |
24 | 取样频率(采用频率) | 4 | 小 | 取样点/秒(Hz) | |
28 | 位元(组)率 | 4 | 小 | = 取样频率 * 位元深度 / 8 | Byte率 = 采样频率 音频通道数 每次采样得到的样本位数 / 8 |
32 | 区块对齐 | 2 | 小 | 4 | |
36 | 子区块2标识 | 4 | 大 | “data” | |
40 | 子区块2大小 | 4 | 小 | N(=位元(组) 秒数 声道数量) | 音频数据的大小 |
44 | 音频数据 | =N | 小 | <音频数据从此开始> |
代码实现
1
|
// 音频数据的大小
|
使用AudioRecord
录制pcm音频
1
|
/**
|
PCM转WAV
只要加上wav头文件即可。
使用AudioTrack
播放pcm音频
AudioTrack 类为java程序实现了控制和播放简单的音频。它允许将 PCM音频流传输到音频接收器进行播放。这是通过将音频数据推给 AudioTrack对象实现的,可以使用
write(byte[], int, int)
,write(short[], int, int)
或write(float[], int, int, int)
方法。AudioTrack可以在两种模式下运行:static 或 streaming。
在Streaming模式下,应用程序使用其中一种write()方法将连续的数据流写入AudioTrack 。当数据从Java层传输到native层并排队等待播放时,它们会阻塞并返回。在播放音频数据块时,流模式非常有用,例如:
- 由于声音播放的持续时间太长而不能装入内存,
- 由于音频数据的特性(高采样率,每个样本的位数……)而不能装入内存
- 在先前排队的音频正在播放时接收或生成。
在处理能够装入内存的短音时,应选择静态模式,并且需要尽可能以最小的延迟播放。因此,对于经常播放的UI和游戏声音而言,静态模式将是优选的,并且可能具有最小的开销。
一旦创建,AudioTrack对象将初始化其关联的音频缓冲区。在构建过程中指定的这个缓冲区的大小决定了AudioTrack在耗尽数据之前可以播放多长时间。
对于使用静态模式的AudioTrack,此大小是可以从中播放的最大声音大小。
对于流模式,数据将以小于或等于总缓冲区大小的块形式写入音频接收器。AudioTrack不是 final,因此允许使用子类,但不建议使用这种类型的子类.
使用 AudioTrack 播放音频
1
|
/**
|
demo在github上的地址
疑惑
- 采样位数是如何获取的?
Thanks