Save the current state.

master
Holger Wirtz 5 years ago
parent 449c7f72d1
commit 8d8ee66397
  1. 89
      DCfilter.h
  2. 26
      MicroMDAEPiano.ino
  3. 20
      OnePoleLP.h
  4. 2
      config.h
  5. 53
      effect_modulated_delay.cpp
  6. 7
      effect_modulated_delay.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

@ -57,8 +57,8 @@ AudioAmplifier inverter;
AudioEffectModulatedDelay modchorus_r;
AudioEffectModulatedDelay modchorus_l;
AudioSynthWaveform modulator;
AudioFilterStateVariable chorus_filter_r;
AudioFilterStateVariable chorus_filter_l;
//AudioFilterStateVariable chorus_filter_r;
//AudioFilterStateVariable chorus_filter_l;
AudioConnection patchCord0(queue_r, peak_r);
AudioConnection patchCord1(queue_l, peak_l);
AudioConnection patchCord2(queue_r, freeverb_r);
@ -70,10 +70,12 @@ AudioConnection patchCord9(modulator, inverter);
AudioConnection patchCord10(inverter, 0, modchorus_l, 1);
AudioConnection patchCord11(queue_r, 0, mixer_r, 0);
AudioConnection patchCord12(queue_l, 0, mixer_l, 0);
AudioConnection patchCord13(modchorus_r, chorus_filter_r);
AudioConnection patchCord14(modchorus_l, chorus_filter_l);
AudioConnection patchCord15(chorus_filter_r, 0, mixer_r, 2);
AudioConnection patchCord16(chorus_filter_l, 0, mixer_l, 2);
//AudioConnection patchCord13(modchorus_r, chorus_filter_r);
//AudioConnection patchCord14(modchorus_l, chorus_filter_l);
//AudioConnection patchCord15(chorus_filter_r, 0, mixer_r, 2);
//AudioConnection patchCord16(chorus_filter_l, 0, mixer_l, 2);
AudioConnection patchCord15(modchorus_r, 0, mixer_r, 2);
AudioConnection patchCord16(modchorus_l, 0, mixer_l, 2);
AudioConnection patchCord17(freeverb_r, 0, mixer_r, 1);
AudioConnection patchCord18(freeverb_l, 0, mixer_l, 1);
AudioConnection patchCord19(mixer_r, volume_r);
@ -238,12 +240,12 @@ void setup()
modulator.amplitude(1.0);
modulator.offset(0.0);
inverter.gain(-1.0); // change phase for second modulated delay (faked stereo mode)
chorus_filter_r.frequency(3500);
chorus_filter_r.resonance(0.7);
chorus_filter_r.octaveControl(1);
chorus_filter_l.frequency(3500);
chorus_filter_l.resonance(0.7);
chorus_filter_l.octaveControl(1);
//chorus_filter_r.frequency(3500);
//chorus_filter_r.resonance(0.7);
//chorus_filter_r.octaveControl(1);
//chorus_filter_l.frequency(3500);
//chorus_filter_l.resonance(0.7);
//chorus_filter_l.octaveControl(1);
modchorus_r.offset(15.0);
modchorus_l.offset(15.0);

@ -1,4 +1,3 @@
// From "git clone --recursive https://github.com/SpotlightKid/ykchorus.git"
/*
==============================================================================
This file is part of Tal-NoiseMaker by Patrick Kunz.
@ -22,24 +21,23 @@
==============================================================================
*/
#if !defined(__DCBlock_h)
#define __DCBlock_h
#if !defined(__OnePoleLP_h)
#define __OnePoleLP_h
class DCBlock {
class OnePoleLP {
public:
float inputs, outputs, lastOutput;
DCBlock() {
OnePoleLP() {
lastOutput = inputs = outputs = 0.0f;
}
~DCBlock() {}
~OnePoleLP() {}
inline void tick(float *sample, float cutoff) {
outputs = *sample - inputs + (0.999f - cutoff * 0.4f) * outputs;
inputs = *sample;
lastOutput = outputs;
*sample = lastOutput;
void tick(float *sample, float cutoff) {
float p = (cutoff * 0.98f) * (cutoff * 0.98f) * (cutoff * 0.98f) * (cutoff * 0.98f);
outputs = (1.0f - p) * (*sample) + p * outputs;
*sample = outputs;
}
};

@ -56,7 +56,7 @@
#define USE_XFADE_DATA 1
// CHORUS parameters
#define CHORUS_DELAY_LENGTH_SAMPLES (15*AUDIO_BLOCK_SAMPLES) // one AUDIO_BLOCK_SAMPLES = 2.902ms
#define CHORUS_WAVEFORM_MOD WAVEFORM_TRIANGLE // WAVEFORM_SINE WAVEFORM_TRIANGLE WAVEFORM_SAWTOOTH WAVEFORM_SAWTOOTH_REVERSE
#define CHORUS_WAVEFORM_MOD WAVEFORM_SINE // WAVEFORM_SINE WAVEFORM_TRIANGLE WAVEFORM_SAWTOOTH WAVEFORM_SAWTOOTH_REVERSE
//*************************************************************************************************
//* DEBUG OUTPUT SETTINGS
//*************************************************************************************************

@ -26,7 +26,8 @@
#include "arm_math.h"
#include "effect_modulated_delay.h"
#include "config.h"
#include "DCBlock.h"
#include "DCfilter.h"
#include "OnePoleLP.h"
#include "limits.h"
extern config_t configuration;
@ -51,6 +52,7 @@ boolean AudioEffectModulatedDelay::begin(short *delayline, int d_length)
_delay_length = 0;
_delay_offset = 0.0;
_cb_index = 0;
z1 = 0;
if (delayline == NULL) {
return (false);
@ -65,7 +67,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();
lp = new OnePoleLP();
dcFilter = new DCfilter(0.9);
return (true);
}
@ -77,12 +80,12 @@ void AudioEffectModulatedDelay::set_modulator_filter_coeffs(void)
// Example: https://web.fhnw.ch/technik/projekte/eit/Fruehling2016/MuelZum/html/parametric_equalizer_example_8c-example.html
// Coeeficients calculated with https://arachnoid.com/BiQuadDesigner/index.html
// SR = 44110, Fc = 400 Hz; Q=0.707
modulator_filter_coeffs[0] = 7.80321719e-4; // b0
modulator_filter_coeffs[1] = 0.00156064; // b1
modulator_filter_coeffs[2] = 7.80321719e-4; // b2
modulator_filter_coeffs[3] = 1.91943335; // -a1
modulator_filter_coeffs[4] = -0.92255463; // -a2
// SR = 44110, Fc = 20 Hz; Q=0.707
modulator_filter_coeffs[0] = 5.06973332e-7; // b0
modulator_filter_coeffs[1] = 1.01394666e-6; // b1
modulator_filter_coeffs[2] = modulator_filter_coeffs[0]; // b2
modulator_filter_coeffs[3] = 1.99798478; // -a1
modulator_filter_coeffs[4] = -0.99798681; // -a2
}
void AudioEffectModulatedDelay::update(void)
@ -124,32 +127,22 @@ void AudioEffectModulatedDelay::update(void)
// calculate modulation index into circular buffer
cb_mod_index = (_cb_index - (_delay_offset + mod_number));
/* if (cb_mod_index >= _delay_length)
cb_mod_index -= _delay_length; */
if (cb_mod_index < 0) // check for negative offsets and correct them
cb_mod_index += _delay_length;
if (*mp < 0.0)
{
if (cb_mod_index == 0)
cb_mod_index_neighbor = _delay_length;
else
cb_mod_index_neighbor = cb_mod_index - 1;
*bp = round(float(_delayline[cb_mod_index]) * mod_fraction + float(_delayline[cb_mod_index_neighbor]) * (1.0 - mod_fraction));
}
if (cb_mod_index == 0)
cb_mod_index_neighbor = _delay_length;
else
{
if (cb_mod_index == _delay_length)
cb_mod_index_neighbor = 0;
else
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;
cb_mod_index_neighbor = cb_mod_index - 1;
//*bp = round(float(_delayline[cb_mod_index]) * mod_fraction + float(_delayline[cb_mod_index_neighbor]) * (1.0 - mod_fraction));
*bp = (round(float(_delayline[cb_mod_index]) * mod_fraction + float(_delayline[cb_mod_index_neighbor]) * (1.0 - mod_fraction))+z1)/2;
z1 = *bp;
float bp_f = *bp / float(SHRT_MAX);
lp->tick(&bp_f, 0.95f);
*bp = round(bp_f * SHRT_MAX);
*bp = dcFilter->next(*bp);
// push the pointers forward
bp++; // next audio data

@ -27,7 +27,8 @@
#include "Arduino.h"
#include "AudioStream.h"
#include "config.h"
#include "DCBlock.h"
#include "DCfilter.h"
#include "OnePoleLP.h"
#define MODULATION_MAX_FACTOR 0.75
@ -60,7 +61,9 @@ 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;
int16_t z1;
OnePoleLP *lp;
DCfilter *dcFilter;
};
#endif

Loading…
Cancel
Save