Hi. I was inspired by this tutorial for Vital and Erica Synths Steampipe and wanted to implement some physical modelling instrument inspired by Karplus-Strong algorithm.
I started with tuned comb
opcode and slowly implemented lowpass filter inside feedback loop with noise burst exciter. It kinda works when it’s in pluck mode. When it’s in flute mode it sounds either too metalic or too noisy (depends on parameters and played note).
Does anyone here have some low-level implementation of Karplus-Strong?
Or does anyone have some tip how to improve my instument?
I am especially interested in these questions:
- How to control decay time? It seems it depends both on exciter impulse amplitude, lowpass frequency and note… (It’s controllable using
comb
opcode, so there is some internal math in it.) - How to introduce resonances? In Vital one can add resonances to comb filter itself but I don’t understand how to implement it in Csound. I tried adding some resonances using
moogladder
orreson
opcodes but I did something wrong and it started producing screeching sounds. - Why does it sound kinda like a sitar? What am I missing to made it’s tone more guitarish?
Here is the code of my instrument:
<Cabbage>
form caption("Karplus-Strong hard way") size(400, 300), colour(58, 110, 182), pluginid("def1")
keyboard bounds(8, 158, 381, 95)
rslider bounds(14, 48, 60, 60) range(0, 3, 0.5, 1, 0.001) channel("jetvol") text("jetvol")
checkbox bounds(14, 114, 130, 30) text("pluck?") channel("pluck")
rslider bounds(80, 48, 60, 60) range(-0.9, 0.9, 0, 1, 0.001) text("noisecol") channel("noisecol")
label bounds(38, 20, 80, 16) text("EXCITER")
label bounds(182, 22, 80, 16) text("FILTER")
rslider bounds(164, 48, 60, 60) range(800, 8000, 8000, 1, 0.001) text("freq") channel("freq")
rslider bounds(226, 48, 60, 60) range(0, 1, 0.8, 1, 0.001) channel("clip") text("clip")
rslider bounds(332, 48, 60, 60) range(0, 2, 1, 1, 0.001) channel("vol")
label bounds(320, 24, 80, 16) text("VOL")
</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
; Karplus-Strong done in hard way (manually)
;instrument will be triggered by keyboard widget
instr 1
; exciter volume (0-3)
kjetvol chnget "jetvol"
; noise color (-0.9-0.9)
knoisecol chnget "noisecol"
; is pluck?
ipluck chnget "pluck"
if ipluck==1 then
kEnv madsr .01, .01, 0, .1
else
kEnv madsr .1, .01, 0.8, .1
endif
anoise noise 0.3, knoisecol
; exciter signal:
aping = kEnv*anoise*kjetvol
; debug to print delay times
; printf_i "delay = %f\n", 1, (1/p4)
printf_i "hz = %d\n", 1, p4
; tuned delay line: (this whole block until delayw)
adump delayr 1
ares deltapi 1/p4
ifreq chnget "freq"
; lowpass to smooth out higher harmonics
ares butterlp ares, ifreq
ares dcblock ares ; dcblock for good measure
iclip chnget "clip"
ares clip ares, 0, iclip
delayw (ares*0.998)+aping
kvol chnget "vol"
kanticlick madsr 0.01, 0, 1, 0.01
ares = ares * kanticlick * kvol
outs ares, ares
endin
</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
</CsScore>
</CsoundSynthesizer>