libsdl-org / SDL_mixer

An audio mixer that supports various file formats for Simple Directmedia Layer.
zlib License
433 stars 146 forks source link

Added Mix_PauseAudio() call to suspend/resume entire audio output #424

Closed Wohlstand closed 2 years ago

Wohlstand commented 2 years ago

This call allows cheaper pausing/resuming of the whole audio processing without pausing every playing channel or music stream.

For example, this call can be used to pause the entire audio playback when the game is not focused.

Note: the "pause_async_music" call is required for music which is playing asynchronously from the main audio output processor, for example, OS Native MIDI. However, the stuff doesn't affect CMD Music which will still play (however, never tested this as I never used CMD music for my needs) Tested this, and it works, because it uses SIGSTOP and SIGCONT signals were literally suspended/resumes the running process.

sezero commented 2 years ago

What is so special about the pause_async_music thing, and why not simply use the existing Mix_PauseMusic and Mix_ResumeMusic instead of it? Unless I'm missing something, you can do something like:

void Mix_PauseAudio(int pause_on)
{
    SDL_PauseAudioDevice(audio_device, pause_on);
    if (pause_on) Mix_PauseMusic();
    else Mix_ResumeMusic();
}

And your pause_async_music misses setting music_active, I guess it was not intentional.

Wohlstand commented 2 years ago

The goal of this call is to make no internal environment touching, just suspend/resume the audio output processing, like you froze everything but no internal environment changes made. Calling Mix_PauseMusic() / Mix_ResumeMusic() is not a solution, and this will cause the next problem: if you had paused music before, and you going to pause the audio stream, and when you resume the audio stream, the music gets unexpectedly resumed (but it's intended to remain it paused as it was paused before the output suspension).

And your pause_async_music misses setting music_active, I guess it was not intentional.

Right, this makes the explained problem here... So, I should check the music pause state (the music_active flag) and don't try to pause/resume music when the pause state is set. Speaking about normal codecs, there is totally no care about music pause/resume state, it will pause automatically as I pause the entire output stream. This call is needed for asynchronous codecs only which will keep playing in the background no matter will I suspend or resume the audio stream or not.

So, I should do next:

Wohlstand commented 2 years ago

Okay, now should be fine. Again, the pause_async_music() call is required for pausing/resuming asynchronous music streams only without any internal environment changes as this kills the idea of the Mix_PauseAudio() goal to "freeze the time". All other normal codecs get paused/resumed with the audio stream without any interaction at all and there is totally no worry.

Wohlstand commented 2 years ago

Ping?

slouken commented 2 years ago

This seems good, although you probably want to document that it pauses all SDL audio processing, not just SDL_mixer.

Wohlstand commented 2 years ago

Ye, this call is intended to pause entire SDL Audio processing.