Skip to content

Always clamp frames_needed to the allowed mix/max range in the mixer #2843

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 7, 2023

Conversation

johnnovak
Copy link
Member

@johnnovak johnnovak commented Sep 7, 2023

This fixes tripping the check_casts at the start of MIXER_MixData when putting your laptop to sleep on macOS when audio playback is active. Probably it fixes all sorts of other weird edge cases.

This is a medium-term solution to ensure safety until the mixer code is thoroughly refactored. Triggering and/or understanding all the special cases when the 'frames_needed' under/overshoot can happen is rather tricky with the current code.

With this fix in place, we're no longer tripping the assert, but I think we also need to pause the emulation before going into sleep mode because after waking up the music jumps forward after a few seconds (e.g. try Space Quest 3 intro). Probably because the timers haven't been stopped before entering sleep mode or something. So while I think we need this safety clamping, this is not a 100% fix to the general sleep/resume problem.

I'm wondering is the sleep/resume timing issue is a more pervasive DOSBox problem and it would affect every part of the emulation, not just the audio. I'm actually unsure how to deal with sleep/resume when timers are involved. Is there such a thing as "sleep/hibernation aware timers" that you can use to calculate your delta timings?

With this trace logging in place, I got the following output and assertion failure in debug mode when I close then reopen my laptop while the audio is playing.

// Mix a certain amount of new sample frames
static void MIXER_MixData(const int frames_requested)
{
	constexpr auto capture_buf_frames = 1024;

	if (frames_requested > UINT16_MAX) {
		LOG_TRACE("frames_requested greater than MAX_UINT16");
	}

image

This fixes tripping the check_casts at the start of `MIXER_MixData` when
putting your laptop to sleep on macOS when audio playback is active.
Probably it fixes all sorts of other weird edge cases.

This is a medium-term solution to ensure safety until the mixer code is
thorougly refactored. Triggering and/or understanding all the special
cases when the 'frames_needed' under/overshoot can happen is rather
tricky with the current code.
@johnnovak johnnovak marked this pull request as ready for review September 7, 2023 07:49
@johnnovak johnnovak requested a review from kcgen September 7, 2023 07:50
@johnnovak johnnovak self-assigned this Sep 7, 2023
@johnnovak johnnovak added audio Audio related issues or enhancements bug Something isn't working labels Sep 7, 2023
@kcgen
Copy link
Member

kcgen commented Sep 7, 2023

we also need to pause the emulation before going into sleep mode

The OS should make this 100% transparent to all user-space services and application - the memory space and instruction space should be frozen and then resumed without any action needed on the applications' side.

because after waking up the music jumps forward after a few seconds (e.g. try Space Quest 3 intro). Probably because the timers haven't been stopped before entering sleep mode or something.

This says the OS is probably not making sure all the interfacing devices are "fully" resumed, and our application is being brought back from suspend prematurely. Like waking up and seeing the world still being forme around you and then falling through your bed into an unreconstructed void.

But yeah: we're not going to fix buggy OSes.. maybe we need some extra checks at the SDL level (I remember some APIs to check how "backed up" SDL is, and maybe we could simply block in a "while(condition) + sleep" until some state is achieved on the SDL side and we're safe to carry on).

Copy link
Member

@kcgen kcgen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All looks good, @johnnovak.

@johnnovak
Copy link
Member Author

johnnovak commented Sep 7, 2023

The OS should make this 100% transparent to all user-space services and application - the memory space and instruction space should be frozen and then resumed without any action needed on the applications' side.

That's what I suspected and yes, that's something that should be 100% the OSes job.

because after waking up the music jumps forward after a few seconds (e.g. try Space Quest 3 intro). Probably because the timers haven't been stopped before entering sleep mode or something.

This says the OS is probably not making sure all the interfacing devices are "fully" resumed, and our application is being brought back from suspend prematurely. Like waking up and seeing the world still being forme around you and then falling through your bed into an unreconstructed void.

Like when I get up in the middle of the night to go out to pee, and sometimes I don't even know on which plane of existence I am 😅 🌚

I'm still somewhat confused about the issue because if I use VLC or play a YouTube video in the browser, then close and reopen my laptop, there are no weird audio glitches and most importantly, there are no "time jumps" in the playback a few seconds later. So that's why I thought that although the OS should handle sleep/resume, the application still should be coded in a "sleep/resume-aware" (or "tolerant") way, but yeah, not explicitly handle it.

Ultimately, I don't know, I'm just speaking about my actual experience of comparing DOSBox that behaves erratically on sleep/awake compared to any other "established" app on macOS that doesn't misbehave in a similar fashion.

But yeah: we're not going to fix buggy OSes.. maybe we need some extra checks at the SDL level (I remember some APIs to check how "backed up" SDL is, and maybe we could simply block in a "while(condition) + sleep" until some state is achieved on the SDL side and we're safe to carry on).

Agree 100% on that; I just wanted to make sure we're not doing something "wrong" that makes DOSBox "sleep/wake intolerant" or something 😅 Maybe a discussion for later and it's not a super high priority thing—I just wanted to raise it, I guess 😄

@johnnovak johnnovak merged commit a25af54 into main Sep 7, 2023
@kcgen kcgen deleted the jn/mixer-fix branch September 26, 2023 21:13
@johnnovak johnnovak changed the title Always clamp 'frames_needed' to the allowed mix/max range in the mixer Always clamp frames_needed to the allowed mix/max range in the mixer Dec 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
audio Audio related issues or enhancements bug Something isn't working
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants