常见音频格式的基础知识
PCM
脉冲编码调制(Pulse Code Modulation),是未经压缩的音频数据裸流,它由模拟信号经过采样、量化、编码转换成的数字音频数据。
PCM的文件/流中只有数据,需要参数来描述。描述PCM数据的6个参数:
-
Sample Rate采样频率,8kHz(电话),44.1kHz(CD),48kHz(DVD)
-
Sample Size量化位数,通常该值为16bit
-
Number of Channels通道个数,常见有立体声和单声道
-
Sign,表示样本数据是否有符合位
-
Byte Ordering字节序,通常为little-endian
-
Integer Or Floating Point整形或浮点型,大多数PCM样本使用整形,一些精度要求高的使用浮点型。
比较重要的参数有:采样频率、通(声)道数
数据格式
如果是单声道的音频文件,采样数据按时间的先后顺序依次存入,如果是双声道的就按照LRLRLR的方式存储,16bit的存储和字节序有关。
G711
G711是国际电信联盟ITU-T定制出来的一套语言压缩标准,它代表了对数PCM(pulse code modulation/脉冲编码调制)抽样标准。采样率一般为8KHz。
G.711 标准下主要有两种压缩算法,u-law,主要应用于北美和日本;a-law,主要应用于欧洲和其他地区:
-
a-law:将一个13bit的pcm数据编码成一个8bit的pcm数据(PCMA)
-
u-law:将一个14bit的pcm数据编码成一个8bit的pcm数据(PCMU)
G711主要应用于电话语言通信,因为人声最大频率在3.4kHz,所以8kHz的采样率可以保证还原原始的声音。
WAV文件
wav是一种无损的音频文件格式。所有的WAV都有一个文件头,包含了这个音频的编码参数。wav对音频流的编码没有硬性规定,除了PCM之外,还有几乎所有支持ACM规范的编码都可以为WAV的音频流进行编码。
对PCM数据来说,加上wav文件头就变成了wav格式。
不同格式的数据,wav文件头的格式也略有不同,标准PCM数据的wav文件头是44字节,而ulaw或alaw的文件头会多一个区块,占58字节。
PCM数据对应的WAV文件头:
区块名 | bytes | 端序 | 内容 | 说明 |
ChunkID | 4 | 大 | "RIFF" | |
ChunkSzie | 4 | 小 | N+sizeof(head)-8 | N是音频数据的长度 |
Format | 4 | 大 | "WAVE" | |
Subchunk1ID | 4 | 大 | "fmt " | fmt加空格 |
Subchunk1IDsize | 4 | 小 | 16or18 | |
AudioFormat | 2 | 小 | 音频格式 | PCM: 0x01;a-law: 0x06;u-law: 0x07 |
NumChannels | 2 | 小 | 通道数 | 单声道:1,立体声:2 |
SampleRate | 4 | 小 | 采样频率Hz | |
ByteRate | 4 | 小 | SampleRate * NumChannels * BitsPerSample/8 | |
BlockAlign | 2 | 小 | NumChannels * BitsPerSample/8 | |
BitPerSample | 2or4 | 小 | 8bits=8, 16bits=16 采样位深 |
是压缩编码数据时占4字节,正常编码数据占2字节 |
factchunkID | 4 | 大 | "fact" | 压缩编码的数据需要这个块,否则不需要 |
factchunkIDsize | 4 | 小 | 4 | |
factData | 4 | 小 | 可以是音频数据长度 | |
Subchunk2ID | 4 | 大 | "data" | |
Subchunk2IDsize | 4 | 小 | N | 音频数据的长度 |
data | N | 小 |
//WAVE文件一般有四种块,它们依次是:RIFF块、格式块、附加块(可选),数据块
#pragma pack(1)
typedef struct {
//RIFF块
uint8_t riffID[4]; //RIFF标识
uint32_t fileSize; //文件大小
uint8_t fccType[4]; //WAVE标志
//fmt块
uint8_t fmtID[4]; //fmt
uint32_t ckLen; //块大小 pcm-0x10;ulaw-0x12;alaw-0x12
uint16_t wFormatTag; //音频格式 pcm-0x01;ulaw-0x07;alaw-0x06
uint16_t nChannels; //采样声道数
uint32_t nSamplesPerSec; //采样率
uint32_t nAvgBytesPerSec; //每秒字节数 采样率*采样精度/8(字节位数)
uint16_t cbSize;
uint32_t bPerSample; //每个采样位数,量化数(pcm为2byte)
//fact块,压缩编码须有该块
uint8_t factID[4]; //fact
uint32_t factSzie; //4
uint32_t factData;
//data块
uint8_t wdid[4]; //data 标志
uint32_t wdSize; //块大小
} WAVFILEHEADER;
//0x3A(58)字节
//针对ulaw和alaw,未经压缩的原始pcm对应的wav文件头有所不同
#pragma pack()
ADTS
ADTS的全称是Audio Data Transport Stream,是AAC音频的一种传输流格式。
这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。也就是说它每一帧都有头信息,可以在任意位置开始解码。
AAC音频文件的每一帧由Header和Data组成,header长度为7字节或者9字节,一般为7字节,有CRC校验为9字节。
如下表:
bits | ||
fixed_header | ||
syncword | 12 | 同步头,总是0xFFF |
ID | 1 | 0标识MPEG-4,1标识MPEG-2 |
layer | 2 | 总是00 |
protection_absent | 1 | 1没有CRC,0有CRC |
profile | 2 | AAC级别 |
sampling_frequency_index | 4 | 采样率列表的下标 |
private_bit | 1 | |
channel_configuration | 3 | 声道数 |
original_copy | 1 | |
home | 1 | |
variable_header | ||
copyright_id_bit | 1 | |
copyright_id_start | 1 | |
aac_frame_length | 13 | 帧长度,包括帧头和数据 |
adts_buffer_fullness | 11 | 0x7FF表示码率可变 |
number_of_raw_data_blocks_in_frame | 2 | |
//采样率列表
static unsigned const samplingFrequencyTable[16] = {
96000, 88200, 64000, 48000,
44100, 32000, 24000, 22050,
16000, 12000, 11025, 8000,
7350, 0, 0, 0
};