Skip to content
Snippets Groups Projects
Commit 0eca35ae authored by Stan Seibert's avatar Stan Seibert
Browse files

Fixed "bug" (you shouldn't pipe wav files anyway) that prevented wav

files from being piped to other programs.  We now write the wav header
at the beginning with bogus (max signed 32 bit int - header size) size
info and go back and fix it if the file is seekable at the end.


git-svn-id: http://svn.xiph.org/trunk/ao@1733 0101bb08-14d6-0310-b084-bc0e0c8e3800
parent 4af8157f
No related branches found
No related tags found
No related merge requests found
......@@ -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)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment