拙网论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 213|回复: 0

WAVE头分析代码

[复制链接]

949

主题

1001

帖子

3736

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3736
发表于 2018-7-24 18:18:12 | 显示全部楼层 |阅读模式
这篇文章是网络上流行的比较广泛的针对WAVE头分析的文章, 整体写的简单明了非常好,但是
  
18H
  
  
2
  
  
int
  
  
采样率(每秒样本数),表示每个通道的播放速度,
  
应该是不对的, 如果按这个该文章的计算,WAVE头只有42byte, 实际上wave头是44byte.
参考MS的标准文档知道这个采样率是占4byte.( WAVE PCM soundfile format )
//----------------------------------------------------------------
WAVE文件格式剖析 WAVE 文件作为多媒体中使用的声波文件格式之一,它是以RIFF格式为标准的。RIFF是英文Resource Interchange FileFormat的缩写,每个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      longint   文件长度(WAVE文件的大小, 不含前8个字节)
Format        4      char       "WAVE"标志
SubChunk1ID   4      char       "fmt"标志
SubChunk1Size 4                 过渡字节(不定)
AudioFormat   2      shortint  格式类别(1PCM格式的声音数据)
NumChannels   2      shortint  通道数(单声道为1, 双声道为2)
SampleRate    4      longint   采样率(每秒样本数), 表示每个通道的播放速度
                                一般情况是每秒采样44100
                              
ByteRate      4      longint   波形音频数据传输速率, 其值为:通道数*每秒数据位数*每样本的数据位数/8
                                播放软件可以利用该值估计缓冲区大小
                                2*
BlockAlign    2      shortint  每样本的数据位数(按字节算), 其值为:通道数*每样本的数据位值/8 播放
软件需要一次处理多个该值大小的字节数据, 以便将其值用于缓冲区的调整
                                每样本占几个字节 : NumChannels * 16/8
                              
BitsPerSample 2                 每样本的数据位数, 表示每个声道中各个样本的数据位数. 如果有多个声道,
                                对每个声道而言, 样本大小都一样
                                就是分辨率, 一般是16, 8位也有但是要少一些.
                              
SubChunk2ID       4      char   数据标记"data"
SubChunk2Size 4      longint   语音数据的长度
*/
#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 shortint 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 C4 86 01 00 57 41 56 4566 6D 74 20
10 00 00 00 01 00 02 00 44AC 00 00 10 B1 02 00
04 00 10 00 64 61 74 61 A0 86 01 00D7 FA DA FE
52 49 4646          ChunkID           "RIFF"
C4 86 0100          ChunkSize      
57 41 5645           Format            "WAVE"
66 6D 74 20          SubChunk1ID       "fmt"
10 00 0000          SubChunk1Size
0100                 AudioFormat
0200                 NumChannels
44 AC 0000          SampleRate
10 B1 0200          ByteRate
0400                 BlockAlign
1000                 BitsPerSample
64 61 7461          SubChunk2ID
A0 86 0100          SubChunk2Size
*/

版权声明:本文为博主原创文章,未经博主允许不得转载。https://blog.csdn.net/sshcx/article/details/1593923


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|抱朴守拙BBS

GMT+8, 2025-5-26 07:30 , Processed in 0.225494 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表