精华内容
下载资源
问答
  • wave文件格式

    2014-05-04 17:04:17
    wave文件格式描述 WAVE文件作为多媒体中使用的声波文件格式之一,它是以RIFF格式为标准的。 RIFF是英文Resource Interchange File Format的缩写,每个WAVE文件的头四个 字节便是“RIFF”。
  • wave格式文件操作

    2012-02-08 22:15:39
    对.wav文件进行读写操作 介绍wave格式文件的存储格式和各个位置的含义 内附源代码
  • WAVE文件格式

    千次阅读 2017-04-15 13:50:24
    WAVE文件格式分析 来源: http://soundfile.sapp.org/doc/WaveFormat/ http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf Wave文件是用于多媒体文件存储的Microsoft RIFF(Resource Interchange...

    WAVE文件格式分析

    来源:
    http://soundfile.sapp.org/doc/WaveFormat/
    http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf

    Wave文件是用于多媒体文件存储的Microsoft RIFF(Resource Interchange File Format 资源交换档案标准)规范的子集之一。一个RIFF文件以一个文件头(File Header)开始,接着是一系列数据块(data chunk)。一个Wave文件常常是一个带有一个单“WAVE”块的RIFF文件。该“WAVE”chunk由两个子快组成,一个“fmt”chunk用于详细说明数据格式,一个“data”chunk包含实际的样本数据。这种形式我们称为规范形式。
    这里写图片描述

    OffsetSizeNameDescription
    04ChunkIDASCII码”0x52494646”对应字母”RIFF”
    44ChunkSize块大小是指除去ChunkID与ChunkSize的剩余部分有多少字节数据。注意:小尾字节序数。 Value=36+SubChunk2Size 或者 Value=4+(8+SubChunk1Size)+(8+SubChunk2Size)
    84FormatASCII码”0x57415645”对应字母”WAVE”。该块由两个子快组成,一个“fmt”chunk用于详细说明数据格式,一个“data”chunk包含实际的样本数据。
    124Subchunk1IDASCII码”0x666d7420”对应字母”fmt “。
    164Subchunk1Size如果文件采用PCM编码,则该子块剩余字节数为16。
    202AudioFormat如果文件采用PCM编码(线性量化),则AudioFormat=1。AudioFormat代表不同的压缩方式。
    222NumChannels声道数,单声道(Mono)为1, 双声道(Stereo)为 2。
    244SampleRate取样率,例:44.1kHz,48kHz。
    284ByteRate传输速率,单位:Byte/s。 Value==SampleRateNumChannelsBitsPerSample/8
    322BlockAlign一个样点(包含所有声道)的字节数。 Value==NumChannelsBitsPerSample/8
    342BitsPerSample每个样点对应的位数。
    2ExtraParamSize如果采用PCM编码,该值不存在。
    XExtraParams用于存储其他参数。如果采用PCM编码,该值不存在。
    364Subchunk2IDASCII码”0x64617461”对应字母”data”。
    404Subchunk2Size实际样本数据的大小(单位:字节)。 Value==NumSamplesNumChannelsBitsPerSample/8
    44*Data实际的音频数据 。

    这里写图片描述
    这里写图片描述
    上图所示例子,该WAVE文件采用PCM编码。该音频具有双声道,每个样点进行16位量化编码,双声道的一个样点占4字节,存储顺序是每个样点的左右声道交替存储。


    Q & A

    • 8bit与16bit样值的二进制编码表示是一样的吗?

      8bit样值以无符号形式存储,取值范围0-255 。而16bit样值以有符号的补码形式存储,取值范围-32768 to 32767。

    • 现有的WAV支持哪几种音频压缩方法

    AudioFormatDescription
    0 (0x0000)Unknown
    1 (0x0001)PCM/uncompressed
    2 (0x0002)Microsoft ADPCM
    6 (0x0006)ITU G.711 a-law
    7 (0x0007)ITU G.711 µ-law
    17 (0x0011)IMA ADPCM
    20 (0x0016)ITU G.723 ADPCM (Yamaha)
    49 (0x0031)ITU G.721 ADPCM
    80 (0x0050)MPEG
    65,536 (0xFFFF)Experimental

    展开全文
  • WAVE 文件格式分析

    千次阅读 2019-08-07 17:11:12
    WAVE 文件作为多媒体中使用的声音波形文件格式之一,它是以RIFF(Resource Interchange File Format)格式为标准的。每个WAVE文件的头四个字节便是“RIFF”。...WAVE文件各部分内容及格式见后文。 常见的声音...

             WAVE 文件作为多媒体中使用的声音波形文件格式之一,它是以RIFF(Resource Interchange File Format)格式为标准的。每个WAVE文件的头四个字节便是“RIFF”。WAVE 文件由文件头和数据体两大部分组成。其中文件头又分为 RIFF/WAV 文件标识段和声音数据格式说明段两部分。WAVE文件各部分内容及格式见后文。

             常见的声音文件主要有两种,分别对应于单声道(11.025KHz 采样率、8Bit 的采样值)和双声道(44.1KHz 采样率、16Bit 的采样值)。采样率是指:声音信号在“模→数”转换过程中单位时间内采样的次数。采样值是指每一次采样周期 
    内声音模拟信号的积分值。

             对于单声道声音文件,采样数据为八位的短整数(short int 00H-FFH);而对于双声道立体声声音文件,每次采样数据为一个16位的整数(int),高八位和低八位分别代表左右两个声道。

            WAVE 文件数据块包含以脉冲编码调制(PCM)格式表示的样本。WAVE 文件是由样本组织而成的。在单声道 WAVE 文件中,声道0代表左声道,声道1代表右声道。在多声道WAVE文件中,样本是交替出现的。

            WAVE 文件除了前面一小段文件头对数据组织进行说明之外,Data 块就是声音的原始采样数据,WAVE 文件虽然可以压缩,但一般都使用不压缩的格式。44.1KHz 采样率、16Bit的分辨率、双声道,所以WAVE可以保存音质要求非常高的声音文件,CD 采用的也是这种格式,声音方面的专家或是音乐发烧友们应该非常熟悉。但这种文件的体积也非常大,以 44.1KHz 16bit 双声道的数据为例,一分钟的声音数据量为:4100*2byte*2channel*60s/1024/1024=10.09M 。所以不合适在网上传送。

    下面我们具体地分析 WAVE 文件的格式:

    以下是对各个字段的详细解说:

    对于Data块,根据声道数和采样率的不同情况:

    下面我们看一个具体的例子,声音文件如下:

    对应的分析如下图所示:

    1.PCM Wave格式详解

    WAVE文件格式是微软RIFF(Resource Interchange File Format,资源交换文件标准)的一种,是针对于多媒体文件存储的一种文件格式和标准。 一般而言,RIFF文件由文件头和数据两部分组成,一个WAVE文件由一个“WAVE”数据块组成,这个“WAVE”块又由一个”fmt”子数据块和一个“data”子 数据块组成,也称这种格式为“Canonical form”(权威/牧师格式),如下图所示:

    “WAVE”格式由两个子数据块构成:“fmt”块和“data”块,其中“fmt”块的详细解释如下: Subchunk1ID: 占4个字节,内容为“fmt ”的ASCII码(0x666d7420),以大端存储。
    Subchunk1Size: 占4个字节,存储该子块的字节数(不含前面的Subchunk1ID和Subchunk1Size这8个字节),以小端方式存储。
    AudioFormat:占2个字节,以小端方式存储,存储音频文件的编码格式,例如若为PCM则其存储值为1,若为其他非PCM格式的则有一定的压缩。
    NumChannels: 占2个字节,以小端方式存储,通道数,单通道(Mono)值为1,双通道(Stereo)值为2,等等。
    SampleRate: 占4个字节,以小端方式存储,采样率,如8k,44.1k等。
    ByteRate: 占4个字节,以小端方式存储,每秒存储的bit数,其值=SampleRate * NumChannels * BitsPerSample/8
    BlockAlign: 占2个字节,以小端方式存储,块对齐大小,其值=NumChannels * BitsPerSample/8
    BitsPerSample: 占2个字节,以小端方式存储,每个采样点的bit数,一般为8,16,32等。
    接下来是两个可选的扩展参数:
    ExtraParamSize: 占2个字节,表示扩展段的大小。
    ExtraParams: 扩展段其他自定义的一些参数的具体内容,大小由前一个字段给定。

    其中,对于每个采样点的bit数,不同的bit数读取数据的方式不同:

    “WAVE”格式文件的第二个子数据块是“data”,其个字段的详细解释如下:
    Subchunk2ID: 占4个字节,内容为“data”的ASCII码(0x64617461),以大端存储。
    Subchunk2Size: 占4个字节,内容为接下来的正式的数据部分的字节数,其值=NumSamples * NumChannels * BitsPerSample/8
    Data: 真正的语音数据部分。

    一个Wave文件头的实例

    设一个wave文件的前72个字节的十六进制内容如下(可以使用Ultra Edit等工具查看wave文件头):

    则其个字段的解析如下图:

    使用C语言文件操作库函数实现的Wave文件读取的实例代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    // define Wave format structure
    typedef struct tWAVEFORMATEX
    {
        short wFormatTag;         /* format type */
        short nChannels;          /* number of channels (i.e. mono, stereo...) */
        unsigned int nSamplesPerSec;     /* sample rate */
        unsigned int nAvgBytesPerSec;    /* for buffer estimation */
        short nBlockAlign;        /* block size of data */
        short wBitsPerSample;     /* number of bits per sample of mono data */
        short cbSize;             /* the count in bytes of the size of */
                                        /* extra information (after cbSize) */
    } WAVEFORMATEX, *PWAVEFORMATEX;
    
    char* wavread(char *fname, WAVEFORMATEX *wf);
    
    int main(){
      char fname[] = "test.wav";
      char *speech;
      WAVEFORMATEX wf;
      
      speech = wavread(fname, &wf);
      // afterward processing...
      
      return 0;
    }
    
    // read wave file
    char* wavread(char *fname, WAVEFORMATEX *wf){
      FILE* fp;
      char str[32];
      char *speech;
      unsigned int subchunk1size; // head size
      unsigned int subchunk2size; // speech data size
    
      // check format type
      fp = fopen(fname,"r");
      if(!fp){
          fprintf(stderr,"Can not open the wave file: %s.\n",fname);
          return NULL;
      }
      fseek(fp, 8, SEEK_SET);
      fread(str, sizeof(char), 7, fp);
      str[7] = '\0';
      if(strcmp(str,"WAVEfmt")){
          fprintf(stderr,"The file is not in WAVE format!\n");
          return NULL;
      }
      
      // read format header
      fseek(fp, 16, SEEK_SET);
      fread((unsigned int*)(&subchunk1size),4,1,fp);
      fseek(fp, 20, SEEK_SET);
      fread(wf, subchunk1size, 1, fp);
      
      // read wave data
      fseek(fp, 20+subchunk1size, SEEK_SET);
      fread(str, 1, 4, fp);
      str[4] = '\0';
      if(strcmp(str,"data")){
          fprintf(stderr,"Locating data start point failed!\n");
          return NULL;
      }
      fseek(fp, 20+subchunk1size+4, SEEK_SET);
      fread((unsigned int*)(&subchunk2size), 4, 1, fp);
      speech = (char*)malloc(sizeof(char)*subchunk2size);
      if(!speech){
          fprintf(stderr, "Memory alloc failed!\n");
          return NULL;
      }
      fseek(fp, 20+subchunk1size+8, SEEK_SET);
      fread(speech, 1, subchunk2size, fp);
    
      fclose(fp);
      return speech;
    }

     

    展开全文
  • 详解WAVE音频文件格式

    千次阅读 2019-02-21 15:25:12
    详解WAVE音频文件格式
                   

    详解WAVE音频文件格式

     WAVE声音文件格式是目前Windows最直接保存声音数据的文件格式.在涉及声音信号处理时大多是对WAV文件直接操作,有必要搞清楚所研究声音的文件格式.

    1 RIFF文件与WAV文件

     在Windows环境下,大部分多媒体文件都依循着一种结构来存放信息,称为资源互换文件格式(Resources Interchange File Format),简称RIFF。比如声音的WAV文件,视频的AVI文件,动画的MMM文件等均是由此结构衍生出来的.所以,要掌握多媒体文件格式,首先得认识RIFF的结构.

     RIFF是一种树状结构,其基本组成单位是chunk(即块),每个chunk由辨识码,数据大小和数据组成,如下图。可以看出,一个chunk的长度,就是数据的大小加上8Byte.


    一般而言,chunk本身不允许内部再包含chunk,但有两个例外:以"RIFF"和以"UST"为辨识码的chunk。针对这两种chunk,RIFF又从原先的"裸数据"中切出4Byte作为"格式辨别码",如下图所示.


    对RIFF的树状结构有所了解之后,可以知道它相当于一个根目录,而格式辨识码则相当于具体的盘符如C:,D:等等.Windows下的各种多媒体文件格式就如同在磁盘机下规定只能存放怎样的目录,而在该目录下仅能存放何种数据.

    2 WAV文件头

     顾名思义,WAV就是波形音频文件(Wave Audio),是Windows中用来表示数字化声音的一种标准格式,其文件扩展名为.wav,是一种非常简单的RIFF文件,格式辨识码为"WAVE".整个WAV文件分成两部分:文件头和数据块.WAV格式文件主要有两种文件头.

    2.1标准的44字节文件头

     这种WAV是最简单的一种RIFF格式,包含两个chunk:<fmt—chunk>,<wave—data>,这两个子块都是一个WAV文件必须包含的.
     <fmt—chunk>子块,描述了波形数据<wave~data>的格式,对于44字节文件头,它由结构PCMWAVEF0RMAT组成,其子块大小是sizeof(PCMWAVEF0RMAT),数据是PCMWAVEF0RMAT的数据,如下图所示,其中PCMWAVEF0RMAT是PCM波形音频数据的数据格式结构,大小是l6字节(少数为18字节),定义如下:


     RIFF WAVE Chunk
        =======================
        |名称   |所占字节数 |  具体内容   
        =======================
        | ID      |  4 Bytes    |  'RIFF'    
        ----------------------------------------
        | Size   |  4 Bytes    |             
        ----------------------------------------
        | Type  |  4 Bytes    |  'WAVE'    
        ----------------------------------------

    以'RIFF'作为标示,然后紧跟着为size字段,该size是整个wav文件大小减去ID和Size所占用的字节数,即FileLen - 8 =Size.然后是Type字段,为'WAVE',表示是wav文件.结构定义如下:

     struct RIFF_HEADER { char szRiffID[4];  // 'R','I','F','F' DWORD dwRiffSize; char szRiffFormat[4]; // 'W','A','V','E' };

      Format Chunk
       ====================================================
       | 名称                       |   字节数 |             具体内容               
       ====================================================
        |ID                           |  4Bytes  |   'fmt'                            
       -----------------------------------------------------------------------------------------------
        | Size                      |  4 Bytes  | 数值为16或18,18则最后又附加信息    
       -----------------------------------------------------------------------------------------------
        | FormatTag           |  2 Bytes  | 编码方式,一般为0x0001(WAVE—FORMAT_PCM)             
       -----------------------------------------------------------------------------------------------    
        | Channels              |  2Bytes  | 声道数目,1--单声道;2--双声道       
        ----------------------------------------------------------------------------------------------  
        | SamplesPerSec   |  4 Bytes  | 采样频率                           
       -----------------------------------------------------------------------------------------------   
        | AvgBytesPerSec  |  4 Bytes  | 每秒所需字节数  ===> WAVE_FORMAT
       -------------------------------------------------------------------------------------------------
        | BlockAlign            |  2 Bytes  | 数据块对齐单位(每个采样需要的字节数) 
       -------------------------------------------------------------------------------------------------
        | BitsPerSample     |  2 Bytes  | 每个采样需要的bit数                                 
       -------------------------------------------------------------------------------------------------
       |                               |  2 Bytes  | 附加信息(可选,通过Size来判断有无) 
        ------------------------------------------------------------------------------------------------

    以'fmt '作为标示.一般情况下Size为16,此时最后附加信息没有;如果为18则最后多了2个字节的附加信息.主要由一些软件制成的wav格式中含有该2个字节的
    附加信息.结构定义如下:

     struct WAVE_FORMAT { WORD wFormatTag; WORD wChannels; DWORD dwSamplesPerSec; DWORD dwAvgBytesPerSec; WORD wBlockAlign; WORD wBitsPerSample; }; struct FMT_BLOCK { char  szFmtID[4]; // 'f','m','t',' ' DWORD  dwFmtSize; WAVE_FORMAT wavFormat; };

    为了产生出能够正确读出的WAV文件,必须严格注意以下几个分量间的特定关系,否则产生出的文件将无法正常播放:
    nAvgBytesPerSec = nSamplesPerSec*nChannels*wBitsPerSample/8
    nBlockAlign = nChannels*wBitsPerSample/8
    根据以上规则,下图给出一个8kHz采样,16bit量化的声音文件的<fmt—chunk>.

    2.2 58字节文件头

    如果不是Windows的标准WAV文件,而是经过了一些软件处理的,往往就是58字节的文件头,如下图所示.


    它比44字节的多了一个fact子块.<fact—ck>储存了关于WAV文件内容的重要信息.该子块定义如下:

    Fact Chunk
        ======================
        |名称  |所占字节数|  具体内容   
        ======================
        | ID     |  4 Bytes   |  'fact'    
        ---------------------------------------
        | Size  |  4 Bytes  |  数值为4   
        -------------------------------------
        | data  |  4 Bytes |            
        -------------------------------------

    Fact Chunk是可选字段,一般当wav文件由某些软件转化而成,则包含该Chunk.结构定义如下:

     struct FACT_BLOCK { char  szFactID[4]; // 'f','a','c','t' DWORD  dwFactSize; };

    3 "data"子块数据安排方式

     "data"子块中装的是真正的声音数据.除非安装其它特殊软件,否则Windows目前仅提供WAVE_FORMAT_PCM一种数据格式,即脉冲编码调制(Pulse Code Modulation).针对此惭式,Windows中"data"子块中数据存放的形式如下图所示,根据声道数不同及取样位数的不同,安排4位的位置.


        Data Chunk头结构定义如下:

    struct DATA_BLOCK { char szDataID[4]; // 'd','a','t','a' DWORD dwDataSize; };

     注意:Windows中将16位值的范围定为[-32768,32767].另外,0并不一定代表无声,而是由中间数值来决定,即8位的时候为128,l6位时0才是无声.所以,编程中需要放入无声的数据时,必须先认清声音格式是l6位还是8位.
     通常解压缩后得到的文件仅仅是裸数据,不能正常播放声音.了解了WAV文件格式后,就可以按照标准的44字节格式,在解码数据前编写一个正确的WAV文件头,使其成为一个有效的WAV文件.

    4 实例文件分析

      下面我们来分析一个真正的WAVE文件(http://download.csdn.net/detail/ce123/5771797).


    对照前面的讲解,看懂这个文件的结构应该非常容易大笑.

               

    再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

    展开全文
  • wave文件格式详解

    千次阅读 2020-06-29 17:59:36
    wav格式,是微软开发的一种文件格式规范,整个文件分为两部分。第一部分是“总文件头”,就包括两个信息,chunkID,其值为“RIFF”,占四个字节;ChunkSize,其值是整个wav文件除去chunkID和ChunkSize,后面所有文件...

    目录

     

    第一节 wav格式scheme介绍

    第二节 真实wav文件分析

    第三节 python读取wav文件


    第一节 wav格式scheme介绍

    wav格式,是微软开发的一种文件格式规范,整个文件分为两部分。第一部分是“总文件头”,就包括两个信息,chunkID,其值为“RIFF”,占四个字节;ChunkSize,其值是整个wav文件除去chunkID和ChunkSize,后面所有文件大小的字节数,占四个字节。

    第二部分是Format,其值为“wave”,占四个字节。它包括两个子chunk,分别是“fmt ”和“data”。在fmt子chunk中定义了该文件格式的参数信息,对于音频而言,包括:采样率、通道数、位宽、编码等等;data部分是“数据块”,即一帧一帧的二进制数据,对于音频而言,就是原始的PCM数据。

    图一 wav格式文件示意图

    表一 wav格式字段说明

    Offset

    Size

    Name

    Description

    0

    4

    ChunkID

    ASCII码“0x52494646”对应字母“RIFF

    4

    4

    ChunkSize

    块大小是指除去ChunkIDChunkSize的剩余部分有多少字节数据。注意:小尾字节序数。 

    8

    4

    Format

    ASCII码“0x57415645”对应字母“WAVE”。该块由两个子块组成,一个“fmt”块用于详细说明数据格式,一个“data”块包含实际的样本数据。

    12

    4

    Subchunk1ID

    ASCII码“0x666d7420”对应字母“fmt ”。

    16

    4

    Subchunk1Size

    如果文件采用PCM编码,则该子块剩余字节数为16

    20

    2

    AudioFormat

    如果文件采用PCM编码(线性量化),则AudioFormat=1AudioFormat代表不同的压缩方式,表二说明了相应的压缩方式。

    22

    2

    NumChannels

    声道数,单声道(Mono)为1,双声道(Stereo)为2

    24

    4

    SampleRate

    取样率,例:44.1kHz48kHz

    28

    4

    ByteRate

    传输速率,单位:Byte/s

    32

    2

    BlockAlign

    一个样点(包含所有声道)的字节数。

    34

    2

    BitsPerSample

    每个样点对应的位数。

     

    2

    ExtraParamSize

    如果采用PCM编码,该值不存在。

     

    X

    ExtraParams

    用于存储其他参数。如果采用PCM编码,该值不存在。

    36

    4

    Subchunk2ID

    ASCII码“0x64617461”对应字母 data”。

    40

    4

    Subchunk2Size

    实际样本数据的大小(单位:字节)。

    44

    *

    Data

    实际的音频数据

     

    表二 wave支持格式

    AudioFormat

    Description

    0 (0x0000)

    Unknown

    1 (0x0001)

    PCM/uncompressed

    2 (0x0002)

    Microsoft ADPCM

    6 (0x0006)

    ITU G.711 a-law

    7 (0x0007)

    ITU G.711 µ-law

    17 (0x0011)

    IMA ADPCM

    20 (0x0016)

    ITU G.723 ADPCM (Yamaha)

    49 (0x0031)

    ITU G.721 ADPCM

    80 (0x0050)

    MPEG

    65,536 (0xFFFF)

    Experimental

    第二节 真实wav文件分析

    实例分析:

    下面notepad++打开一个wav的文件,看看里面十六进制内容。开始四个字节从小到大分别是0x52H、0x49H、0x46H、0x46H,分别对应ASCII的R、I、F、F字符。

    根据第一节的格式介绍,其后四个字节是整个文件除去ChunkID、ChunkSize的大小,这里是00003224H,十进制为12836。从偏移字节地址8开始的四个字节为Format字段,内容为0x57415645,其对应的就是ASCII字符W、A、V、E。

    0c~0f字节内容表示subchunk1ID的值“fmt(空格)”。

    10H~13H值为ox00000010,十进制为16,表明该字块剩余占空间大小,14H-15H值为0001H,表明当前编码PCM。

    16H-17H,表明通道数,为1;18H-1bH表明采样率,0x00001f40,十进制为8000。紧接着四个字节表明字节率,每个采样点占两个字节,那么该值为0x00003e80,十进制为16000。20H-21H对应BlockAlign,表示每个样本点占字节数0x0002,两个字节;22H-23H表明每个样本点占bit为数,0x0010,16个,与前一个值两个字节对应上。该音频文件是PCM格式,那么fmt子chunk在10H-13H为16,表明到该头字段结束处的剩余字节数为16,从14H到23H(包括23H字节)正好是16个字节。

    24H-27H的值为ASCII字符d、a、t、a。其后四个字节为小端方式存储的数据“0x00003200”,表明音频数据段的大小为0x00003200,十进制为12800。从2c的a8H到322b的00H结束,正好是3200H个字节。

    再看一个双声道的实例。下图是一个双声道的音频文件。

    16H-17H,表明通道数,为2;18H-19H表明采样率,0x0000ac44,十进制为44100,表明当前wav录音文件的采样率是44.1K。紧接着四个字节表明字节率,每个采样点占两个字节,且是双声道,那么该值为ox0002b110,十进制为176400(44100*4)。20H-21H对应BlockAlign,表示每个样本点占字节数0x0004,4个字节,它是每个采样点占2个字节*双声道;22H-23H表明每个采样点占bit位数,0x0010,16位。

    注释:采样点占bit位:是对波形进行离散采样,表示深度分8位、16位、24位等,不考虑声道数目;样本点占字节数得考虑声道数,双声道是单声道的2倍。

    第三节 python读取wav文件

    读取上面给的第一个示例wav文件

    # coding: utf-8
    
    import wave
    from typing import Any, Dict
    import numpy as np
    
    nchannels = 0
    sampwidth = 0
    framerate = 0
    
    def _WriteWav(fp: str, data: Dict) -> None:
        # 打开WAV文档
        f = wave.open(fp, "wb")
        # 配置声道数、量化位数和取样频率
        f.setnchannels(nchannels)
        f.setsampwidth(sampwidth)
        f.setframerate(framerate)
        # 将wav_data转换为二进制数据写入文件
        f.writeframes(data)
        f.close()
    
    def _ReadWave(wav_path: str) -> None:
        global nchannels, sampwidth, framerate
        f = wave.open(wav_path, 'rb')
        params = f.getparams()
        nchannels, sampwidth, framerate, nframes = params[:4]
        print("时常:", float(nframes / framerate))
        print("channels:", nchannels)
        print("sampewidth:", sampwidth)
        print("framerate:", framerate)
        print("framenumber:", nframes)
        strData = f.readframes(nframes)  # 读取音频,字符串格式
        print("len of strdata: ", len(strData))
        waveData = np.fromstring(strData, dtype=np.int16)#将字符串转化为int
    
    if __name__ == "__main__":
        filename = "data/20200423152348/0.wav"
        _ReadWave(filename)
    
    

    Import wave包,通过open函数读取wav文件。

    输出结果:

    时常: 0.8
    channels: 1
    sampewidth: 2
    framerate: 8000
    framenumber: 6400
    len of strdata:  12800
    
    WAVE_FORMAT_PCM = 0x0001
    
    _array_fmts = None, 'b', 'h', None, 'i'
    
    import audioop
    import struct
    import sys
    from chunk import Chunk
    from collections import namedtuple
    
    
    class Wave_read:
      
    
    class Wave_write:
        
    
    def open(f, mode=None):
       

    wave包主要包含三部分,函数open、类Wave_read、类Wave_write。

    其中open的代码如下:

    def open(f, mode=None):
        if mode is None:
            if hasattr(f, 'mode'):
                mode = f.mode
            else:
                mode = 'rb'
        if mode in ('r', 'rb'):
            return Wave_read(f)
        elif mode in ('w', 'wb'):
            return Wave_write(f)
        else:
            raise Error("mode must be 'r', 'rb', 'w', or 'wb'")
    

    最终返回write或者read的对象,根据mode参数来选择。所以在_ReadWave函数中f = wave.open(path, ‘rb’),表明f是一个Wave_read对象。对wave文件的读取主要在Wave_read中。下面看看该类的主要代码。

    class Wave_read:   
    
        def initfp(self, file):
            self._convert = None
            self._soundpos = 0
            self._file = Chunk(file, bigendian = 0)
            if self._file.getname() != b'RIFF':
                raise Error('file does not start with RIFF id')
            if self._file.read(4) != b'WAVE':
                raise Error('not a WAVE file')
            self._fmt_chunk_read = 0
            self._data_chunk = None
            while 1:
                self._data_seek_needed = 1
                try:
                    chunk = Chunk(self._file, bigendian = 0)
                except EOFError:
                    break
                chunkname = chunk.getname()
                if chunkname == b'fmt ':
                    self._read_fmt_chunk(chunk)
                    self._fmt_chunk_read = 1
                elif chunkname == b'data':
                    if not self._fmt_chunk_read:
                        raise Error('data chunk before fmt chunk')
                    self._data_chunk = chunk
                    self._nframes = chunk.chunksize // self._framesize
                    self._data_seek_needed = 0
                    break
                chunk.skip()
            if not self._fmt_chunk_read or not self._data_chunk:
                raise Error('fmt chunk and/or data chunk missing')
    
    
        def readframes(self, nframes):
            if self._data_seek_needed:
                self._data_chunk.seek(0, 0)
                pos = self._soundpos * self._framesize
                if pos:
                    self._data_chunk.seek(pos, 0)
                self._data_seek_needed = 0
            if nframes == 0:
                return b''
            data = self._data_chunk.read(nframes * self._framesize)
            if self._sampwidth != 1 and sys.byteorder == 'big':
                data = audioop.byteswap(data, self._sampwidth)
            if self._convert and data:
                data = self._convert(data)
            self._soundpos = self._soundpos + len(data) // (self._nchannels * self._sampwidth)
            return data
    
        def _read_fmt_chunk(self, chunk):
            wFormatTag, self._nchannels, self._framerate, dwAvgBytesPerSec, wBlockAlign = struct.unpack_from('<HHLLH', chunk.read(14))
            if wFormatTag == WAVE_FORMAT_PCM:
                sampwidth = struct.unpack_from('<H', chunk.read(2))[0]
                self._sampwidth = (sampwidth + 7) // 8
            else:
                raise Error('unknown format: %r' % (wFormatTag,))
            self._framesize = self._nchannels * self._sampwidth
            self._comptype = 'NONE'
            self._compname = 'not compressed'
    
    
    
    

    主要包括三个函数,其他细节省略,可以自己去看wave的源码,比较好理解。initfp()函数进行了大部分的格式处理。包括对头文件的解析和数据的提取。通过不断的构建chunk对象把wave格式的文件进行解包。在第一次构建chunk时,读取总的RIFF字符和ChunkSize,然后确认“wave”字符,最后循环读取子chunk,分别是fmt和data,具体可以看下面chunk的代码。主要处理逻辑在__init__( )初始化函数和read( )函数中。

    class Chunk:
        def __init__(self, file, align=True, bigendian=True, inclheader=False):
            import struct
            self.closed = False
            self.align = align      # whether to align to word (2-byte) 
            if bigendian:
                strflag = '>'
            else:
                strflag = '<'
            self.file = file
            self.chunkname = file.read(4)
            if len(self.chunkname) < 4:
                raise EOFError
            try:
                self.chunksize = struct.unpack_from(strflag+'L', file.read(4))[0]
            except struct.error:
                raise EOFError
            if inclheader:
                self.chunksize = self.chunksize - 8 # subtract header
    
        def read(self, size=-1):
            if self.closed:
                raise ValueError("I/O operation on closed file")
            if self.size_read >= self.chunksize:
                return b''
            if size < 0:
                size = self.chunksize - self.size_read
            if size > self.chunksize - self.size_read:
                size = self.chunksize - self.size_read
            data = self.file.read(size)
            self.size_read = self.size_read + len(data)
            if self.size_read == self.chunksize and \
               self.align and \
               (self.chunksize & 1):
                dummy = self.file.read(1)
                self.size_read = self.size_read + len(dummy)
            return data
    

    细心的对着第一节和第二节的内容,来解读源码会比较容易理解,对wave文件格式以及python的wave包代码逻辑也有非常清晰的了解。

    展开全文
  • Wave文件格式.pdf

    2021-10-04 22:32:10
    Wave文件格式.pdf
  • 详解WAVE文件格式

    2015-08-06 11:36:45
    整理网上和读书时的资料,结合自己的实际经验,给出wav头格式的解释和源代码,既是对 自己的总结,同时又服务大家。另外在给出几个实际例子,如果看了这篇文档还不能正确写出 wave文件,那就要吊起来打了
  • wave文件 wav格式

    2014-09-11 11:04:35
    2. wave文件格式   2.1 概述   WAVE文件是计算机领域最常用的数字化声音文件格式之一,它是微软专门为Windows系统定义的波形文件格式(Waveform Audio),由于其扩展名为"*.wav"。   WAVE是...
  • wave文件格式解析

    2012-03-21 11:35:36
    这个比较简单,是解析wav文件格式的,wav是比较常见的音频格式了,所以一看就会明白
  • wave格式的音频文件

    2011-03-11 15:15:58
    用C编写的一个程序来产生一个.wave格式的音频文件
  • WAVE文件格式解析代码

    2012-03-30 09:48:14
    WAVE文件格式解析代码,代码简单易读,短小精悍。
  • 简单的PCM类型的WAVE文件格式 简单的PCM类型的WAVE文件格式
  • 本文将详细分析WAVE音频文件的格式,并通过C语言对wave文件头进行读写操作。WAVE音频文件格式分析–实现C语言读写文件头WAVE音频文件WAVE文件格式是一种由微软和IBM联合开发的用于音频数字存储的标准, 它采用RIFF...
  • wave文件格式分析

    千次阅读 2017-04-13 16:57:17
    wave(waveform audio file format)文件格式是微软和IBM的音频标准文件格式,支持压缩和无压缩,但通常为无压缩格式,所以文件较大,音质较好。 它采用RIFF即chunk文件存储方式。
  • WAVE文件格式剖析.mht

    2009-12-08 18:54:16
    WAVE文件格式剖析 比较好的Wave格式介绍
  • WAVE文件格式剖析

    2014-10-16 15:31:27
    WAVE文件格式剖析 WAVE文件作为多媒体中使用的声波文件格式之一,它是以RIFF格式为标准的。RIFF是英文Resource Interchange File Format的缩写,每个WAVE文件的头四个字节便是“RIFF”。WAVE文件由文件头和数据体两...
  • WAVE 文件格式

    2010-12-22 14:08:00
    time: 2010-12-7 13:43:29WAVE 文件格式简介 WAV文件格式的应用是非常广泛的。 这里首先值得一提的是,... Wave文件使用三个参数来表示声音 ,它们是:声道数、采样位数和采样频率。 采样位数:即采样值或取样值(就
  • WAVE文件格式分析

    2017-04-16 19:14:39
    WAVE文件是计算机领域最常用的数字化声音文件格式之一,它是微软专门为Windows系统定义的波形文件格式(Waveform Audio),其扩展名为"*.wav",数据本身的格式为PCM或压缩型。最基本的WAVE文件是PCM(脉冲编码调制)...
  • WAVE PCM 声音文件格式

    千次阅读 2013-05-07 09:48:11
    WAVE文件格式是Microsoft为存储多媒体的RIFF规范的一部分。一个RIFF文件以一个文件头开始,然后是一系列的数据块。一个WAVE文件常常仅由一个WAVE块构成,WAVE块包含一个说明格式的fmt块和存储取样信息的数据块。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 28,348
精华内容 11,339
关键字:

wave是什么格式文件