From 98210171046023d90b94d78205ca6ad8c542a319 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Fri, 30 Aug 2019 12:46:27 +0200 Subject: [PATCH] Added tests for DC-filter. --- DCBlock.h | 46 ++++++++++++++++++++ effect_modulated_delay.cpp | 9 ++++ effect_modulated_delay.h | 2 + mozzi/DCfilter.h | 89 ++++++++++++++++++++++++++++++++++++++ mozzi/DCfilter.ino | 50 +++++++++++++++++++++ 5 files changed, 196 insertions(+) create mode 100644 DCBlock.h create mode 100644 mozzi/DCfilter.h create mode 100644 mozzi/DCfilter.ino diff --git a/DCBlock.h b/DCBlock.h new file mode 100644 index 0000000..0e286c6 --- /dev/null +++ b/DCBlock.h @@ -0,0 +1,46 @@ +// From "git clone --recursive https://github.com/SpotlightKid/ykchorus.git" +/* + ============================================================================== + This file is part of Tal-NoiseMaker by Patrick Kunz. + + Copyright(c) 2005-2010 Patrick Kunz, TAL + Togu Audio Line, Inc. + http://kunz.corrupt.ch + + This file may be licensed under the terms of of the + GNU General Public License Version 2 (the ``GPL''). + + Software distributed under the License is distributed + on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either + express or implied. See the GPL for the specific language + governing rights and limitations. + + You should have received a copy of the GPL along with this + program. If not, go to http://www.gnu.org/licenses/gpl.html + or write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + ============================================================================== + */ + +#if !defined(__DCBlock_h) +#define __DCBlock_h + +class DCBlock { +public: + float inputs, outputs, lastOutput; + + DCBlock() { + lastOutput = inputs = outputs = 0.0f; + } + + ~DCBlock() {} + + inline void tick(float *sample, float cutoff) { + outputs = *sample - inputs + (0.999f - cutoff * 0.4f) * outputs; + inputs = *sample; + lastOutput = outputs; + *sample = lastOutput; + } +}; + +#endif diff --git a/effect_modulated_delay.cpp b/effect_modulated_delay.cpp index f5a74d8..0187451 100644 --- a/effect_modulated_delay.cpp +++ b/effect_modulated_delay.cpp @@ -26,6 +26,8 @@ #include "arm_math.h" #include "effect_modulated_delay.h" #include "config.h" +#include "DCBlock.h" +#include "limits.h" extern config_t configuration; @@ -63,6 +65,8 @@ boolean AudioEffectModulatedDelay::begin(short *delayline, int d_length) set_modulator_filter_coeffs(); modulator_filter_data = {1, modulator_filter_state, modulator_filter_coeffs}; + dcBlock = new DCBlock(); + return (true); } @@ -141,6 +145,11 @@ void AudioEffectModulatedDelay::update(void) cb_mod_index_neighbor = cb_mod_index + 1; *bp = round(float(_delayline[cb_mod_index_neighbor]) * mod_fraction + float(_delayline[cb_mod_index]) * (1.0 - mod_fraction)); } + + // simple Test for DC filter + float bp_f=*bp/SHRT_MAX; + dcBlock->tick(&bp_f, 0.01f); + *bp=bp_f*SHRT_MAX; // push the pointers forward bp++; // next audio data diff --git a/effect_modulated_delay.h b/effect_modulated_delay.h index 9ded4a1..6688e45 100644 --- a/effect_modulated_delay.h +++ b/effect_modulated_delay.h @@ -27,6 +27,7 @@ #include "Arduino.h" #include "AudioStream.h" #include "config.h" +#include "DCBlock.h" #define MODULATION_MAX_FACTOR 0.75 @@ -59,6 +60,7 @@ class AudioEffectModulatedDelay : arm_biquad_casd_df1_inst_f32 modulator_filter_data; float32_t modulator_filter_state[4]; float32_t modulator_filter_coeffs[5]; + DCBlock *dcBlock; }; #endif diff --git a/mozzi/DCfilter.h b/mozzi/DCfilter.h new file mode 100644 index 0000000..2b2dde7 --- /dev/null +++ b/mozzi/DCfilter.h @@ -0,0 +1,89 @@ +/* + * DCfilter.h + * + * Copyright 2012 Tim Barrass. + * + * This file is part of Mozzi. + * + * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * + */ + +#ifndef DCFILTER_H +#define DCFILTER_H + +/* +tb2010 adapted from: +robert bristow-johnson, DSP Trick: Fixed-Point DC Blocking Filter with Noise-Shaping +http://www.dspguru.com/book/export/html/126 + +y[n] = x[n] - x[n-1] + a * y[n-1] + +Where y[n] is the output at the current time n, and x[n] is the input at the current time n. + +also, see DC Blocker Algorithms, http://www.ingelec.uns.edu.ar/pds2803/materiales/articulos/04472252.pdf + */ + +/** +A DC-blocking filter useful for highlighting changes in control signals. +The output of the filter settles to 0 if the incoming signal stays constant. If the input changes, the +filter output swings to track the change and eventually settles back to 0. +*/ +class DCfilter +{ +public: +/** +Instantiate a DC-blocking filter. +@param pole sets the responsiveness of the filter, +how long it takes to settle to 0 if the input signal levels out at a constant value. +*/ + DCfilter(float pole):acc(0),prev_x(0),prev_y(0) + { + A = (int)(32768.0*(1.0 - pole)); + } + +/* almost original + // timing: 20us + int next(int x) + { + setPin13High(); + acc -= prev_x; + prev_x = (long)x<<15; + acc += prev_x; + acc -= A*prev_y; + prev_y = acc>>15; // quantization happens here + int filtered = (int)prev_y; + // acc has y[n] in upper 17 bits and -e[n] in lower 15 bits + setPin13Low(); + return filtered; + } + */ + + /** + Filter the incoming value and return the result. + @param x the value to filter + @return filtered signal + */ + // timing :8us + inline + int next(int x) + { + acc += ((long)(x-prev_x)<<16)>>1; + prev_x = x; + acc -= (long)A*prev_y; // acc has y[n] in upper 17 bits and -e[n] in lower 15 bits + prev_y = (acc>>16)<<1; // faster than >>15 but loses bit 0 + if (acc & 32784) prev_y += 1; // adds 1 if it was in the 0 bit position lost in the shifts above + return prev_y; + } + +private: + long acc; + int prev_x, prev_y,A; +}; + +/** +@example 05.Control_Filters/DCFilter/DCFilter.ino +This example demonstrates the DCFilter class. +*/ + +#endif // #ifndef DCFILTER_H diff --git a/mozzi/DCfilter.ino b/mozzi/DCfilter.ino new file mode 100644 index 0000000..56fb2be --- /dev/null +++ b/mozzi/DCfilter.ino @@ -0,0 +1,50 @@ +/* Example of filtering an analog input to remove DC bias, + using Mozzi sonification library. + + Demonstrates DCfilter(), DC-blocking filter useful for + highlighting changes in control signals. + The output of the filter settles to 0 if the incoming signal stays constant. + If the input changes, the filter output swings to track the change and + eventually settles back to 0. + + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html + + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Tim Barrass 2013, CC by-nc-sa. + +*/ + +#include +#include + +int sensorPin = A0; + +DCfilter dcFiltered(0.9); // parameter sets how long the filter takes to settle + +void setup() { + //Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches + Serial.begin(115200); + startMozzi(); +} + + +void updateControl(){ + // read the value from the sensor: + int sensorValue = mozziAnalogRead(sensorPin); + Serial.print(sensorValue); + Serial.print(" Filtered = "); + Serial.println(dcFiltered.next(sensorValue)); +} + + +int updateAudio(){ + return 0; +} + + +void loop(){ + audioHook(); +}