diff --git a/Components/AudioToggle/AudioToggle.hpp b/Components/AudioToggle/AudioToggle.hpp index cd9d0e483..c009fe781 100644 --- a/Components/AudioToggle/AudioToggle.hpp +++ b/Components/AudioToggle/AudioToggle.hpp @@ -24,6 +24,7 @@ class Toggle: public Outputs::Speaker::SampleSource { void get_samples(std::size_t number_of_samples, std::int16_t *target); void set_sample_volume_range(std::int16_t range); void skip_samples(const std::size_t number_of_samples); + static constexpr bool get_is_stereo() { return false; } void set_output(bool enabled); bool get_output(); diff --git a/Components/SN76489/SN76489.hpp b/Components/SN76489/SN76489.hpp index dbc2e5cab..eafac818a 100644 --- a/Components/SN76489/SN76489.hpp +++ b/Components/SN76489/SN76489.hpp @@ -32,6 +32,7 @@ class SN76489: public Outputs::Speaker::SampleSource { void get_samples(std::size_t number_of_samples, std::int16_t *target); bool is_zero_level(); void set_sample_volume_range(std::int16_t range); + static constexpr bool get_is_stereo() { return false; } private: int master_divider_ = 0; diff --git a/Machines/AmstradCPC/AmstradCPC.cpp b/Machines/AmstradCPC/AmstradCPC.cpp index a53e0d3b9..4a8ff2677 100644 --- a/Machines/AmstradCPC/AmstradCPC.cpp +++ b/Machines/AmstradCPC/AmstradCPC.cpp @@ -128,7 +128,7 @@ class AYDeferrer { speaker_.set_input_rate(1000000); // Per the CPC Wiki: // "A is output to the right, channel C is output left, and channel B is output to both left and right". - ay_.set_output_mixing(true, 0.0, 0.5, 1.0, 1.0, 0.5, 0.0); + ay_.set_output_mixing(0.0, 0.5, 1.0, 1.0, 0.5, 0.0); } ~AYDeferrer() { @@ -156,14 +156,14 @@ class AYDeferrer { } /// @returns the AY itself. - GI::AY38910::AY38910 &ay() { + GI::AY38910::AY38910 &ay() { return ay_; } private: Concurrency::DeferringAsyncTaskQueue audio_queue_; - GI::AY38910::AY38910 ay_; - Outputs::Speaker::LowpassSpeaker speaker_; + GI::AY38910::AY38910 ay_; + Outputs::Speaker::LowpassSpeaker> speaker_; HalfCycles cycles_since_update_; }; diff --git a/Machines/Apple/AppleII/AppleII.cpp b/Machines/Apple/AppleII/AppleII.cpp index 397d24afb..90f53048a 100644 --- a/Machines/Apple/AppleII/AppleII.cpp +++ b/Machines/Apple/AppleII/AppleII.cpp @@ -108,7 +108,7 @@ template class ConcreteMachine: Concurrency::DeferringAsyncTaskQueue audio_queue_; Audio::Toggle audio_toggle_; - Outputs::Speaker::LowpassSpeaker speaker_; + Outputs::Speaker::LowpassSpeaker speaker_; Cycles cycles_since_audio_update_; // MARK: - Cards diff --git a/Machines/Atari/2600/Bus.hpp b/Machines/Atari/2600/Bus.hpp index 36c8a16b1..4b21b4a0b 100644 --- a/Machines/Atari/2600/Bus.hpp +++ b/Machines/Atari/2600/Bus.hpp @@ -41,7 +41,7 @@ class Bus { Concurrency::DeferringAsyncTaskQueue audio_queue_; TIASound tia_sound_; - Outputs::Speaker::LowpassSpeaker speaker_; + Outputs::Speaker::LowpassSpeaker speaker_; // joystick state uint8_t tia_input_value_[2] = {0xff, 0xff}; diff --git a/Machines/Atari/2600/TIASound.hpp b/Machines/Atari/2600/TIASound.hpp index ec41e40de..8bc84cc2a 100644 --- a/Machines/Atari/2600/TIASound.hpp +++ b/Machines/Atari/2600/TIASound.hpp @@ -29,6 +29,7 @@ class TIASound: public Outputs::Speaker::SampleSource { // To satisfy ::SampleSource. void get_samples(std::size_t number_of_samples, int16_t *target); void set_sample_volume_range(std::int16_t range); + static constexpr bool get_is_stereo() { return false; } private: Concurrency::DeferringAsyncTaskQueue &audio_queue_; diff --git a/Machines/Atari/ST/AtariST.cpp b/Machines/Atari/ST/AtariST.cpp index a4791e412..c8056e9e1 100644 --- a/Machines/Atari/ST/AtariST.cpp +++ b/Machines/Atari/ST/AtariST.cpp @@ -497,8 +497,8 @@ class ConcreteMachine: JustInTimeActor midi_acia_; Concurrency::DeferringAsyncTaskQueue audio_queue_; - GI::AY38910::AY38910 ay_; - Outputs::Speaker::LowpassSpeaker speaker_; + GI::AY38910::AY38910 ay_; + Outputs::Speaker::LowpassSpeaker> speaker_; HalfCycles cycles_since_audio_update_; JustInTimeActor dma_; diff --git a/Machines/ColecoVision/ColecoVision.cpp b/Machines/ColecoVision/ColecoVision.cpp index 3c02ec646..02aacc6df 100644 --- a/Machines/ColecoVision/ColecoVision.cpp +++ b/Machines/ColecoVision/ColecoVision.cpp @@ -405,9 +405,9 @@ class ConcreteMachine: Concurrency::DeferringAsyncTaskQueue audio_queue_; TI::SN76489 sn76489_; - GI::AY38910::AY38910 ay_; - Outputs::Speaker::CompoundSource mixer_; - Outputs::Speaker::LowpassSpeaker, false> speaker_; + GI::AY38910::AY38910 ay_; + Outputs::Speaker::CompoundSource> mixer_; + Outputs::Speaker::LowpassSpeaker>> speaker_; std::vector bios_; std::vector cartridge_; diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index fc89a1f37..a5c890207 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -592,7 +592,7 @@ class ConcreteMachine: Concurrency::DeferringAsyncTaskQueue audio_queue_; SoundGenerator sound_generator_; - Outputs::Speaker::LowpassSpeaker speaker_; + Outputs::Speaker::LowpassSpeaker speaker_; bool speaker_is_enabled_ = false; diff --git a/Machines/Electron/SoundGenerator.hpp b/Machines/Electron/SoundGenerator.hpp index 9df5769da..fff2ba15c 100644 --- a/Machines/Electron/SoundGenerator.hpp +++ b/Machines/Electron/SoundGenerator.hpp @@ -28,6 +28,7 @@ class SoundGenerator: public ::Outputs::Speaker::SampleSource { void get_samples(std::size_t number_of_samples, int16_t *target); void skip_samples(std::size_t number_of_samples); void set_sample_volume_range(std::int16_t range); + static constexpr bool get_is_stereo() { return false; } private: Concurrency::DeferringAsyncTaskQueue &audio_queue_; diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index fd46acdb9..150f9eeb5 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -760,11 +760,11 @@ class ConcreteMachine: Intel::i8255::i8255 i8255_; Concurrency::DeferringAsyncTaskQueue audio_queue_; - GI::AY38910::AY38910 ay_; + GI::AY38910::AY38910 ay_; Audio::Toggle audio_toggle_; Konami::SCC scc_; - Outputs::Speaker::CompoundSource mixer_; - Outputs::Speaker::LowpassSpeaker, false> speaker_; + Outputs::Speaker::CompoundSource, Audio::Toggle, Konami::SCC> mixer_; + Outputs::Speaker::LowpassSpeaker, Audio::Toggle, Konami::SCC>> speaker_; Storage::Tape::BinaryTapePlayer tape_player_; bool tape_player_is_sleeping_ = false; diff --git a/Machines/MasterSystem/MasterSystem.cpp b/Machines/MasterSystem/MasterSystem.cpp index e7cb76f14..ce98a0bf8 100644 --- a/Machines/MasterSystem/MasterSystem.cpp +++ b/Machines/MasterSystem/MasterSystem.cpp @@ -424,7 +424,7 @@ class ConcreteMachine: Concurrency::DeferringAsyncTaskQueue audio_queue_; TI::SN76489 sn76489_; - Outputs::Speaker::LowpassSpeaker speaker_; + Outputs::Speaker::LowpassSpeaker speaker_; std::vector> joysticks_; Inputs::Keyboard keyboard_; diff --git a/Outputs/Speaker/Implementation/CompoundSource.hpp b/Outputs/Speaker/Implementation/CompoundSource.hpp index bafed9986..8d9032e15 100644 --- a/Outputs/Speaker/Implementation/CompoundSource.hpp +++ b/Outputs/Speaker/Implementation/CompoundSource.hpp @@ -57,6 +57,8 @@ template class CompoundSource: push_volumes(); } + static constexpr bool get_is_stereo() { return CompoundSourceHolder::get_is_stereo(); } + private: void push_volumes() { source_holder_.set_scaled_volume_range(volume_range_, volumes_.data()); @@ -73,6 +75,10 @@ template class CompoundSource: std::size_t size() { return 0; } + + static constexpr bool get_is_stereo() { + return false; + } }; template class CompoundSourceHolder { @@ -107,6 +113,10 @@ template class CompoundSource: return 1+next_source_.size(); } + static constexpr bool get_is_stereo() { + return S::get_is_stereo() || CompoundSourceHolder::get_is_stereo(); + } + private: S &source_; CompoundSourceHolder next_source_;