From c105acf1c78102f98f738d622b871dc2061e4e79 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 9 Feb 2024 10:48:42 -0500 Subject: [PATCH] Adopt a full type for stereo samples, gaining + and +=. --- Components/AY38910/AY38910.cpp | 5 +-- Machines/Enterprise/Dave.cpp | 4 +- .../xcschemes/Clock Signal.xcscheme | 2 +- .../Speaker/Implementation/CompoundSource.hpp | 8 ++-- Outputs/Speaker/Speaker.hpp | 37 ++++++++++++++++--- 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/Components/AY38910/AY38910.cpp b/Components/AY38910/AY38910.cpp index 83168b287..e2ad41467 100644 --- a/Components/AY38910/AY38910.cpp +++ b/Components/AY38910/AY38910.cpp @@ -210,13 +210,12 @@ template void AY38910::evaluate_output_volume() { // Mix additively, weighting if in stereo. if constexpr (is_stereo) { -// int16_t *const output_volumes = reinterpret_cast(&output_volume_); - output_volume_[0] = int16_t(( + output_volume_.left = int16_t(( volumes_[volumes[0]] * channel_levels[0] * a_left_ + volumes_[volumes[1]] * channel_levels[1] * b_left_ + volumes_[volumes[2]] * channel_levels[2] * c_left_ ) >> 8); - output_volume_[1] = int16_t(( + output_volume_.right = int16_t(( volumes_[volumes[0]] * channel_levels[0] * a_right_ + volumes_[volumes[1]] * channel_levels[1] * b_right_ + volumes_[volumes[2]] * channel_levels[2] * c_right_ diff --git a/Machines/Enterprise/Dave.cpp b/Machines/Enterprise/Dave.cpp index 940755014..ba079087b 100644 --- a/Machines/Enterprise/Dave.cpp +++ b/Machines/Enterprise/Dave.cpp @@ -106,7 +106,7 @@ void Audio::get_samples(std::size_t number_of_samples, Outputs::Speaker::StereoS while(c < number_of_samples) { // I'm unclear on the details of the time division multiplexing so, // for now, just sum the outputs. - output_level[0] = + output_level.left = volume_ * (use_direct_output_[0] ? channels_[0].amplitude[0] @@ -117,7 +117,7 @@ void Audio::get_samples(std::size_t number_of_samples, Outputs::Speaker::StereoS noise_.amplitude[0] * noise_.final_output )); - output_level[1] = + output_level.right = volume_ * (use_direct_output_[1] ? channels_[0].amplitude[1] diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme index 474fa352e..19b54b90e 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme +++ b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme @@ -62,7 +62,7 @@ class CompoundSource: static constexpr bool is_stereo = S::is_stereo || CompoundSourceHolder::is_stereo; - template void get_samples(std::size_t number_of_samples, std::int16_t *target) { + // TODO: fix below for mixed mono/stereo sources. + template + void get_samples(std::size_t number_of_samples, typename SampleT::type *target) { // Get the rest of the output. next_source_.template get_samples(number_of_samples, target); @@ -72,7 +74,7 @@ template class CompoundSource: // Get this component's output. auto buffer_size = number_of_samples * (output_stereo ? 2 : 1); - int16_t local_samples[buffer_size]; + typename SampleT::type local_samples[number_of_samples]; source_.get_samples(number_of_samples, local_samples); // Merge it in; furthermore if total output is stereo but this source isn't, @@ -127,7 +129,7 @@ template class CompoundSource: } } - void get_samples(std::size_t number_of_samples, std::int16_t *target) { + void get_samples(std::size_t number_of_samples, typename SampleT<::Outputs::Speaker::is_stereo()>::type *target) { source_holder_.template get_samples<::Outputs::Speaker::is_stereo()>(number_of_samples, target); } diff --git a/Outputs/Speaker/Speaker.hpp b/Outputs/Speaker/Speaker.hpp index d65a54fc4..5195b4f77 100644 --- a/Outputs/Speaker/Speaker.hpp +++ b/Outputs/Speaker/Speaker.hpp @@ -14,13 +14,38 @@ namespace Outputs::Speaker { -template struct SampleT; -template <> struct SampleT { using type = std::array; }; // TODO: adopt left/right as per Dave? -template <> struct SampleT { using type = std::int16_t; }; - // Shorthands. -using MonoSample = SampleT::type; -using StereoSample = SampleT::type; +using MonoSample = int16_t; +struct StereoSample { +#if TARGET_RT_BIG_ENDIAN + int16_t right, left; +#else + int16_t left, right; +#endif + + StereoSample() = default; + StereoSample(const StereoSample &rhs) { + left = rhs.left; + right = rhs.right; + } + + StereoSample &operator +=(const StereoSample &rhs) { + left += rhs.left; + right += rhs.right; + return *this; + } + + StereoSample operator +(const StereoSample &rhs) { + StereoSample result; + result.left = left + rhs.left; + result.right = right + rhs.right; + return *this; + } +}; + +template struct SampleT { + using type = std::conditional_t; +}; /*! Provides a communication point for sound; machines that have a speaker provide an