本文的目标是在无数字信号处理基础的情况背景下说明PCM转频谱的原理。
通常音频播放软件的频谱图就是频谱数据了,一般音频数据有两种可视化的模式,波形图和频谱图。
WAV文件格式可以记录多种数据类型,其中头部分记录的是音频数据类型,声道数量,采样率,采样深度之类的信息。 其中数据类型为1时表示此WAV文件使用的是PCM编码的数据,也就是从理论上来说WAV里面的数据不一定就是PCM。
PCM格式的数据,表示的就是波形图。
类似的, 苹果的AIFF也可以作为PCM的容器。
wiki上有详细解释。 我对这个编码的理解就是声波冲击到麦克风上面的时候产生的压力的数值,或者声音震动使麦克风的那个膜产生了震动的幅度值。 声音大的话震动的幅度会大一些。
由于声音是一个连续的数据, 而计算机处理的是离散的数据,所以需要对声音进行编码采集,才有了采样率这个事儿。 而且PCM只是表示那个幅值,本身并不包含采样率,频道之类的信息,所以才需要WAV的头信息进行说明,不然拿到数据了都不知道这到底是个啥。
声音是通过震动产生的,而震动是有不同频率的。比较低沉的声音震动频率就偏低,而尖锐的声音振动频率就偏高。
不同于波形图随着时间的变长绘制的内容也越来越长,频谱图长度始终是一定的,但是会上下波动。
为啥出来这么个东西呢? 上图中左边是波形图,右边是其对应的频谱
傅立叶变换是啥就不讲了,反正在这里咱们就是用它来把PCM转换成频谱图的。
简单的从流程上说,就是
- 拿到PCM数据
- 把这个数据傅立叶变换一下
- 傅立叶变换之后的输出显示出来
大功告成,所有内容都可以在工程里面看到
示例项目的傅立叶变换在苹果体系内使用了Accelerate框架
Draw waveform from CMSampleBuffer
示例如何从CMSampleBuffer中读出音频源数据并展示出来。
关键方法:文档 CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer
其中第三个参数bufferListSize
需要注意,如果不对的话会返回kCMSampleBufferError_ArrayTooSmall
,无法成功获取AudioBufferList
. 根据这里看到的信息,可能需要获取两次。
另外取出的AudioBuffer
里面的mData
的数据类型不固定,可能是浮点值,也可能是有符号的16位整型,并且字节序也可能不确定,所以处理时需要注意。