00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 using namespace std;
00058
00059 #include<iostream>
00060 #include<string>
00061 #include<cstdio>
00062 #include<cstring>
00063 #include<cstdlib>
00064 #include<vector>
00065
00066 #ifndef FILEMANAGERINCLUDED
00067 #include"filemanager.cpp"
00068 #endif
00069
00070 #ifndef PARAMETERSINCLUDED
00071 #include "parameters.cpp"
00072 #endif
00073
00074
00075 #define WAVEFILEINCLUDED
00076
00077 class wavefile {
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 protected:char ChunkID[4];
00136 unsigned long int ChunkSize;
00137 char Format[4];
00138 char Subchunk1ID[4];
00139 unsigned long int Subchunk1Size;
00140 unsigned short int AudioFormat;
00141 unsigned short int NumChannels;
00142 unsigned long int SampleRate;
00143 unsigned long int ByteRate;
00144 unsigned short int BlockAlign;
00145 unsigned short int BitsPerSample;
00146 char Subchunk2ID[4];
00147 unsigned long int Subchunk2Size;
00148 char *data;
00149 string path;
00150 unsigned long int locinc;
00151 unsigned long int curloc;
00152 FILE* fptr;
00153
00154 public: wavefile () {
00155 path=filemgr.newTempFile();
00156 strncpy(ChunkID,"RIFF",4);
00157 strncpy(Format,"WAVE",4);
00158 strncpy(Subchunk1ID,"fmt ",4);
00159 Subchunk1Size=16;
00160 AudioFormat=1;
00161 NumChannels=1;
00162 SampleRate=SAMPLERATE;
00163 BitsPerSample=BPS;
00164 ByteRate=SampleRate * NumChannels * BitsPerSample/8;
00165 BlockAlign=NumChannels * BitsPerSample/8;
00166 strncpy(Subchunk2ID,"data",4);
00167 data=NULL;
00168 Subchunk2Size=0;
00169 ChunkSize=4 + (8 + Subchunk1Size) + (8 + Subchunk2Size);
00170 locinc=(unsigned long int)((double)ByteRate*(double)FRAMELENGTH);
00171 curloc=0;
00172 }
00173
00174 unsigned long int getlocinc() {
00175
00176 return (unsigned long int)((double)ByteRate*(double)FRAMELENGTH);
00177 }
00178
00179 wavefile (char* frdata,unsigned long int frsize) {
00180 path= filemgr.newTempFile();
00181 strncpy(ChunkID,"RIFF",4);
00182 strncpy(Format,"WAVE",4);
00183 strncpy(Subchunk1ID,"fmt ",4);
00184 Subchunk1Size=16;
00185 AudioFormat=1;
00186 NumChannels=1;
00187 SampleRate=SAMPLERATE;
00188 BitsPerSample=BPS;
00189 ByteRate=SampleRate * NumChannels * BitsPerSample/8;
00190 BlockAlign=NumChannels * BitsPerSample/8;
00191 strncpy(Subchunk2ID,"data",4);
00192 Subchunk2Size=frsize;
00193 if((data=(char *)malloc(Subchunk2Size))==NULL) {
00194 cout<<"Cannot allocate memory\n\n";
00195 return;
00196 }
00197 for(unsigned long int i=0;i<Subchunk2Size;i++) {
00198 data[i]=frdata[i];
00199 }
00200 ChunkSize=4 + (8 + Subchunk1Size) + (8 + Subchunk2Size);
00201 locinc=(unsigned long int)((double)ByteRate*(double)FRAMELENGTH);
00202 curloc=0;
00203 }
00204
00205 wavefile (string wavepath) {
00206
00207 char ID[4];
00208 unsigned long int size;
00209 unsigned short int num;
00210 FILE* fp;
00211 char str[256];
00212 strcpy(str,"./sig2fv ");
00213 strcat(str,wavepath.c_str());
00214 strcat(str," -shift 0.02 -o mfcc.fil -coefs melcep");
00215 system(str);
00216 cout<<"MFCCs generated"<<endl;
00217 fptr=fopen("mfcc.fil","rb");
00218 fp=fopen(wavepath.c_str(),"r+");
00219 if(fp==NULL) {
00220 printf("Error opening file\n");
00221 exit(0);
00222 }
00223 fread(ID,1,4,fp);
00224 strncpy(ChunkID,ID,4);
00225 fread(&size,4,1,fp);
00226 ChunkSize=size;
00227 fread(ID,1,4,fp);
00228 strncpy(Format,ID,4);
00229 fread(ID,1,4,fp);
00230 strncpy(Subchunk1ID,ID,4);
00231 fread(&size,1,4,fp);
00232 Subchunk1Size=size;
00233 fread(&num,1,2,fp);
00234 AudioFormat=num;
00235 fread(&num,1,2,fp);
00236 NumChannels=num;
00237 fread(&size,1,4,fp);
00238 SampleRate=size;
00239 fread(&size,1,4,fp);
00240 ByteRate=size;
00241 fread(&num,1,2,fp);
00242 BlockAlign=num;
00243 fread(&num,1,2,fp);
00244 BitsPerSample=num;
00245 fseek(fp,Subchunk1Size-16,SEEK_CUR);
00246 if(Subchunk1Size>16 && AudioFormat==1)
00247 Subchunk1Size=16;
00248 fread(ID,1,4,fp);
00249 if(strncmp(ID,"fact",4)==0) {
00250 fread(&size,1,4,fp);
00251 fseek(fp,size,SEEK_CUR);
00252 fread(ID,1,4,fp);
00253 }
00254 strncpy(Subchunk2ID,ID,4);
00255 fread(&size,1,4,fp);
00256 Subchunk2Size=size;
00257 data=(char *)malloc(Subchunk2Size);
00258 fread(data,1,Subchunk2Size,fp);
00259 ChunkSize=4 + (8 + Subchunk1Size) + (8 + Subchunk2Size);
00260 fclose(fp);
00261 path=wavepath;
00262 locinc=(unsigned long int)((double)ByteRate*(double)FRAMELENGTH);
00263 curloc=0;
00264 }
00265
00266 wavefile (wavefile& wv) {
00267
00268 path=filemgr.newTempFile();
00269 strncpy(ChunkID,wv.ChunkID,4);
00270 ChunkSize=wv.ChunkSize;
00271 strncpy(Format,wv.Format,4);
00272 strncpy(Subchunk1ID,wv.Subchunk1ID,4);
00273 Subchunk1Size=wv.Subchunk1Size;
00274 AudioFormat=wv.AudioFormat;
00275 NumChannels=wv.NumChannels;
00276 SampleRate=wv.SampleRate;
00277 ByteRate=wv.ByteRate;
00278 BlockAlign=wv.BlockAlign;
00279 BitsPerSample=wv.BitsPerSample;
00280 strncpy(Subchunk2ID,wv.Subchunk2ID,4);
00281 Subchunk2Size=wv.Subchunk2Size;
00282 data=(char *)malloc(Subchunk2Size);
00283
00284 for(unsigned long int i=0;i<Subchunk2Size;i++) {
00285 data[i]=wv.data[i];
00286 }
00287 curloc=wv.curloc;
00288 locinc=wv.locinc;
00289 }
00290
00291 wavefile (const wavefile& wv) {
00292
00293 path=filemgr.newTempFile();
00294 strncpy(ChunkID,wv.ChunkID,4);
00295 ChunkSize=wv.ChunkSize;
00296 strncpy(Format,wv.Format,4);
00297 strncpy(Subchunk1ID,wv.Subchunk1ID,4);
00298 Subchunk1Size=wv.Subchunk1Size;
00299 AudioFormat=wv.AudioFormat;
00300 NumChannels=wv.NumChannels;
00301 SampleRate=wv.SampleRate;
00302 ByteRate=wv.ByteRate;
00303 BlockAlign=wv.BlockAlign;
00304 BitsPerSample=wv.BitsPerSample;
00305 strncpy(Subchunk2ID,wv.Subchunk2ID,4);
00306 Subchunk2Size=wv.Subchunk2Size;
00307 data=(char *)malloc(Subchunk2Size);
00308
00309 for(unsigned long int i=0;i<Subchunk2Size;i++) {
00310 data[i]=wv.data[i];
00311 }
00312 curloc=wv.curloc;
00313 locinc=wv.locinc;
00314 }
00315
00316 int makeMono(int type) {
00317
00318
00319 unsigned long int i;
00320 unsigned long int m;
00321 short int j;
00322 unsigned char avg8;
00323 short int avg16;
00324 unsigned int sum8;
00325 long int sum16;
00326 unsigned char *monodata8;
00327 short int *monodata16;
00328 switch(BitsPerSample) {
00329 case 8: monodata8=(unsigned char *)malloc(Subchunk2Size/NumChannels);
00330 for(i=0,m=0;i<Subchunk2Size;i+=BlockAlign,m++) {
00331 for(j=0,sum8=0;j<BlockAlign;j+=BitsPerSample/8) {
00332 sum8+=data[i+j];
00333 }
00334 avg8=sum8/NumChannels;
00335 if(sum8 > 255)
00336 return -1;
00337 if(type==1)
00338 monodata8[m]=sum8;
00339 if(type==2)
00340 monodata8[m]=avg8;
00341 }
00342 Subchunk2Size/=NumChannels;
00343 free(data);
00344 data=(char *)malloc(Subchunk2Size);
00345 for(unsigned long int l=0;l<Subchunk2Size;l++) {
00346 data[l]=monodata8[l];
00347 }
00348
00349 free(monodata8);
00350 NumChannels=1;
00351 BlockAlign=NumChannels*BitsPerSample/8;
00352 ByteRate=SampleRate * NumChannels *BitsPerSample/8;
00353 ChunkSize=4 + (8 + Subchunk1Size) + (8 + Subchunk2Size);
00354 commit();
00355 break;
00356 case 16:monodata16=(short int *)malloc(Subchunk2Size/NumChannels);
00357 for(i=0,m=0;i<Subchunk2Size;i+=BlockAlign,m++) {
00358 for(j=0,sum16=0;j<BlockAlign;j+=BitsPerSample/8) {
00359 sum16+=data[i+j];
00360 }
00361 avg16=sum16/NumChannels;
00362 if(sum16 > 32767 || sum16 < -32768)
00363 return 1;
00364 if(type==1)
00365 monodata16[m]=sum16;
00366 if(type==2)
00367 monodata16[m]=avg16;
00368 }
00369 Subchunk2Size/=NumChannels;
00370 free(data);
00371 data=(char *)malloc(Subchunk2Size);
00372 for(unsigned long int l=0;l<Subchunk2Size;l++) {
00373 data[l]=monodata16[l];
00374 }
00375
00376 free(monodata16);
00377 NumChannels=1;
00378 BlockAlign=NumChannels*BitsPerSample/8;
00379 ByteRate=SampleRate * NumChannels *BitsPerSample/8;
00380 ChunkSize=4 + (8 + Subchunk1Size) + (8 + Subchunk2Size);
00381 commit();
00382 break;
00383 default:
00384 break;
00385 }
00386 return 0;
00387 }
00388
00389
00390 int makePerm(string dest) {
00391
00392 string tpath=path;
00393 filemgr.makePerm(dest,tpath);
00394 path=dest;
00395 }
00396
00397 int getFirstFrame (char *frmdata,unsigned long int* frsize) {
00398
00399 *frsize=locinc;
00400
00401 for(unsigned long int i=0;i<locinc;i++) {
00402 frmdata[i]=data[i];
00403 }
00404 curloc=locinc;
00405 *frsize=locinc;
00406
00407 for(unsigned long int i=0;i<locinc;i++) {
00408 frmdata[i]=data[i];
00409 }
00410 curloc=locinc;
00411 return SUCCESS;
00412 }
00413
00414 int getNextFrame (char *frmdata,unsigned long int* frsize) {
00415
00416 if((curloc+locinc)>Subchunk2Size) {
00417 return 2;
00418 }
00419 *frsize=locinc;
00420
00421 for(unsigned long int i=0;i<locinc;i++) {
00422 frmdata[i]=data[i+curloc];
00423 }
00424 curloc=curloc+locinc;
00425 return SUCCESS;
00426 }
00427
00428 int getFrame(unsigned long int i, string framename) {
00429 curloc=i*getlocinc();
00430 char* frmdata=(char*)malloc(getlocinc());
00431 for(i=0;i<locinc;i++) {
00432 frmdata[i]=data[i+curloc];
00433 }
00434 char ID[4];
00435 unsigned long int size;
00436 unsigned short int num;
00437 FILE* frmptr=fopen(framename.c_str(),"w+");
00438 if(frmptr==NULL) {
00439 printf("Error committing file\n");
00440 return 1;
00441 }
00442 strncpy(ID,ChunkID,4);
00443 fwrite(ID,1,4,frmptr);
00444 size=4 + (8 + Subchunk1Size) + (8 + getlocinc());
00445 fwrite(&size,4,1,frmptr);
00446 strncpy(ID,Format,4);
00447 fwrite(ID,1,4,frmptr);
00448 strncpy(ID,Subchunk1ID,4);
00449 fwrite(ID,1,4,frmptr);
00450 size=Subchunk1Size;
00451 fwrite(&size,1,4,frmptr);
00452 num=AudioFormat;
00453 fwrite(&num,1,2,frmptr);
00454 num=NumChannels;
00455 fwrite(&num,1,2,frmptr);
00456 size=SampleRate;
00457 fwrite(&size,1,4,frmptr);
00458 size=ByteRate;
00459 fwrite(&size,1,4,frmptr);
00460 num=BlockAlign;
00461 fwrite(&num,1,2,frmptr);
00462 num=BitsPerSample;
00463 fwrite(&num,1,2,frmptr);
00464 strncpy(ID,Subchunk2ID,4);
00465 fwrite(ID,1,4,frmptr);
00466 size=getlocinc();
00467 fwrite(&size,1,4,frmptr);
00468 fwrite(frmdata,1,getlocinc(),frmptr);
00469 fclose(frmptr);
00470 return 1;
00471 }
00472
00473 vector<double> getMFCC(int *status) {
00474 unsigned long int line_no;
00475 char str[16];
00476 vector<double> mfcc;
00477 char** endptr;
00478 endptr=(char**)malloc(sizeof(char**));
00479 double temp;
00480 for(int i=0;i<MAX_DIM;i++) {
00481 if(( fscanf(fptr,"%s",str))==EOF) {
00482 *status=FAILURE;
00483 return mfcc;
00484 }
00485 temp=strtod(str,endptr);
00486 mfcc.push_back(temp);
00487 }
00488 *status=SUCCESS;
00489 return mfcc;
00490 }
00491
00492 int appendFrame (string fpath) {
00493 char* frmdata;
00494 unsigned long int frsize=getlocinc();
00495 FILE* fptr;
00496 frmdata=(char*)malloc(getlocinc());
00497 fptr=fopen(fpath.c_str(),"r+");
00498 fseek(fptr,44,SEEK_SET);
00499 fread((char*)frmdata,sizeof(char),getlocinc(),fptr) ;
00500 char* olddata;
00501 olddata=(char*)malloc(Subchunk2Size);
00502 for(unsigned long int i=0;i<Subchunk2Size;i++) {
00503 olddata[i]=data[i];
00504 }
00505 free(data);
00506 Subchunk2Size=Subchunk2Size+frsize;
00507 if((data=(char*)malloc(Subchunk2Size))==NULL) {
00508 cout<<"Error reallocating data\n";
00509 abort();
00510 }
00511 for(unsigned long int i=0;i<Subchunk2Size-frsize;i++) {
00512 data[i]=olddata[i];
00513 }
00514 for(unsigned long int i=Subchunk2Size-frsize;i<Subchunk2Size;i++) {
00515 data[i]=frmdata[i-(Subchunk2Size-frsize)];
00516 }
00517 ChunkSize=4 + (8 + Subchunk1Size) + (8 + Subchunk2Size);
00518 free(olddata);
00519 free(frmdata);
00520 fclose(fptr);
00521 }
00522
00523 int getData(char* frmdata,unsigned long int* frsize) {
00524 if((frmdata=(char*)malloc( Subchunk2Size ))==NULL)
00525 return FAILURE;
00526 *frsize= Subchunk2Size ;
00527 for(unsigned long int i=0;i<Subchunk2Size;i++) {
00528 frmdata[i]=data[i];
00529 }
00530 return SUCCESS;
00531 }
00532
00533 int commit(void) {
00534
00535 char ID[4];
00536 unsigned long int size;
00537 unsigned short int num;
00538 FILE* fp;
00539
00540 fp=fopen(path.c_str(),"w+");
00541 if(fp==NULL) {
00542 printf("Error committing file\n");
00543 return 1;
00544 }
00545 strncpy(ID,ChunkID,4);
00546 fwrite(ID,1,4,fp);
00547 size=ChunkSize;
00548 fwrite(&size,4,1,fp);
00549 strncpy(ID,Format,4);
00550 fwrite(ID,1,4,fp);
00551 strncpy(ID,Subchunk1ID,4);
00552 fwrite(ID,1,4,fp);
00553 size=Subchunk1Size;
00554 fwrite(&size,1,4,fp);
00555 num=AudioFormat;
00556 fwrite(&num,1,2,fp);
00557 num=NumChannels;
00558 fwrite(&num,1,2,fp);
00559 size=SampleRate;
00560 fwrite(&size,1,4,fp);
00561 size=ByteRate;
00562 fwrite(&size,1,4,fp);
00563 num=BlockAlign;
00564 fwrite(&num,1,2,fp);
00565 num=BitsPerSample;
00566 fwrite(&num,1,2,fp);
00567 strncpy(ID,Subchunk2ID,4);
00568 fwrite(ID,1,4,fp);
00569 size=Subchunk2Size;
00570 fwrite(&size,1,4,fp);
00571 fwrite(data,1,Subchunk2Size,fp);
00572 fclose(fp);
00573 return 1;
00574 }
00575
00576
00577 int showDetails() {
00578 cout << "ChunkID\t\t:" << ChunkID[0] << ChunkID[1] << ChunkID[2] << ChunkID[3] << "\n";
00579 cout << "ChunkSize\t:" << ChunkSize << "\n" ;
00580 cout << "Format\t\t:" << Format[0] << Format[1] << Format[2] << Format[3] << "\n" ;
00581 cout << "-----------------------------\n";
00582 cout << "Subchunk1ID\t:" << Subchunk1ID[0] << Subchunk1ID[1] << Subchunk1ID[2] << Subchunk1ID[3] << "\n" ;
00583 cout << "Subchunk1Size\t:" << Subchunk1Size << "\n" ;
00584 cout << "AudioFormat\t:" << AudioFormat << "\n" ;
00585 cout << "NumChannels\t:" << NumChannels << "\n" ;
00586 cout << "SampleRate\t:" << SampleRate << "\n" ;
00587 cout << "ByteRate\t:" << ByteRate << "\n" ;
00588 cout << "BlockAlign\t:" << BlockAlign << "\n" ;
00589 cout << "BitsPerSample\t:" << BitsPerSample << "\n" ;
00590 cout << "-----------------------------\n";
00591 cout << "Subchunk2ID\t:" << Subchunk2ID[0] << Subchunk2ID[1] << Subchunk2ID[2] << Subchunk2ID[3] << "\n" ;
00592 cout << "Subchunk2Size\t:" << Subchunk2Size << "\n" ;
00593 cout << "data\t\t:" << "/* Unprintable data */\n";
00594
00595 cout << "-----------------------------\n";
00596 cout << "path\t\t:" << path << "\n" ;
00597 cout << "locinc\t\t:" << locinc << "\n" ;
00598 cout << "curloc\t\t:" << curloc << "\n" ;
00599 return SUCCESS;
00600 }
00601
00602 ~wavefile () {
00603
00604 if((filemgr.checkTempFile(path))==0) {
00605 commit();
00606 }
00607 else {
00608 filemgr.delTempFile(path);
00609 }
00610 free(data);
00611 }
00612
00613 unsigned long int nFrames() {
00614 return Subchunk2Size/getlocinc();
00615 }
00616 };
00617