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 "Console.hxx"
#include "SoundSDL2.hxx"
#include "AudioQueue.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SoundSDL2::SoundSDL2(OSystem& osystem)
: Sound(osystem),
myIsInitializedFlag(false),
myVolume(100)
myVolume(100),
myAudioQueue(0),
myCurrentFragment(0)
{
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);
mute(true);
@ -107,6 +110,12 @@ void SoundSDL2::open()
return;
}
myAudioQueue = audioQueue;
myUnderrun = true;
myCurrentFragment = 0;
myTimeIndex = 0;
myFragmentIndex = 0;
// Adjust volume to that defined in settings
setVolume(myOSystem.settings().getInt("volume"));
@ -131,6 +140,9 @@ void SoundSDL2::close()
{
if(!myIsInitializedFlag) return;
myAudioQueue = 0;
myCurrentFragment = 0;
mute(true);
myOSystem.logMessage("SoundSDL2::close", 2);
@ -189,12 +201,70 @@ void SoundSDL2::adjustVolume(Int8 direction)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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)
{
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

View File

@ -21,6 +21,7 @@
#define SOUND_SDL2_HXX
class OSystem;
class AudioQueue;
#include "SDL_lib.hxx"
@ -58,7 +59,7 @@ class SoundSDL2 : public Sound
Initializes the sound device. This must be called before any
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
@ -116,6 +117,13 @@ class SoundSDL2 : public Sound
// Audio specification structure
SDL_AudioSpec myHardwareSpec;
AudioQueue* myAudioQueue;
Int16* myCurrentFragment;
uInt32 myTimeIndex;
uInt32 myFragmentIndex;
bool myUnderrun;
private:
// Callback function invoked by the SDL Audio library when it needs data
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);
// 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
myTIA->enableAutoFrame(framerate <= 0);

View File

@ -19,6 +19,7 @@
#define SOUND_HXX
class OSystem;
class AudioQueue;
#include "bspf.hxx"
@ -50,7 +51,7 @@ class Sound
Start the sound system, initializing it if necessary. This must be
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