Crackling and screeching.... but it is correlated with the TIA :)

This commit is contained in:
Christian Speckner 2018-01-25 20:48:34 +01:00
parent 4ec553785f
commit 8198f6ccaf
4 changed files with 86 additions and 7 deletions

View File

@ -28,12 +28,15 @@
#include "OSystem.hxx" #include "OSystem.hxx"
#include "Console.hxx" #include "Console.hxx"
#include "SoundSDL2.hxx" #include "SoundSDL2.hxx"
#include "AudioQueue.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SoundSDL2::SoundSDL2(OSystem& osystem) SoundSDL2::SoundSDL2(OSystem& osystem)
: Sound(osystem), : Sound(osystem),
myIsInitializedFlag(false), myIsInitializedFlag(false),
myVolume(100) myVolume(100),
myAudioQueue(0),
myCurrentFragment(0)
{ {
myOSystem.logMessage("SoundSDL2::SoundSDL2 started ...", 2); myOSystem.logMessage("SoundSDL2::SoundSDL2 started ...", 2);
@ -96,7 +99,7 @@ void SoundSDL2::setEnabled(bool state)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SoundSDL2::open() void SoundSDL2::open(AudioQueue* audioQueue)
{ {
myOSystem.logMessage("SoundSDL2::open started ...", 2); myOSystem.logMessage("SoundSDL2::open started ...", 2);
mute(true); mute(true);
@ -107,6 +110,12 @@ void SoundSDL2::open()
return; return;
} }
myAudioQueue = audioQueue;
myUnderrun = true;
myCurrentFragment = 0;
myTimeIndex = 0;
myFragmentIndex = 0;
// Adjust volume to that defined in settings // Adjust volume to that defined in settings
setVolume(myOSystem.settings().getInt("volume")); setVolume(myOSystem.settings().getInt("volume"));
@ -131,6 +140,9 @@ void SoundSDL2::close()
{ {
if(!myIsInitializedFlag) return; if(!myIsInitializedFlag) return;
myAudioQueue = 0;
myCurrentFragment = 0;
mute(true); mute(true);
myOSystem.logMessage("SoundSDL2::close", 2); myOSystem.logMessage("SoundSDL2::close", 2);
@ -189,12 +201,70 @@ void SoundSDL2::adjustVolume(Int8 direction)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SoundSDL2::processFragment(Int16* stream, uInt32 length) void SoundSDL2::processFragment(Int16* stream, uInt32 length)
{} {
if (myUnderrun && myAudioQueue->size() > 1) {
myUnderrun = false;
myCurrentFragment = myAudioQueue->dequeue(myCurrentFragment);
myFragmentIndex = 0;
}
if (!myCurrentFragment) {
memset(stream, 0, 2 * length);
return;
}
bool isStereoTIA = myAudioQueue->isStereo();
bool isStereo = myHardwareSpec.channels == 2;
uInt32 sampleRateTIA = myAudioQueue->sampleRate();
uInt32 sampleRate = myHardwareSpec.freq;
uInt32 fragmentSize = myAudioQueue->fragmentSize();
uInt32 outputSamples = isStereo ? (length >> 1) : length;
for (uInt32 i = 0; i < outputSamples; i++) {
myTimeIndex += sampleRateTIA;
if (myTimeIndex > sampleRate) {
myFragmentIndex += myTimeIndex / sampleRate;
myTimeIndex %= sampleRate;
}
if (myFragmentIndex >= fragmentSize) {
myFragmentIndex %= fragmentSize;
Int16* nextFragment = myAudioQueue->dequeue(myCurrentFragment);
if (nextFragment)
myCurrentFragment = nextFragment;
else
myUnderrun = true;
}
if (isStereo) {
if (isStereoTIA) {
stream[2*i] = myCurrentFragment[2*myFragmentIndex];
stream[2*i + 1] = myCurrentFragment[2*myFragmentIndex + 1];
} else {
stream[2*i] = stream[2*i + 1] = myCurrentFragment[myFragmentIndex];
}
} else {
if (isStereoTIA) {
stream[i] =
((myCurrentFragment[2*myFragmentIndex] / 2) + (myCurrentFragment[2*myFragmentIndex + 1] / 2));
} else {
stream[i] = myCurrentFragment[myFragmentIndex];
}
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SoundSDL2::callback(void* udata, uInt8* stream, int len) void SoundSDL2::callback(void* udata, uInt8* stream, int len)
{ {
SDL_memset(stream, 0, len); // Write 'silence' SoundSDL2* self = static_cast<SoundSDL2*>(udata);
if (self->myAudioQueue)
self->processFragment(reinterpret_cast<Int16*>(stream), len >> 1);
else
SDL_memset(stream, 0, len);
} }
#endif // SOUND_SUPPORT #endif // SOUND_SUPPORT

View File

@ -21,6 +21,7 @@
#define SOUND_SDL2_HXX #define SOUND_SDL2_HXX
class OSystem; class OSystem;
class AudioQueue;
#include "SDL_lib.hxx" #include "SDL_lib.hxx"
@ -58,7 +59,7 @@ class SoundSDL2 : public Sound
Initializes the sound device. This must be called before any Initializes the sound device. This must be called before any
calls are made to derived methods. calls are made to derived methods.
*/ */
void open() override; void open(AudioQueue* audioQueue) override;
/** /**
Should be called to close the sound device. Once called the sound Should be called to close the sound device. Once called the sound
@ -116,6 +117,13 @@ class SoundSDL2 : public Sound
// Audio specification structure // Audio specification structure
SDL_AudioSpec myHardwareSpec; SDL_AudioSpec myHardwareSpec;
AudioQueue* myAudioQueue;
Int16* myCurrentFragment;
uInt32 myTimeIndex;
uInt32 myFragmentIndex;
bool myUnderrun;
private: private:
// Callback function invoked by the SDL Audio library when it needs data // Callback function invoked by the SDL Audio library when it needs data
static void callback(void* udata, uInt8* stream, int len); static void callback(void* udata, uInt8* stream, int len);

View File

@ -580,7 +580,7 @@ void Console::initializeAudio()
// const string& sound = myProperties.get(Cartridge_Sound); // const string& sound = myProperties.get(Cartridge_Sound);
// myOSystem.sound().setChannels(sound == "STEREO" ? 2 : 1); // myOSystem.sound().setChannels(sound == "STEREO" ? 2 : 1);
myOSystem.sound().open(); myOSystem.sound().open(myAudioQueue.get());
// Make sure auto-frame calculation is only enabled when necessary // Make sure auto-frame calculation is only enabled when necessary
myTIA->enableAutoFrame(framerate <= 0); myTIA->enableAutoFrame(framerate <= 0);

View File

@ -19,6 +19,7 @@
#define SOUND_HXX #define SOUND_HXX
class OSystem; class OSystem;
class AudioQueue;
#include "bspf.hxx" #include "bspf.hxx"
@ -50,7 +51,7 @@ class Sound
Start the sound system, initializing it if necessary. This must be Start the sound system, initializing it if necessary. This must be
called before any calls are made to derived methods. called before any calls are made to derived methods.
*/ */
virtual void open() = 0; virtual void open(AudioQueue* audioQueue) = 0;
/** /**
Should be called to stop the sound system. Once called the sound Should be called to stop the sound system. Once called the sound