Cabbage Logo
Back to Cabbage Site

Noob question about instruments & toggling effects

Hey everyone, noob here

I am doing an effect plugin that has multiple effects that can be toggled on and off by buttons.
In order to do that, i am doing an instrument for each effect, and apply the ‘signal processing’ to the output if the button channel value is toggled on.

Example :

   a1,a2	ins
    kporttime	linseg	0,0.001,0.01
    kfold	portk	kfold,kporttime

    if kBitcrushButton==1 then
        a1	LoFi	a1,kbits*0.6,kfold
        a2	LoFi	a2,kbits*0.6,kfold
        a1	=	a1 * klevel
        a2	=	a2 * klevel
    endif        
    outs	a1,a2

I feel like my logic is wrong, because it seems too sketchy for a simple toggle of an effect.
Also, it creates an issue.
Because i have 1 instrument for each effect, i run them all in my CsScore like :

<CsScore>lo
    ;causes Csound to run for about 7000 years...
    f0 z
    f1 0 1024 10 1

    i2 0 [60*60*24*7] 
    i3 0 [60*60*24*7] 
    i4 0 [60*60*24*7] 
    i5 0 [60*60*24*7] 
    i6 0 [60*60*24*7] 
</CsScore>

And i think it’s multiplying the audio, because when i test my plugin in my Daw, it adds 12dB to the audio !

Thanks for reading me, I’d appreciate if someone could help me.

Nobody can answer that simple logic question ?

You have to give us some time. Users on this group span many different time zones. Don’t worry, you’ll always get a reply. In fact, I challenge you to find a single post to this group that didn’t receive a timely and prompt reply.

Seems like a perfectly good approach to me. I would go one further and put the if kBitCrushButton at the very top of the instrument so Csound doesn’t need to waste resources on calling portk or linseg if they are not needed.

Outputting signals from 5 instruments will result is the signals being summed. So you should scale them back. You can simply multiple the outputs by .2 in this case.

Another option would be to send all the outputs to an audio channel and then scale that single channel’s contents before outputting. For example:

instr 1
...
chnmix a1, "leftSignal"
chnmix a2, "rightSignal"
endin

instr 2
...
chnmix a1, "leftSignal"
chnmix a2, "rightSignal"
endin

instr 100 ; instrument that will read the channel data and output
kGain chnget "gain"
aLeft chnget "leftSignal"
aRight chnget "rightSignal"
outs aLeft*kGain, aRight*kGain
endin

In this way you an have on master gain control that will be applied quickly to all signals. Note you could also do this in each instrument too. It’s really a matter of personal preference. :wink:

That’s what I thought ! But chnmix-ing everything into a “leftSignal” and “rightSignal” and running all instruments, it produces a horrible high pitched sine sound!

That’s how i am doing it :

<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d 
</CsOptions>
<CsInstruments>
; Initialize the global variables. 
sr = 44100
ksmps = 64
nchnls = 2
0dbfs=1
massign	0,0

//This Times X Different Effects :
instr 2 ; Reverb
    kVerbButton chnget "verb_channel"
       
    kFdBack chnget "size"
    kFco chnget "fco"
        aInL inch 1
        aInR inch 2
        aOutL, aOutR reverbsc aInL, aInR, kFdBack, kFco
        if kVerbButton==0 then
          chnmix aInL, "leftSignal"
          chnmix aInR, "rightSignal"
        endif
        if kVerbButton==1 then
          chnmix aOutL, "leftSignal"
          chnmix aOutR, "rightSignal"
        endif          
endin

instr 99
   aLeft chnget "leftSignal"
   aRight chnget "rightSignal"
   outs aLeft, aRight
endin

</CsInstruments>
<CsScore>lo
    ;causes Csound to run for about 7000 years...
    f0 z
    f1 0 1024 10 1

    i2 0 [60*60*24*7] 
    i3 0 [60*60*24*7] 
    i4 0 [60*60*24*7] 
    i5 0 [60*60*24*7] 
    i6 0 [60*60*24*7] 

    i99 0 [60*60*24*7] 
</CsScore>

How is that ?

(Sorry i have been impatient haha :grimacing: )

My bad, we forgot to clear the channels at the end :wink:

instr 99
   aLeft chnget "leftSignal"
   aRight chnget "rightSignal"
   outs aLeft, aRight
   
   chnclear "leftSignal"
   chnclear "rightSignal"
endin

So I just have to clear the channels in the “Master” instrument 99 ? Because when i do that it sounds good but the signals still sum up

Yes, but don’t forget to apply some kind of scaling to the signals:

instr 99
   aLeft chnget "leftSignal"
   aRight chnget "rightSignal"
   outs aLeft*2, aRight*.2
   
   chnclear "leftSignal"
   chnclear "rightSignal"
endin

Careful, I think that should be:
outs aLeft*.2, aRight*.2

:exploding_head:

Sorry, I just got a chance to read the whole thread and think about it for a few minutes… first off welcome to the boards @nra … like @rorywalsh said, there are lots of helpful people here that answer all sorts of questions, I’ve learned a lot hanging around here over the years. But in the scheme of things, the Csound (and in turn, the Cabbage) community is fairly small… and is entirely volunteer.

Anyways on to the problem at hand… believe it or not, I’m actually working on something very similar to this myself!

The problem I saw with this solution is that all of the processing is done in parallel (hence why you have to rebalance for the gain), and that might be perfectly acceptable for your situation, but it didn’t suit my needs. For example, in this case I wanted my LoFi to then route as the input into the reverb.

This can be done by moving the processing for all of these into UDOs rather than instruments, and then having one instrument that calls al of the UDOs and feeds them into each other. Since all of the instruments are on full-time anyway, the only benefit I see to having them separate is “modularity” for future use… in which case, UDO is probably the way to go anyway!

The multi-fx I’m working on has UDOs for modulation, distortion, delay, and reverb. This example code isn’t perfect and I still need to do some trouble-shooting. I think I’m also summing the delay here and not adjusting when routing delay to reverb, but the idea was to allow the delay taps to optionally re-feed the reverb (that’s what the boolean “kOrder” value is for).

Each UDO reads it’s own widgets and toggles and decides what to do, and then one instrument calls them in turn. Essentially it routes like this:

  ; This sends all audio out to effects
  aSigL, aSigR FlexDist aInL, aInR
  aSigL, aSigR FlexMod aSigL, aSigR
; aSigL, aSigR FlexMod aInL, aInR

  ; ensure kOrder is binary
  kOrder = kOrder==1 ? 1 : 0

  ; send to del and rev, and route del to rev if enabled
  aDelL, aDelR FlexDel aSigL, aSigR
  aRevL, aRevR FlexRev aSigL+(aDelL*kOrder), aSigR+(aDelR*kOrder)
 
  ; This adds Dist+Chorus audio to Del+Rev audio
  aSigL += aDelL+aRevL
  aSigR += aDelR+aRevR

That might be overkill for what your goal is… but overkill and over-complication is one of my hobbies!

1 Like