|
| 1 | +#include "stdio.h" |
| 2 | + |
| 3 | +typedef unsigned char ID[4]; |
| 4 | + |
| 5 | +typedef struct |
| 6 | +{ |
| 7 | + ID chunkID; /* {'f', 'm', 't', ' '} */ |
| 8 | + long chunkSize; |
| 9 | + |
| 10 | + short wFormatTag; |
| 11 | + unsigned short wChannels; |
| 12 | + unsigned long dwSamplesPerSec; |
| 13 | + unsigned long dwAvgBytesPerSec; |
| 14 | + unsigned short wBlockAlign; |
| 15 | + unsigned short wBitsPerSample; |
| 16 | + /* Note: there may be additional fields here, |
| 17 | + depending upon wFormatTag. */ |
| 18 | +} FormatChunk; |
| 19 | + |
| 20 | +typedef struct |
| 21 | +{ |
| 22 | + ID chunkID; /* {'d', 'a', 't', 'a'} */ |
| 23 | + long chunkSize; |
| 24 | + unsigned char waveformData[]; |
| 25 | +} DataChunk; |
| 26 | + |
| 27 | +void usage(char *command) |
| 28 | +{ |
| 29 | + printf("usage:\n" |
| 30 | + "\t%s pcmfile wavfile channel samplerate bitspersample\n", command); |
| 31 | +} |
| 32 | + |
| 33 | +int main(int argc, char *argv[]) |
| 34 | +{ |
| 35 | + FILE *pcmfile, *wavfile; |
| 36 | + long pcmfile_size, chunk_size; |
| 37 | + FormatChunk formatchunk; |
| 38 | + DataChunk datachunk; |
| 39 | + int i, read_len; |
| 40 | + char buf[1024]; |
| 41 | + short tmp; |
| 42 | + |
| 43 | + if (argc != 6) { |
| 44 | + usage(argv[0]); |
| 45 | + return 1; |
| 46 | + } |
| 47 | + |
| 48 | + pcmfile = fopen(argv[1], "rb"); |
| 49 | + if (pcmfile == NULL) { |
| 50 | + printf("!Error: Can't open pcmfile.\n"); |
| 51 | + return 1; |
| 52 | + } |
| 53 | + fseek(pcmfile, 0, SEEK_END); |
| 54 | + pcmfile_size = ftell(pcmfile); |
| 55 | + fseek(pcmfile, 0, SEEK_SET); |
| 56 | + |
| 57 | + wavfile = fopen(argv[2], "wb"); |
| 58 | + if (wavfile == NULL) { |
| 59 | + printf("!Error: Can't create wavfile.\n"); |
| 60 | + return 1; |
| 61 | + } |
| 62 | + |
| 63 | + fwrite("RIFF", 1, 4, wavfile); |
| 64 | + fwrite("xxxx", 1, 4, wavfile); //reserved for the total chunk size |
| 65 | + fwrite("WAVE", 1, 4, wavfile); |
| 66 | + |
| 67 | + formatchunk.chunkID[0] = 'f'; |
| 68 | + formatchunk.chunkID[1] = 'm'; |
| 69 | + formatchunk.chunkID[2] = 't'; |
| 70 | + formatchunk.chunkID[3] = ' '; |
| 71 | + formatchunk.chunkSize = sizeof(FormatChunk) - sizeof(ID) - sizeof(long); |
| 72 | + formatchunk.wFormatTag = 1; /* uncompressed */ |
| 73 | + formatchunk.wChannels = atoi(argv[3]); |
| 74 | + formatchunk.dwSamplesPerSec = atoi(argv[4]); |
| 75 | + formatchunk.wBitsPerSample = atoi(argv[5]); |
| 76 | + formatchunk.wBlockAlign = formatchunk.wChannels * (formatchunk.wBitsPerSample >> 3); |
| 77 | + formatchunk.dwAvgBytesPerSec = formatchunk.wBlockAlign * formatchunk.dwSamplesPerSec; |
| 78 | + fwrite(&formatchunk, 1, sizeof(formatchunk), wavfile); |
| 79 | + |
| 80 | + datachunk.chunkID[0] = 'd'; |
| 81 | + datachunk.chunkID[1] = 'a'; |
| 82 | + datachunk.chunkID[2] = 't'; |
| 83 | + datachunk.chunkID[3] = 'a'; |
| 84 | + datachunk.chunkSize = pcmfile_size; |
| 85 | + fwrite(&datachunk, 1, sizeof(ID)+sizeof(long), wavfile); |
| 86 | + |
| 87 | + while((read_len = fread(buf, 1, sizeof(buf), pcmfile)) != 0) { |
| 88 | + /* revert the endiean */ |
| 89 | +#if 0 |
| 90 | + for (i=0; i<read_len; i+=2) { |
| 91 | + tmp = buf[i]; |
| 92 | + buf[i] = buf[i+1]; |
| 93 | + buf[i+1] = tmp; |
| 94 | + } |
| 95 | +#endif |
| 96 | + fwrite(buf, 1, read_len, wavfile); |
| 97 | + } |
| 98 | + |
| 99 | + fseek(wavfile, 4, SEEK_SET); |
| 100 | + chunk_size = 4 + (8 + formatchunk.chunkSize) + (8 + datachunk.chunkSize); |
| 101 | + fwrite(&chunk_size, 1, 4, wavfile); |
| 102 | + |
| 103 | + fclose(pcmfile); |
| 104 | + fclose(wavfile); |
| 105 | +} |
0 commit comments