zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

commit 953604dcd7c46dde3cb1349b36fe6bab524aee3d
parent ffae59f5aa87665a1e1aa67c87be39dbaac1413d
Author: Hans Petter Selasky <hps@selasky.org>
Date:   Fri,  3 Apr 2020 16:58:18 +0200

Add support for per-note filtercutoff.

Tested with ROLI seaboard and MIDI Player Pro (MPE mode).

Signed-off-by: Hans Petter Selasky <hps@selasky.org>

Diffstat:
Msrc/Misc/Part.cpp | 7+++++++
Msrc/Synth/ADnote.cpp | 8++++----
Msrc/Synth/PADnote.cpp | 4++--
Msrc/Synth/SUBnote.cpp | 7++++---
Msrc/Synth/SynthNote.cpp | 17+++++++++++++++++
Msrc/Synth/SynthNote.h | 5+++++
6 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/src/Misc/Part.cpp b/src/Misc/Part.cpp @@ -738,6 +738,13 @@ void Part::SetController(unsigned int type, note_t note, float value, } break; } + case C_filtercutoff: + for(auto &d:notePool.activeDesc()) { + if(d.note == note && d.playing()) + for(auto &s:notePool.activeNotes(d)) + s.note->setFilterCutoff(value); + } + break; default: break; } diff --git a/src/Synth/ADnote.cpp b/src/Synth/ADnote.cpp @@ -1085,9 +1085,11 @@ float ADnote::getFMvoicebasefreq(int nvoice) const */ void ADnote::computecurrentparameters() { + const float relfreq = getFilterCutoffRelFreq(); int nvoice; float voicefreq, voicepitch, FMfreq, FMrelativepitch, globalpitch; + globalpitch = 0.01f * (NoteGlobalPar.FreqEnvelope->envout() + NoteGlobalPar.FreqLfo->lfoout() * ctl.modwheel.relmod); @@ -1096,8 +1098,7 @@ void ADnote::computecurrentparameters() * NoteGlobalPar.AmpEnvelope->envout_dB() * NoteGlobalPar.AmpLfo->amplfoout(); - NoteGlobalPar.Filter->update(ctl.filtercutoff.relfreq, - ctl.filterq.relq); + NoteGlobalPar.Filter->update(relfreq, ctl.filterq.relq); //compute the portamento, if it is used by this note @@ -1135,8 +1136,7 @@ void ADnote::computecurrentparameters() /****************/ auto *voiceFilter = NoteVoicePar[nvoice].Filter; if(voiceFilter) { - voiceFilter->update(ctl.filtercutoff.relfreq, - ctl.filterq.relq); + voiceFilter->update(relfreq, ctl.filterq.relq); } if(NoteVoicePar[nvoice].noisetype == 0) { //compute only if the voice isn't noise diff --git a/src/Synth/PADnote.cpp b/src/Synth/PADnote.cpp @@ -251,6 +251,7 @@ inline void PADnote::fadein(float *smps) void PADnote::computecurrentparameters() { + const float relfreq = getFilterCutoffRelFreq(); const float globalpitch = 0.01f * (NoteGlobalPar.FreqEnvelope->envout() + NoteGlobalPar.FreqLfo->lfoout() * ctl.modwheel.relmod + NoteGlobalPar.Detune); @@ -259,8 +260,7 @@ void PADnote::computecurrentparameters() * NoteGlobalPar.AmpEnvelope->envout_dB() * NoteGlobalPar.AmpLfo->amplfoout(); - NoteGlobalPar.GlobalFilter->update(ctl.filtercutoff.relfreq, - ctl.filterq.relq); + NoteGlobalPar.GlobalFilter->update(relfreq, ctl.filterq.relq); //compute the portamento, if it is used by this note float portamentofreqrap = 1.0f; diff --git a/src/Synth/SUBnote.cpp b/src/Synth/SUBnote.cpp @@ -490,9 +490,10 @@ void SUBnote::computecurrentparameters() newamplitude = volume * AmpEnvelope->envout_dB() * 2.0f; //Filter - if(GlobalFilter) - GlobalFilter->update(ctl.filtercutoff.relfreq, - ctl.filterq.relq); + if(GlobalFilter) { + const float relfreq = getFilterCutoffRelFreq(); + GlobalFilter->update(relfreq, ctl.filterq.relq); + } } void SUBnote::computeallfiltercoefs(bpfilter *filters, float envfreq, diff --git a/src/Synth/SynthNote.cpp b/src/Synth/SynthNote.cpp @@ -10,6 +10,7 @@ of the License, or (at your option) any later version. */ #include "SynthNote.h" +#include "../Params/Controller.h" #include "../Misc/Util.h" #include "../globals.h" #include <cstring> @@ -175,6 +176,22 @@ void SynthNote::setPitch(float freq_, float log2_freq_) { legato.setDecounter(0); //avoid chopping sound due fade-in } +void SynthNote::setFilterCutoff(float value) +{ + filtercutoff_relfreq = + (value - 64.0f) * ctl.filtercutoff.depth / 4096.0f * 3.321928f; +} + +float SynthNote::getFilterCutoffRelFreq(void) +{ + const float value = filtercutoff_relfreq; + + if (value == 0.0f) + return (ctl.filtercutoff.relfreq); + else + return (value); +} + float SynthNote::getRandomFloat() { return (getRandomUint() / (INT32_MAX * 1.0f)); } diff --git a/src/Synth/SynthNote.h b/src/Synth/SynthNote.h @@ -75,6 +75,10 @@ class SynthNote /* For per-note pitch */ void setPitch(float freq_, float log2_freq_); + /* For per-note filter cutoff */ + void setFilterCutoff(float); + float getFilterCutoffRelFreq(void); + /* Random numbers with own seed */ float getRandomFloat(); prng_t getRandomUint(); @@ -126,6 +130,7 @@ class SynthNote const SYNTH_T &synth; const AbsTime &time; WatchManager *wm; + smooth_float filtercutoff_relfreq; }; }