WAVE头分析代码

2024-01-29 09:48
文章标签 分析 代码 wave

本文主要是介绍WAVE头分析代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这篇文章是网络上流行的比较广泛的针对WAVE头分析的文章, 整体写的简单明了非常好,但是

18H

2

int

采样率(每秒样本数),表示每个通道的播放速度,

应该是不对的, 如果按这个该文章的计算,WAVE头只有42byte, 实际上wave头是44byte.

参考MS的标准文档知道这个采样率是占4byte.( WAVE PCM soundfile format )

// ----------------------------------------------------------------

WAVE文件格式剖析

 
WAVE 文件作为多媒体中使用的声波文件格式之一,它是以RIFF格式为标准的。RIFF是英文Resource Interchange File Format的缩写,每个WAVE文件的头四个字节便是"RIFF"WAVE文件由文件头和数据体两大部分组成。其中文件头又分为RIFFWAV文件 标识段和声音数据格式说明段两部分。WAVE文件各部分内容及格式见附表。[!21ki@][@21ki!]
常 见的声音文件主要有两种,分别对应于单声道(11.025KHz 采样率、8Bit的采样值)和双声道(44.1KHz采样率、16Bit的采样值)。采样率是指:声音信号在""转换过程中单位时间内采样的次数。 采样值是指每一次采样周期内声音模拟信号的积分值。[!21ki@][@21ki!]
对于单声道声音文件,采样数据为八位的短整数(short int 00H-FFH);而对于双声道立体声声音文件,每次采样数据为一个16位的整数(int),高八位和低八位分别代表左右两个声道。[!21ki@][@21ki!]
        WAVE文件数据块包含以脉冲编码调制(PCM)格式表示的样本。WAVE文件是由样本组织而成的。在单声道WAVE文件中,声道0代表左声道,声道1代表右声道。在多声道WAVE文件中,样本是交替出现的。

  WAVE文件格式说明表  [!21ki@][@21ki!]

 

偏移地址

字节数

数据类型

  

 

文件头[!21ki@][@21ki!]

00H

4

char

"RIFF"标志

04H

4

long int

文件长度

08H

4

char

"WAVE"标志

0CH

4

char

"fmt"标志

10H

4

 

过渡字节(不定)

14H

2

int

格式类别(10HPCM形式的声音数据)

16H

2

int

通道数,单声道为1,双声道为2

18H

2

int

采样率(每秒样本数),表示每个通道的播放速度,

1CH

4

long int

波形音频数据传送速率,其值为通道数×每秒数据位数×每样本的数据位数/8。播放软件利用此值可以估计缓冲区的大小。

20H

2

int

数据块的调整数(按字节算的),其值为通道数×每样本的数据位值/8。播放软件需要一次处理多个该值大小的字节数据,以便将其值用于缓冲区的调整。

22H

2

 

每样本的数据位数,表示每个声道中各个样本的数据位数。如果有多个声道,对每个声道而言,样本大小都一样。

24H

4

char

数据标记符"data

28H

4

long int

语音数据的长度

  PCM数据的存放方式: [!21ki@][@21ki!]

 

样本1

样本2

8位单声道

0声道

0声道

8位立体声

0声道(左)

1声道(右)

0声道(左)

1声道(右)

16位单声道

0声道低字节

0声道高字节

0声道低字节

0声道高字节

16位立体声

0声道(左)低字节

0声道(左)高字节

1声道(右)低字节

1声道(右)高字节

 WAVE文件的每个样本值包含在一个整数i中,i的长度为容纳指定样本长度所需的最小字节数。首先存储低有效字节,表示样本幅度的位放在i的高有效位上,剩下的位置为0,这样8位和16位的PCM波形样本的数据格式如下所示。  [!21ki@][@21ki!]

样本大小

数据格式

最大值

最小值

8PCM

unsigned int

225

0

16PCM

int

32767

-32767

分析WAVE头的代码

/*

                     WAVE文件头(PCM格式)

                    

field         size   type       description

-----------------------------------------------------------------------

ChunkID       4      char       "RIFF"标志

ChunkSize     4      long int   文件长度(WAVE文件的大小, 不含前8个字节)

Format        4      char       "WAVE"标志

SubChunk1ID   4      char       "fmt "标志

SubChunk1Size 4                 过渡字节(不定)

AudioFormat   2      short int  格式类别(1PCM格式的声音数据)

NumChannels   2      short int  通道数(单声道为1, 双声道为2)

SampleRate    4      long int   采样率(每秒样本数), 表示每个通道的播放速度

                                一般情况是每秒采样44100

                               

ByteRate      4      long int   波形音频数据传输速率, 其值为:通道数*每秒数据位数*每样本的数据位数/8

                                播放软件可以利用该值估计缓冲区大小

                                2 *

BlockAlign    2      short int  每样本的数据位数(按字节算), 其值为:通道数*每样本的数据位值/8 播放

软件需要一次处理多个该值大小的字节数据, 以便将其值用于缓冲区的调整

                                每样本占几个字节 : NumChannels * 16/8

                               

BitsPerSample 2                 每样本的数据位数, 表示每个声道中各个样本的数据位数. 如果有多个声道,

                                对每个声道而言, 样本大小都一样

                                就是分辨率, 一般是16, 8位也有但是要少一些.

                               

SubChunk2ID       4      char   数据标记"data"

SubChunk2Size 4      long int   语音数据的长度

*/

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <mem.h>

/* WAVE文件头 */

typedef struct wave_tag

{

    char              ChunkID[5];       // "RIFF"标志

    unsigned long int ChunkSize;    // 文件长度(WAVE文件的大小, 不含前8个字节)

    char              Format[5];    // "WAVE"标志

   

    char             SubChunk1ID[5];   // "fmt "标志

    unsigned long int SubChunk1Size;    /*

                                    * 过渡字节(不定)

                                    * 16 for PCM. This is the size of the rest of the

                                    * Subchunk which follows this number.

                                    */

    unsigned short int   AudioFormat;  /*

                                    * 格式类别(10HPCM格式的声音数据)

                                    * PCM=1 (i.e. Linear quantization)

                                    * Values other than 1 indicate some form of compression.

                                    */

    unsigned short int   NumChannels;  // 通道数(单声道为1, 双声道为2)

    //unsigned short int SampleRate;       // 采样率(每秒样本数), 表示每个通道的播放速度

    unsigned long int    SampleRate;       // 采样率(每秒样本数), 表示每个通道的播放速度

    unsigned long int ByteRate;     /*

                                     * 波形音频数据传输速率, 其值为:通道数*每秒数据位数*每样本的数据位数/8

                                     * 播放软件可以利用该值估计缓冲区大小

                                     */

    unsigned short int   BlockAlign;       /*

                                      * 每样本的数据位数(按字节算), 其值为:通道数*每样本的数据位值/8 播放

                                     * 软件需要一次处理多个该值大小的字节数据, 以便将其值用于缓冲区的调整

                                     */

    unsigned short int   BitsPerSample;    /*

                                    * 每样本的数据位数, 表示每个声道中各个样本的数据位数. 如果有多个声道,

                                    * 对每个声道而言, 样本大小都一样

                                    */

   

    char              SubChunk2ID[5];   // 数据标记"data"

    unsigned long int SubChunk2Size;    // 语音数据的长度

} WAVE;

/* 分辨率为16的样本 */

typedef struct swatch16_tag

{

     char swing;

     

} swatch16;

/* 分辨率为8的样本 */

typedef struct swatch8_tag

{

   

} swatch8;

// 爱情复兴 :), 长度: 41.5MB(43,554,860 字节)

#define    FILE_PATH  "aiqingfuxing1.wav"

/*

 * 分析音频文件格式

 */

int

main ( void )

{

    FILE   *stream;

    WAVE   wav;

   

    stream = fopen( FILE_PATH, "r" );  /* open a file for reading */

   

    /*

     * wav文件的各个field

     */

    fread(wav.ChunkID,          4, 1, stream);

    wav.ChunkID[4] = (char)0;

    fread(&(wav.ChunkSize),     4, 1, stream);

    fread(wav.Format,           4, 1, stream);

    wav.Format[4] = (char)0;

    fread(wav.SubChunk1ID,      4, 1, stream);                                                                                          

    wav.SubChunk1ID[4] = (char)0;

    fread(&(wav.SubChunk1Size), 4, 1, stream);

    fread(&(wav.AudioFormat),   2, 1, stream);

    fread(&(wav.NumChannels),   2, 1, stream);

    fread(&(wav.SampleRate), 4, 1, stream);

    fread(&(wav.ByteRate),      4, 1, stream);

    fread(&(wav.BlockAlign), 2, 1, stream);

    fread(&(wav.BitsPerSample), 2, 1, stream);

    fread(wav.SubChunk2ID,      4, 1, stream);

    wav.SubChunk2ID[4] = (char)0;

    fread(&(wav.SubChunk2Size), 4, 1, stream);

   

    printf("ChunkID---->%s/n",         wav.ChunkID);

    printf("ChunkSize---->%ld/n",      wav.ChunkSize);

    printf("Format---->%s/n",          wav.Format);

    printf("SubChunk1ID---->%s/n",     wav.SubChunk1ID);

    printf("SubChunk1Size---->%ld/n", wav.SubChunk1Size);

    printf("AudioFormat---->%d/n",     wav.AudioFormat);

    printf("NumChannels---->%d/n",     wav.NumChannels);

    printf("SampleRate---->%ld/n",     wav.SampleRate);

    printf("ByteRate---->%ld/n",       wav.ByteRate);

    printf("BlockAlign---->%d/n",      wav.BlockAlign);

    printf("BitsPerSample---->%d/n",   wav.BitsPerSample);

    printf("SubChunk2ID---->%s/n",     wav.SubChunk2ID);

    printf("SubChunk2Size---->%ld/n", wav.SubChunk2Size);

   

    printf("*************rrr**********/n");   //

   

   

    system( "pause" );

    return 0;

}

/*

              打印结果

ChunkID---->RIFF

ChunkSize---->43554852

Format---->WAVE

SubChunk1ID---->fmt

SubChunk1Size---->16

AudioFormat---->1

NumChannels---->2

SampleRate---->44100

ByteRate---->176400

BlockAlign---->4

BitsPerSample---->16

SubChunk2ID---->data

SubChunk2Size---->43554816

*************rrr**********

请按任意键继续. . .

*/

/*

                  WAVE头的16进制码

52 49 46 46 C 4 86 01 00 57 41 56 45 66 6D 74 20

10 00 00 00 01 00 02 00 44 AC 00 00 10 B1 02 00

04 00 10 00 64 61 74 61 A 0 86 01 00 D7 FA DA FE

52 49 46 46          ChunkID           "RIFF"

C4 86 01 00          ChunkSize      

57 41 56 45           Format            "WAVE"

66 6D 74 20          SubChunk1ID       "fmt "

10 00 00 00          SubChunk1Size

01 00                 AudioFormat

02 00                 NumChannels

44 AC 00 00          SampleRate

10 B1 02 00          ByteRate

04 00                 BlockAlign

10 00                 BitsPerSample

64 61 74 61          SubChunk2ID

A0 86 01 00          SubChunk2Size

*/

这篇关于WAVE头分析代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/656519

相关文章

Java中Map.Entry()含义及方法使用代码

《Java中Map.Entry()含义及方法使用代码》:本文主要介绍Java中Map.Entry()含义及方法使用的相关资料,Map.Entry是Java中Map的静态内部接口,用于表示键值对,其... 目录前言 Map.Entry作用核心方法常见使用场景1. 遍历 Map 的所有键值对2. 直接修改 Ma

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Python主动抛出异常的各种用法和场景分析

《Python主动抛出异常的各种用法和场景分析》在Python中,我们不仅可以捕获和处理异常,还可以主动抛出异常,也就是以类的方式自定义错误的类型和提示信息,这在编程中非常有用,下面我将详细解释主动抛... 目录一、为什么要主动抛出异常?二、基本语法:raise关键字基本示例三、raise的多种用法1. 抛

github打不开的问题分析及解决

《github打不开的问题分析及解决》:本文主要介绍github打不开的问题分析及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、找到github.com域名解析的ip地址二、找到github.global.ssl.fastly.net网址解析的ip地址三

Mysql的主从同步/复制的原理分析

《Mysql的主从同步/复制的原理分析》:本文主要介绍Mysql的主从同步/复制的原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录为什么要主从同步?mysql主从同步架构有哪些?Mysql主从复制的原理/整体流程级联复制架构为什么好?Mysql主从复制注意

深入解析 Java Future 类及代码示例

《深入解析JavaFuture类及代码示例》JavaFuture是java.util.concurrent包中用于表示异步计算结果的核心接口,下面给大家介绍JavaFuture类及实例代码,感兴... 目录一、Future 类概述二、核心工作机制代码示例执行流程2. 状态机模型3. 核心方法解析行为总结:三

python获取cmd环境变量值的实现代码

《python获取cmd环境变量值的实现代码》:本文主要介绍在Python中获取命令行(cmd)环境变量的值,可以使用标准库中的os模块,需要的朋友可以参考下... 前言全局说明在执行py过程中,总要使用到系统环境变量一、说明1.1 环境:Windows 11 家庭版 24H2 26100.4061

pandas实现数据concat拼接的示例代码

《pandas实现数据concat拼接的示例代码》pandas.concat用于合并DataFrame或Series,本文主要介绍了pandas实现数据concat拼接的示例代码,具有一定的参考价值,... 目录语法示例:使用pandas.concat合并数据默认的concat:参数axis=0,join=

java -jar命令运行 jar包时运行外部依赖jar包的场景分析

《java-jar命令运行jar包时运行外部依赖jar包的场景分析》:本文主要介绍java-jar命令运行jar包时运行外部依赖jar包的场景分析,本文给大家介绍的非常详细,对大家的学习或工作... 目录Java -jar命令运行 jar包时如何运行外部依赖jar包场景:解决:方法一、启动参数添加: -Xb

C#代码实现解析WTGPS和BD数据

《C#代码实现解析WTGPS和BD数据》在现代的导航与定位应用中,准确解析GPS和北斗(BD)等卫星定位数据至关重要,本文将使用C#语言实现解析WTGPS和BD数据,需要的可以了解下... 目录一、代码结构概览1. 核心解析方法2. 位置信息解析3. 经纬度转换方法4. 日期和时间戳解析5. 辅助方法二、L