mirror of https://github.com/stella-emu/stella.git
Crackling and screeching.... but it is correlated with the TIA :)
This commit is contained in:
parent
4ec553785f
commit
8198f6ccaf
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue