diff --git a/src/ao_wav.c b/src/ao_wav.c index d63e5b7911d90edbc540fa38e2dc003e3dbb3d46..51c3e2163b15c91a086826e0da1c5488841930a7 100644 --- a/src/ao_wav.c +++ b/src/ao_wav.c @@ -139,6 +139,7 @@ static int ao_wav_open(ao_device *device, ao_sample_format *format) { ao_wav_internal *internal = (ao_wav_internal *) device->internal; unsigned char buf[WAV_HEADER_LEN]; + int size = 0x7fffffff; /* Use a bogus size initially */ /* Store information */ internal->wave.common.wChannels = format->channels; @@ -146,6 +147,43 @@ static int ao_wav_open(ao_device *device, ao_sample_format *format) internal->wave.common.dwSamplesPerSec = format->rate; memset(buf, 0, WAV_HEADER_LEN); + + /* Fill out our wav-header with some information. */ + strncpy(internal->wave.riff.id, "RIFF",4); + internal->wave.riff.len = size - 8; + strncpy(internal->wave.riff.wave_id, "WAVE",4); + + strncpy(internal->wave.format.id, "fmt ",4); + internal->wave.format.len = 16; + + internal->wave.common.wFormatTag = WAVE_FORMAT_PCM; + internal->wave.common.dwAvgBytesPerSec = + internal->wave.common.wChannels * + internal->wave.common.dwSamplesPerSec * + (internal->wave.common.wBitsPerSample >> 3); + + internal->wave.common.wBlockAlign = + internal->wave.common.wChannels * + (internal->wave.common.wBitsPerSample >> 3); + + strncpy(internal->wave.data.id, "data",4); + + internal->wave.data.len = size - 44; + + strncpy(buf, internal->wave.riff.id, 4); + WRITE_U32(buf+4, internal->wave.riff.len); + strncpy(buf+8, internal->wave.riff.wave_id, 4); + strncpy(buf+12, internal->wave.format.id,4); + WRITE_U32(buf+16, internal->wave.format.len); + WRITE_U16(buf+20, internal->wave.common.wFormatTag); + WRITE_U16(buf+22, internal->wave.common.wChannels); + WRITE_U32(buf+24, internal->wave.common.dwSamplesPerSec); + WRITE_U32(buf+28, internal->wave.common.dwAvgBytesPerSec); + WRITE_U16(buf+32, internal->wave.common.wBlockAlign); + WRITE_U16(buf+34, internal->wave.common.wBitsPerSample); + strncpy(buf+36, internal->wave.data.id, 4); + WRITE_U32(buf+40, internal->wave.data.len); + if (fwrite(buf, sizeof(char), WAV_HEADER_LEN, device->file) != WAV_HEADER_LEN) { return 0; /* Could not write wav header */ @@ -174,7 +212,7 @@ static int ao_wav_play(ao_device *device, const char *output_samples, static int ao_wav_close(ao_device *device) { ao_wav_internal *internal = (ao_wav_internal *) device->internal; - unsigned char buf[WAV_HEADER_LEN]; + unsigned char buf[4]; /* For holding length values */ long size; @@ -185,53 +223,30 @@ static int ao_wav_close(ao_device *device) return 0; /* Wav header corrupt */ } - /* Rewind file */ - if (fseek(device->file, 0, SEEK_SET) < 0) { - return 0; /* Wav header corrupt */ - } - - /* Fill out our wav-header with some information. */ + /* Go back and set correct length info */ - strncpy(internal->wave.riff.id, "RIFF",4); internal->wave.riff.len = size - 8; - strncpy(internal->wave.riff.wave_id, "WAVE",4); - - strncpy(internal->wave.format.id, "fmt ",4); - internal->wave.format.len = 16; - - internal->wave.common.wFormatTag = WAVE_FORMAT_PCM; - internal->wave.common.dwAvgBytesPerSec = - internal->wave.common.wChannels * - internal->wave.common.dwSamplesPerSec * - (internal->wave.common.wBitsPerSample >> 3); - - internal->wave.common.wBlockAlign = - internal->wave.common.wChannels * - (internal->wave.common.wBitsPerSample >> 3); - - strncpy(internal->wave.data.id, "data",4); - internal->wave.data.len = size - 44; - strncpy(buf, internal->wave.riff.id, 4); - WRITE_U32(buf+4, internal->wave.riff.len); - strncpy(buf+8, internal->wave.riff.wave_id, 4); - strncpy(buf+12, internal->wave.format.id,4); - WRITE_U32(buf+16, internal->wave.format.len); - WRITE_U16(buf+20, internal->wave.common.wFormatTag); - WRITE_U16(buf+22, internal->wave.common.wChannels); - WRITE_U32(buf+24, internal->wave.common.dwSamplesPerSec); - WRITE_U32(buf+28, internal->wave.common.dwAvgBytesPerSec); - WRITE_U16(buf+32, internal->wave.common.wBlockAlign); - WRITE_U16(buf+34, internal->wave.common.wBitsPerSample); - strncpy(buf+36, internal->wave.data.id, 4); - WRITE_U32(buf+40, internal->wave.data.len); + /* Rewind to riff len and write it */ + if (fseek(device->file, 4, SEEK_SET) < 0) + return 0; /* Wav header corrupt */ + + WRITE_U32(buf, internal->wave.riff.len); + if (fwrite(buf, sizeof(char), 4, device->file) < 4) + return 0; /* Wav header corrupt */ - if (fwrite(buf, sizeof(char), WAV_HEADER_LEN, device->file) - < WAV_HEADER_LEN) - return 0; - return 1; + /* Rewind to data len and write it */ + if (fseek(device->file, 40, SEEK_SET) < 0) + return 0; /* Wav header corrupt */ + + WRITE_U32(buf, internal->wave.data.len); + if (fwrite(buf, sizeof(char), 4, device->file) < 4) + return 0; /* Wav header corrupt */ + + + return 1; /* Wav header correct */ } static void ao_wav_device_clear(ao_device *device)