HTK中的wav文件格式

来源:互联网 发布:07式作战靴淘宝网 编辑:程序博客网 时间:2024/06/06 08:37

HTK3.4程序员手册(1.1)--HTK中的wav文件格式
by 云龙 


1.1.1
 HTK中的Wav
文件格式

HTK3.4支持wav文件格式称为HTK格式。头部为HTKhdr结构,占12个字节。无头的wav文件。默认16000Hz,单声道(mono),16位。Motorola PCM(MSB,LSB)格式。平时通过Cool Edit录制的语音是wav带文件头的Intel PCM(LSB,MSB)格式。

Wav文件格式有两种,Motorola PCM(MSB,LSB)格式和Intel PCM(LSB,MSB)格式。Motorola PCM(MSB,LSB)格式是采用Big Endian方式存储。Intel PCM(LSB,MSB)格式是采用Little Endian的方式存储。那么如何将Intel PCM(LSB,MSB)Little Endian转换为Big Endian格式呢?
 

//Intel PCM(LSB,MSB)Little Endian转换为Big Endian格式

int ConvertIntelPCMtoMotorolaPCM(int Src,int *Dst){

        int Low8 = (Src&0xFF)<<8;

        int High8 = (Src&0xFF00)>>8;

        int New16 = Low8 | High8 ;

        *Dst = New16;

        return 1;

}

 

HTK3.4持的wav文件格式(无头的wav文件。默认16000Hz,单声道(mono),16位。Motorola PCM(MSB,LSB)格式)又是怎么样的呢?
 

       HTK3.4中的HTK Header结构:

typedef struct {              /* HTK File Header */

   int32 nSamples;                 //4字节,语音样本数。一个样本16byte

   int32 sampPeriod; //4字节,一个样本持续的时间(百ns)。/* Sample period in 100ns units */

   short sampSize;                 //2字节,一个语音样本占的字节数。16byte=2字节

   short sampKind;                //2字节,种类。这里=0

} HTKhdr;

注意:HTK中写到文件的时候要把字节位置颠倒。比如nSamples1-4字节写为4-1位置。

 

HTK3.4中读取HTKhdr的函数:

/* EXPORT ReadHTKHeader: get header from HTK file, return false not HTK */

Boolean ReadHTKHeader(FILE *f, long *nSamp, long *sampP, short *sampS,

                      short *kind, Boolean *bSwap)

{

   HTKhdr hdr;

   int n = sizeof hdr;    //n=12

  

   if (fread(&hdr, 1, n, f) != n)

      return FALSE;

   if (!natReadOrder && vaxOrder){

      *bSwap = TRUE;

   }else{

      *bSwap=MustSwap(UNKNOWNSO);

   }

   if (*bSwap){

      SwapInt32(&hdr.nSamples);         //将颠倒的byte倒回来,下同

      SwapInt32(&hdr.sampPeriod);         //…

      SwapShort(&hdr.sampSize);         //…

      SwapShort(&hdr.sampKind);         //…

   }

//这个if纯属检查参数,同样的检查在HTK3.4中还有N多

   if (hdr.sampSize <= 0 || hdr.sampSize > 5000 || hdr.nSamples <= 0 ||

       hdr.sampPeriod <= 0 || hdr.sampPeriod > 1000000)

      return FALSE;

   *nSamp = hdr.nSamples; *sampP = hdr.sampPeriod;

   *sampS = hdr.sampSize; *kind = hdr.sampKind;

   return TRUE;

}

 

 

例如w2.wav头部

00 00 99 2000 00 02 71 00 02 00 00 00 9A 01 24 00 E6 01 12 01 3C 01 47 01 B0 01 67 01 3B 01 4D

W2.wav头部:

nSamples4字节)

00 00 99 20

sampPeriod

00 00 02 714字节)

sampSize

00 022字节)

sampKind

00 002字节)

颠倒回来:20 99 00 00

样本数=0x9920 = 39200

文件大小= 39200*2+12字节

=78412字节

和文件属性中的大小相同

颠倒回来:71 02 00 00

=0x0271 = 625

一个样本持续的时间=

1/16000 * 107= 625(百纳秒)

颠倒回来:02 00

每个样本的字节数=0x00 02

=2

种类=0

种类参照下表。

 

HTK代码中支持的语音种类编号:(WAVEFORM=0,其他依次类推)

enum _BaseParmKind{

      WAVEFORM,            /* Raw speech waveform (handled by HWave) */

      LPC,LPREFC,LPCEPSTRA,LPDELCEP,   /* LP-based Coefficients */

      IREFC,                           /* Ref Coef in 16 bit form */

      MFCC,                            /* Mel-Freq Cepstra */

      FBANK,                           /* Log Filter Bank */

      MELSPEC,                         /* Mel-Freq Spectrum (Linear) */

      USER,                            /* Arbitrary user specified data */

      DISCRETE,                        /* Discrete VQ symbols (shorts) */

      PLP,                             /* Standard PLP coefficients */

      ANON};

 

HTKWave结构的信息:

typedef struct _Wave{   /* Internal wave file representation */

   MemHeap *mem;        /* memory heap for this wave rec */

   FileFormat fmt;      /* Format of associated source file */

   Boolean isPipe;      /* Source is a pipe */

   HTime sampPeriod;    /* Sample period in 100ns units */

   int  hdrSize;        /* Header size in bytes */

   long nSamples;       /* No of samples in data */

   long nAvail;         /* Num samples allocated for data */

   short *data;         /* Actual data (always short once loaded) */

   int frSize;          /* Num samples per frame */

   int frRate;          /* Frame rate */

   int frIdx;           /* Start of next frame */

}WaveRec;

 

HTK中默认一个窗=250000百纳秒=25000微秒=25毫秒。

每一个窗口包含的样本数 =窗大小/每个样本持续的时间 = 250000/625 = 400个样本

w->frSize = (int) (winDur / w->sampPeriod);
 

Wav头部也有2种,44字节和58字节。其中44字节头文件的wav文件格式:

WAV文件头(共占用44Bytes):

偏移地址

数据类型

字节数

内容

例值(16进制)

00H

char

4

“RIFF”标志

52 49 46 46

04H

long int

4

波形数据块大小=文件大小-8=数据大小+44-8

例如:04 7F 02 00(逆向)

长度=00h*2^24   +02h*2^16+7fh*2^8+04h

08H

char

4

“WAVE”标志

57 41 56 45

0CH

char

4

“fmt”标志

66 6D 74 20

10H

char

4

格式数据块的大小

10 00 00 00

14H

int

2

格式类别

wFormatTag=WAVE_FORMAT_PCM=1

01 00

16H

int

2

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

nChannels

01 00

18H

int

4

采样率:表示每秒采集到的样本数

nSamplesPerSec

22 56 00 00(倒序)

nSamplesPerSec=(56)*2^8+22

1CH

long int

4

比特率

nAvgBytesPerSec=采样率*声道数*采样大小/8

44 AC 00 00(倒序)

20H

int

2

每个样本的字节数(byte

nBlockAlign =声道数*采样大小/8

02 00

22H

int

2

每样本的数据位数(bit

wBitsPerSample = 声道数*采样大小

10 00

24H

char

4

数据标记符”data”

64 61 74 61

28H

long int

4

波形数据大小=文件大小-44(字节)

如果文件大小=22950字节

那么数据大小=22906字节

该值=0x7A 59 00 00

0x597A==22906

0 0
原创粉丝点击