#include #include #include //need to link with -lm switch #include //ensures machine independent use of PI #ifndef M_PI #define M_PI 3.14159265358979323846 #endif //function prototypes //single tone unsigned long int tone(unsigned long int SampleRate,double frequency,unsigned long int tenth_seconds,FILE *fp); //main line of program int main(int argc, char *argv[]) { //variables FILE *fp; FILE *fp2; unsigned long int file_position_ChunkSize; unsigned long int file_position_SubChunk2Size; //wave header, format and data sections //header block char ChunkID[4]={'R','I','F','F'};//very start of file RIFF header block group id unsigned long int ChunkSize=0;//set this to the total file size minus 8 to ignore RIFF and WAVE char Format[4]={'W','A','V','E'}; unsigned long int header_size = sizeof(ChunkSize);//ignore sGroupID and sRiffType //printf("header size -> %d\n",(int)header_size); //format block char SubChunk1ID[4]={'f','m','t',' '};//format block group id unsigned long int SubChunk1Size=0;//length of rest of chunk in bytes excludes FsGroupID and dwChunkSize unsigned short int AudioFormat =1;//always 1 to indicate PCM format unsigned short int NumChannels =2;//stereo so 2 channels unsigned long int SampleRate = 44100;//the audio sampling rate unsigned short int BitsPerSample=16;//16 bits per sample //when writing to file do wBlockAlign BEFORE dwBitsPerSample unsigned short int BlockAlign = NumChannels * (BitsPerSample/8); //when writing to file do dwAvgBytesPerSec BEFORE wBlockAlign unsigned long int ByteRate = SampleRate * NumChannels * (BitsPerSample/8); SubChunk1Size = sizeof(AudioFormat)+sizeof(NumChannels)+sizeof(SampleRate) +sizeof(BitsPerSample)+sizeof(BlockAlign)+sizeof(ByteRate); //printf("dwChunkSize minus FsGroupID & dwChunkSize -> %d\n",(unsigned short int)dwChunkSize); //data block unsigned long int NumSamples=0;//the number of data samples written to the file char SubChunk2ID[4]={'d','a','t','a'}; unsigned long int SubChunk2Size=NumSamples * NumChannels * (BitsPerSample/8); //data is held in array in functions in as -> short int data[2]={0,0}; ChunkSize =4 + (8+SubChunk1Size) + (8+SubChunk2Size);//should total out at 36 //printf("%li\n",ChunkSize); /* see if file name is specified */ if (argc!=3) { printf("Need input and output filenames\n"); exit(1); } if ((fp= fopen(argv[2], "wb")) == NULL) //wb means open for writing of binary file - file need not exist { printf("cannot open output file\n"); exit(1); } //the input file if ((fp2= fopen(argv[1], "rb")) == NULL) //wb means open for writing of binary file - file need not exist { printf("cannot open input file\n"); exit(1); } printf("Fitness WAV writer -> Started\n"); //to allow time taken calculation clock_t start_clock = clock(); //chunk 1 fwrite(ChunkID, sizeof(ChunkID[0]) ,4 ,fp ); file_position_ChunkSize=ftell(fp); fwrite(&ChunkSize,sizeof(ChunkSize),1,fp); fwrite(Format, sizeof(Format[0]) ,4 ,fp ); //chunk 2 fwrite(&SubChunk1ID, sizeof(SubChunk1ID[0]) ,4 ,fp ); fwrite(&SubChunk1Size,sizeof(SubChunk1Size),1,fp); fwrite(&AudioFormat,sizeof(AudioFormat),1,fp); fwrite(&NumChannels,sizeof(NumChannels),1,fp); fwrite(&SampleRate,sizeof(SampleRate),1,fp); fwrite(&ByteRate,sizeof(ByteRate),1,fp); fwrite(&BlockAlign,sizeof(BlockAlign),1,fp); fwrite(&BitsPerSample,sizeof(BitsPerSample),1,fp); //chunk 3 //sound data header fwrite(SubChunk2ID,sizeof(SubChunk2ID[0]),4,fp); file_position_SubChunk2Size=ftell(fp); fwrite(&SubChunk2Size,sizeof(SubChunk2Size),1,fp); //file format repeats,frequency,tone time (hundredths seconds),space time (hundredths seconds) int repeats=2; double frequency=440.0; int tone_time=10; int space_time=10; int i=0; int value=0; //value =fscanf(fp2,"%i,%lf,%i,%i",&repeats,&frequency,&tone_time,&space_time); //printf("%i\n",value); //printf("%i,%lf,%i,%i",repeats,frequency,tone_time,space_time); printf("Repeats\tFrequency\tTone_time\tSpace_time (both in 10th of seconds)\n"); //read from text file while ((fscanf(fp2,"%i,%lf,%i,%i,",&repeats,&frequency,&tone_time,&space_time))==4) { printf("%i\t%lf\t%i\t\t%i\n",repeats,frequency,tone_time,space_time); for (i=0;i %g seconds\n",(clock()-start_clock)/(double)CLOCKS_PER_SEC); //the end so close file fclose(fp); //the end so close file fclose(fp2); printf("Fitness WAV writer -> Finished\n"); return 0; } //generate tone unsigned long int tone(unsigned long int SampleRate,double frequency,unsigned long int tenth_seconds,FILE *fp) { //function variables unsigned long int i=0; unsigned long int j=0; double t=(M_PI*2*frequency)/(SampleRate); //not same formula as c# version which was //double t=(M_PI*2*frequency)/(SampleRate*NumChannels); //that gave 500hz when 1khz was specified short int amplitude =32760; unsigned long int elements=0;//used to write out number of elements recorded //array for the data short int data[2]={0,0}; //write sound data to file for(i=0;i<(SampleRate/10)*tenth_seconds;i++) { data[0]= (amplitude * sin(t*i) ); data[1]= data[0]; elements=elements+ fwrite(data, sizeof(data[0]) ,2 ,fp ); } //printf("%i elements written -> %d bytes each\n",(int)elements ,sizeof(data[0]) ); return ((SampleRate/10)*tenth_seconds);//test return }