@qidiandasheng
2020-07-01T10:25:37.000000Z
字数 2984
阅读 1200
音视频
人的说话频率基本上为300Hz-3400Hz,但是人耳朵听觉频率基本上为20Hz-20000Hz。
实际中,人发出的声音信号为模拟信号,想要在实际中处理必须为数字信号,即采用采样、量化、编码的处理方案。处理的第一步为采样,即模数转换。
简单地说就是通过波形采样的方法记录1秒钟长度的声音,需要多少个数据。根据奈魁斯特(NYQUIST)采样定理,用两倍于一个正弦波的频繁率进行采样就能完全真实地还原该波形。
所以,对于声音信号而言,要想对离散信号进行还原,必须将抽样频率定为40KHz以上。实际中,一般定为44.1KHz。44.1KHz采样率的声音就是要花费44100个数据来描述1秒钟的声音波形。
原则上采样率越高,声音的质量越好,采样频率一般共分为22.05KHz、44.1KHz、48KHz三个等级。22.05 KHz只能达到FM广播的声音品质,44.1KHz则是理论上的CD音质界限,48KHz则已达到DVD音质了。
音频码率,又称为比特率:是指一个音频流中每秒钟能通过的数据量。 如128kbps,其中ps(per second)为每秒,kb为千位,那么128kbps表示一秒钟能传输的数据量是128千位。 对于格式相同的文件来说,码率越大的话,音质越好。
单位转换:128kbps=128000bits=16000bytes=16kb
对于音频信号而言,必须进行编码。在这里,编码指信源编码,即数据压缩。如果,未经过数据压缩,直接量化进行传输则被称为PCM(脉冲编码调制)。
要算一个PCM音频流的码率是一件很轻松的事情,采样率值×采样大小值×声道数 bps。一个采样率为44.1KHz,采样大小为16bit,双声道的PCM编码的WAV文件,它的数据速率则为 44.1K×16×2 =1411.2 Kbps。则1秒需要176.4KB的空间,1分钟则约为10.34M。
是指处理的声音是单声道还是立体声。单声道在声音处理过程中只有单数据流,而立体声则需要左、右声道的两个数据流。显然,立体声的效果要好,但相应的数据量要比单声道的数据量加倍。
人嘴说话——>声电转换——>采样(模数转换)——>量化(将数字信号用适当的数值表示)——>编码(数据压缩)——>传输(网络或者其他方式)——>解码(数据还原)——>反采样(数模转换)——>电声转换——>人耳听声。
PCM数据是最原始的音频数据完全无损,所以PCM数据虽然音质优秀但体积庞大,为了解决这个问题先后诞生了一系列的音频格式,这些音频格式运用不同的方法对音频数据进行压缩,其中有无损压缩(ALAC、APE、FLAC)和有损压缩(MP3、AAC、OGG、WMA)两种。
目前最为常用的音频格式是MP3,MP3是一种有损压缩的音频格式,设计这种格式的目的就是为了大幅度的减小音频的数据量,它舍弃PCM音频数据中人类听觉不敏感的部分。
MP3格式中的码率(BitRate)代表了MP3数据的压缩质量,现在常用的码率有128kbit/s、160kbit/s、320kbit/s等等,这个值越高声音质量也就越高。MP3编码方式常用的有两种固定码率(Constant bitrate,CBR)和可变码率(Variable bitrate,VBR)。
MP3格式中的数据通常由两部分组成,一部分为ID3用来存储歌名、演唱者、专辑、音轨数等信息,另一部分为音频数据。音频数据部分以帧(frame)为单位存储,每个音频都有自己的帧头,如图所示就是一个MP3文件帧结构图(图片同样来自互联网)。MP3中的每一个帧都有自己的帧头,其中存储了采样率等解码必须的信息,所以每一个帧都可以独立于文件存在和播放,这个特性加上高压缩比使得MP3文件成为了音频流播放的主流格式。帧头之后存储着音频数据,这些音频数据是若干个PCM数据帧经过压缩算法压缩得到的,对CBR的MP3数据来说每个帧中包含的PCM数据帧是固定的,而VBR是可变的。
我们可以列出一个经典的音频播放流程(以MP3为例):
在iOS系统中apple对上述的流程进行了封装并提供了不同层次的接口(图片引自官方文档)。
下面对其中的中高层接口进行功能说明:
如果你只是想实现音频的播放,没有其他需求AVFoundation会很好的满足你的需求。它的接口使用简单、不用关心其中的细节;
如果你的app需要对音频进行流播放并且同时存储,那么AudioFileStreamer加AudioQueue能够帮到你,你可以先把音频数据下载到本地,一边下载一边用NSFileHandler等接口读取本地音频文件并交给AudioFileStreamer或者AudioFile解析分离音频帧,分离出来的音频帧可以送给AudioQueue进行解码和播放。如果是本地文件直接读取文件解析即可。(这两个都是比较直接的做法,这类需求也可以用AVFoundation+本地server的方式实现,AVAudioPlayer会把请求发送给本地server,由本地server转发出去,获取数据后在本地server中存储并转送给AVAudioPlayer。另一个比较trick的做法是先把音频下载到文件中,在下载到一定量的数据后把文件路径给AVAudioPlayer播放,当然这种做法在音频seek后就回有问题了。);
如果你正在开发一个专业的音乐播放软件,需要对音频施加音效(均衡器、混响器),那么除了数据的读取和解析以外还需要用到AudioConverter来把音频数据转换成PCM数据,再由AudioUnit+AUGraph来进行音效处理和播放(但目前多数带音效的app都是自己开发音效模块来做PCM数据的处理,这部分功能自行开发在自定义性和扩展性上会比较强一些。PCM数据通过音效器处理完成后就可以使用AudioUnit播放了,当然AudioQueue也支持直接使对PCM数据进行播放。)。