From 983407896c44c059fe8bf2ec1c684a48e8a991a7 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 1 Jun 2019 17:29:57 -0400 Subject: [PATCH] Ensures consistent audio pipeline. --- Machines/Apple/Macintosh/Audio.cpp | 11 ++++++----- Machines/Apple/Macintosh/Audio.hpp | 5 ++--- Machines/Apple/Macintosh/Macintosh.cpp | 9 +++++++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Machines/Apple/Macintosh/Audio.cpp b/Machines/Apple/Macintosh/Audio.cpp index 77f806725..e319d4db6 100644 --- a/Machines/Apple/Macintosh/Audio.cpp +++ b/Machines/Apple/Macintosh/Audio.cpp @@ -24,7 +24,9 @@ void Audio::post_sample(uint8_t sample) { const auto write_pointer = sample_queue_.write_pointer.load(); const auto read_pointer = sample_queue_.read_pointer.load(); const decltype(write_pointer) next_write_pointer = (write_pointer + 1) % sample_queue_.buffer.size(); - if(next_write_pointer == read_pointer) return; + if(next_write_pointer == read_pointer) { + return; + } sample_queue_.buffer[write_pointer] = sample; sample_queue_.write_pointer.store(next_write_pointer); @@ -64,13 +66,12 @@ void Audio::get_samples(std::size_t number_of_samples, int16_t *target) { // that's something to return to. // TODO: temporary implementation. Very inefficient. Replace. - while(number_of_samples--) { - *target = volume_multiplier_ * int16_t(sample_queue_.buffer[read_pointer] * volume_ * enabled_mask_); - ++target; + for(std::size_t sample = 0; sample < number_of_samples; ++sample) { + target[sample] = volume_multiplier_ * int16_t(sample_queue_.buffer[read_pointer]);// * volume_ * enabled_mask_); ++subcycle_offset_; if(subcycle_offset_ == sample_length) { -// printf("%d: %d\n", sample_queue_.buffer[read_pointer], volume_multiplier_ * sample_queue_.buffer[read_pointer] * volume_ * enabled_mask_); +// printf("%d: %d\n", sample_queue_.buffer[read_pointer], volume_multiplier_ * int16_t(sample_queue_.buffer[read_pointer])); subcycle_offset_ = 0; const unsigned int next_read_pointer = (read_pointer + 1) % sample_queue_.buffer.size(); if(next_read_pointer != write_pointer) { diff --git a/Machines/Apple/Macintosh/Audio.hpp b/Machines/Apple/Macintosh/Audio.hpp index 4f9b9ff27..f123020c7 100644 --- a/Machines/Apple/Macintosh/Audio.hpp +++ b/Machines/Apple/Macintosh/Audio.hpp @@ -61,7 +61,7 @@ class Audio: public ::Outputs::Speaker::SampleSource { // A queue of fetched samples; read from by one thread, // written to by another. struct { - std::array buffer; + std::array buffer; std::atomic read_pointer, write_pointer; } sample_queue_; @@ -71,8 +71,7 @@ class Audio: public ::Outputs::Speaker::SampleSource { int enabled_mask_ = 0; std::int16_t volume_multiplier_ = 0; - - std::size_t subcycle_offset_; + std::size_t subcycle_offset_ = 0; }; } diff --git a/Machines/Apple/Macintosh/Macintosh.cpp b/Machines/Apple/Macintosh/Macintosh.cpp index 60e2b8082..e4bb411c0 100644 --- a/Machines/Apple/Macintosh/Macintosh.cpp +++ b/Machines/Apple/Macintosh/Macintosh.cpp @@ -59,6 +59,10 @@ class ConcreteMachine: audio_.speaker.set_input_rate(float(CLOCK_RATE)); } + ~ConcreteMachine() { + audio_.queue.flush(); + } + void set_scan_target(Outputs::Display::ScanTarget *scan_target) override { video_.set_scan_target(scan_target); } @@ -236,6 +240,7 @@ class ConcreteMachine: // video_.run_for(time_since_video_update_.flush()); // As above: flush audio after video. + via_.flush(); audio_.queue.perform(); } @@ -344,6 +349,10 @@ class ConcreteMachine: audio_.time_since_update += duration; } + void flush() { + audio_.flush(); + } + private: ConcreteMachine &machine_; RealTimeClock &clock_;