From f95015c7f60dd3269029d14ce46ddd8c5fe97231 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 3 Apr 2017 21:16:39 -0400 Subject: [PATCH 1/2] Pulled out the divisor for audio. --- Machines/Atari2600/Atari2600.cpp | 6 +++--- Machines/Atari2600/Atari2600.hpp | 3 --- Machines/Atari2600/Bus.hpp | 7 ++++--- Machines/Atari2600/Speaker.hpp | 2 ++ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Machines/Atari2600/Atari2600.cpp b/Machines/Atari2600/Atari2600.cpp index 8abeb1d67..e3d732b9e 100644 --- a/Machines/Atari2600/Atari2600.cpp +++ b/Machines/Atari2600/Atari2600.cpp @@ -38,7 +38,7 @@ Machine::Machine() : void Machine::setup_output(float aspect_ratio) { bus_->tia_.reset(new TIA); bus_->speaker_.reset(new Speaker); - bus_->speaker_->set_input_rate((float)(get_clock_rate() / 38.0)); + bus_->speaker_->set_input_rate((float)(get_clock_rate() / (double)CPUTicksPerAudioTick)); bus_->tia_->get_crt()->set_delegate(this); } @@ -149,8 +149,8 @@ void Machine::crt_did_end_batch_of_frames(Outputs::CRT::CRT *crt, unsigned int n bus_->tia_->set_output_mode(TIA::OutputMode::PAL); } - bus_->speaker_->set_input_rate((float)(clock_rate / 38.0)); - bus_->speaker_->set_high_frequency_cut_off((float)(clock_rate / (38.0 * 2.0))); + bus_->speaker_->set_input_rate((float)(clock_rate / (double)CPUTicksPerAudioTick)); + bus_->speaker_->set_high_frequency_cut_off((float)(clock_rate / ((double)CPUTicksPerAudioTick * 2.0))); set_clock_rate(clock_rate); } } diff --git a/Machines/Atari2600/Atari2600.hpp b/Machines/Atari2600/Atari2600.hpp index 9147e3f95..550ec3db3 100644 --- a/Machines/Atari2600/Atari2600.hpp +++ b/Machines/Atari2600/Atari2600.hpp @@ -23,9 +23,6 @@ namespace Atari2600 { -const unsigned int number_of_upcoming_events = 6; -const unsigned int number_of_recorded_counters = 7; - class Machine: public CRTMachine::Machine, public ConfigurationTarget::Machine, diff --git a/Machines/Atari2600/Bus.hpp b/Machines/Atari2600/Bus.hpp index 864d22715..8d5d731a9 100644 --- a/Machines/Atari2600/Bus.hpp +++ b/Machines/Atari2600/Bus.hpp @@ -9,9 +9,10 @@ #ifndef Atari2600_Bus_hpp #define Atari2600_Bus_hpp +#include "Atari2600.hpp" #include "PIA.hpp" -#include "TIA.hpp" #include "Speaker.hpp" +#include "TIA.hpp" namespace Atari2600 { @@ -38,8 +39,8 @@ class Bus { // speaker backlog accumlation counter unsigned int cycles_since_speaker_update_; inline void update_audio() { - unsigned int audio_cycles = cycles_since_speaker_update_ / 114; - cycles_since_speaker_update_ %= 114; + unsigned int audio_cycles = cycles_since_speaker_update_ / (CPUTicksPerAudioTick * 3); + cycles_since_speaker_update_ %= (CPUTicksPerAudioTick * 3); speaker_->run_for_cycles(audio_cycles); } diff --git a/Machines/Atari2600/Speaker.hpp b/Machines/Atari2600/Speaker.hpp index b5bf42488..3cf5afc9c 100644 --- a/Machines/Atari2600/Speaker.hpp +++ b/Machines/Atari2600/Speaker.hpp @@ -13,6 +13,8 @@ namespace Atari2600 { +const int CPUTicksPerAudioTick = 38; + class Speaker: public ::Outputs::Filter { public: Speaker(); From ed6b135015bb7566c755a7e1bf77cd79c4ed074c Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 15 Apr 2017 21:18:00 -0400 Subject: [PATCH 2/2] Made final switch to permit high-sampling rate Atari audio. --- Machines/Atari2600/Speaker.cpp | 21 +++++++++++---------- Machines/Atari2600/Speaker.hpp | 4 +++- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Machines/Atari2600/Speaker.cpp b/Machines/Atari2600/Speaker.cpp index 86c27c02f..d573c363f 100644 --- a/Machines/Atari2600/Speaker.cpp +++ b/Machines/Atari2600/Speaker.cpp @@ -44,6 +44,7 @@ void Atari2600::Speaker::get_samples(unsigned int number_of_samples, int16_t *ta target[c] = 0; for(int channel = 0; channel < 2; channel++) { divider_counter_[channel] ++; + int divider_value = divider_counter_[channel] / (38 / CPUTicksPerAudioTick); int level = 0; switch(control_[channel]) { case 0x0: case 0xb: // constant 1 @@ -51,24 +52,24 @@ void Atari2600::Speaker::get_samples(unsigned int number_of_samples, int16_t *ta break; case 0x4: case 0x5: // div2 tone - level = (divider_counter_[channel] / (divider_[channel]+1))&1; + level = (divider_value / (divider_[channel]+1))&1; break; case 0xc: case 0xd: // div6 tone - level = (divider_counter_[channel] / ((divider_[channel]+1)*3))&1; + level = (divider_value / ((divider_[channel]+1)*3))&1; break; case 0x6: case 0xa: // div31 tone - level = (divider_counter_[channel] / (divider_[channel]+1))%30 <= 18; + level = (divider_value / (divider_[channel]+1))%30 <= 18; break; case 0xe: // div93 tone - level = (divider_counter_[channel] / ((divider_[channel]+1)*3))%30 <= 18; + level = (divider_value / ((divider_[channel]+1)*3))%30 <= 18; break; case 0x1: // 4-bit poly level = poly4_counter_[channel]&1; - if(divider_counter_[channel] == divider_[channel]+1) { + if(divider_value == divider_[channel]+1) { divider_counter_[channel] = 0; advance_poly4(channel); } @@ -76,14 +77,14 @@ void Atari2600::Speaker::get_samples(unsigned int number_of_samples, int16_t *ta case 0x2: // 4-bit poly div31 level = poly4_counter_[channel]&1; - if(divider_counter_[channel]%(30*(divider_[channel]+1)) == 18) { + if(divider_value%(30*(divider_[channel]+1)) == 18) { advance_poly4(channel); } break; case 0x3: // 5/4-bit poly level = output_state_[channel]; - if(divider_counter_[channel] == divider_[channel]+1) { + if(divider_value == divider_[channel]+1) { if(poly5_counter_[channel]&1) { output_state_[channel] = poly4_counter_[channel]&1; advance_poly4(channel); @@ -94,7 +95,7 @@ void Atari2600::Speaker::get_samples(unsigned int number_of_samples, int16_t *ta case 0x7: case 0x9: // 5-bit poly level = poly5_counter_[channel]&1; - if(divider_counter_[channel] == divider_[channel]+1) { + if(divider_value == divider_[channel]+1) { divider_counter_[channel] = 0; advance_poly5(channel); } @@ -102,7 +103,7 @@ void Atari2600::Speaker::get_samples(unsigned int number_of_samples, int16_t *ta case 0xf: // 5-bit poly div6 level = poly5_counter_[channel]&1; - if(divider_counter_[channel] == (divider_[channel]+1)*3) { + if(divider_value == (divider_[channel]+1)*3) { divider_counter_[channel] = 0; advance_poly5(channel); } @@ -110,7 +111,7 @@ void Atari2600::Speaker::get_samples(unsigned int number_of_samples, int16_t *ta case 0x8: // 9-bit poly level = poly9_counter_[channel]&1; - if(divider_counter_[channel] == divider_[channel]+1) { + if(divider_value == divider_[channel]+1) { divider_counter_[channel] = 0; advance_poly9(channel); } diff --git a/Machines/Atari2600/Speaker.hpp b/Machines/Atari2600/Speaker.hpp index 3cf5afc9c..26886c8b2 100644 --- a/Machines/Atari2600/Speaker.hpp +++ b/Machines/Atari2600/Speaker.hpp @@ -13,7 +13,9 @@ namespace Atari2600 { -const int CPUTicksPerAudioTick = 38; +// This should be a divisor of 38; audio counters are updated every 38 cycles — though lesser dividers +// will give greater resolution to changes in audio state. 1, 2 and 19 are the only divisors of 38. +const int CPUTicksPerAudioTick = 2; class Speaker: public ::Outputs::Filter { public: