diff --git a/Components/6560/6560.cpp b/Components/6560/6560.cpp index 2a240d29a..a14647c5e 100644 --- a/Components/6560/6560.cpp +++ b/Components/6560/6560.cpp @@ -12,6 +12,7 @@ using namespace MOS; MOS6560::MOS6560() : _crt(new Outputs::CRT::CRT(65*4, 4, Outputs::CRT::NTSC60, 1)), + _speaker(new Speaker), _horizontal_counter(0), _vertical_counter(0), _cycles_since_speaker_update(0), @@ -34,7 +35,7 @@ MOS6560::MOS6560() : // show only the centre _crt->set_visible_area(_crt->get_rect_for_area(16, 237, 11*4, 55*4, 4.0f / 3.0f)); - _speaker.set_input_rate(255681.75); // assuming NTSC; clock rate / 4 + _speaker->set_input_rate(255681.75); // assuming NTSC; clock rate / 4 } void MOS6560::set_output_mode(OutputMode output_mode) @@ -119,13 +120,13 @@ void MOS6560::set_register(int address, uint8_t value) case 0xc: case 0xd: update_audio(); - _speaker.set_control(address - 0xa, value); + _speaker->set_control(address - 0xa, value); break; case 0xe: update_audio(); _registers.auxiliary_colour = _colours[value >> 4]; - _speaker.set_volume(value & 0xf); + _speaker->set_volume(value & 0xf); break; case 0xf: @@ -361,7 +362,7 @@ void MOS6560::set_graphics_value(uint8_t value, uint8_t colour_value) void MOS6560::update_audio() { - _speaker.run_for_cycles(_cycles_since_speaker_update >> 2); + _speaker->run_for_cycles(_cycles_since_speaker_update >> 2); _cycles_since_speaker_update &= 3; } diff --git a/Components/6560/6560.hpp b/Components/6560/6560.hpp index 1f06d8ca9..14a13c06a 100644 --- a/Components/6560/6560.hpp +++ b/Components/6560/6560.hpp @@ -25,8 +25,8 @@ namespace MOS { class MOS6560 { public: MOS6560(); - Outputs::CRT::CRT *get_crt() { return _crt.get(); } - Outputs::Speaker *get_speaker() { return &_speaker; } + std::shared_ptr get_crt() { return _crt; } + std::shared_ptr get_speaker() { return _speaker; } enum OutputMode { PAL, NTSC @@ -63,7 +63,7 @@ class MOS6560 { uint8_t get_register(int address); private: - std::unique_ptr _crt; + std::shared_ptr _crt; // audio state class Speaker: public ::Outputs::Filter { @@ -81,7 +81,8 @@ class MOS6560 { unsigned int _shift_registers[4]; uint8_t _control_registers[4]; uint8_t _volume; - } _speaker; + }; + std::shared_ptr _speaker; unsigned int _cycles_since_speaker_update; void update_audio(); diff --git a/Machines/Atari2600/Atari2600.cpp b/Machines/Atari2600/Atari2600.cpp index a757f25f8..0ff4a2ed5 100644 --- a/Machines/Atari2600/Atari2600.cpp +++ b/Machines/Atari2600/Atari2600.cpp @@ -56,7 +56,8 @@ Machine::Machine() : void Machine::setup_output(float aspect_ratio) { - _crt = new Outputs::CRT::CRT(228, 1, 263, Outputs::CRT::ColourSpace::YIQ, 228, 1, 1); + _speaker.reset(new Speaker); + _crt.reset(new Outputs::CRT::CRT(228, 1, 263, Outputs::CRT::ColourSpace::YIQ, 228, 1, 1)); _crt->set_output_device(Outputs::CRT::Television); // this is the NTSC phase offset function; see below for PAL @@ -70,7 +71,7 @@ void Machine::setup_output(float aspect_ratio) "float phaseOffset = 6.283185308 * float(iPhase - 1u) / 13.0;" "return mix(float(y) / 14.0, step(1, iPhase) * cos(phase + phaseOffset), amplitude);" "}"); - _speaker.set_input_rate((float)(get_clock_rate() / 38.0)); + _speaker->set_input_rate((float)(get_clock_rate() / 38.0)); } void Machine::switch_region() @@ -92,15 +93,14 @@ void Machine::switch_region() _crt->set_new_timing(228, 312, Outputs::CRT::ColourSpace::YUV, 228, 1); _is_pal_region = true; - _speaker.set_input_rate((float)(get_clock_rate() / 38.0)); + _speaker->set_input_rate((float)(get_clock_rate() / 38.0)); if(delegate) delegate->machine_did_change_clock_rate(this); } void Machine::close_output() { - delete _crt; - _crt = nullptr; + _crt.reset(); } Machine::~Machine() @@ -598,17 +598,17 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin case 0x15: case 0x16: update_audio(); - _speaker.set_control(decodedAddress - 0x15, *value); + _speaker->set_control(decodedAddress - 0x15, *value); break; case 0x17: case 0x18: update_audio(); - _speaker.set_divider(decodedAddress - 0x17, *value); + _speaker->set_divider(decodedAddress - 0x17, *value); break; case 0x19: case 0x1a: update_audio(); - _speaker.set_volume(decodedAddress - 0x19, *value); + _speaker->set_volume(decodedAddress - 0x19, *value); break; case 0x1c: @@ -781,7 +781,7 @@ void Machine::update_audio() // logged_time = time_now; // } - _speaker.run_for_cycles(audio_cycles); + _speaker->run_for_cycles(audio_cycles); _cycles_since_speaker_update %= 114; } diff --git a/Machines/Atari2600/Atari2600.hpp b/Machines/Atari2600/Atari2600.hpp index c8e3fa53a..77e30626e 100644 --- a/Machines/Atari2600/Atari2600.hpp +++ b/Machines/Atari2600/Atari2600.hpp @@ -92,8 +92,8 @@ class Machine: public CPU6502::Processor, public CRTMachine::Machine { // to satisfy CRTMachine::Machine virtual void setup_output(float aspect_ratio); virtual void close_output(); - virtual Outputs::CRT::CRT *get_crt() { return _crt; } - virtual Outputs::Speaker *get_speaker() { return &_speaker; } + virtual std::shared_ptr get_crt() { return _crt; } + virtual std::shared_ptr get_speaker() { return _speaker; } virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor::run_for_cycles(number_of_cycles); } virtual double get_clock_rate(); // TODO: different rate for PAL @@ -197,8 +197,8 @@ class Machine: public CPU6502::Processor, public CRTMachine::Machine { void update_timers(int mask); // outputs - Outputs::CRT::CRT *_crt; - Speaker _speaker; + std::shared_ptr _crt; + std::shared_ptr _speaker; // current mode bool _is_pal_region; diff --git a/Machines/CRTMachine.hpp b/Machines/CRTMachine.hpp index ce693f5cc..c193199c4 100644 --- a/Machines/CRTMachine.hpp +++ b/Machines/CRTMachine.hpp @@ -24,8 +24,8 @@ class Machine { virtual void setup_output(float aspect_ratio) = 0; virtual void close_output() = 0; - virtual Outputs::CRT::CRT *get_crt() = 0; - virtual Outputs::Speaker *get_speaker() = 0; + virtual std::shared_ptr get_crt() = 0; + virtual std::shared_ptr get_speaker() = 0; virtual void run_for_cycles(int number_of_cycles) = 0; diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index 9e25a30b8..c6a0e2688 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -59,6 +59,7 @@ Machine::Machine() : void Machine::setup_output(float aspect_ratio) { + _speaker.reset(new Speaker); _crt.reset(new Outputs::CRT::CRT(crt_cycles_per_line, 8, Outputs::CRT::DisplayType::PAL50, 1)); _crt->set_rgb_sampling_function( "vec3 rgb_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate)" @@ -74,7 +75,7 @@ void Machine::setup_output(float aspect_ratio) // The maximum output frequency is 62500Hz and all other permitted output frequencies are integral divisions of that; // however setting the speaker on or off can happen on any 2Mhz cycle, and probably (?) takes effect immediately. So // run the speaker at a 2000000Hz input rate, at least for the time being. - _speaker.set_input_rate(2000000 / clock_rate_audio_divider); + _speaker->set_input_rate(2000000 / clock_rate_audio_divider); } void Machine::close_output() @@ -201,7 +202,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin if(!isReadOperation(operation)) { update_audio(); - _speaker.set_divider(*value); + _speaker->set_divider(*value); _tape.set_counter(*value); } break; @@ -227,10 +228,10 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin // update speaker mode bool new_speaker_is_enabled = (*value & 6) == 2; - if(new_speaker_is_enabled != _speaker.get_is_enabled()) + if(new_speaker_is_enabled != _speaker->get_is_enabled()) { update_audio(); - _speaker.set_is_enabled(new_speaker_is_enabled); + _speaker->set_is_enabled(new_speaker_is_enabled); _tape.set_is_enabled(!new_speaker_is_enabled); } @@ -508,7 +509,7 @@ inline void Machine::update_audio() { unsigned int difference = _frameCycles - _audioOutputPosition; _audioOutputPosition = _frameCycles; - _speaker.run_for_cycles(difference / clock_rate_audio_divider); + _speaker->run_for_cycles(difference / clock_rate_audio_divider); _audioOutputPositionError = difference % clock_rate_audio_divider; } diff --git a/Machines/Electron/Electron.hpp b/Machines/Electron/Electron.hpp index 2571b7538..d5f593e1a 100644 --- a/Machines/Electron/Electron.hpp +++ b/Machines/Electron/Electron.hpp @@ -159,8 +159,8 @@ class Machine: // to satisfy CRTMachine::Machine virtual void setup_output(float aspect_ratio); virtual void close_output(); - virtual Outputs::CRT::CRT *get_crt() { return _crt.get(); } - virtual Outputs::Speaker *get_speaker() { return &_speaker; } + virtual std::shared_ptr get_crt() { return _crt; } + virtual std::shared_ptr get_speaker() { return _speaker; } virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor::run_for_cycles(number_of_cycles); } virtual double get_clock_rate() { return 2000000; } @@ -227,8 +227,8 @@ class Machine: bool _fast_load_is_in_data; // Outputs - std::unique_ptr _crt; - Speaker _speaker; + std::shared_ptr _crt; + std::shared_ptr _speaker; }; } diff --git a/Machines/Vic-20/Vic20.hpp b/Machines/Vic-20/Vic20.hpp index 43af4d36c..28b5d6926 100644 --- a/Machines/Vic-20/Vic20.hpp +++ b/Machines/Vic-20/Vic20.hpp @@ -168,8 +168,8 @@ class Machine: // to satisfy CRTMachine::Machine virtual void setup_output(float aspect_ratio); virtual void close_output() {} - virtual Outputs::CRT::CRT *get_crt() { return _mos6560->get_crt(); } - virtual Outputs::Speaker *get_speaker() { return _mos6560->get_speaker(); } + virtual std::shared_ptr get_crt() { return _mos6560->get_crt(); } + virtual std::shared_ptr get_speaker() { return _mos6560->get_speaker(); } virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor::run_for_cycles(number_of_cycles); } virtual double get_clock_rate() { return 1022727; } // TODO: or 1108405 for PAL; see http://www.antimon.org/dl/c64/code/stable.txt diff --git a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm index dcc21d12c..195788843 100644 --- a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm +++ b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm @@ -63,7 +63,7 @@ struct MachineDelegate: CRTMachine::Machine::Delegate { - (float)idealSamplingRateFromRange:(NSRange)range { @synchronized(self) { - Outputs::Speaker *speaker = self.machine->get_speaker(); + std::shared_ptr speaker = self.machine->get_speaker(); if(speaker) { return speaker->get_ideal_clock_rate_in_range((float)range.location, (float)(range.location + range.length)); @@ -80,7 +80,7 @@ struct MachineDelegate: CRTMachine::Machine::Delegate { - (BOOL)setSpeakerDelegate:(Outputs::Speaker::Delegate *)delegate sampleRate:(float)sampleRate bufferSize:(NSUInteger)bufferSize { @synchronized(self) { - Outputs::Speaker *speaker = self.machine->get_speaker(); + std::shared_ptr speaker = self.machine->get_speaker(); if(speaker) { speaker->set_output_rate(sampleRate, (int)bufferSize);