diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 9db5a7946..b56d8fc56 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -55,6 +55,7 @@ #include "Version.hxx" #include "TIAConstants.hxx" #include "FrameLayout.hxx" +#include "AudioQueue.hxx" #include "frame-manager/FrameManager.hxx" #include "frame-manager/FrameLayoutDetector.hxx" #include "frame-manager/YStartDetector.hxx" @@ -71,6 +72,8 @@ namespace { constexpr uInt8 YSTART_EXTRA = 2; + constexpr uInt8 AUDIO_QUEUE_CAPACITY_FRAGMENTS = 20; + constexpr uInt8 AUDIO_QUEUE_HALF_FRAMES_PER_FRAGMENT = 1; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -179,6 +182,9 @@ Console::Console(OSystem& osystem, unique_ptr& cart, myConsoleTiming = ConsoleTiming::secam; } + createAudioQueue(); + myTIA->setAudioQueue(myAudioQueue.get()); + bool joyallow4 = myOSystem.settings().getBool("joyallow4"); myOSystem.eventHandler().allowAllDirections(joyallow4); @@ -727,6 +733,35 @@ void Console::setTIAProperties() myTIA->setHeight(height); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Console::createAudioQueue() +{ + uInt32 fragmentSize, sampleRate; + + switch (myConsoleTiming) { + case ConsoleTiming::ntsc: + fragmentSize = 262 * AUDIO_QUEUE_HALF_FRAMES_PER_FRAGMENT; + sampleRate = 2 * 262 * 60; + break; + + case ConsoleTiming::pal: + case ConsoleTiming::secam: + fragmentSize = 312 * AUDIO_QUEUE_HALF_FRAMES_PER_FRAGMENT; + sampleRate = 2 * 312 * 50; + break; + + default: + throw runtime_error("invalid console timing"); + } + + myAudioQueue = make_unique( + fragmentSize, + AUDIO_QUEUE_CAPACITY_FRAGMENTS, + myProperties.get(Cartridge_Sound) == "STEREO", + sampleRate + ); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Console::setControllers(const string& rommd5) { diff --git a/src/emucore/Console.hxx b/src/emucore/Console.hxx index 8f527828d..7e67e70dd 100644 --- a/src/emucore/Console.hxx +++ b/src/emucore/Console.hxx @@ -27,6 +27,7 @@ class M6532; class Cartridge; class CompuMate; class Debugger; +class AudioQueue; #include "bspf.hxx" #include "Control.hxx" @@ -322,6 +323,11 @@ class Console : public Serializable */ void setTIAProperties(); + /** + Create the audio queue + */ + void createAudioQueue(); + /** Adds the left and right controllers to the console. */ @@ -381,6 +387,9 @@ class Console : public Serializable // The frame manager instance that is used during emulation. unique_ptr myFrameManager; + // The audio fragment queue that connects TIA and audio driver + unique_ptr myAudioQueue; + // Pointer to the Cartridge (the debugger needs it) unique_ptr myCart; diff --git a/src/emucore/tia/Audio.cxx b/src/emucore/tia/Audio.cxx new file mode 100644 index 000000000..9f697b332 --- /dev/null +++ b/src/emucore/tia/Audio.cxx @@ -0,0 +1,28 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2018 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "Audio.hxx" +#include "AudioQueue.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Audio::Audio() {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Audio::setAudioQueue(AudioQueue* queue) +{ + myAudioQueue = queue; +} diff --git a/src/emucore/tia/Audio.hxx b/src/emucore/tia/Audio.hxx new file mode 100644 index 000000000..d309c0f76 --- /dev/null +++ b/src/emucore/tia/Audio.hxx @@ -0,0 +1,39 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2018 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef TIA_AUDIO_HXX +#define TIA_AUDIO_HXX + +class AudioQueue; + +class Audio { + public: + Audio(); + + void setAudioQueue(AudioQueue *queue); + + private: + AudioQueue* myAudioQueue; + + private: + Audio(const Audio&) = delete; + Audio(Audio&&) = delete; + Audio& operator=(const Audio&) = delete; + Audio& operator=(Audio&&) = delete; +}; + +#endif // TIA_AUDIO_HXX diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index c8ab43d40..ae9c9666a 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -23,6 +23,7 @@ #include "DelayQueueIteratorImpl.hxx" #include "TIAConstants.hxx" #include "frame-manager/FrameManager.hxx" +#include "AudioQueue.hxx" #ifdef DEBUGGER_SUPPORT #include "CartDebug.hxx" @@ -115,6 +116,12 @@ void TIA::setFrameManager(AbstractFrameManager *frameManager) myFrameManager->setJitterFactor(myJitterFactor); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void TIA::setAudioQueue(AudioQueue* queue) +{ + myAudio.setAudioQueue(queue); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIA::clearFrameManager() { diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx index 968b927df..da7f29c10 100644 --- a/src/emucore/tia/TIA.hxx +++ b/src/emucore/tia/TIA.hxx @@ -28,6 +28,7 @@ #include "DelayQueueIterator.hxx" #include "frame-manager/AbstractFrameManager.hxx" #include "FrameLayout.hxx" +#include "Audio.hxx" #include "Background.hxx" #include "Playfield.hxx" #include "Missile.hxx" @@ -39,6 +40,8 @@ #include "Control.hxx" #include "System.hxx" +class AudioQueue; + /** This class is a device that emulates the Television Interface Adaptor found in the Atari 2600 and 7800 consoles. The Television Interface @@ -103,12 +106,18 @@ class TIA : public Device public: /** - * Configure the frame manager. + Configure the frame manager. */ void setFrameManager(AbstractFrameManager *frameManager); /** - * Clear the configured frame manager and deteach the lifecycle callbacks. + Set the audio queue. This needs to be dynamic as the queue is created after + the timing has been determined. + */ + void setAudioQueue(AudioQueue *audioQueue); + + /** + Clear the configured frame manager and deteach the lifecycle callbacks. */ void clearFrameManager(); @@ -638,6 +647,8 @@ class TIA : public Device Player myPlayer1; Ball myBall; + Audio myAudio; + /** * The paddle readout circuits. */ diff --git a/src/emucore/tia/module.mk b/src/emucore/tia/module.mk index ef2adef45..569dfc35e 100644 --- a/src/emucore/tia/module.mk +++ b/src/emucore/tia/module.mk @@ -9,7 +9,8 @@ MODULE_OBJS := \ src/emucore/tia/Ball.o \ src/emucore/tia/Background.o \ src/emucore/tia/LatchedInput.o \ - src/emucore/tia/PaddleReader.o + src/emucore/tia/PaddleReader.o \ + src/emucore/tia/Audio.o MODULE_DIRS += \ src/emucore/tia