C 读取HTK生成的MFCC文件

来源:互联网 发布:soc管理平台 知乎 编辑:程序博客网 时间:2024/06/05 15:17

http://blog.csdn.net/linmingan/article/details/50897559

HTK生成的MFCC文件由头文件和数据域组成。


文件的结构如下(按照字节顺序列出): 
帧数:4字节(第0-第3字节) 
采样周期:4字节(第4-第7字节) 
每一帧的字节数:2字节(第8-第9字节) 
参数类型:2字节(第10-第11字节) 
数据:N字节(第12字节开始-文件结尾) 


需要注意的点: 
1、因为HTK每一个MFCC特征都占4字节,所以每一帧的MFCC特征数=每一帧的字节数/4; 
2、HTK的MFCC数据存储方式是大端存储;所以对于小段机器,需要进行大端到小段的转换。 


读取HTK的MFCC文件总体流程如下: 
1、读帧数 
2、读采样周期 
3、读每一帧的字节数 
4、读参数类型 
5、读取数据(每次读取4个字节,然后进行大端到小段的转换) 


具体代码如下: 

HTKread.h

#include "stdio.h"#ifndef _HTKREAD_H_#define _HTKREAD_H#ifdef __cplusplusextern "C"{#endif//--------------HTK Header Parameters-------------int number_of_frames;int fea_vector_length;int sample_period;short number_of_bytes_per_frame;short parameter_kind;float * frame_data;//-------- New -------------void endianSwap4(union byte4 *un);short endianSwap2int(short a);int endianSwap4int(int a);float endianSwap4float(float a);int findTokenInString(char *string, char *search_token);void HTKHeader(FILE *inFile);float* Read_frame_feat(FILE *inFile);#ifdef __cplusplus}#endif#endif<p><span style="font-family:FangSong_GB2312; font-size:14px"><span style="font-family:FangSong_GB2312; font-size:14px">HTKread.c</span></span></p>

HTKread.c

#include "HTKread.h"#include <string.h>#include<stdlib.h>//#include "Platform.h"union byte2 {char byte[2];short numint;};union byte4 {char byte[4];int numint;float numfloat;};short endianSwap2int(short a) {union byte2 un;char c1;un.numint = a;// swapc1 = un.byte[0];un.byte[0] = un.byte[1];un.byte[1] = c1;return un.numint;}int endianSwap4int(int a) {union byte4 un;char c1;un.numint = a;// swapc1= un.byte[0];un.byte[0] = un.byte[3];un.byte[3] = c1;c1 = un.byte[1];un.byte[1] = un.byte[2];un.byte[2] = c1;return un.numint;}float endianSwap4float(float a) {union byte4 un;char c1;un.numfloat = a;// swapc1 = un.byte[0];un.byte[0] = un.byte[3];un.byte[3] = c1;c1 = un.byte[1];un.byte[1] = un.byte[2];un.byte[2] = c1;return un.numfloat;}void endianSwap4(union byte4 *un) {    // swap    char c1 = (*un).byte[0];    (*un).byte[0] = (*un).byte[3];    (*un).byte[3] = c1;    c1 = (*un).byte[1];    (*un).byte[1] = (*un).byte[2];    (*un).byte[2] = c1;}int findTokenInString(char *string, char *search_token) {int search_token_length;char token_buffer[256] = {'\0'};char search_buffer[256] = {'\0'};int byte_counter;int i;char input_char;search_token_length = strlen(search_token);if (search_token_length > 256){printf("findTokenInString(): search token length %ld bigger than size of token_buffer, terminating!\n", search_token_length);return 1;}(void) strcpy(token_buffer, search_token);    // copy the search token into a buffer of a fixed length (the search token can in general have a variable length); we want a fixed lengthbyte_counter = 0;while (1) {// shift the search buffer by 1for (i = 0; i < search_token_length - 1; i++){search_buffer[i] = search_buffer[i + 1];}input_char = string[byte_counter];if (input_char == '\0') {break;}search_buffer[search_token_length - 1] = input_char;if (!strcmp(search_buffer, token_buffer)) {return byte_counter - search_token_length + 1;}byte_counter++;}return -1;              // -1 -> didn't find the token}void HTKHeader(FILE *inFile){fread(&number_of_frames,4,1,inFile);fread(&sample_period, 4, 1, inFile);fread(&number_of_bytes_per_frame, 2, 1, inFile);fread(¶meter_kind, 2, 1, inFile);number_of_frames = endianSwap4int(number_of_frames);sample_period = endianSwap4int(sample_period);number_of_bytes_per_frame = endianSwap2int(number_of_bytes_per_frame);fea_vector_length = number_of_bytes_per_frame/4;                  // each sample is float32printf("number_of_frames=%d\nfea_vector_length=%d\n",number_of_frames,fea_vector_length);}float* Read_frame_feat(FILE *inFile){float temp_data=0.0;short feat_dim;frame_data = (float *)malloc(sizeof(float)*fea_vector_length);for(feat_dim=0;feat_dim<fea_vector_length;feat_dim++){if (fread(&temp_data,4,1,inFile)!=1){printf("Error reading features!");exit(0);}frame_data[feat_dim]=endianSwap4float(temp_data);//printf("%f ",frame_data[feat_dim]);}//printf("\n");return frame_data;}






测试:

#include"HTKread.h"//#include"Platform.h"//#include "./HMFCC/HMFCC.h"#include <stdio.h>int main(){int i;FILE *htk_file;char *fname_htk_fea_in="..\\Out.mfc";float * data;//char *hmfcc_argv[]={"HMFCC","-A", "-C", "..//mfcc_64ms_step32ms.cfg", "..//temp.wav", "..//Out.mfcc"};//CreatMFCC(6,hmfcc_argv);//computing the MFCC//-------------Open Input HTK file----------------if((htk_file = fopen(fname_htk_fea_in,"rb"))==NULL){printf("Cannot open input HTK feature file %s\n", fname_htk_fea_in);return 0;}//read HTK headerHTKHeader(htk_file);for(i=0;i<number_of_frames;i++){data = Read_frame_feat(htk_file);if(data!=NULL)printf("readed %d frame feat\n",i);}fclose(htk_file);return 0;}



0 0