Cabbage Logo
Back to Cabbage Site

Confusion with synths and reverb

hi there,
i know this may be a stupid question but im only new so forgive me haha
i just made a synth and i would like to have sliders for the room size and cut off point.
my problem arises when it could to sending the signal of my synth through the reverb
can anyone help me with this? all i need is to be able to place my synth through a simple reverb, and to be able to control them manually through the vst.
the easiest ,method you have will do find because its for a college assigment so i need something that i will be able to understand

many many thanks
kenan

Hi Kenan, welcome to Cabbage and the forums in general.

I’m not quite sure what trouble you’re running into… but I think I can make a pretty good guess. A common problem when getting started is understanding the idea of always on “global” instruments. Your synth instrument will stop processing as soon as the note stops, so if that same instrument is making the reverb, you’ll never hear it!

You could add length to each note using xtratim or a MIDI friendly envelope function like madsr to the event, and have the processing happen within the same instrument. It’s not a common solution, but I am pretty sure it would technically work and be pretty easy to implement. It has some serious drawbacks however, so I’d suggest a different method.

I’d suggest that you have two instruments in the .csd file, one that is controlled by MIDI and makes the synthesized sounds… then have it send it’s output to an audio channel using chnset or a global a-rate variable (for example gaReverbSend).

The second instrument should always be on and reads in the channel or global variable, processes it, and zeroes the variable out (this is important, don’t forget that step!). An easy way to have an always on instrument is like this in the score section:
i99 0 z

This would turn on instrument 99 as soon as processing begins, and leave it running for so long we can consider it “forever”.

Hopefully that helps, but if I guessed wrong and that’s not the problem you’re running into, feel free to go into more detail or even post code. Good luck!

Hi t_grey
Thanks for the warm welcome :slight_smile: i feel right at home, i hope youre keeping well and safe durning the unsettling times of the covid 19 virus. forgive me if it was a bit hard to understand im still getting use to what exactly im doing :slight_smile:
i remeber learning a bit about global effects.
ill look into impalmenting it into my code now and getting back to you.
is it possible to controll the parameters with pots on my synth ?
below i’ve left my code so you can see what exactly im doing and maybe give some feedback if you have anytime, im a super beginner and I will be presenting this code in class so I’m making sure everything i do, i understand :slight_smile:
many thanks,
Kenan

bounds(0, 0, 0, 0)
form caption(“Kenan’s Synth”) size(700, 400), colour(220, 255, 200), pluginid(“def1”)
keyboard bounds(2, 248, 685, 95)

groupbox bounds(8, 34, 307, 91), colour(255, 255, 255, 255), fontcolour(255, 0, 0, 255) outlinecolour(0, 0, 0, 255) corners(10)
groupbox bounds(407, 32, 174, 95), colour(255, 255, 255, 255), fontcolour(255, 0, 0, 255) outlinecolour(0, 0, 0, 255) corners(10)
groupbox bounds(570, 140, 105, 99), colour(255, 255, 255, 255), fontcolour(255, 0, 0, 255) outlinecolour(0, 0, 0, 255) corners(10)
groupbox bounds(364, 142, 151, 98), colour(255, 255, 255, 255), fontcolour(255, 0, 0, 255) outlinecolour(0, 0, 0, 255) corners(10)

groupbox bounds(166, 142, 165, 99), colour(255, 255, 255, 255), fontcolour(255, 0, 0, 255) outlinecolour(0, 0, 0, 255) corners(10)
groupbox bounds(6, 136, 106, 107), colour(255, 255, 255, 255), fontcolour(255, 0, 0, 255) outlinecolour(0, 0, 0, 255) corners(10)
rslider bounds(418, 52, 76, 72), channel(“size”), range(0, 1, 0.2, 1, 0.001), text(“Room Size”), colour(255, 255, 255, 255), textcolour(0, 0, 0, 255)
rslider bounds(496, 54, 74, 72), channel(“fco”), range(1, 22000, 10000, 1, 0.001), text(“Cut-Off Freq”), colour(255, 255, 255, 255), textcolour(0, 0, 0, 255)

rslider bounds(8, 56, 81, 63), channel(“att”), range(0, 1, 0.01, 1, 0.01), text(“Attack”) textcolour(0, 0, 0, 255)
rslider bounds(80, 56, 80, 63), channel(“dec”), range(0, 1, 0.5, 1, 0.01), text(“Decay”) textcolour(0, 0, 0, 255)
rslider bounds(146, 56, 85, 64), channel(“sus”), range(0, 1, 0.5, 1, 0.01), text(“Sustain”) textcolour(0, 0, 0, 255)
rslider bounds(226, 56, 82, 65), channel(“rel”), range(0, 1, 0.55, 1, 0.01), text(“Release”) textcolour(0, 0, 0, 255)
rslider bounds(584, 162, 77, 69), channel(“gain”), range(0, 1, 0.3, 1, 0.01), text(“Volume”) textcolour(0, 0, 0, 255)
rslider bounds(368, 167, 73, 70) range(500, 20000, 10000, 1, 0.001) text(“Cutoff”) channel(“Cutoff”) colour(207, 39, 39, 255) textcolour(0, 0, 0, 255)
rslider bounds(438, 166, 71, 67) range(0, 0.9, 0, 1, 0.001) text(“Peak”) channel(“Peak”) colour(200, 51, 51, 255) textcolour(0, 0, 0, 255)
rslider bounds(170, 164, 71, 67) range(0, 10, 0, 1, 0.001) text(“Rate”) channel(“Rate”) colour(54, 74, 185, 255) textcolour(0, 0, 0, 255)
rslider bounds(242, 164, 81, 67) range(0, 1, 0.1, 1, 0.001) text(“Intensity”) channel(“Intensity”) colour(45, 61, 221, 255) textcolour(0, 0, 0, 255)
checkbox bounds(16, 172, 93, 28) text(“LFO Mod”), channel(“EnableLFO”), radiogroup(“99”) value(1) colour:1(7, 33, 130, 255) fontcolour:0(0, 0, 0, 255) fontcolour:1(0, 0, 0, 255)
checkbox bounds(16, 203, 90, 29) text(“Pitch Mod”), channel(“Enablepitch”), radiogroup(“99”) colour:1(6, 50, 123, 255) fontcolour:0(0, 0, 0, 255) fontcolour:1(0, 0, 0, 255)
label bounds(402, 144, 80, 16) text(“Filter”) fontcolour(0, 0, 0, 255)
label bounds(206, 144, 80, 16) text(“LFO”) fontcolour(0, 0, 0, 255)
label bounds(20, 138, 80, 16) text(“Mods”) fontcolour(0, 0, 0, 255)
label bounds(120, 36, 80, 16) text(“ADSR”) fontcolour(0, 0, 0, 255)
label bounds(454, 34, 80, 16) text(“Reverb”) fontcolour(0, 0, 0, 255)

-n -d -+rtmidi=NULL -M0 -m0d --midi-key-cps=4 --midi-velocity-amp=5 ; Initialize the global variables. ksmps = 4 nchnls = 2 0dbfs = 1

;instrument will be triggered by keyboard widget
instr 1

iFreq =p4
iAtt chnget “att”
iDec chnget “dec”
iSus chnget “sus”
iRel chnget “rel”
kCutOff chnget “Cutoff”
kPeak chnget “Peak”
kIntense chnget “Intensity”
krate chnget “Rate”
kGain chnget “gain”
kFdBack chnget “size”
kFco chnget “fco”
kGain chnget “gain”

kEnv madsr iAtt, iDec, iSus, iRel

kLFO lfo kIntense, krate, 5

if chnget:k(“EnableLFO”) == 1 then
aVco vco2 p5kEnv, iFreq
aLp moogladder aVco, kCutOff
kLFO,kPeak

else
aVco vco2 p5kEnv, iFreqkLFO+iFreq
aLp moogladder aVco, kCutOff,kPeak

endif

outs aLpkGain, aLpkGain

endin

;causes Csound to run for about 7000 years... f0 z

We’re making the best of the situation, a good plus side is I’ve been getting to spend a lot of time working on my csound/cabbage projects lately! Hope everything is good on your end as well.

Absolutely! The interface GUI is completely separate from the instruments, you can read in any of the GUI variables into whatever instrument you need (or even multiple instruments if needed) with a simple chnget.

Can you edit your post to have the code pre-formatted? The HTML markup destroys a lot of the important tags like
</Cabbage>
and I think some mathematical operators are missing because of it too.

Btw, what I meant was, when you’re posting code you can just hightlight the code and hit the “Pre-format” button, it should do all the hard work!

Hey,
From your advice on using globals i’ve figured it out and its working quite well for me :slight_smile:
thank you so much for the help !!
all the best and hopefully we’ll chat again soon
Kenan

Also thanks for this tip!!! this is really useful :smiley:

I made a real simple example… I think everything is in order here, and hopefully it makes the concepts clear, but feel free to keep asking if not!

<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

; initialize a global variable to feed
gaRev init 0


;instrument will be triggered by keyboard widget
instr 1
kEnv madsr .1, .2, .6, .4
aOut vco2 p5, p4
outs aOut*kEnv, aOut*kEnv

; feed output into global variable
gaRev+=aOut*kEnv

endin

; always on reverb instrument reads and clears global variable
instr 99
iRevTime = 5
aRev reverb gaRev, iRevTime
gaRev=0

outs aRev, aRev
endin

</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
i99 0 z
</CsScore>
</CsoundSynthesizer>

Hey guys. If you don’t like the idea of using global variables you can also do this with named channels. Here’s the code @t_grey posted, but this time with named channels.

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
kEnv madsr .1, .2, .6, .4
aOut vco2 p5, p4
outs aOut*kEnv, aOut*kEnv

; feed output into named channel - using chnmix
chnmix aOut*kEnv, "synth1" 

endin

; always on reverb instrument reads and clears global variable
instr 99
iRevTime = 5
aIn chnget "synth1"
aRev reverb aIn, iRevTime
outs aRev, aRev
;clear channel
chnclear "synth1"
endin

</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
i99 0 z
</CsScore>
</CsoundSynthesizer>
1 Like

Thanks for the additional example Rory!

I’m used to doing this the old fashioned way with global variables, so I didn’t want to end up giving a bad example. Tho that makes me wonder, is using channel for this type of behavior now the preferred method for any reasons, especially performance?

I don’t think it’s makes any difference in terms of performance. I just prefer the cleanliness of the syntax :wink:

Funny, that’s the same reason I prefer the other method. :rofl:

There are two other ways you can do it, and they both have advantages over regular global variables or channels. One is an array of global variables. Initialize the array in the same place you would initialize any global variable, like this:

gaGlobalVarArray[] init 64 (for a 64-member array)

then you use each member of the array like any other global variable. They start counting at 0. So you have gaGlobalVarArray[0], gaGlobalVarArray[1], etc.

The second method, my own preferred way, is to use the zak opcodes. These work almost the same as global arrays but have their own set of opcodes to make using them easy.

The reason I like this method, is because they use numerical indexes to switch between n different global variables. This lets you do cool things like use p-fields to send different notes into different variables, for instance if you wanted to have several different reverb buses with different effects, and switch between them just by changing a p-field. For instance, putting the line
gaGlobalVarArray[p4] = aSig
into your instrument means just by changing p4 you are sending the output to a different location. Its like a modular patchbay.

Ah yes, I forgot all about the zak opcodes. I’ve used them in the past, but that was a long time ago. I’m not sure why I stopped using them, they did exactly what they were supposed to!