开始之前,先来了解下很基础的知识 - 计算机的存储单位和整数存储在计算机所占的内存大小。
1).计算机最小的存储单位是“位” 也就是bit或binary digits,用来存放一个二进制数,即 0或1。 8个二进制位为一个字节Byte。
2).对于 16-bit(16位)的计算机,int是以两个字节来储存的,而32-bit的计算机,则是以4个字节,即32个bit来储存的。
如果想要明白singed与unsigned的区别,除了这两个基本知识,还需要了解整数在计算机中的存储方式,以16-bit 计算机为例,定义 int a = 1; 那么a的存储方式用表格来表示
0000000000000001
首先需要提到的一点是,在C语言中十进制的整数都会转化为二进制存储在计算机。继续,上面所声明的 int a = 1,也就是 int signed a =1,C语言默认a是一个signed类型。 上面表格中最左端的为最高位,最右端的为最低位。signed类型的整数,只用了去除最高位,剩下的15位来进行编码的,而最高位只是用来做标记(sign),标记整数的正负,0表示正,1表示负。所以对于signed的整数,的存储范围是(-2^15 to 2^15-1),也就是 -32768 到 +32767的整数。
而对于unsigned的整数,其16位全部用来编码,存储范围便是(0 to 2^16-1),即 0到 65535 的非负整数。所以呢 你可以声明 int a = 1,或者 int a = -1, 但是不可以声明 unsigned a = -1 。但是需要提到的一点是,不管整数的类型是signed 还是 unsigned,都用了16位来存储,也就是说16位全部用来存储数据
Base integer types for all target OS's and CPU's
UInt8 8-bit unsigned integer
SInt8 8-bit signed integer
UInt16 16-bit unsigned integer
SInt16 16-bit signed integer
UInt32 32-bit unsigned integer
SInt32 32-bit signed integer
UInt64 64-bit unsigned integer
SInt64 64-bit signed integer
PCM脉冲编码调制(Pulse Code Modulation)
脉冲编码调制就是把一个时间连续,取值连续的模拟信号变换成时间离散,取值离散的数字信号后在信道中传输。脉冲编码调制就是对模拟信号先抽样,再对样值幅度量化,编码的过程。
总结起来就是三个步骤:
1、抽样;
2、量化;
3、编码;
PCM基础概念
了解PCM的基本原理之后,再看看PCM衍生出来的常见概念。
1、声道;
录制和播放时,音频信号的数量。
2、采样率;
每秒从连续信号中提取并组成离散信号的采样个数,单位是赫兹(Hz);
奈奎斯特采样定理:当采样频率大于声音最高频率的两倍,能完整的保留声音的信息。
3、采样深度;
量化的二进制位数,常为16位;
4、码率;
音频流每秒的大小,单位常用bps;
一个采样率为44.1KHz,采样大小为16bit,双声道的PCM编码的文件,码率为 44.1K×16×2 =1411.2 Kbps
PCM数据操作
了解完PCM的相关概念后,再来看看PCM相关的数据操作。
1、PCM混合;
重采样,对位相加,溢出处理;
2、单声道变立体声;
增加声道,复制数据;
3、立体声变单声道;
减少声道,声道混合或只取其一;
4、音量调整和静音;
改变量化值,对数优化,清零静音;
5、播放速率调整;
快放:相邻位合并,缩减长度;
慢放:长度增加,量化值不变;
Audio Unit 播放 PCM
AudioStreamBasicDescription
iOS的音频描述结构体,包括解析音频数据需要的各种参数
mSampleRate:采样率
mFormatID:编码格式
mFormatFlags:数据格式;(L/R,整形or浮点)
mBytesPerPacket:每个Packet的Bytes数
mFramesPerPacket:每个Packet的帧数
mBytesPerFrame:每帧的Byte数
mChannelsPerFrame:每帧的声道数
mBitsPerChannel:每个声道的采样深度
立体声的PCM音频数据,通常是以L/R交替(左右声道交替)的方式存储。
在iOS平台可以通过设置kAudioFormatFlagIsNonInterleaved,使得左右声道的数据分别存储在AudioBufferList的两个AudioBuffers中。
由于硬件要求,录制和播放都是整形格式。但在音频处理的过程中, 音频数据可能会溢出(整形格式表示范围有限),故而有些处理需要用浮点数来进行。
/**********************************/
PCM文件:模拟音频信号经模数转换(A/D变换)直接形成的二进制序列,该文件没有附加的文件头和文件结束标志。Windows的Convert工具可以把PCM音频格式的文件转换成Microsoft的WAV格式的文件。
将音频数字化,其实就是将声音数字化。最常见的方式是透过脉冲编码调制PCM(Pulse Code Modulation) 。运作原理如下。首先我们考虑声音经过麦克风,转换成一连串电压变化的信号,如图一所示。这张图的横座标为秒,纵座标为电压大小。要将这样的信号转为 PCM 格式的方法,是使用三个参数来表示声音,它们是:声道数、采样位数和采样频率。
采样频率:即取样频率,指每秒钟取得声音样本的次数。采样频率越高,声音的质量也就越好,声音的还原也就越真实,但同时它占的资源比较多。由于人耳的分辨率很有限,太高的频率并不能分辨出来。在16位声卡中有22KHz、44KHz等几级,其中,22KHz相当于普通FM广播的音质,44KHz已相当于CD音质了,目前的常用采样频率都不超过48KHz。
采样位数:即采样值或取样值(就是将采样样本幅度量化)。它是用来衡量声音波动变化的一个参数,也可以说是声卡的分辨率。它的数值越大,分辨率也就越高,所发出声音的能力越强。
声道数很好理解,有单声道和立体声之分,单声道的声音只能使用一个喇叭发声(有的也处理成两个喇叭输出同一个声道的声音),立体声的pcm可以使两个喇叭都发声(一般左右声道有分工) ,更能感受到空间效果。
在计算机中采样位数一般有8位和16位之分,但有一点请大家注意,8位不是说把纵坐标分成8份,而是分成2的8次方即256份; 同理16位是把纵坐标分成2的16次方65536份; 而采样频率一般有11025HZ(11KHz),22050HZ(22KHz)、44100Hz(44KHz)三种。
那么,现在我们就可以得到pcm文件所占容量的公式: 存储量=(采样频率*采样位数*声道)*时间/8(单位:字节数) 例如,数字激光唱盘(CD-DA,红皮书标准)的标准采样频率为44.lkHz,采样数位为16位,立体声(2声道),可以几乎无失真地播出频率高达22kHz的声音,这也是人类所能听到的最高频率声音。激光唱盘一分钟音乐需要的存储量为: (44.1*1000*l6*2)*60/8=10,584,000(字节)=10.584MBytes 这个数值就是pcm声音文件在硬盘中所占磁盘空间的存储量。 计算机音频文件的格式决定了其声音的品质,日常生活中电话、收音机等均为模拟音频信号,即不存在采样频率和采样位数的概念,我们可以这样比较一下: 44KHz,16BIT的声音称作:CD音质; 22KHz、16Bit的声音效果近似于立体声(FM Stereo)广播,称作:广播音质; 11kHz、8Bit的声音,称作:电话音质。 微软的WAV文件就是pcm编码的一种。
采样率和采样深度是数字音频技术里两个重要的参数。
采样深度代表取样中对声音强度记录的精细程度。
采样深度可以理解为采集卡处理声音的解析度。这个数值越大,解析度就越高,录制和回放的声音就越真实。电脑中的声音文件是用数字0和1来表示的。连续的模拟信号按一定的采样频率经数码脉冲取样后,每一个离散的脉冲信号被以一定的量化精度量化成一串二进制编码流,这串编码流的位数即为采样深度,也称为量化精度。
pcm是没有编码、没有压缩的格式,更方便处理,所以输出这种格式。首先格式用AudioStreamBasicDescription这个结构体描述,这里包含了音频相关的知识:
采样率SampleRate: 每秒钟采样的次数
帧frame:每一次采样的数据对应一帧
声道数mChannelsPerFrame:人的两个耳朵对统一音源的感受不同带来距离定位,多声道也是为了立体感,每个声道有单独的采样数据,所以多一个声道就多一批的数据。
最后是每一次采样单个声道的数据格式:由mFormatFlags和mBitsPerChannel确定。mBitsPerChannel是数据大小,即采样位深,越大取值范围就更大,不容易数据溢出。mFormatFlags里包含是否有符号、整数或浮点数、大端或是小端等。有符号数就有正负之分,声音也是波,振动有正负之分。这里采用s16格式,即有符号的16比特整数格式。
从上至下是一个包含关系:每秒有SampleRate次采样,每次采样一个frame,每个frame有mChannelsPerFrame个样本,每个样本有mBitsPerChannel这么多数据。所以其他的数据大小都可以用以上这些来计算得到。当然前提是数据时没有编码压缩的
AVFormatIDKey,//格式
AVSampleRateKey, //采样率8000次
AVNumberOfChannelsKey, //通道的数目
AVLinearPCMBitDepthKey, //采样位数 默认 16
AVLinearPCMIsBigEndianKey, //大端还是小端 是内存的组织方式
AVLinearPCMIsFloatKey, //采样信号是整数还是浮点数
AVEncoderBitRateKey, //解码率
AVEncoderBitDepthHintKey, //位深度
AVEncoderBitRatePerChannelKey, //声道采样率
AVEncoderAudioQualityKey, //音频编码质量
AVLinearPCMIsNonInterleaved //交叉的
AVAudioFileTypeKey // AudioFile.h文件中可以查看具体的
AVEncoderAudioQualityForVBRKey //动态比特率,取值是 AVAudioQuality,只和AVAudioBitRateStrategy_Variable有关
AVEncoderBitRateKey //编码比特率
注意
AVEncoderBitRateKey和AVEncoderBitRatePerChannelKey只需要设置一个 ;only one of AVEncoderBitRateKey and AVEncoderBitRatePerChannelKey should be provided.
AVEncoderBitRatePerChannelKey //每个声道的比特率
AVEncoderBitRateStrategyKey //编码比特率的策略
网友评论