What would be the best way to smooth out a MIDI CC signal?
Been searching for Csound implementations of a “slew limiter” (with different keywords) and I’m not having much luck. It feels like it should be fairly obvious.
The situation is, I want to use the breath control from my Yamaha WX11 windcontroller (CC02) to modulate the cutoff frequency of a lowpass filter. With midicontrolchange
, it works fairly well… except in higher registers where I get a “zipping” effect, sonically similar to aliasing.
Here’s a very simple version based on the default Cabbage synth:
<Cabbage>
form caption("Untitled") size(400, 300), colour(58, 110, 182), pluginid("def1")
keyboard bounds(8, 158, 381, 95)
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
; Initialize the global variables.
ksmps = 32
nchnls = 2
0dbfs = 1
;instrument will be triggered by keyboard widget
instr 1
kBreath init 1
midicontrolchange 2, kBreath, 0, 1
kEnv madsr .1, .2, .6, .4
aOut vco2 p5, p4
aOut moogvcf aOut, kBreath*5000, 0
outs aOut*kEnv, aOut*kEnv
endin
</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
</CsScore>
</CsoundSynthesizer>
I also created a legato version, using @iainmccurdy’s BasicMonophonicSynth.csd. The legato works well, the filter has the same issue.
<Cabbage>
form caption("Breath Solo") size(400, 300), colour(58, 110, 182), pluginid("def1")
keyboard bounds(8, 158, 381, 95)
rslider bounds(122,14,70,70), channel("cutoff"), range(0,22000,2000,.5,.01), text("Cutoff")
rslider bounds(200,14,70,70), channel("res"), range(0,1,0.7,1,.01), text("Resonance")
</Cabbage>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsoundSynthesizer>
<CsInstruments>
ksmps = 32
nchnls = 2
0dbfs = 1
;INITIALISE GLOBAL VARIABLES
gkcps init 0
gkCutOff init 0
gkRes init 0
instr 1
kcont init 1
midicontrolchange 2, kcont, 0, 1
kCutOff chnget "cutoff"
kRes chnget "res"
gkCutOff=kcont*kCutOff
gkRes=kcont*kRes
gkcps = p4
schedkwhen 1, 0, 1, 2, 0, 3600
endin
instr 2
kreleaseflag release
gkNumInstr1 active 1
if gkNumInstr1!=0||kreleaseflag=1 kgoto KEEP_PLAYING
turnoff
KEEP_PLAYING:
kporttime linseg 0, .01, 1, 1, 1
kporttime = kporttime * 0.04
kcps portk gkcps, kporttime
asig vco2 0.3, kcps
aFilt moogladder asig, gkCutOff, gkRes
aenv linsegr 0,0.001,1,0.01,0
outs aFilt * aenv, aFilt * aenv
endin
</CsInstruments>
<CsScore>
f 0 z
</CsScore>
</CsoundSynthesizer>
Again, I’m guessing it’s quite simple. I probably just don’t have the right keywords.
Thanks!