From e1d671daf7aac0c13297f780a8306524cd09bb43 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 13 May 2023 22:16:42 -0400 Subject: [PATCH] Avoid paying for an OPLL if not connected. --- Machines/MSX/MSX.cpp | 82 +++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 28 deletions(-) diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index 07bd9b2d9..d897795fd 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -130,6 +130,47 @@ class AYPortHandler: public GI::AY38910::PortHandler { }; }; + +template struct Speaker; + +template <> struct Speaker { + Speaker() : + ay(GI::AY38910::Personality::AY38910, audio_queue), + audio_toggle(audio_queue), + scc(audio_queue), + mixer(ay, audio_toggle, scc), + speaker(mixer) {} + + Concurrency::AsyncTaskQueue audio_queue; + GI::AY38910::AY38910 ay; + Audio::Toggle audio_toggle; + Konami::SCC scc; + + using CompundSource = Outputs::Speaker::CompoundSource, Audio::Toggle, Konami::SCC>; + CompundSource mixer; + Outputs::Speaker::PullLowpass speaker; +}; + +template <> struct Speaker { + Speaker() : + opll(audio_queue, 1), + ay(GI::AY38910::Personality::AY38910, audio_queue), + audio_toggle(audio_queue), + scc(audio_queue), + mixer(ay, audio_toggle, scc, opll), + speaker(mixer) {} + + Concurrency::AsyncTaskQueue audio_queue; + Yamaha::OPL::OPLL opll; + GI::AY38910::AY38910 ay; + Audio::Toggle audio_toggle; + Konami::SCC scc; + + using CompundSource = Outputs::Speaker::CompoundSource, Audio::Toggle, Konami::SCC, Yamaha::OPL::OPLL>; + CompundSource mixer; + Outputs::Speaker::PullLowpass speaker; +}; + using Target = Analyser::Static::MSX::Target; template @@ -155,26 +196,20 @@ class ConcreteMachine: ConcreteMachine(const Target &target, const ROMMachine::ROMFetcher &rom_fetcher): z80_(*this), i8255_(i8255_port_handler_), - opll_(audio_queue_, 1), - ay_(GI::AY38910::Personality::AY38910, audio_queue_), - audio_toggle_(audio_queue_), - scc_(audio_queue_), - mixer_(ay_, audio_toggle_, scc_, opll_), - speaker_(mixer_), tape_player_(3579545 * 2), - i8255_port_handler_(*this, audio_toggle_, tape_player_), + i8255_port_handler_(*this, speaker_.audio_toggle, tape_player_), ay_port_handler_(tape_player_), memory_slots_{{*this}, {*this}, {*this}, {*this}}, clock_(ClockRate) { set_clock_rate(ClockRate); clear_all_keys(); - ay_.set_port_handler(&ay_port_handler_); - speaker_.set_input_rate(3579545.0f / 2.0f); + speaker_.ay.set_port_handler(&ay_port_handler_); + speaker_.speaker.set_input_rate(3579545.0f / 2.0f); tape_player_.set_clocking_hint_observer(this); // Set the AY to 50% of available volume, the toggle to 10% and leave 40% for an SCC. - mixer_.set_relative_volumes({0.5f, 0.1f, 0.4f, has_opll ? 0.5f : 0.0f}); + speaker_.mixer.set_relative_volumes({0.5f, 0.1f, 0.4f, has_opll ? 0.5f : 0.0f}); // Install the proper TV standard and select an ideal BIOS name. const std::string machine_name = "MSX"; @@ -317,7 +352,7 @@ class ConcreteMachine: } ~ConcreteMachine() { - audio_queue_.flush(); + speaker_.audio_queue.flush(); } void set_scan_target(Outputs::Display::ScanTarget *scan_target) final { @@ -337,7 +372,7 @@ class ConcreteMachine: } Outputs::Speaker::Speaker *get_speaker() final { - return &speaker_; + return &speaker_.speaker; } void run_for(const Cycles cycles) final { @@ -375,7 +410,7 @@ class ConcreteMachine: cartridge_primary().handler = std::make_unique(static_cast(slot)); break; case Analyser::Static::MSX::Cartridge::KonamiWithSCC: - cartridge_primary().handler = std::make_unique(static_cast(slot), scc_); + cartridge_primary().handler = std::make_unique(static_cast(slot), speaker_.scc); break; case Analyser::Static::MSX::Cartridge::ASCII8kb: cartridge_primary().handler = std::make_unique(static_cast(slot)); @@ -590,7 +625,7 @@ class ConcreteMachine: case 0xa2: update_audio(); - *cycle.value = GI::AY38910::Utility::read(ay_); + *cycle.value = GI::AY38910::Utility::read(speaker_.ay); break; case 0xa8: case 0xa9: @@ -634,7 +669,7 @@ class ConcreteMachine: case 0xa0: case 0xa1: update_audio(); - GI::AY38910::Utility::write(ay_, port == 0xa1, *cycle.value); + GI::AY38910::Utility::write(speaker_.ay, port == 0xa1, *cycle.value); break; case 0xa8: case 0xa9: @@ -680,7 +715,7 @@ class ConcreteMachine: case 0x7c: case 0x7d: if constexpr (has_opll) { - opll_.write(address, *cycle.value); + speaker_.opll.write(address, *cycle.value); break; } [[fallthrough]]; @@ -742,7 +777,7 @@ class ConcreteMachine: } if(outputs & Output::Audio) { update_audio(); - audio_queue_.perform(); + speaker_.audio_queue.perform(); } } @@ -805,7 +840,7 @@ class ConcreteMachine: private: void update_audio() { - speaker_.run_for(audio_queue_, time_since_ay_update_.divide_cycles(Cycles(2))); + speaker_.speaker.run_for(speaker_.audio_queue, time_since_ay_update_.divide_cycles(Cycles(2))); } class i8255PortHandler: public Intel::i8255::PortHandler { @@ -872,16 +907,6 @@ class ConcreteMachine: JustInTimeActor> vdp_; Intel::i8255::i8255 i8255_; - Concurrency::AsyncTaskQueue audio_queue_; - Yamaha::OPL::OPLL opll_; - GI::AY38910::AY38910 ay_; - Audio::Toggle audio_toggle_; - Konami::SCC scc_; - - using CompundSource = Outputs::Speaker::CompoundSource, Audio::Toggle, Konami::SCC, Yamaha::OPL::OPLL>; - CompundSource mixer_; - Outputs::Speaker::PullLowpass speaker_; - Storage::Tape::BinaryTapePlayer tape_player_; bool tape_player_is_sleeping_ = false; bool allow_fast_tape_ = false; @@ -896,6 +921,7 @@ class ConcreteMachine: } i8255PortHandler i8255_port_handler_; + Speaker speaker_; AYPortHandler ay_port_handler_; /// The current primary and secondary slot selections; the former retains whatever was written