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 "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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue