Skip to content

Commit

Permalink
Removed the broken audio streaming code, other small cleanups.
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Mar 19, 2015
1 parent 5cbb32e commit 1e78ef2
Showing 1 changed file with 43 additions and 252 deletions.
295 changes: 43 additions & 252 deletions src/audio/SDL_audio.c
Expand Up @@ -286,67 +286,6 @@ finalize_audio_entry_points(void)
#undef FILL_STUB
}

#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
/* Streaming functions (for when the input and output buffer sizes are different) */
/* Write [length] bytes from buf into the streamer */
static void
SDL_StreamWrite(SDL_AudioStreamer * stream, Uint8 * buf, int length)
{
int i;

for (i = 0; i < length; ++i) {
stream->buffer[stream->write_pos] = buf[i];
++stream->write_pos;
}
}

/* Read [length] bytes out of the streamer into buf */
static void
SDL_StreamRead(SDL_AudioStreamer * stream, Uint8 * buf, int length)
{
int i;

for (i = 0; i < length; ++i) {
buf[i] = stream->buffer[stream->read_pos];
++stream->read_pos;
}
}

static int
SDL_StreamLength(SDL_AudioStreamer * stream)
{
return (stream->write_pos - stream->read_pos) % stream->max_len;
}

/* Initialize the stream by allocating the buffer and setting the read/write heads to the beginning */
#if 0
static int
SDL_StreamInit(SDL_AudioStreamer * stream, int max_len, Uint8 silence)
{
/* First try to allocate the buffer */
stream->buffer = (Uint8 *) SDL_malloc(max_len);
if (stream->buffer == NULL) {
return -1;
}

stream->max_len = max_len;
stream->read_pos = 0;
stream->write_pos = 0;

/* Zero out the buffer */
SDL_memset(stream->buffer, silence, max_len);

return 0;
}
#endif

/* Deinitialize the stream simply by freeing the buffer */
static void
SDL_StreamDeinit(SDL_AudioStreamer * stream)
{
SDL_free(stream->buffer);
}
#endif

/* device hotplug support... */

Expand Down Expand Up @@ -655,17 +594,12 @@ int SDLCALL
SDL_RunAudio(void *devicep)
{
SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
const int silence = (int) device->spec.silence;
const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
const int stream_len = (device->convert.needed) ? device->convert.len : device->spec.size;
Uint8 *stream;
int stream_len;
void *udata;
void (SDLCALL * fill) (void *userdata, Uint8 * stream, int len);
Uint32 delay;

#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
/* For streaming when the buffer sizes don't match up */
Uint8 *istream;
int istream_len = 0;
#endif
void *udata = device->spec.userdata;
void (SDLCALL *fill) (void *, Uint8 *, int) = device->spec.callback;

/* The audio mixing is always a high priority thread */
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
Expand All @@ -674,202 +608,59 @@ SDL_RunAudio(void *devicep)
device->threadid = SDL_ThreadID();
current_audio.impl.ThreadInit(device);

/* Set up the mixing function */
fill = device->spec.callback;
udata = device->spec.userdata;

/* By default do not stream */
device->use_streamer = 0;

if (device->convert.needed) {
#if 0 /* !!! FIXME: I took len_div out of the structure. Use rate_incr instead? */
/* If the result of the conversion alters the length, i.e. resampling is being used, use the streamer */
if (device->convert.len_mult != 1 || device->convert.len_div != 1) {
/* The streamer's maximum length should be twice whichever is larger: spec.size or len_cvt */
stream_max_len = 2 * device->spec.size;
if (device->convert.len_mult > device->convert.len_div) {
stream_max_len *= device->convert.len_mult;
stream_max_len /= device->convert.len_div;
}
if (SDL_StreamInit(&device->streamer, stream_max_len, silence) <
0)
return -1;
device->use_streamer = 1;

/* istream_len should be the length of what we grab from the callback and feed to conversion,
so that we get close to spec_size. I.e. we want device.spec_size = istream_len * u / d
*/
istream_len =
device->spec.size * device->convert.len_div /
device->convert.len_mult;
/* Loop, filling the audio buffers */
while (!device->shutdown) {
/* Fill the current buffer with sound */
if (device->convert.needed) {
stream = device->convert.buf;
} else if (device->enabled) {
stream = current_audio.impl.GetDeviceBuf(device);
} else {
/* if the device isn't enabled, we still write to the
fake_stream, so the app's callback will fire with
a regular frequency, in case they depend on that
for timing or progress. They can use hotplug
now to know if the device failed. */
stream = NULL;
}
#endif
stream_len = device->convert.len;
} else {
stream_len = device->spec.size;
}

/* Calculate the delay while paused */
delay = ((device->spec.samples * 1000) / device->spec.freq);

/* Determine if the streamer is necessary here */
#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
if (device->use_streamer == 1) {
/* This code is almost the same as the old code. The difference is, instead of reading
directly from the callback into "stream", then converting and sending the audio off,
we go: callback -> "istream" -> (conversion) -> streamer -> stream -> device.
However, reading and writing with streamer are done separately:
- We only call the callback and write to the streamer when the streamer does not
contain enough samples to output to the device.
- We only read from the streamer and tell the device to play when the streamer
does have enough samples to output.
This allows us to perform resampling in the conversion step, where the output of the
resampling process can be any number. We will have to see what a good size for the
stream's maximum length is, but I suspect 2*max(len_cvt, stream_len) is a good figure.
*/
while (!device->shutdown) {

if (device->paused) {
SDL_Delay(delay);
continue;
}

/* Only read in audio if the streamer doesn't have enough already (if it does not have enough samples to output) */
if (SDL_StreamLength(&device->streamer) < stream_len) {
/* Set up istream */
if (device->convert.needed) {
if (device->convert.buf) {
istream = device->convert.buf;
} else {
continue;
}
} else {
/* FIXME: Ryan, this is probably wrong. I imagine we don't want to get
* a device buffer both here and below in the stream output.
*/
istream = current_audio.impl.GetDeviceBuf(device);
if (istream == NULL) {
istream = device->fake_stream;
}
}

/* Read from the callback into the _input_ stream */
// !!! FIXME: this should be LockDevice.
SDL_LockMutex(device->mixer_lock);
(*fill) (udata, istream, istream_len);
SDL_UnlockMutex(device->mixer_lock);

/* Convert the audio if necessary and write to the streamer */
if (device->convert.needed) {
SDL_ConvertAudio(&device->convert);
if (istream == NULL) {
istream = device->fake_stream;
}
/* SDL_memcpy(istream, device->convert.buf, device->convert.len_cvt); */
SDL_StreamWrite(&device->streamer, device->convert.buf,
device->convert.len_cvt);
} else {
SDL_StreamWrite(&device->streamer, istream, istream_len);
}
}

/* Only output audio if the streamer has enough to output */
if (SDL_StreamLength(&device->streamer) >= stream_len) {
/* Set up the output stream */
if (device->convert.needed) {
if (device->convert.buf) {
stream = device->convert.buf;
} else {
continue;
}
} else {
stream = current_audio.impl.GetDeviceBuf(device);
if (stream == NULL) {
stream = device->fake_stream;
}
}

/* Now read from the streamer */
SDL_StreamRead(&device->streamer, stream, stream_len);

/* Ready current buffer for play and change current buffer */
if (stream != device->fake_stream) {
current_audio.impl.PlayDevice(device);
/* Wait for an audio buffer to become available */
current_audio.impl.WaitDevice(device);
} else {
SDL_Delay(delay);
}
}
if (stream == NULL) {
stream = device->fake_stream;
}

/* !!! FIXME: this should be LockDevice. */
SDL_LockMutex(device->mixer_lock);
if (device->paused) {
SDL_memset(stream, silence, stream_len);
} else {
(*fill) (udata, stream, stream_len);
}
} else
#endif
{
/* Otherwise, do not use the streamer. This is the old code. */
const int silence = (int) device->spec.silence;

/* Loop, filling the audio buffers */
while (!device->shutdown) {
/* Fill the current buffer with sound */
if (device->convert.needed) {
stream = device->convert.buf;
} else if (device->enabled) {
stream = current_audio.impl.GetDeviceBuf(device);
} else {
/* if the device isn't enabled, we still write to the
fake_stream, so the app's callback will fire with
a regular frequency, in case they depend on that
for timing or progress. They can use hotplug
now to know if the device failed. */
stream = NULL;
}
SDL_UnlockMutex(device->mixer_lock);

/* Convert the audio if necessary */
if (device->enabled && device->convert.needed) {
SDL_ConvertAudio(&device->convert);
stream = current_audio.impl.GetDeviceBuf(device);
if (stream == NULL) {
stream = device->fake_stream;
}

/* !!! FIXME: this should be LockDevice. */
SDL_LockMutex(device->mixer_lock);
if (device->paused) {
SDL_memset(stream, silence, stream_len);
} else {
(*fill) (udata, stream, stream_len);
}
SDL_UnlockMutex(device->mixer_lock);

/* Convert the audio if necessary */
if (device->enabled && device->convert.needed) {
SDL_ConvertAudio(&device->convert);
stream = current_audio.impl.GetDeviceBuf(device);
if (stream == NULL) {
stream = device->fake_stream;
} else {
SDL_memcpy(stream, device->convert.buf,
device->convert.len_cvt);
}
SDL_memcpy(stream, device->convert.buf,
device->convert.len_cvt);
}
}

/* Ready current buffer for play and change current buffer */
if (stream != device->fake_stream) {
current_audio.impl.PlayDevice(device);
/* Wait for an audio buffer to become available */
current_audio.impl.WaitDevice(device);
} else {
SDL_Delay(delay);
}
/* Ready current buffer for play and change current buffer */
if (stream == device->fake_stream) {
SDL_Delay(delay);
} else {
current_audio.impl.PlayDevice(device);
current_audio.impl.WaitDevice(device);
}
}

/* Wait for the audio to drain.. */
/* Wait for the audio to drain. */
current_audio.impl.WaitDone(device);

/* If necessary, deinit the streamer */
#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
if (device->use_streamer == 1)
SDL_StreamDeinit(&device->streamer);
#endif

return 0;
}

Expand Down

0 comments on commit 1e78ef2

Please sign in to comment.