wavefile.cpp

Go to the documentation of this file.
00001 //--------------------------------------
00002 //          File: wavefile.cpp
00003 //--------------------------------------
00004 
00005 /* Microsoft's WAVE soundfile class */
00006 /* Project: VoX */
00007 
00008 /* The WAVE file format is a subset of Microsoft's RIFF specification for the
00009 storage of multimedia files. A RIFF file starts out with a file header followed
00010 by a sequence of data chunks. A WAVE file is often just a RIFF file with a
00011 single "WAVE" chunk which consists of two sub-chunks -- a "fmt " chunk
00012 specifying the data format and a "data" chunk containing the actual sample
00013 data.
00014 
00015 Notes:
00016 
00017 * The default byte ordering assumed for WAVE data files is little-endian.
00018 Files written using the big-endian byte ordering scheme have the
00019 identifier RIFX instead of RIFF.
00020 * The sample data must end on an even byte boundary. Whatever that means.
00021 * 8-bit samples are stored as unsigned bytes, ranging from 0 to 255. 16-bit
00022 samples are stored as 2's-complement signed integers, ranging from -32768
00023 to 32767.
00024 * There may be additional subchunks in a Wave data stream. If so, each will
00025 have a char[4] SubChunkID, and unsigned long SubChunkSize, and
00026 SubChunkSize amount of data.
00027 * RIFF stands for Resource Interchange File Format.
00028 
00029 For more info see http://www.ora.com/centers/gff/formats/micriff/index.htm
00030 
00031 References:
00032 
00033 1. http://netghost.narod.ru/gff/graphics/summary/micriff.htm
00034 2. http://www.lightlink.com/tjweber/StripWav/WAVE.html
00035 
00036 General discussion of RIFF files:
00037 Multimedia applications require the storage and management of a wide
00038 variety of data, including bitmaps, audio data, video data, and peripheral
00039 device control information. RIFF provides a way to store all these varied
00040 types of data. The type of data a RIFF file contains is indicated by the
00041 file extension. Examples of data that may be stored in RIFF files are:
00042 
00043 * Audio/visual interleaved data (.AVI)
00044 * Waveform data (.WAV)
00045 * Bitmapped data (.RDI)
00046 * MIDI information (.RMI)
00047 * Color palette (.PAL)
00048 * Multimedia movie (.RMN)
00049 * Animated cursor (.ANI)
00050 * A bundle of other RIFF files (.BND)
00051 
00052 NOTE: At this point, AVI files are the only type of RIFF files that have
00053 been fully implemented using the current RIFF specification. Although WAV
00054 files have been implemented, these files are very simple, and their
00055 developers typically use an older specification in constructing them.*/
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 Offset  Size  Name             Description
00080 
00081 The canonical WAVE format starts with the RIFF header:
00082 
00083 0         4   ChunkID          Contains the letters "RIFF" in ASCII form
00084                                (0x52494646 big-endian form).
00085 4         4   ChunkSize        36 + SubChunk2Size, or more precisely:
00086                                4 + (8 + SubChunk1Size) + (8 + SubChunk2Size)
00087                                This is the size of the rest of the chunk
00088                                following this number.  This is the size of the
00089                                entire file in bytes minus 8 bytes for the
00090                                two fields not included in this count:
00091                                ChunkID and ChunkSize.
00092 8         4   Format           Contains the letters "WAVE"
00093                                (0x57415645 big-endian form).
00094 
00095 The "WAVE" format consists of two subchunks: "fmt " and "data":
00096 The "fmt " subchunk describes the sound data's format:
00097 
00098 12        4   Subchunk1ID      Contains the letters "fmt "
00099                                (0x666d7420 big-endian form).
00100 16        4   Subchunk1Size    16 for PCM.  This is the size of the
00101                                rest of the Subchunk which follows this number.
00102 20        2   AudioFormat      PCM = 1 (i.e. Linear quantization)
00103                                Values other than 1 indicate some
00104                                form of compression.
00105 22        2   NumChannels      Mono = 1, Stereo = 2, etc.
00106 24        4   SampleRate       8000, 44100, etc.
00107 28        4   ByteRate         == SampleRate * NumChannels * BitsPerSample/8
00108 32        2   BlockAlign       == NumChannels * BitsPerSample/8
00109                                The number of bytes for one sample including
00110                                all channels. I wonder what happens when
00111                                this number isn't an integer?
00112 34        2   BitsPerSample    8 bits = 8, 16 bits = 16, etc.
00113           2   ExtraParamSize   if PCM, then doesn't exist
00114           X   ExtraParams      space for extra parameters
00115 
00116 The "data" subchunk contains the size of the data and the actual sound:
00117 
00118 36        4   Subchunk2ID      Contains the letters "data"
00119                                (0x64617461 big-endian form).
00120 40        4   Subchunk2Size    == NumSamples * NumChannels * BitsPerSample/8
00121                                This is the number of bytes in the data.
00122                                You can also think of this as the size
00123                                of the read of the subchunk following this
00124                                number.
00125 44        *   Data             The actual sound data.
00126 
00127 As an example, here are the opening 72 bytes of a WAVE file with bytes shown as hexadecimal numbers:
00128 
00129 52 49 46 46 24 08 00 00 57 41 56 45 66 6d 74 20 10 00 00 00 01 00 02 00
00130 22 56 00 00 88 58 01 00 04 00 10 00 64 61 74 61 00 08 00 00 00 00 00 00
00131 24 17 1e f3 3c 13 3c 14 16 f9 18 f9 34 e7 23 a6 3c f2 24 f2 11 ce 1a 0d
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; /*Location of open wavefile*/
00150             unsigned long int locinc; /*Size of Each Subchunk2Size of each frame*/
00151             unsigned long int curloc; /*Current frame start location*/
00152             FILE* fptr; /*Associated with mfcc.fil*/
00153 
00154   public: wavefile () {
00155             path=filemgr.newTempFile();/*generate a new temporary file*/
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             /*gets the location increment*/
00176             return (unsigned long int)((double)ByteRate*(double)FRAMELENGTH);
00177           }
00178 
00179           wavefile (char* frdata,unsigned long int frsize) {
00180             path= filemgr.newTempFile();/*generate a new temporary file*/
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           /*Constructor: opens the file specified by the path and initialises all private variables, allocates buffer for data, and copy data*/
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); //Skipping extraParams
00246             if(Subchunk1Size>16 && AudioFormat==1)
00247               Subchunk1Size=16;
00248             fread(ID,1,4,fp);
00249             if(strncmp(ID,"fact",4)==0) { //Skipping fact subchunk
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           /*Copy Constructor: copy all private variables except for the path, reallocates buffer for data, and copy data*/
00268             path=filemgr.newTempFile();/*generate a new temporary file*/
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             //data  --> wv.data(Subchunk2Size bytes)
00284             for(unsigned long int i=0;i<Subchunk2Size;i++) {
00285               data[i]=wv.data[i];
00286             }
00287             curloc=wv.curloc; /*Current frame start location*/
00288             locinc=wv.locinc;
00289           }
00290 
00291           wavefile (const wavefile& wv) {
00292           /*Copy Constructor: copy all private variables except for the path, reallocates buffer for data, and copy data*/
00293             path=filemgr.newTempFile();/*generate a new temporary file*/
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             // data  --> wv.data(Subchunk2Size bytes)
00309             for(unsigned long int i=0;i<Subchunk2Size;i++) {
00310               data[i]=wv.data[i];
00311             }
00312             curloc=wv.curloc; /*Current frame start location*/
00313             locinc=wv.locinc;
00314           }
00315 
00316           int makeMono(int type) {
00317           /*Converts this wavefile to monochannel, if it is multichannel*/
00318           /*type=1 => Sum; type = 2 => Avg; ret = -1 => clip;*/
00319             unsigned long int i; //multi channel data iterator
00320             unsigned long int m; //mono channel data iterator
00321             short int j; //channel iterator
00322             unsigned char avg8; //8-bit sample avg
00323             short int avg16; //16-bit sample avg
00324             unsigned int sum8; //8-bit sample sum
00325             long int sum16; //16-bit sample sum
00326             unsigned char *monodata8; //modified (mono channel) data
00327             short int *monodata16; //modified (mono channel) data
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                       //memcpy(data,monodata8,Subchunk2Size);
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                       //memcpy(data,monodata16,Subchunk2Size);
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://unhandled
00384                       break;
00385             }
00386             return 0;
00387           }
00388 
00389  
00390          int makePerm(string dest) {
00391           /*makes a wave file permanent*/
00392             string tpath=path;
00393             filemgr.makePerm(dest,tpath);
00394             path=dest;
00395           }
00396 
00397           int getFirstFrame (char *frmdata,unsigned long int* frsize) {
00398           /*Copies first frame of locinc samples (if needed, padding is done) in wf and returns the length of frame*/
00399             *frsize=locinc;
00400             // frmdata-->data(locinc bytes)
00401             for(unsigned long int i=0;i<locinc;i++) {
00402               frmdata[i]=data[i];
00403             }
00404             curloc=locinc;
00405             *frsize=locinc;
00406             // frmdata-->data(locinc bytes)
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           /*Copies next frame of locinc samples (if needed, padding is done) in wf and returns the length of frame*/
00416             if((curloc+locinc)>Subchunk2Size) {
00417               return 2;
00418             }
00419             *frsize=locinc;
00420             // frmdata-->data+curloc(locinc bytes)
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) {/*simple, no smoothening*//*appends a frame to this wavefile*/
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          /*copies all private variables & data back to the location specified by path*/
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             //cout << "data\t\t:" << data << "\n" ;
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           /*Destructor: closes the file specified by the path and copies all private variables & data back, deallocates buffer for data, and try to delete the temporary file */
00604             if((filemgr.checkTempFile(path))==0)/*this is permanent file*/ {
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 

Best viewed on Get Firefox!. Generated on Mon Mar 28 22:09:09 2005 for VoX by  doxygen 1.4.2 . This project hosted by SourceForge.net Logo .