一、音频相关概念
1、样本
A/D转换器以每秒钟上万次的速率对声波进行采样,每个采样点都记录下了原始模拟声波在某一时刻的状态,通常称之为样本。通过将一串连续的样本连接起来,就可以在计算机中描述一段声音了。
2、采样频率
每一秒钟所采样的数目称为采样频率,单位hz,典型值是11025Hz、22050Hz和44100Hz。
采样频率的选择应该遵循奈奎斯特(Harry Nyquist)采样理论:如果对某一模拟信号进行采样,则采样后可还原的最高信号频率只有采样频率的一半,或者说只要采样频率高于输入信号最高频率的两倍,就能从采样信号系列重构原始信号。
3、采样分辩率(采样精度)
采样分辨率指的是在数字音频中用于表示每个采样值的位数。它决定了数字音频系统可以表示的动态范围和精度。常见的采样分辨率有8位、12位和16位等。位数越高,表示的动态范围越大,音频质量也更高。
4、数据传输速率
每秒平均传输的字节数,播放软件利用此值可以估计缓冲区的大小,计算公式:声道数×采样频率×每样本的数据位数 / 8
4、WAV文件
WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范, “RIFF”是wav文件识别码.
数据本身的格式为PCM或压缩型,属于无损音乐格式的一种。所有的WAV都有一个文件头,这个文件头音频流的编码参数。数据块的记录方式是little-endian字节顺序,标志符并不是字符串而是单独的符号。
-
偏移地址 大小(字节) 数据块类型 内容 00H~03H 4 4字符 大写字符串"RIFF",标明该文件为有效的 RIFF 格式文档。 04H~07H 4 长整数 从下一个字段首地址开始到文件末尾的总字节数。该字段的数值加 8 为当前文件的实际长度。 08H~0BH 4 4字符 所有 WAV 格式的文件此处为字符串"WAVE",标明该文件是 WAV 格式文件。 0CH~OFH 4 4字符 小写字符串"fmt ",最后一位空格。 10H~13H 4 整数 过滤字节(一般为00000010H),若为00000012 H则说明数据头携带附加信息(见“附加信息”)。 14H~15H 2 整数 PCM 脉冲编码调制格式种类(该数值通常为1,表示数据为线性PCM编码) 16H~17H 2 整数 通道数,单声道为1,双声道为2 18H~1BH 4 长整数 采样频率 1CH~1FH 4 长整数 数据传输速率(每秒平均字节数) 20H~21H 2 整数 采样帧大小。该数值为:声道数×位数/8。播放软件需要一次处理多个该值大小的字节数据,用该数值调整缓冲区。 22H~23H 2 整数 采样位数,存储每个采样值所用的二进制数位数 随后2字节 2 整数 附加信息(可选,由上方过滤字节确定) 随后 ... 不定长度字符 "fact",该部分是可选部分,一般当WAV文件是由某些软件转换而来时,包含该部分。
若包含该部分:
(1)该部分的前4字节为数据头,一般为4个字母,
(2)随后4个字节表示长度,即除去头(4字节)和长度(4字节)之后,数据本身的长度。(3)最后的字节为数据本身。
例如:“66 61 7374 04 00 00 00 F8 2F 14 00“,"66 61 73 74"是fact字段的数据头,"04 00 00 00是数据本身的长度,“F8 2F 14 00”是数据本身。(注意是little-endian字节顺序)随后4字节 4 4字符 数据标志符"data" 随后4字节 4 长整型 DATA总数据长度字节 随后 ... DATA数据块 //数据头定义 struct T_RecorderWavHeader { //RIFF chunk descriptor 12byte char riff[4]; // = "RIFF" uint32_t size_8; // = FileSize - 8 char wave[4]; // = "WAVE" //fmt sub-chunk 24byte char fmt[4]; // = "fmt " uint32_t format_size; // = 过滤字节(一般为00000010H,若为00000012H说明数据头携带附加信息) uint16_t format_tag; // = 常见的 WAV 文件使用 PCM 脉冲编码调制格式,该数值通常为 1 uint16_t channels; // = 声道个数: 单声道为 1,立体声或双声道为 2 uint32_t samples_per_sec; // = 采样频率 : 8000 | 6000 | 11025 | 16000 | 22050 | 44100 uint32_t avg_bytes_per_sec; // = 数据传输速率(每秒平均字节数):声道数×采样频率×每样本的数据位数/8。播放软件利用此值可以估计缓冲区的大小。 // = samples_per_sec * channels * bits_per_sample / 8 uint16_t block_align; // = 每采样点字节数 : 声道数×位数/8。播放软件需要一次处理多个该值大小的字节数据,用该数值调整缓冲区。 // = channels * bits_per_sample / 8 uint16_t bits_per_sample; // = 采样位数: 存储每个采样值所用的二进制数位数, 8 | 16 //data sub-chunk 8byte char data[4]; // = "data"; uint32_t data_size; // = 纯数据长度 : FileSize - 44 }; // 根据本系统的具体字节序处理的存放格式 #if __BYTE_ORDER == __LITTLE_ENDIAN #define RIFF ('F'<<24 | 'F'<<16 | 'I'<<8 | 'R'<<0) #define WAVE ('E'<<24 | 'V'<<16 | 'A'<<8 | 'W'<<0) #define FMT (' '<<24 | 't'<<16 | 'm'<<8 | 'f'<<0) #define DATA ('a'<<24 | 't'<<16 | 'a'<<8 | 'd'<<0) #define LE_SHORT(val) (val) #define LE_INT(val) (val) #elif __BYTE_ORDER == __BIG_ENDIAN #define RIFF ('R'<<24 | 'I'<<16 | 'F'<<8 | 'F'<<0) #define WAVE ('W'<<24 | 'A'<<16 | 'V'<<8 | 'E'<<0) #define FMT ('f'<<24 | 'm'<<16 | 't'<<8 | ' '<<0) #define DATA ('d'<<24 | 'a'<<16 | 't'<<8 | 'a'<<0) #define LE_SHORT(val) bswap_16(val) #define LE_INT(val) bswap_32(val) #endif
根据对WAV格式的了解,编写了一个对wav音频文件的裁剪工具,欢迎大家点击下载。
-
参考博客:【音频驱动】Linux之ALSA声卡、WAV文件相关概念_alsa 音频-CSDN博客