diff --git a/Components/SID/SID.cpp b/Components/SID/SID.cpp index b36359c90..90c2c8763 100644 --- a/Components/SID/SID.cpp +++ b/Components/SID/SID.cpp @@ -10,7 +10,13 @@ using namespace MOS::SID; -SID::SID(Concurrency::AsyncTaskQueue &audio_queue) : audio_queue_(audio_queue) {} +SID::SID(Concurrency::AsyncTaskQueue &audio_queue) : + audio_queue_(audio_queue), + output_filter_( + SignalProcessing::BiquadFilter::Type::LowPass, + 1000000.0f, + 15000.0f + ) {} void SID::write(const Numeric::SizedInt<5> address, const uint8_t value) { last_write_ = value; @@ -158,7 +164,7 @@ void SID::apply_samples(const std::size_t number_of_samples, Outputs::Speaker::M ); // Sum, apply volume and output. - const auto sample = + const auto sample = output_filter_.apply(int16_t( ( volume_ * ( direct_sample + @@ -166,7 +172,8 @@ void SID::apply_samples(const std::size_t number_of_samples, Outputs::Speaker::M - 227 // DC offset. ) - 88732 - ) / 3; + ) / 3 + )); // Maximum range of above: 15 * (4095 * 3 - 227) = [-3405, 180870] // So subtracting 88732 will move to the centre of the range, and 3 is the smallest // integer that avoids clipping. diff --git a/Components/SID/SID.hpp b/Components/SID/SID.hpp index c7a9c8243..a5ca4a05c 100644 --- a/Components/SID/SID.hpp +++ b/Components/SID/SID.hpp @@ -299,6 +299,8 @@ private: Numeric::SizedInt<4> filter_channels_; Numeric::SizedInt<3> filter_mode_; void update_filter(); + + SignalProcessing::BiquadFilter output_filter_; }; } diff --git a/SignalProcessing/BiquadFilter.hpp b/SignalProcessing/BiquadFilter.hpp index e1770ae10..8c8254622 100644 --- a/SignalProcessing/BiquadFilter.hpp +++ b/SignalProcessing/BiquadFilter.hpp @@ -8,6 +8,7 @@ #pragma once +#include #include #include @@ -31,9 +32,9 @@ public: const Type type, const float sample_rate, const float frequency, - const float resonance, - const float gain, - const bool normalise + const float resonance = 0.707f, + const float gain = 8, + const bool normalise = true ) { const float w0 = 2.0f * std::numbers::pi_v * frequency / sample_rate; const float alpha = std::sin(w0) / (2.0f * resonance); @@ -133,7 +134,8 @@ public: } } for(int c = 0; c < 5; c++) { - coefficients_[c] = int16_t(coefficients[c] * 4096.0f); + assert(std::abs(coefficients[c]) < 32768.0f / 16384.0f); + coefficients_[c] = int16_t(coefficients[c] * 16384.0f); } } @@ -144,7 +146,7 @@ public: coefficients_[2] * inputs_[1] - coefficients_[3] * outputs_[0] - coefficients_[4] * outputs_[1] - ) >> 12; + ) >> 14; inputs_[1] = inputs_[0]; inputs_[0] = input;