专栏首页Linux内核深入分析Linux音频驱动-WAV文件格式分析

Linux音频驱动-WAV文件格式分析

概述

WAV文件格式是Microsoft的RIFF规范的一个子集,用于存储多媒体文件。WAV(RIFF)文件由若干个Chunk组成,分别为: RIFF WAVE Chunk,Format Chunk,Fact Chunk(可选),Data Chunk。具体格式如下:

RIFF Chunk

根据RIFF的格式,可以抽象出RIFF chunk的结构体:

struct RIFF_CHUNK
{
    char ChunkID[4]; //'R','I','F','F'
    unsigned int ChunkSize;
    char Format[4];  //'W','A','V','E'
};

其中ChunkSize代表的是整个wav_file的大小减去ChunkID和ChunkSize的大小,即wav_file_size=ChunkSize+8。

Format Chunk

Format chunk主要是描述音频数据的格式。根据Format chunk的格式,可以抽象出Format Chunk的数据结构:

struct FORMAT_CHUNK
{
    char FmtID[4]; //'f','m','t'
    unsigned int FmtSize;
    unsigned short FmtTag;
    unsigned short FmtChannels;
    unsigned int SampleRate;
    unsigned int ByteRate;
    unsigned short BlockAilgn;
    unsigned short BitsPerSample;
};

.FmtSize: 通常取值为16或者18,16代表是该音频使用PCM编码方式。

.FmtTag: 如果上述取值为16,则此值通常为1,代表该音频的编码方式是PCM编码。

.FmtChannels: 声道数目,1代表单声道,2代表双声道,就是所谓的立体声。

.SampleRate: 采样频率。如果对此概念不是很了解,可以查看此文章: Linux音频驱动-声音采集过程

.ByteRate: 每秒所需的字节数。等于SampleRate * NumChannels * BitsPerSample/8。

.BlockAilgn: 数据块对齐单位。等于NumChannels * BitsPerSample/8。

.BitsPerSample: 采样位数。

Data Chunk

Data Chunk主要是描述raw sound数据和大小,根据Data Chunk格式,抽象出Data Chunk的数据结构:

struct DATA_CHUNK
{
    char DataID[4]; //'d','a','t','a'
    unsigned int DataSize;
};

DataSize就是整个raw data的大小。

实例分析

1. 在网上下载wav的音频文件,使用mediainfo显示该音频文件的详细信息。

root@test:~$ mediainfo ~/Download/test.wav 
General
Complete name                            : /home/test/Download/test.wav
Format                                   : Wave
File size                                : 44.2 MiB
Duration                                 : 4mn 22s
Overall bit rate mode                    : Constant
Overall bit rate                         : 1 411 Kbps

Audio
ID                                       : 0
Format                                   : PCM
Format settings, Endianness              : Little
Codec ID                                 : 1
Duration                                 : 4mn 22s
Bit rate mode                            : Constant
Bit rate                                 : 1 411.2 Kbps
Channel(s)                               : 2 channels
Sampling rate                            : 44.1 KHz
Bit depth                                : 16 bits
Stream size                              : 44.2 MiB (100%)

2. 使用vim使用十六进制打开该文件

      1 0000000: 5249 4646 741d c302 5741 5645 666d 7420  RIFFt...WAVEfmt                            
      2 0000010: 1000 0000 0100 0200 44ac 0000 10b1 0200  ........D.......
      3 0000020: 0400 1000 6461 7461 501d c302 0100 0000  ....dataP.......
      4 0000030: ffff 0000 0000 0000 0000 0100 0000 ffff  ................
      5 0000040: 0000 0100 0000 ffff 0000 0000 ffff 0100  ................
      6 0000050: 0200 ffff fdff 0100 0300 ffff ffff 0200  ................
      7 0000060: 0000 feff 0100 0200 ffff feff 0100 0200  ................
      8 0000070: ffff ffff 0100 0000 ffff 0100 0000 ffff  ................

3. 分析上述的数据

"52 49 46 46" 对应的Ascii码字符为"RIFF"。

"74 1d c3 02" 对应的就是ChunkSize,对应的十六进制是:0x2c31d74=46341492。那整个wav文件的大小就为: 46341492+8=46341500。将此值转化为MB位单位: 44.2MB,可以验证上述使用mediainfo的信息。

"57 41 56 45" 对应的Ascii码字符为"WAVE"。 "66 6d 74 20" 对应的Ascii码字符为"fmt"。

"10 00 00 00" 四字节对应的是该音频的编码方式,通常为16,代表PCM编码方式。也就是十六进制0x10。

"01 00" 对应为1,代表PCM编码方式。

"02 00" 通道个数,通道数为2,验证上述mediainfo的信息。

"44 ac 00 00" 采用频率,转化为十六进制为: 0xac44=44100=44.1KHz

"10 b1 02 00" 每秒所需的字节数,转化为十六进制为: 0x2b110=176400。通过此值可以计算该音频的时长: 46341500/17600=4.37。0.37*60=22.2,则该音频的时长为4mn22s。

"04 00" 数据对齐单位。

"10 00" 采样位数,等于0x10=16。

"64 61 74 61" 对应的Ascill码字符为"data"。

"50 1d c3 02" 对应该音频的raw数据的大小,转化为十六进制为0x2c31d50=46341456,此值等于wav_size-44=46341500-44。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Linux音频驱动-OSS和ALSA声音系统简介及其比较

    昨天想在Ubuntu上用一下HTK工具包来绘制语音信号的频谱图和提取MFCC的结果,但由于前段时间把Ubuntu升级到13.04,系统的声卡驱动是ALSA(Ad...

    DragonKingZhu
  • 进程调度开篇

    在前面的几篇文章中,我们重点分析了如果通过fork, vfork, pthread_create去创建一个进程或者线程,以及后面说了在内核层面do_fork的实...

    DragonKingZhu
  • page compaction原理

    如果你的ubuntu机器经过长时间运行,比如1个月没关机,这时候你去看buddinfo和pagetypeinfo的信息。

    DragonKingZhu
  • RBAC打造通用WEB权限

    RBAC不用给用户单个分配权限,只用指向对应的角色就会有对应的权限,而且分配权限和收回权限都很方便

    菲宇
  • 大数据日志收集框架之Flume入门

    我是攻城师
  • 国内首个零信任产业标准工作组成立,腾讯iOA重磅升级

    6月24日,在中国产业互联网发展联盟标准专委会指导下,腾讯联合零信任领域共16家机构企业,共同成立国内首个“零信任产业标准工作组”, 覆盖产、学、研、用四大领域...

    腾讯安全
  • [PHP] 使用xdebug查看php的性能损耗

    xdebug除了调试程序外 , 还可以来检测程序的性能损耗点 , 展示成图表的形式

    陶士涵
  • 【企业数字化转型】DIKW:数据、信息、知识、智慧的金字塔层次模型

    随着人类社会从工业经济时代进入知识经济时代,知识管理的出现为21世纪知识经济时代的企业组织提供必须的管理基础。以彼得.德鲁克博士(Peter F. Drucke...

    一个会写诗的程序员
  • Git回滚和撤销---吃上后悔药、坐上时光机

    这种情况有可能是在 git add 操作的时候一些不必要的文件也加进来了,所以想撤销,重新 add 。

    AntDream
  • MapReduce编程模型

    通过WordCount程序理解MapReduce编程模型 WordCount,名为单词统计,功能是统计文本文件中每个单词出现的次数。例如下图中,有两个文本(蓝色...

    企鹅号小编

扫码关注云+社区

领取腾讯云代金券