Switch to SDL_OpenAudioDevice & friends, fix silence with very tight buffer

settings.
This commit is contained in:
Christian Speckner 2018-08-09 23:41:15 +02:00
parent efb998129b
commit 95867f91cd
3 changed files with 24 additions and 21 deletions

View File

@ -45,6 +45,15 @@ SoundSDL2::SoundSDL2(OSystem& osystem, AudioSettings& audioSettings)
{ {
myOSystem.logMessage("SoundSDL2::SoundSDL2 started ...", 2); myOSystem.logMessage("SoundSDL2::SoundSDL2 started ...", 2);
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
ostringstream buf;
buf << "WARNING: Failed to initialize SDL audio system! " << endl
<< " " << SDL_GetError() << endl;
myOSystem.logMessage(buf.str(), 0);
return;
}
// The sound system is opened only once per program run, to eliminate // The sound system is opened only once per program run, to eliminate
// issues with opening and closing it multiple times // issues with opening and closing it multiple times
// This fixes a bug most prevalent with ATI video cards in Windows, // This fixes a bug most prevalent with ATI video cards in Windows,
@ -57,28 +66,18 @@ SoundSDL2::SoundSDL2(OSystem& osystem, AudioSettings& audioSettings)
desired.callback = callback; desired.callback = callback;
desired.userdata = static_cast<void*>(this); desired.userdata = static_cast<void*>(this);
ostringstream buf; myDevice = SDL_OpenAudioDevice(0, 0, &desired, &myHardwareSpec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
if(SDL_OpenAudio(&desired, &myHardwareSpec) < 0)
if(myDevice == 0)
{ {
buf << "WARNING: Couldn't open SDL audio system! " << endl ostringstream buf;
buf << "WARNING: Couldn't open SDL audio device! " << endl
<< " " << SDL_GetError() << endl; << " " << SDL_GetError() << endl;
myOSystem.logMessage(buf.str(), 0); myOSystem.logMessage(buf.str(), 0);
return; return;
} }
// Make sure the sample buffer isn't to big (if it is the sound code
// will not work so we'll need to disable the audio support)
if((float(myHardwareSpec.samples) / float(myHardwareSpec.freq)) >= 0.25)
{
buf << "WARNING: Sound device doesn't support realtime audio! Make "
<< "sure a sound" << endl
<< " server isn't running. Audio is disabled." << endl;
myOSystem.logMessage(buf.str(), 0);
SDL_CloseAudio();
return;
}
myIsInitializedFlag = true; myIsInitializedFlag = true;
mute(true); mute(true);
@ -91,7 +90,7 @@ SoundSDL2::~SoundSDL2()
{ {
if (!myIsInitializedFlag) return; if (!myIsInitializedFlag) return;
SDL_CloseAudio(); SDL_CloseAudioDevice(myDevice);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -165,7 +164,7 @@ void SoundSDL2::mute(bool state)
{ {
if(myIsInitializedFlag) if(myIsInitializedFlag)
{ {
SDL_PauseAudio(state ? 1 : 0); SDL_PauseAudioDevice(myDevice, state ? 1 : 0);
} }
} }
@ -182,9 +181,9 @@ void SoundSDL2::setVolume(uInt32 percent)
myAudioSettings.setVolume(percent); myAudioSettings.setVolume(percent);
myVolume = percent; myVolume = percent;
SDL_LockAudio(); SDL_LockAudioDevice(myDevice);
myVolumeFactor = static_cast<float>(percent) / 100.f; myVolumeFactor = static_cast<float>(percent) / 100.f;
SDL_UnlockAudio(); SDL_UnlockAudioDevice(myDevice);
} }
} }
@ -241,7 +240,7 @@ void SoundSDL2::initResampler()
Int16* nextFragment = nullptr; Int16* nextFragment = nullptr;
if (myUnderrun) if (myUnderrun)
nextFragment = myAudioQueue->size() > myEmulationTiming->prebufferFragmentCount() ? nextFragment = myAudioQueue->size() >= myEmulationTiming->prebufferFragmentCount() ?
myAudioQueue->dequeue(myCurrentFragment) : nullptr; myAudioQueue->dequeue(myCurrentFragment) : nullptr;
else else
nextFragment = myAudioQueue->dequeue(myCurrentFragment); nextFragment = myAudioQueue->dequeue(myCurrentFragment);

View File

@ -129,6 +129,8 @@ class SoundSDL2 : public Sound
// Audio specification structure // Audio specification structure
SDL_AudioSpec myHardwareSpec; SDL_AudioSpec myHardwareSpec;
SDL_AudioDeviceID myDevice;
shared_ptr<AudioQueue> myAudioQueue; shared_ptr<AudioQueue> myAudioQueue;
EmulationTiming* myEmulationTiming; EmulationTiming* myEmulationTiming;

View File

@ -204,4 +204,6 @@ void EmulationTiming::recalculate()
myPrebufferFragmentCount, myPrebufferFragmentCount,
discreteDivCeil(myMaxCyclesPerTimeslice * myAudioSampleRate, myAudioFragmentSize * myCyclesPerSecond) discreteDivCeil(myMaxCyclesPerTimeslice * myAudioSampleRate, myAudioFragmentSize * myCyclesPerSecond)
) + myAudioQueueExtraFragments; ) + myAudioQueueExtraFragments;
(cout << myAudioQueueCapacity << " " << myPrebufferFragmentCount << std::endl).flush();
} }