From 668a5ca04101e5d0a3f3821de7dc8201ed8942b5 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 31 Dec 2024 10:25:11 -0500 Subject: [PATCH] Make a real attempt at some degree of audio. --- Machines/Commodore/Plus4/Audio.hpp | 35 ++++++++++++++++++++++-------- Machines/Commodore/Plus4/Plus4.cpp | 4 ++++ Machines/Commodore/Plus4/Video.hpp | 5 +++-- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/Machines/Commodore/Plus4/Audio.hpp b/Machines/Commodore/Plus4/Audio.hpp index 4bec24df9..471dd3851 100644 --- a/Machines/Commodore/Plus4/Audio.hpp +++ b/Machines/Commodore/Plus4/Audio.hpp @@ -13,8 +13,8 @@ namespace Commodore::Plus4 { -// PAL: / 160 -// NTSC: / 128 +// PAL: / 160 i.e. 5*32 +// NTSC: / 128 i.e. 4*32 // 111860.78125 = NTSC // 110840.46875 = PAL @@ -26,23 +26,37 @@ public: template void apply_samples(std::size_t size, Outputs::Speaker::MonoSample *const target) { + const auto count_frequency = [&](int index) { + if(!counts_[index]) { + counts_[index] = frequencies_[index] * frequency_multiplier_; + states_[index] ^= 1; + } else { + --counts_[index]; + } + }; + for(size_t c = 0; c < size; c++) { + count_frequency(0); + count_frequency(1); Outputs::Speaker::apply( target[c], Outputs::Speaker::MonoSample( - ((r_ + c) & 128) ? external_volume_ : -external_volume_ + ( + ((states_[0] & masks_[0]) * external_volume_) + + ((states_[1] & masks_[1]) * external_volume_) + ) * volume_ )); } r_ += size; } void set_sample_volume_range(const std::int16_t range) { - external_volume_ = range; + external_volume_ = range >> 5; } bool is_zero_level() const { - return !(sound1_on_ || sound2_on_ || sound2_noise_on_) || !volume_; + return !(masks_[0] || masks_[1] || sound2_noise_on_) || !volume_; } template void set_frequency_low(uint8_t value) { @@ -60,8 +74,8 @@ public: void set_constrol(uint8_t value) { audio_queue_.enqueue([this, value] { volume_ = value & 0xf; - sound1_on_ = value & 0x10; - sound2_on_ = value & 0x20; + masks_[0] = (value & 0x10) ? 1 : 0; + masks_[1] = (value & 0x20) ? 1 : 0; sound2_noise_on_ = value & 0x40; sound_dc_ = value & 0x80; }); @@ -74,9 +88,12 @@ private: // Audio-thread state. int16_t external_volume_ = 0; int frequencies_[2]{}; + int frequency_multiplier_ = 5; + int counts_[2]{}; + + int states_[2]{}; + int masks_[2]{}; - bool sound1_on_ = false; - bool sound2_on_ = false; bool sound2_noise_on_ = false; bool sound_dc_ = false; uint8_t volume_ = 0; diff --git a/Machines/Commodore/Plus4/Plus4.cpp b/Machines/Commodore/Plus4/Plus4.cpp index 9b12523da..f8ec1fd9c 100644 --- a/Machines/Commodore/Plus4/Plus4.cpp +++ b/Machines/Commodore/Plus4/Plus4.cpp @@ -444,6 +444,10 @@ private: void run_for(const Cycles cycles) final { m6502_.run_for(cycles); + + // I don't know why. + update_audio(); + audio_queue_.perform(); } void flush_output(int outputs) override { diff --git a/Machines/Commodore/Plus4/Video.hpp b/Machines/Commodore/Plus4/Video.hpp index 795764d4a..09e233794 100644 --- a/Machines/Commodore/Plus4/Video.hpp +++ b/Machines/Commodore/Plus4/Video.hpp @@ -307,7 +307,6 @@ public: ); shifter_.advance(); - ++video_counter_; } if(increment_character_position_ && character_fetch_) { @@ -477,7 +476,9 @@ public: break; case HorizontalEvent::BeginShiftRegister: - character_window_ = video_shift_ = enable_display_; + if(enable_display_) { + character_window_ = video_shift_ = true; + } next_pixels_ = 0; break; }