From 4870506f6e23a32ff48a59df221effb744c1eb72 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 26 Nov 2020 16:24:48 -0500 Subject: [PATCH] Implements skip_audio. --- Machines/Apple/AppleIIgs/Sound.cpp | 29 +++++++++++++++++++++-------- Machines/Apple/AppleIIgs/Sound.hpp | 8 +++++--- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/Machines/Apple/AppleIIgs/Sound.cpp b/Machines/Apple/AppleIIgs/Sound.cpp index cdd92e13b..682954e10 100644 --- a/Machines/Apple/AppleIIgs/Sound.cpp +++ b/Machines/Apple/AppleIIgs/Sound.cpp @@ -174,6 +174,27 @@ uint8_t GLU::get_address_high() { // MARK: - Update logic. +void GLU::skip_audio(EnsoniqState &state, size_t number_of_samples) { + // Just advance all oscillator pointers and check for interrupts. + // If a read occurs to the current-output level, generate it then. + + for(int c = 0; c < local_.oscillator_count; c++) { + // Don't do anything for halted oscillators. + if(state.oscillators[c].control&1) continue; + + // Update phase. + state.oscillators[c].position += state.oscillators[c].velocity * number_of_samples; + + // Check for stops, and any interrupts that therefore flow. + if((state.oscillators[c].control & 1) && (state.oscillators[c].position & state.oscillators[c].overflow_mask)) { + // Apply halt, set interrupt request flag. + state.oscillators[c].position = 0; + state.oscillators[c].control |= 1; + state.oscillators[c].interrupt_request = true; + } + } +} + void GLU::generate_audio(size_t number_of_samples, std::int16_t *target) { auto next_store = pending_stores_[pending_store_read_].load(std::memory_order::memory_order_acquire); uint8_t next_amplitude = 255; @@ -291,11 +312,3 @@ int16_t GLU::EnsoniqState::Oscillator::output(uint8_t *ram) { // Samples are unsigned 8-bit; do the proper work to make volume work correctly. return int8_t(level ^ 128) * volume; } - -void GLU::skip_audio(EnsoniqState &state, size_t number_of_samples) { - (void)number_of_samples; - (void)state; - - // Just advance all oscillator pointers and check for interrupts. - // If a read occurs to the current-output level, generate it then. -} diff --git a/Machines/Apple/AppleIIgs/Sound.hpp b/Machines/Apple/AppleIIgs/Sound.hpp index ca3e91c13..7cf949f8d 100644 --- a/Machines/Apple/AppleIIgs/Sound.hpp +++ b/Machines/Apple/AppleIIgs/Sound.hpp @@ -77,14 +77,16 @@ class GLU: public Outputs::Speaker::SampleSource { uint8_t table_size; // Derived state. - uint32_t overflow_mask; // If a non-zero bit gets anywhere into the overflow mask, this channel - // has wrapped around. It's a function of table_size. + uint32_t overflow_mask; // If a non-zero bit gets anywhere into the overflow mask, this channel + // has wrapped around. It's a function of table_size. + bool interrupt_request = false; // Will be non-zero if this channel would request an interrupt, were + // it currently enabled to do so. uint8_t sample(uint8_t *ram); int16_t output(uint8_t *ram); } oscillators[32]; - // TODO: do all of these need to be on the audio thread? + // Some of these aren't actually needed on both threads. uint8_t control; uint8_t interrupt_state; int oscillator_count;