/*Modified by: bhw * EMail: bhwshx@163.com * Date: 2009年02月24日 星期二 19时49分12秒*/ /*********************************************************/ // WaveHeader.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define PI 3.1415926535897932384626433832795 // Microsoft wav pcm sound file format. Normal 44 bytes header typedef struct _tagMsWavPcmHeader44 { unsigned char ChunkID[4], // "RIFF"; The "RIFF" the mainchunk; Format[4], // "WAVE"; The "WAVE" format consists of two subchunks: "fmt " and "data" SubChunk1ID[4], // "fmt " SubChunk2ID[4]; // "data" unsigned short AudioFormat, // 1 for PCM. Linear quantization NumChannels, // 1->Mono, 2->stereo, etc.. BlockAlign, // = NumChannels * BitsPerSample / 8 BitsPerSample; // 8->8bits, 16->16bits, etc.. unsigned long SampleRate, // 8000, 11025, 16000, 44100, 48000, etc.. ByteRate, // = SampleRate * NumChannels * BitsPerSample/8 SubChunk1Size, // 16 for PCM. This is the size of the rest of the subchunk which follows this data. ChunkSize, // FileSize - 8; The size following this data SubChun2Size; // = NumSamples * NumChannels * BitsPerSample / 8. The size of data } wav_pcm_header44; void wave_generator(FILE *fpwav, wav_pcm_header44 *phwav); int main(int argc, char *argv[]) { FILE *fpSrcWav, *fpDestWav; unsigned long size; wav_pcm_header44 hwav; if (argc != 3) { printf("Missing parameters:/nFormat: WaveIn.wav WaveOut.wav/n"); return 0; } /* * 1. Get wave header information demo */ fpSrcWav = fopen(argv[1], "rb"); if (fpSrcWav != NULL) { fread(&hwav, sizeof(wav_pcm_header44), 1, fpSrcWav); /* Check wave header */ if ( (0 == memcmp(hwav.ChunkID, "RIFF", 4)) && (0==memcmp(hwav.Format, "WAVE", 4)) &&/ (0==memcmp(hwav.SubChunk1ID, "fmt ", 4)) &&(0==memcmp(hwav.SubChunk2ID, "data", 4)) &&/ (1==hwav.AudioFormat)) { printf("Wave audio data format:/n"); printf("Channel number: %d/n", hwav.NumChannels); printf("SampleRate: %ldHz/n", hwav.SampleRate); printf("BitsPerSample: %dbits/n", hwav.BitsPerSample); printf("Audio data size:%ld/n", hwav.SubChun2Size); } fclose(fpSrcWav); } else { printf("Open wave file %s failed!/n", argv[1]); return 0; } /* * 2. Generate wave file demo */ fpDestWav = fopen(argv[2], "wb+"); if (fpDestWav != NULL) { /* initial wave file header */ memcpy(hwav.ChunkID, "RIFF", 4); hwav.ChunkSize = sizeof(wav_pcm_header44) - 8; memcpy(hwav.Format, "WAVE", 4); memcpy(hwav.SubChunk1ID, "fmt ", 4); hwav.SubChunk1Size = 16; hwav.AudioFormat = 1; hwav.NumChannels = 2; // set channels as stereo hwav.SampleRate = 16000; // set sample rate as 16KHz hwav.BitsPerSample = 16; // set one sample use 16bits hwav.ByteRate = hwav.SampleRate * hwav.NumChannels * hwav.BitsPerSample / 8; hwav.BlockAlign = hwav.NumChannels * hwav.BitsPerSample / 8; memcpy(hwav.SubChunk2ID, "data", 4); hwav.SubChun2Size = 0; // 1. pre write wave header fwrite(&hwav, sizeof(wav_pcm_header44), 1, fpDestWav); // 2. write wave data wave_generator(fpDestWav, &hwav); // 3. rewrite wave header fseek(fpDestWav, 0, SEEK_END); size = ftell(fpDestWav); // get file size fseek(fpDestWav, 0, SEEK_SET); hwav.ChunkSize = size - 8; // update size hwav.SubChun2Size = size - sizeof(wav_pcm_header44); fwrite(&hwav, sizeof(wav_pcm_header44), 1, fpDestWav); fclose(fpDestWav); } else { printf("Create wave file %s failed!/n", argv[2]); return 0; } return 0; } void wave_generator(FILE *fpwav, wav_pcm_header44 *phwav) { short vout; int i; double inc, fout, phase = 0; if(16 != phwav->BitsPerSample) { printf("Wave generator don't support this format/n"); exit(0); } // Generate 1Khz inc = 2*PI*1000/phwav->SampleRate; for(i=0; i<65536; ++i) // generate 65536 blocks { phase += inc; if (phase >= 2*PI) { phase -= 2*PI; } fout = sin(phase); // get 1KHz sin wave for(i=0; i<phwav->NumChannels; ++i) // for NumChannels { vout = (short)(32767 * fout); fwrite(&vout, sizeof(short), 1, fpwav); fout *= fout; // for next channel } } }