Fixed 'stuck' notes when changing video modes.

This is most apparent in OSX, where toggling windowed/fullscreen mode can sometimes take up to one second,
and any sounds playing from the ROM become stuck until the operation completes.
Also present on other systems to some extent.
Sound is now muted until the operation is complete.
This commit is contained in:
Stephen Anthony 2018-08-31 20:52:56 -02:30
parent baadecc866
commit 09b3d980f3
6 changed files with 36 additions and 41 deletions

View File

@ -86,6 +86,10 @@
* The debugger 'uhex' command is now honoured in CDF and BUS schemes.
* When switching screenmodes, the sound is now paused and later resumed.
This fixes popping and cracking sounds apparent on some systems, notably
OSX when toggling windowed/fullscreen mode.
* Updated PAL palette.
* For UNIX systems: in the ROM launcher, when using symlinks use the

View File

@ -71,18 +71,10 @@ class SoundNull : public Sound
Set the mute state of the sound object. While muted no sound is played.
@param state Mutes sound if true, unmute if false
*/
void mute(bool state) override { }
/**
Get the fragment size.
@return The previous (old) mute state
*/
uInt32 getFragmentSize() const override { return 512; }
/**
Get the sample rate.
*/
uInt32 getSampleRate() const override { return 31400; }
bool mute(bool state) override { return true; }
/**
Sets the volume of the sound device to the specified level. The

View File

@ -190,12 +190,13 @@ void SoundSDL2::close()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SoundSDL2::mute(bool state)
bool SoundSDL2::mute(bool state)
{
bool oldstate = SDL_GetAudioDeviceStatus(myDevice) == SDL_AUDIO_PAUSED;
if(myIsInitializedFlag)
{
SDL_PauseAudioDevice(myDevice, state ? 1 : 0);
}
return oldstate;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -238,18 +239,6 @@ void SoundSDL2::adjustVolume(Int8 direction)
myOSystem.frameBuffer().showMessage(message);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 SoundSDL2::getFragmentSize() const
{
return myHardwareSpec.samples;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 SoundSDL2::getSampleRate() const
{
return myHardwareSpec.freq;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SoundSDL2::processFragment(float* stream, uInt32 length)
{

View File

@ -73,9 +73,11 @@ class SoundSDL2 : public Sound
/**
Set the mute state of the sound object. While muted no sound is played.
@param state Mutes sound if true, unmute if false
@param state Mutes sound if true, unmute if false
@return The previous (old) mute state
*/
void mute(bool state) override;
bool mute(bool state) override;
/**
Sets the volume of the sound device to the specified level. The
@ -94,10 +96,6 @@ class SoundSDL2 : public Sound
*/
void adjustVolume(Int8 direction) override;
uInt32 getFragmentSize() const override;
uInt32 getSampleRate() const override;
protected:
/**
Invoked by the sound callback to process the next sound fragment.

View File

@ -32,6 +32,7 @@
#include "OSystem.hxx"
#include "Settings.hxx"
#include "TIA.hxx"
#include "Sound.hxx"
#include "FBSurface.hxx"
#include "TIASurface.hxx"
@ -206,6 +207,10 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
const VideoMode& mode = getSavedVidMode(useFullscreen);
if(width <= mode.screen.w && height <= mode.screen.h)
{
// Changing the video mode can take some time, during which the last
// sound played may get 'stuck'
// So we mute the sound until the operation completes
bool oldMuteState = myOSystem.sound().mute(true);
if(setVideoMode(myScreenTitle, mode))
{
myImageRect = mode.image;
@ -220,6 +225,8 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
myOSystem.settings().setValue("fullscreen", fullScreen());
resetSurfaces();
setCursorState();
myOSystem.sound().mute(oldMuteState);
}
else
{
@ -668,6 +675,11 @@ void FrameBuffer::setFullscreen(bool enable)
return;
}
// Changing the video mode can take some time, during which the last
// sound played may get 'stuck'
// So we mute the sound until the operation completes
bool oldMuteState = myOSystem.sound().mute(true);
const VideoMode& mode = getSavedVidMode(enable);
if(setVideoMode(myScreenTitle, mode))
{
@ -684,6 +696,7 @@ void FrameBuffer::setFullscreen(bool enable)
resetSurfaces();
setCursorState();
}
myOSystem.sound().mute(oldMuteState);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -711,6 +724,11 @@ bool FrameBuffer::changeWindowedVidMode(int direction)
else
return false;
// Changing the video mode can take some time, during which the last
// sound played may get 'stuck'
// So we mute the sound until the operation completes
bool oldMuteState = myOSystem.sound().mute(true);
const VideoMode& mode = myCurrentModeList->current();
if(setVideoMode(myScreenTitle, mode))
{
@ -723,8 +741,10 @@ bool FrameBuffer::changeWindowedVidMode(int direction)
resetSurfaces();
showMessage(mode.description);
myOSystem.settings().setValue("tia.zoom", mode.zoom);
myOSystem.sound().mute(oldMuteState);
return true;
}
myOSystem.sound().mute(oldMuteState);
#endif
return false;
}

View File

@ -64,18 +64,10 @@ class Sound
Set the mute state of the sound object. While muted no sound is played.
@param state Mutes sound if true, unmute if false
*/
virtual void mute(bool state) = 0;
/**
Get the fragment size.
@return The previous (old) mute state
*/
virtual uInt32 getFragmentSize() const = 0;
/**
Get the sample rate.
*/
virtual uInt32 getSampleRate() const = 0;
virtual bool mute(bool state) = 0;
/**
Sets the volume of the sound device to the specified level. The