From 6810a6ee58dfa31b906da9c8984ad0f0c9dfd4c7 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 14 Feb 2020 22:51:20 -0500 Subject: [PATCH 1/4] Adjusts the AY volume scale. Hopefully more accurately to model the real thing. --- Components/AY38910/AY38910.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Components/AY38910/AY38910.cpp b/Components/AY38910/AY38910.cpp index c5544b21a..9d9dbdaa7 100644 --- a/Components/AY38910/AY38910.cpp +++ b/Components/AY38910/AY38910.cpp @@ -71,11 +71,13 @@ AY38910::AY38910(Personality personality, Concurrency::DeferringAsyncTaskQueue & } void AY38910::set_sample_volume_range(std::int16_t range) { - // set up volume lookup table + // Set up volume lookup table; the function below is based on a combination of the graph + // from the YM's datasheet, showing a clear power curve, and fitting that to observed + // values reported elsewhere. const float max_volume = float(range) / 3.0f; // As there are three channels. constexpr float root_two = 1.414213562373095f; for(int v = 0; v < 32; v++) { - volumes_[v] = int(max_volume / powf(root_two, float(v ^ 0x1f) / 2.0f)); + volumes_[v] = int(max_volume / powf(root_two, float(v ^ 0x1f) / 3.18f)); } volumes_[0] = 0; // Tie level 0 to silence. evaluate_output_volume(); @@ -185,7 +187,7 @@ void AY38910::evaluate_output_volume() { #undef channel_volume // Mix additively. - output_volume_ = static_cast( + output_volume_ = int16_t( volumes_[volumes[0]] * channel_levels[0] + volumes_[volumes[1]] * channel_levels[1] + volumes_[volumes[2]] * channel_levels[2] @@ -220,7 +222,7 @@ void AY38910::set_register_value(uint8_t value) { int channel = selected_register >> 1; if(selected_register & 1) - tone_periods_[channel] = (tone_periods_[channel] & 0xff) | static_cast((value&0xf) << 8); + tone_periods_[channel] = (tone_periods_[channel] & 0xff) | uint16_t((value&0xf) << 8); else tone_periods_[channel] = (tone_periods_[channel] & ~0xff) | value; } @@ -235,7 +237,7 @@ void AY38910::set_register_value(uint8_t value) { break; case 12: - envelope_period_ = (envelope_period_ & 0xff) | static_cast(value << 8); + envelope_period_ = (envelope_period_ & 0xff) | int(value << 8); break; case 13: @@ -331,15 +333,15 @@ uint8_t AY38910::get_data_output() { } void AY38910::set_control_lines(ControlLines control_lines) { - switch(static_cast(control_lines)) { + switch(int(control_lines)) { default: control_state_ = Inactive; break; - case static_cast(BDIR | BC2 | BC1): + case int(BDIR | BC2 | BC1): case BDIR: case BC1: control_state_ = LatchAddress; break; - case static_cast(BC2 | BC1): control_state_ = Read; break; - case static_cast(BDIR | BC2): control_state_ = Write; break; + case int(BC2 | BC1): control_state_ = Read; break; + case int(BDIR | BC2): control_state_ = Write; break; } update_bus(); From 763159a6f6447dda70a5c7eae8b43f07aaacfb90 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 14 Feb 2020 23:16:10 -0500 Subject: [PATCH 2/4] More neatly ties volume level 0 to silence. --- Components/AY38910/AY38910.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Components/AY38910/AY38910.cpp b/Components/AY38910/AY38910.cpp index 9d9dbdaa7..512bf1341 100644 --- a/Components/AY38910/AY38910.cpp +++ b/Components/AY38910/AY38910.cpp @@ -79,7 +79,11 @@ void AY38910::set_sample_volume_range(std::int16_t range) { for(int v = 0; v < 32; v++) { volumes_[v] = int(max_volume / powf(root_two, float(v ^ 0x1f) / 3.18f)); } - volumes_[0] = 0; // Tie level 0 to silence. + + // Tie level 0 to silence. + for(int v = 31; v >= 0; --v) { + volumes_[v] -= volumes_[0]; + } evaluate_output_volume(); } From e1892ff3704553ca09eb9c1b4e0d140acf261980 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 14 Feb 2020 23:16:44 -0500 Subject: [PATCH 3/4] Resolves crash upon File -> New..., Cancel; also ensures slow performance can't equal no progression. --- OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift | 2 +- OSBindings/Mac/Clock Signal/Machine/CSMachine.mm | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift index 72bfef8c2..54e85c1b0 100644 --- a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift +++ b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift @@ -84,7 +84,7 @@ class MachineDocument: } override func close() { - machine.stop() + machine?.stop() activityPanel?.setIsVisible(false) activityPanel = nil diff --git a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm index 2130b06bb..58705ecb2 100644 --- a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm +++ b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm @@ -770,11 +770,7 @@ struct ActivityObserver: public Activity::Observer { // Grab the time now and, therefore, the amount of time since the timer last fired // (capped at half a second). const auto timeNow = Time::nanos_now(); - const auto duration = timeNow - lastTime; - if(duration > Time::Nanos(500'000'000)) { - lastTime = timeNow; - return; - } + const auto duration = std::min(timeNow - lastTime, Time::Nanos(10'000'000'000 / TICKS)); CGSize pixelSize; BOOL splitAndSync = NO; From eb88c7cfba7b677eddc6c32c5d65ae14a72f2c02 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 14 Feb 2020 23:24:51 -0500 Subject: [PATCH 4/4] Allows up to half a second of hard processing. --- OSBindings/SDL/main.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/OSBindings/SDL/main.cpp b/OSBindings/SDL/main.cpp index dda4872f5..dee03b587 100644 --- a/OSBindings/SDL/main.cpp +++ b/OSBindings/SDL/main.cpp @@ -131,8 +131,7 @@ struct MachineRunner { // now, as there's obviously been some sort of substantial time glitch. const auto time_now = Time::nanos_now(); if(time_now - last_time_ > Time::Nanos(500'000'000)) { - last_time_ = time_now; - return; + last_time_ = time_now - Time::Nanos(500'000'000); } const auto vsync_time = vsync_time_.load();