From: Steinar H. Gunderson Date: Sat, 14 Mar 2015 01:02:55 +0000 (+0100) Subject: Make the RC filter single-pole instead of biquad. X-Git-Url: https://git.sesse.net/?p=c64tapwav;a=commitdiff_plain;h=3683009b430b11acd1a9f8556729bc1e211ce6dc Make the RC filter single-pole instead of biquad. --- diff --git a/decode.cpp b/decode.cpp index ef8630d..5b99b81 100644 --- a/decode.cpp +++ b/decode.cpp @@ -340,11 +340,23 @@ std::vector do_fir_filter(const std::vector& pcm, const float* fil std::vector do_rc_filter(const std::vector& pcm, float freq, int sample_rate) { + // This is only a 6 dB/oct filter, which seemingly works better + // than the Filter class, which is a standard biquad (12 dB/oct). + // The b/c calculations come from libnyquist (atone.c); + // I haven't checked, but I suppose they fall out of the bilinear + // transform of the transfer function H(s) = s/(s + w). std::vector filtered_pcm; filtered_pcm.resize(pcm.size()); - Filter filter = Filter::hpf(2.0 * M_PI * freq / sample_rate); + const float b = 2.0f - cos(2.0 * M_PI * freq / sample_rate); + const float c = b - sqrt(b * b - 1.0f); + float prev_in = 0.0f; + float prev_out = 0.0f; for (unsigned i = 0; i < pcm.size(); ++i) { - filtered_pcm[i] = filter.update(pcm[i]); + float in = pcm[i]; + float out = c * (prev_out + in - prev_in); + filtered_pcm[i] = out; + prev_in = in; + prev_out = out; } if (output_filtered) {