audio: Replace SDL_CreateAndBindAudioStream with SDL_OpenAudioDeviceStream.
This is meant to offer a simplified API for people that are either migrating directly from SDL2 with minimal effort or just want to make noise without any of the fancy new API features. Users of this API can just deal with a single SDL_AudioStream as their only object/handle into the audio subsystem. They are still allowed to open multiple devices (or open the same device multiple times), but cannot change stream bindings on logical devices opened through this function. Destroying the single audio stream will also close the logical device behind the scenes.
This commit is contained in:
@@ -34,7 +34,6 @@ static struct
|
||||
Uint32 soundpos;
|
||||
} wave;
|
||||
|
||||
static SDL_AudioDeviceID device;
|
||||
static SDL_AudioStream *stream;
|
||||
|
||||
static void fillerup(void)
|
||||
@@ -58,30 +57,22 @@ quit(int rc)
|
||||
static void
|
||||
close_audio(void)
|
||||
{
|
||||
if (device != 0) {
|
||||
if (stream) {
|
||||
SDL_DestroyAudioStream(stream);
|
||||
stream = NULL;
|
||||
SDL_CloseAudioDevice(device);
|
||||
device = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
open_audio(void)
|
||||
{
|
||||
device = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &wave.spec);
|
||||
if (!device) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError());
|
||||
SDL_free(wave.sound);
|
||||
quit(2);
|
||||
}
|
||||
stream = SDL_CreateAndBindAudioStream(device, &wave.spec);
|
||||
stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &wave.spec, NULL, NULL);
|
||||
if (!stream) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create audio stream: %s\n", SDL_GetError());
|
||||
SDL_CloseAudioDevice(device);
|
||||
SDL_free(wave.sound);
|
||||
quit(2);
|
||||
}
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamBinding(stream));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -180,11 +180,15 @@ int main(int argc, char **argv)
|
||||
}
|
||||
SDL_PauseAudioDevice(device);
|
||||
SDL_GetAudioDeviceFormat(device, &outspec);
|
||||
stream_out = SDL_CreateAndBindAudioStream(device, &outspec);
|
||||
stream_out = SDL_CreateAudioStream(&outspec, &outspec);
|
||||
if (!stream_out) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create an audio stream for playback: %s!\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
exit(1);
|
||||
} else if (SDL_BindAudioStream(device, stream_out) == -1) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't bind an audio stream for playback: %s!\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SDL_Log("Opening capture device %s%s%s...\n",
|
||||
@@ -200,11 +204,15 @@ int main(int argc, char **argv)
|
||||
}
|
||||
SDL_PauseAudioDevice(device);
|
||||
SDL_GetAudioDeviceFormat(device, &inspec);
|
||||
stream_in = SDL_CreateAndBindAudioStream(device, &inspec);
|
||||
stream_in = SDL_CreateAudioStream(&inspec, &inspec);
|
||||
if (!stream_in) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create an audio stream for capture: %s!\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
exit(1);
|
||||
} else if (SDL_BindAudioStream(device, stream_in) == -1) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't bind an audio stream for capture: %s!\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SDL_SetAudioStreamFormat(stream_in, NULL, &outspec); /* make sure we output at the playback format. */
|
||||
|
||||
@@ -69,7 +69,7 @@ static void iteration(void)
|
||||
done = 1;
|
||||
}
|
||||
} else if (e.type == SDL_EVENT_AUDIO_DEVICE_ADDED) {
|
||||
const SDL_AudioDeviceID which = (SDL_AudioDeviceID ) e.adevice.which;
|
||||
const SDL_AudioDeviceID which = (SDL_AudioDeviceID) e.adevice.which;
|
||||
const SDL_bool iscapture = e.adevice.iscapture ? SDL_TRUE : SDL_FALSE;
|
||||
char *name = SDL_GetAudioDeviceName(which);
|
||||
if (name != NULL) {
|
||||
@@ -80,20 +80,15 @@ static void iteration(void)
|
||||
continue;
|
||||
}
|
||||
if (!iscapture) {
|
||||
dev = SDL_OpenAudioDevice(which, &spec);
|
||||
if (!dev) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open '%s': %s\n", name, SDL_GetError());
|
||||
SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(which, &spec, NULL, NULL);
|
||||
if (!stream) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create/bind an audio stream to %u ('%s'): %s", (unsigned int) which, name, SDL_GetError());
|
||||
} else {
|
||||
SDL_AudioStream *stream;
|
||||
SDL_Log("Opened '%s' as %u\n", name, (unsigned int)dev);
|
||||
stream = SDL_CreateAndBindAudioStream(dev, &spec);
|
||||
if (!stream) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create/bind an audio stream to %u ('%s'): %s", (unsigned int) dev, name, SDL_GetError());
|
||||
SDL_CloseAudioDevice(dev);
|
||||
}
|
||||
SDL_Log("Opened '%s' as %u\n", name, (unsigned int) which);
|
||||
/* !!! FIXME: laziness, this used to loop the audio, but we'll just play it once for now on each connect. */
|
||||
SDL_PutAudioStreamData(stream, sound, soundlen);
|
||||
SDL_FlushAudioStream(stream);
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamBinding(stream));
|
||||
/* !!! FIXME: this is leaking the stream for now. We'll wire it up to a dictionary or whatever later. */
|
||||
}
|
||||
}
|
||||
@@ -101,7 +96,7 @@ static void iteration(void)
|
||||
} else if (e.type == SDL_EVENT_AUDIO_DEVICE_REMOVED) {
|
||||
dev = (SDL_AudioDeviceID)e.adevice.which;
|
||||
SDL_Log("%s device %u removed.\n", devtypestr(e.adevice.iscapture), (unsigned int)dev);
|
||||
SDL_CloseAudioDevice(dev);
|
||||
/* !!! FIXME: we need to keep track of our streams and destroy them here. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ static Uint8 *sound = NULL; /* Pointer to wave data */
|
||||
static Uint32 soundlen = 0; /* Length of wave data */
|
||||
|
||||
/* these have to be in globals so the Emscripten port can see them in the mainloop. :/ */
|
||||
static SDL_AudioDeviceID device = 0;
|
||||
static SDL_AudioStream *stream = NULL;
|
||||
|
||||
|
||||
@@ -37,7 +36,6 @@ static void loop(void)
|
||||
{
|
||||
if (SDL_GetAudioStreamAvailable(stream) == 0) {
|
||||
SDL_Log("done.");
|
||||
SDL_CloseAudioDevice(device);
|
||||
SDL_DestroyAudioStream(stream);
|
||||
SDL_free(sound);
|
||||
SDL_Quit();
|
||||
@@ -65,13 +63,10 @@ test_multi_audio(SDL_AudioDeviceID *devices, int devcount)
|
||||
|
||||
SDL_Log("Playing on device #%d of %d: id=%u, name='%s'...", i, devcount, (unsigned int) devices[i], devname);
|
||||
|
||||
device = SDL_OpenAudioDevice(devices[i], &spec);
|
||||
if (device == 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device failed: %s", SDL_GetError());
|
||||
} else if ((stream = SDL_CreateAndBindAudioStream(device, &spec)) == NULL) { /* we can reuse these, but we'll just make one each time for now. */
|
||||
if ((stream = SDL_OpenAudioDeviceStream(devices[i], &spec, NULL, NULL)) == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Audio stream creation failed: %s", SDL_GetError());
|
||||
SDL_CloseAudioDevice(device);
|
||||
} else {
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamBinding(stream));
|
||||
SDL_PutAudioStreamData(stream, sound, soundlen);
|
||||
SDL_FlushAudioStream(stream);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
@@ -87,7 +82,6 @@ test_multi_audio(SDL_AudioDeviceID *devices, int devcount)
|
||||
}
|
||||
#endif
|
||||
SDL_Log("done.");
|
||||
SDL_CloseAudioDevice(device);
|
||||
SDL_DestroyAudioStream(stream);
|
||||
}
|
||||
SDL_free(devname);
|
||||
@@ -101,29 +95,19 @@ test_multi_audio(SDL_AudioDeviceID *devices, int devcount)
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!");
|
||||
} else {
|
||||
for (i = 0; i < devcount; i++) {
|
||||
char *devname = SDL_GetAudioDeviceName(devices[i]);
|
||||
device = SDL_OpenAudioDevice(devices[i], &spec);
|
||||
if (device == 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device %d of %d (id=%u, name='%s') failed: %s\n", i, devcount, (unsigned int) devices[i], devname, SDL_GetError());
|
||||
}
|
||||
SDL_free(devname);
|
||||
devices[i] = device; /* just replace the physical device ID with the newly-opened logical device ID. */
|
||||
if (device) {
|
||||
SDL_PauseAudioDevice(device); /* hold while we set up all the streams. */
|
||||
streams[i] = SDL_CreateAndBindAudioStream(device, &spec);
|
||||
if (streams[i] == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Audio stream creation failed for device %d of %d: %s", i, devcount, SDL_GetError());
|
||||
} else {
|
||||
SDL_PutAudioStreamData(streams[i], sound, soundlen);
|
||||
SDL_FlushAudioStream(streams[i]);
|
||||
}
|
||||
streams[i] = SDL_OpenAudioDeviceStream(devices[i], &spec, NULL, NULL);
|
||||
if (streams[i] == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Audio stream creation failed for device %d of %d: %s", i, devcount, SDL_GetError());
|
||||
} else {
|
||||
SDL_PutAudioStreamData(streams[i], sound, soundlen);
|
||||
SDL_FlushAudioStream(streams[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* try to start all the devices about the same time. SDL does not guarantee sync across physical devices. */
|
||||
for (i = 0; i < devcount; i++) {
|
||||
if (devices[i]) {
|
||||
SDL_ResumeAudioDevice(devices[i]);
|
||||
if (streams[i]) {
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamBinding(streams[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +127,6 @@ test_multi_audio(SDL_AudioDeviceID *devices, int devcount)
|
||||
}
|
||||
|
||||
for (i = 0; i < devcount; i++) {
|
||||
SDL_CloseAudioDevice(devices[i]);
|
||||
SDL_DestroyAudioStream(streams[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -193,7 +193,6 @@ int main(int argc, char *argv[])
|
||||
char *devname = SDL_GetAudioDeviceName(devices[i]);
|
||||
int j;
|
||||
SDL_AudioSpec spec;
|
||||
SDL_AudioDeviceID dev;
|
||||
|
||||
SDL_Log("Testing audio device: %s\n", devname);
|
||||
SDL_free(devname);
|
||||
@@ -208,24 +207,16 @@ int main(int argc, char *argv[])
|
||||
spec.freq = SAMPLE_RATE_HZ;
|
||||
spec.format = SDL_AUDIO_S16SYS;
|
||||
|
||||
dev = SDL_OpenAudioDevice(devices[i], &spec);
|
||||
if (dev == 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_OpenAudioDevice() failed: %s\n", SDL_GetError());
|
||||
continue;
|
||||
}
|
||||
|
||||
stream = SDL_CreateAndBindAudioStream(dev, &spec);
|
||||
if (stream == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateAndBindAudioStream() failed: %s\n", SDL_GetError());
|
||||
SDL_CloseAudioDevice(dev);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* These are used by the fill_buffer callback */
|
||||
total_channels = spec.channels;
|
||||
active_channel = 0;
|
||||
|
||||
SDL_SetAudioStreamGetCallback(stream, fill_buffer, NULL);
|
||||
stream = SDL_OpenAudioDeviceStream(devices[i], &spec, fill_buffer, NULL);
|
||||
if (stream == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_OpenAudioDeviceStream() failed: %s\n", SDL_GetError());
|
||||
continue;
|
||||
}
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamBinding(stream));
|
||||
|
||||
for (j = 0; j < total_channels; j++) {
|
||||
const int sine_freq = is_lfe_channel(j, total_channels) ? LFE_SINE_FREQ_HZ : SINE_FREQ_HZ;
|
||||
@@ -240,7 +231,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
SDL_CloseAudioDevice(dev);
|
||||
SDL_DestroyAudioStream(stream);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user