@@ -8165,7 +8165,7 @@ mp3_sdlrwops_seek(void *data, int offset, drmp3_seek_origin origin)
81658165}
81668166
81678167
8168- static int OpenSDL2AudioDevice (SDL_AudioSpec * );
8168+ static SDL_bool OpenSDL2AudioDevice (SDL_AudioSpec * want );
81698169static int CloseSDL2AudioDevice (void );
81708170static SDL_bool ResetAudioStream (SDL_AudioStream * * _stream , SDL_AudioSpec * spec , const SDL_AudioSpec * to , const SDL_AudioFormat fromfmt , const Uint8 fromchannels , const int fromfreq );
81718171
@@ -8882,96 +8882,63 @@ ResetAudioStream(SDL_AudioStream **_stream, SDL_AudioSpec *spec, const SDL_Audio
88828882}
88838883
88848884static SDL_bool
8885- ResetAudioStreamForDeviceChange ( SDL_AudioStream * * _stream , SDL_AudioSpec * spec )
8885+ OpenSDL2AudioDevice ( SDL_AudioSpec * appwant )
88868886{
8887- if (* _stream == NULL ) {
8888- return SDL_TRUE ; /* no stream, no need to reset it. */
8889- }
8890- SDL20_FreeAudioStream (* _stream ); /* force it to rebuild because destination format changed. */
8891- * _stream = NULL ;
8892- return ResetAudioStream (_stream , spec , & audio_cbdata -> device_format , spec -> format , spec -> channels , spec -> freq );
8893- }
8887+ SDL_AudioSpec devwant ;
88948888
8895- static int
8896- OpenSDL2AudioDevice (SDL_AudioSpec * want )
8897- {
8898- void (SDLCALL * orig_callback )(void * userdata , Uint8 * stream , int len ) = want -> callback ;
8899- void * orig_userdata = want -> userdata ;
8900- AudioCallbackWrapperData * allocated_cbdata = NULL ;
8901- int retval ;
8889+ /* note that 0x80 isn't perfect silence for U16 formats, but we only have one byte that is used for memset() calls, so it has to do. SDL2 has the same bug. */
8890+ appwant -> silence = SDL_AUDIO_ISSIGNED (appwant -> format ) ? 0x00 : 0x80 ;
8891+ appwant -> size = appwant -> samples * appwant -> channels * (SDL_AUDIO_BITSIZE (appwant -> format ) / 8 );
89028892
8903- /* Two things use the audio device: the app, through 1.2's SDL_OpenAudio,
8904- and the fake CD-ROM device. Either can open the device, and both write
8905- to SDL_AudioStreams to buffer and convert data. We try to open the device
8906- in a format that accommodates both inputs, but we might close the device
8907- and reopen it if we need more channels, etc. */
89088893 if (audio_cbdata != NULL ) { /* device is already open. */
8909- SDL_AudioSpec * have = & audio_cbdata -> device_format ;
8910- if ( (want -> freq > have -> freq ) ||
8911- (want -> channels > have -> channels ) ||
8912- (want -> samples > have -> samples ) ||
8913- (SDL_AUDIO_ISFLOAT (want -> format ) && !SDL_AUDIO_ISFLOAT (have -> format )) ||
8914- (SDL_AUDIO_BITSIZE (want -> format ) > SDL_AUDIO_BITSIZE (have -> format )) ) {
8915- SDL20_CloseAudio ();
8916- } else {
8917- SDL20_LockAudio (); /* Device is already at acceptable parameters, just pause it for further setup by caller. */
8918- return SDL_TRUE ;
8919- }
8920- } else {
8921- allocated_cbdata = audio_cbdata = (AudioCallbackWrapperData * ) SDL20_calloc (1 , sizeof (AudioCallbackWrapperData ));
8922- if (!audio_cbdata ) {
8923- SDL20_OutOfMemory ();
8924- return SDL_FALSE ;
8925- }
8894+ SDL20_LockAudio (); /* Device is already at acceptable parameters, just pause it for further setup by caller. */
8895+ return SDL_TRUE ;
89268896 }
89278897
8928- want -> callback = AudioCallbackWrapper ;
8929- want -> userdata = audio_cbdata ;
8930- retval = (SDL20_OpenAudio (want , & audio_cbdata -> device_format ) == 0 );
8931- if (retval == -1 ) {
8932- if (audio_cbdata -> app_callback_opened || audio_cbdata -> cdrom_opened ) {
8933- SDL20_Log ("sdl12-compat: Uhoh, reopening the SDL2 audio device failed: %s" , SDL20_GetError ());
8934- if (audio_cbdata -> app_callback_opened ) {
8935- /* we aren't going to bother to fake the audio callback for this case. */
8936- SDL20_Log ("sdl12-compat: More audio won't play and app might crash!" );
8937- }
8938- if (audio_cbdata -> cdrom_opened ) {
8939- SDL20_Log ("sdl12-compat: CD-ROM audio will stop now!" );
8940- audio_cbdata -> cdrom_status = SDL12_CD_TRAYEMPTY ;
8941- }
8942- }
8943- if (allocated_cbdata ) {
8944- audio_cbdata = NULL ;
8945- SDL_free (allocated_cbdata );
8946- }
8898+ audio_cbdata = (AudioCallbackWrapperData * ) SDL20_calloc (1 , sizeof (AudioCallbackWrapperData ));
8899+ if (!audio_cbdata ) {
8900+ SDL20_OutOfMemory ();
89478901 return SDL_FALSE ;
89488902 }
89498903
8950- want -> callback = orig_callback ;
8951- want -> userdata = orig_userdata ;
8952- want -> size = want -> samples * want -> channels * (SDL_AUDIO_BITSIZE (want -> format ) / 8 );
8953-
8954- /* note that 0x80 isn't perfect silence for U16 formats, but we only have one byte that is used for memset() calls, so it has to do. SDL2 has the same bug. */
8955- want -> silence = SDL_AUDIO_ISSIGNED (want -> format ) ? 0x00 : 0x80 ;
8956-
8957- /* reset audiostreams if device format changed. */
8958- if (!ResetAudioStreamForDeviceChange (& audio_cbdata -> app_callback_stream , & audio_cbdata -> app_callback_format )) {
8959- SDL20_Log ("sdl12-compat: Uhoh, failed to prepare audio stream for audio device reopen: %s" , SDL20_GetError ());
8960- SDL20_Log ("sdl12-compat: More audio won't play and app might crash!" );
8961- audio_cbdata -> app_callback_opened = SDL_FALSE ;
8962- }
8963-
8964- if (!ResetAudioStreamForDeviceChange (& audio_cbdata -> cdrom_stream , & audio_cbdata -> cdrom_format )) {
8965- SDL20_Log ("sdl12-compat: Uhoh, failed to prepare audio stream for audio device reopen: %s" , SDL20_GetError ());
8966- SDL20_Log ("sdl12-compat: CD-ROM audio will stop now!" );
8967- audio_cbdata -> cdrom_opened = SDL_FALSE ;
8968- audio_cbdata -> cdrom_status = SDL12_CD_TRAYEMPTY ;
8904+ /* Two things use the audio device: the app, through 1.2's SDL_OpenAudio,
8905+ and the fake CD-ROM device. Either can open the device, and both write
8906+ to SDL_AudioStreams to buffer and convert data. We open the device
8907+ in a format that accommodates both inputs.
8908+
8909+ In case the app asks for something really low-quality--an old game
8910+ playing 8-bit mono audio at 8000Hz or whatever--we force the audio
8911+ hardware to something better, in case the app _also_ wants to play
8912+ CD audio, so we can get good quality out of that without reopening
8913+ the device. We have to be able to buffer and convert between the
8914+ app's needs and SDL2's anyhow, so this isn't a big deal. If they
8915+ ask for better than CD quality, we'll allow it and upsample any
8916+ CD audio that is played.
8917+
8918+ If the CD-ROM is opened first, and the app wants better-than-CD
8919+ quality later, there's not much we can do, it'll have to
8920+ downsample, but I suspect this is rare, and the audio will
8921+ still be good enough. */
8922+
8923+ SDL20_memcpy (& devwant , appwant , sizeof (SDL_AudioSpec ));
8924+ devwant .callback = AudioCallbackWrapper ;
8925+ devwant .userdata = audio_cbdata ;
8926+ devwant .freq = SDL_max (devwant .freq , 44100 );
8927+ devwant .channels = SDL_max (devwant .channels , 2 );
8928+ if (SDL_AUDIO_BITSIZE (devwant .format ) < 16 ) {
8929+ devwant .format = AUDIO_S16SYS ;
8930+ }
8931+
8932+ if (SDL20_OpenAudio (& devwant , & audio_cbdata -> device_format ) == -1 ) {
8933+ SDL_free (audio_cbdata );
8934+ audio_cbdata = NULL ;
8935+ return SDL_FALSE ;
89698936 }
89708937
89718938 SDL20_LockAudio ();
89728939 SDL20_PauseAudio (0 ); /* always unpause, but caller will unlock after finalizing setup. */
89738940
8974- return retval ;
8941+ return SDL_TRUE ;
89758942}
89768943
89778944static int
0 commit comments