diff --git a/Makefile b/Makefile index 6734e2e..0458764 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ LDLIBS = -lm PYTHON = python3 PLAY = ffplay -v fatal -nodisp -autoexit -f s32le -ar 48000 -ch_layout mono -i pipe:0 -effects = flanger echo fm phaser discont am distortion +effects = flanger echo fm phaser discont am distortion tremolo flanger_defaults = 0.6 0.6 0.6 0.6 echo_defaults = 0.3 0.3 0.3 0.3 fm_defaults = 0.25 0.25 0.5 0.5 @@ -13,8 +13,9 @@ am_defaults = 0.5 0.5 0.5 0.5 phaser_defaults = 0.3 0.3 0.5 0.5 discont_defaults = 0.8 0.1 0.2 0.2 distortion_defaults = 0.5 0.6 0.8 0.0 +tremolo_defaults = 0.5 0.7 0.0 0.0 -HEADERS = biquad.h discont.h distortion.h echo.h effect.h flanger.h fm.h gensin.h lfo.h phaser.h util.h process.h +HEADERS = biquad.h discont.h distortion.h echo.h effect.h flanger.h fm.h gensin.h lfo.h phaser.h process.h tremolo.h util.h default: @echo "Pick one of" $(effects) diff --git a/convert.c b/convert.c index 6bdeb49..c9e78bc 100644 --- a/convert.c +++ b/convert.c @@ -21,6 +21,7 @@ #include "phaser.h" #include "discont.h" #include "distortion.h" +#include "tremolo.h" static void magnitude_init(float pot1, float pot2, float pot3, float pot4) {} static float magnitude_step(float in) { return u32_to_fraction(magnitude); } @@ -36,6 +37,7 @@ struct effect { EFF(echo), EFF(flanger), EFF(phaser), + EFF(tremolo), /* "Helper" effects */ EFF(am), diff --git a/tremolo.h b/tremolo.h new file mode 100644 index 0000000..2a660ce --- /dev/null +++ b/tremolo.h @@ -0,0 +1,41 @@ +// +// Tremolo effect - amplitude modulation via LFO +// +// Classic guitar amp tremolo effect that modulates volume +// using a sine or triangle wave LFO. +// +static struct { + struct lfo_state lfo; + float depth; + enum lfo_type wave; +} tremolo; + +static inline void tremolo_init(float pot1, float pot2, float pot3, float pot4) +{ + // pot1: LFO rate (0.5 - 15 Hz) + float rate = 0.5 + pot1 * 14.5; + set_lfo_freq(&tremolo.lfo, rate); + + // pot2: depth (0 - 100%) + tremolo.depth = pot2; + + // pot3: waveform (0-0.5 = sine, 0.5-1 = triangle) + tremolo.wave = pot3 < 0.5 ? lfo_sinewave : lfo_triangle; + + fprintf(stderr, "tremolo:"); + fprintf(stderr, " rate=%g Hz", rate); + fprintf(stderr, " depth=%g", pot2); + fprintf(stderr, " wave=%s\n", pot3 < 0.5 ? "sine" : "triangle"); +} + +static inline float tremolo_step(float in) +{ + // Get LFO value (-1 to 1), convert to gain multiplier + float lfo = lfo_step(&tremolo.lfo, tremolo.wave); + + // Convert LFO to amplitude multiplier: 1 - depth*(1-lfo)/2 + // When lfo=1, mult=1; when lfo=-1, mult=1-depth + float mult = 1.0f - tremolo.depth * (1.0f - lfo) * 0.5f; + + return in * mult; +}