diff --git a/WhatsNew.txt b/WhatsNew.txt index 56172f41b..f6458552a 100644 --- a/WhatsNew.txt +++ b/WhatsNew.txt @@ -21,3 +21,4 @@ General: * The timestamp member of the SDL_Event structure is now in nanoseconds, filled in with the time the event was generated, or the time it was queued if that's not available * Added SDL_modf() and SDL_modff() to separate the whole and fractional portions of a floating point number * Added SDL_GetRenderVSync() to get vsync of the given renderer +* Added SDL_PlayAudioDevice() to start audio playback diff --git a/docs/README-migration.md b/docs/README-migration.md index 2c413d381..a18478eec 100644 --- a/docs/README-migration.md +++ b/docs/README-migration.md @@ -47,6 +47,8 @@ The vi format comments have been removed from source code. Vim users can use the SDL_AudioInit() and SDL_AudioQuit() have been removed. Instead you can call SDL_InitSubSytem() and SDL_QuitSubSytem() with SDL_INIT_AUDIO, which will properly refcount the subsystems. You can choose a specific audio driver using SDL_AUDIO_DRIVER hint. +SDL_PauseAudioDevice() is only used to pause audio playback. Use SDL_PlayAudioDevice() to start playing audio. + SDL_FreeWAV has been removed and calls can be replaced with SDL_free. The following functions have been renamed: diff --git a/include/SDL3/SDL_audio.h b/include/SDL3/SDL_audio.h index cd4260c36..bef22bc0f 100644 --- a/include/SDL3/SDL_audio.h +++ b/include/SDL3/SDL_audio.h @@ -466,7 +466,7 @@ extern DECLSPEC int SDLCALL SDL_GetDefaultAudioInfo(char **name, * diskaudio driver. * * An opened audio device starts out paused, and should be enabled for playing - * by calling SDL_PauseAudioDevice(devid, 0) when you are ready for your audio + * by calling SDL_PlayAudioDevice(devid) when you are ready for your audio * callback function to be called. Since the audio driver may modify the * requested size of the audio buffer, you should allocate any local mixing * buffers after you open the audio device. @@ -554,6 +554,7 @@ extern DECLSPEC int SDLCALL SDL_GetDefaultAudioInfo(char **name, * \sa SDL_CloseAudioDevice * \sa SDL_GetAudioDeviceName * \sa SDL_LockAudioDevice + * \sa SDL_PlayAudioDevice * \sa SDL_PauseAudioDevice * \sa SDL_UnlockAudioDevice */ @@ -588,41 +589,56 @@ typedef enum * * \since This function is available since SDL 3.0.0. * + * \sa SDL_PlayAudioDevice * \sa SDL_PauseAudioDevice */ extern DECLSPEC SDL_AudioStatus SDLCALL SDL_GetAudioDeviceStatus(SDL_AudioDeviceID dev); /* @} *//* Audio State */ /** - * Use this function to pause and unpause audio playback on a specified - * device. + * Use this function to play audio on a specified device. * - * This function pauses and unpauses the audio callback processing for a given - * device. Newly-opened audio devices start in the paused state, so you must - * call this function with **pause_on**=0 after opening the specified audio + * Newly-opened audio devices start in the paused state, so you must + * call this function after opening the specified audio * device to start playing sound. This allows you to safely initialize data * for your callback function after opening the audio device. Silence will be * written to the audio device while paused, and the audio callback is * guaranteed to not be called. Pausing one device does not prevent other * unpaused devices from running their callbacks. * - * Pausing state does not stack; even if you pause a device several times, a - * single unpause will start the device playing again, and vice versa. This is - * different from how SDL_LockAudioDevice() works. + * \param dev a device opened by SDL_OpenAudioDevice() + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_LockAudioDevice + * \sa SDL_PauseAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_PlayAudioDevice(SDL_AudioDeviceID dev); + + + +/** + * Use this function to pause audio playback on a specified device. + * + * This function pauses the audio callback processing for a given + * device. Silence will be written to the audio device while paused, and + * the audio callback is guaranteed to not be called. + * Pausing one device does not prevent other unpaused devices from running + * their callbacks. * * If you just need to protect a few variables from race conditions vs your * callback, you shouldn't pause the audio device, as it will lead to dropouts * in the audio playback. Instead, you should use SDL_LockAudioDevice(). * * \param dev a device opened by SDL_OpenAudioDevice() - * \param pause_on non-zero to pause, 0 to unpause * * \since This function is available since SDL 3.0.0. * * \sa SDL_LockAudioDevice + * \sa SDL_PlayAudioDevice */ -extern DECLSPEC void SDLCALL SDL_PauseAudioDevice(SDL_AudioDeviceID dev, - int pause_on); +extern DECLSPEC void SDLCALL SDL_PauseAudioDevice(SDL_AudioDeviceID dev); + /** * Load the audio data of a WAVE file into memory. diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 39232ae68..d6a23b9a9 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -1516,12 +1516,22 @@ SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid) return status; } -void SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on) +void SDL_PauseAudioDevice(SDL_AudioDeviceID devid) { SDL_AudioDevice *device = get_audio_device(devid); if (device) { current_audio.impl.LockDevice(device); - SDL_AtomicSet(&device->paused, pause_on ? 1 : 0); + SDL_AtomicSet(&device->paused, 1); + current_audio.impl.UnlockDevice(device); + } +} + +void SDL_PlayAudioDevice(SDL_AudioDeviceID devid) +{ + SDL_AudioDevice *device = get_audio_device(devid); + if (device) { + current_audio.impl.LockDevice(device); + SDL_AtomicSet(&device->paused, 0); current_audio.impl.UnlockDevice(device); } } diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index ba9584811..fe547ae87 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -842,6 +842,7 @@ SDL3_0.0.0 { SDL_modf; SDL_modff; SDL_GetRenderVSync; + SDL_PlayAudioDevice; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 71e071900..f36fb3cc2 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -870,3 +870,4 @@ #define SDL_modf SDL_modf_REAL #define SDL_modff SDL_modff_REAL #define SDL_GetRenderVSync SDL_GetRenderVSync_REAL +#define SDL_PlayAudioDevice SDL_PlayAudioDevice_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index fb7c9f3d3..9401e94ae 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -576,7 +576,7 @@ SDL_DYNAPI_PROC(SDL_Gamepad*,SDL_OpenGamepad,(SDL_JoystickID a),(a),return) SDL_DYNAPI_PROC(SDL_Joystick*,SDL_OpenJoystick,(SDL_JoystickID a),(a),return) SDL_DYNAPI_PROC(SDL_Sensor*,SDL_OpenSensor,(SDL_SensorID a),(a),return) SDL_DYNAPI_PROC(int,SDL_OpenURL,(const char *a),(a),return) -SDL_DYNAPI_PROC(void,SDL_PauseAudioDevice,(SDL_AudioDeviceID a, int b),(a,b),) +SDL_DYNAPI_PROC(void,SDL_PauseAudioDevice,(SDL_AudioDeviceID a),(a),) SDL_DYNAPI_PROC(int,SDL_PeepEvents,(SDL_Event *a, int b, SDL_eventaction c, Uint32 d, Uint32 e),(a,b,c,d,e),return) SDL_DYNAPI_PROC(int,SDL_PollEvent,(SDL_Event *a),(a),return) SDL_DYNAPI_PROC(int,SDL_PremultiplyAlpha,(int a, int b, Uint32 c, const void *d, int e, Uint32 f, void *g, int h),(a,b,c,d,e,f,g,h),return) @@ -915,3 +915,4 @@ SDL_DYNAPI_PROC(wchar_t*,SDL_wcsstr,(const wchar_t *a, const wchar_t *b),(a,b),r SDL_DYNAPI_PROC(double,SDL_modf,(double a, double *b),(a,b),return) SDL_DYNAPI_PROC(float,SDL_modff,(float a, float *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_GetRenderVSync,(SDL_Renderer *a, int *b),(a,b),return) +SDL_DYNAPI_PROC(void,SDL_PlayAudioDevice,(SDL_AudioDeviceID a),(a),) diff --git a/test/loopwave.c b/test/loopwave.c index a4d05e04d..ab84def17 100644 --- a/test/loopwave.c +++ b/test/loopwave.c @@ -64,7 +64,7 @@ open_audio() } /* Let the audio run */ - SDL_PauseAudioDevice(device, SDL_FALSE); + SDL_PlayAudioDevice(device); } #ifndef __EMSCRIPTEN__ diff --git a/test/loopwavequeue.c b/test/loopwavequeue.c index 6c1c6a475..ea63e3f8f 100644 --- a/test/loopwavequeue.c +++ b/test/loopwavequeue.c @@ -123,7 +123,7 @@ int main(int argc, char *argv[]) /*static x[99999]; SDL_QueueAudio(1, x, sizeof (x));*/ /* Let the audio run */ - SDL_PauseAudioDevice(g_audio_id, 0); + SDL_PlayAudioDevice(g_audio_id); done = 0; diff --git a/test/testaudiocapture.c b/test/testaudiocapture.c index 3f6b12717..90d327931 100644 --- a/test/testaudiocapture.c +++ b/test/testaudiocapture.c @@ -40,13 +40,13 @@ loop() } } else if (e.type == SDL_MOUSEBUTTONDOWN) { if (e.button.button == 1) { - SDL_PauseAudioDevice(devid_out, SDL_TRUE); - SDL_PauseAudioDevice(devid_in, SDL_FALSE); + SDL_PauseAudioDevice(devid_out); + SDL_PlayAudioDevice(devid_in); } } else if (e.type == SDL_MOUSEBUTTONUP) { if (e.button.button == 1) { - SDL_PauseAudioDevice(devid_in, SDL_TRUE); - SDL_PauseAudioDevice(devid_out, SDL_FALSE); + SDL_PauseAudioDevice(devid_in); + SDL_PlayAudioDevice(devid_out); } } } @@ -62,9 +62,9 @@ loop() if (please_quit) { /* stop playing back, quit. */ SDL_Log("Shutting down.\n"); - SDL_PauseAudioDevice(devid_in, 1); + SDL_PauseAudioDevice(devid_in); SDL_CloseAudioDevice(devid_in); - SDL_PauseAudioDevice(devid_out, 1); + SDL_PauseAudioDevice(devid_out); SDL_CloseAudioDevice(devid_out); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); diff --git a/test/testaudiohotplug.c b/test/testaudiohotplug.c index 085dbb030..01386c476 100644 --- a/test/testaudiohotplug.c +++ b/test/testaudiohotplug.c @@ -110,7 +110,7 @@ iteration() SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open '%s': %s\n", name, SDL_GetError()); } else { SDL_Log("Opened '%s' as %u\n", name, (unsigned int)dev); - SDL_PauseAudioDevice(dev, 0); + SDL_PlayAudioDevice(dev); } } } else if (e.type == SDL_AUDIODEVICEREMOVED) { diff --git a/test/testautomation_audio.c b/test/testautomation_audio.c index c6d3df318..500b366ec 100644 --- a/test/testautomation_audio.c +++ b/test/testautomation_audio.c @@ -224,6 +224,7 @@ int audio_initOpenCloseQuitAudio() * \brief Pause and unpause audio * * \sa https://wiki.libsdl.org/SDL_PauseAudioDevice + * \sa https://wiki.libsdl.org/SDL_PlayAudioDevice */ int audio_pauseUnpauseAudio() { @@ -298,8 +299,8 @@ int audio_pauseUnpauseAudio() /* Un-pause audio to start playing (maybe multiple times) */ pause_on = 0; for (k = 0; k <= j; k++) { - SDL_PauseAudioDevice(g_audio_id, pause_on); - SDLTest_AssertPass("Call to SDL_PauseAudioDevice(g_audio_id, %d), call %d", pause_on, k + 1); + SDL_PlayAudioDevice(g_audio_id); + SDLTest_AssertPass("Call to SDL_PlayAudioDevice(g_audio_id), call %d", k + 1); } /* Wait for callback */ @@ -314,8 +315,13 @@ int audio_pauseUnpauseAudio() /* Pause audio to stop playing (maybe multiple times) */ for (k = 0; k <= j; k++) { pause_on = (k == 0) ? 1 : SDLTest_RandomIntegerInRange(99, 9999); - SDL_PauseAudioDevice(g_audio_id, pause_on); - SDLTest_AssertPass("Call to SDL_PauseAudioDevice(g_audio_id, %d), call %d", pause_on, k + 1); + if (pause_on) { + SDL_PauseAudioDevice(g_audio_id); + SDLTest_AssertPass("Call to SDL_PauseAudioDevice(g_audio_id), call %d", k + 1); + } else { + SDL_PlayAudioDevice(g_audio_id); + SDLTest_AssertPass("Call to SDL_PlayAudioDevice(g_audio_id), call %d", k + 1); + } } /* Ensure callback is not called again */ diff --git a/test/testmultiaudio.c b/test/testmultiaudio.c index 1e6ad500f..d3dbb36c3 100644 --- a/test/testmultiaudio.c +++ b/test/testmultiaudio.c @@ -60,7 +60,7 @@ void loop() #ifdef __EMSCRIPTEN__ emscripten_cancel_main_loop(); #endif - SDL_PauseAudioDevice(cbd[0].dev, 1); + SDL_PauseAudioDevice(cbd[0].dev); SDL_CloseAudioDevice(cbd[0].dev); SDL_free(sound); SDL_Quit(); @@ -98,7 +98,7 @@ test_multi_audio(int devcount) if (cbd[0].dev == 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device failed: %s\n", SDL_GetError()); } else { - SDL_PauseAudioDevice(cbd[0].dev, 0); + SDL_PlayAudioDevice(cbd[0].dev); #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(loop, 0, 1); #else @@ -110,7 +110,7 @@ test_multi_audio(int devcount) #endif SDL_Delay(100); } - SDL_PauseAudioDevice(cbd[0].dev, 1); + SDL_PauseAudioDevice(cbd[0].dev); #endif SDL_Log("done.\n"); SDL_CloseAudioDevice(cbd[0].dev); @@ -131,7 +131,7 @@ test_multi_audio(int devcount) for (i = 0; i < devcount; i++) { if (cbd[i].dev) { - SDL_PauseAudioDevice(cbd[i].dev, 0); + SDL_PlayAudioDevice(cbd[i].dev); } } @@ -154,7 +154,7 @@ test_multi_audio(int devcount) #ifndef __EMSCRIPTEN__ for (i = 0; i < devcount; i++) { if (cbd[i].dev) { - SDL_PauseAudioDevice(cbd[i].dev, 1); + SDL_PauseAudioDevice(cbd[i].dev); SDL_CloseAudioDevice(cbd[i].dev); } } diff --git a/test/testsurround.c b/test/testsurround.c index 7241a15cb..051e156a1 100644 --- a/test/testsurround.c +++ b/test/testsurround.c @@ -179,7 +179,7 @@ int main(int argc, char *argv[]) total_channels = spec.channels; active_channel = 0; - SDL_PauseAudioDevice(dev, 0); + SDL_PlayAudioDevice(dev); for (j = 0; j < total_channels; j++) { int sine_freq = is_lfe_channel(j, total_channels) ? LFE_SINE_FREQ_HZ : SINE_FREQ_HZ;