Cabbage Logo
Back to Cabbage Site

Can't get 2 types of Synthesis to sound in the same plug-in

So basically I want an Additive synth and an FM synth in the same plugin. The idea is that when I want to use Add. I turn up it’s volume and when I want to use FM I turn up it’s vol. and turn down the Add. volume.
I have the global volume, ADSR and the additive synth working but when I add the FM synth in it will not sound. It works on it’s on in a separate project.The FM synth code isn’t completely my own which doesn’t help. I’m really really new to this so would really appreciate some guidance.

Here’s the code:

<Cabbage>
form caption("3 Synthesis") size(500, 500), colour(30, 30, 30), pluginID("def1")

groupbox bounds(10, 14, 130, 99) colour(0, 0, 0, 128) linethickness(0)
groupbox bounds(148, 14, 263, 99) colour(0, 0, 0, 128) linethickness(0)
groupbox bounds(8, 128, 466, 99) colour(0, 0, 0, 128) linethickness(0)
groupbox bounds(10, 238, 260, 99) colour(0, 0, 0, 128) linethickness(0)
groupbox bounds(278, 240, 196, 99) colour(0, 0, 0, 128) linethickness(0)

label bounds(202, 20, 150, 20), text("ADSR"), fontcolour(137, 131, 131, 255)
label bounds(10, 20, 130, 20), text("Main Volume"), fontcolour(137, 131, 131, 255)
label bounds(156, 134, 172, 20), text("Additive Synthesis"), fontcolour(137, 131, 131, 255)
label bounds(74, 244, 131, 20), text("FM Synthesis"), fontcolour(137, 131, 131, 255)


keyboard bounds(10, 352, 402, 92)

rslider bounds(46, 46, 60, 60) range(0, 1, 0.5, 1, 0.001) channel("MainVolume") , valuetextbox(1) textboxoutlinecolour(0, 0, 0, 0)

rslider bounds(156, 46, 60, 60), channel("Attack"), range(0, 1, 0.01, 1, 0.01), text("Attack")
rslider bounds(218, 46, 60, 60), channel("Decay"), range(0, 1, 0.1, 1, 0.01), text("Decay")
rslider bounds(280, 46, 60, 60), channel("Sustain"), range(0, 1, 0.2, 1, 0.01), text("Sustain")
rslider bounds(342, 46, 60, 60), channel("Release"), range(0, 1, 0.7, 1, 0.01), text("Release")

rslider bounds(14, 156, 60, 60), channel("AdditiveVolume"), range(0, 1, 0.5, 1, 0.001), text("Add. Volume"),  
rslider bounds(78, 156, 60, 60), channel("Partial2Strength"), range(0, 1, 0, 1, 0.001), text("Partial 2"),  
rslider bounds(144, 156, 60, 60), channel("Partial3Strength"), range(0, 1, 0, 1, 0.001), text("Partial 3"),  
rslider bounds(210, 156, 60, 60), channel("Partial4Strength"), range(0, 1, 0, 1, 0.001), text("Partial 4"),  
rslider bounds(276, 156, 60, 60), channel("Partial5Strength"), range(0, 1, 0, 1, 0.001), text("Partial 5"),  
rslider bounds(342, 156, 60, 60), channel("Partial6Strength"), range(0, 1, 0, 1, 0.001), text("Partial 6"),  
rslider bounds(408, 156, 60, 60), channel("Partial7Strength"), range(0, 1, 0, 1, 0.001), text("Partial 7"), 

rslider bounds(18, 268, 60, 60), channel("FMVolume"), range(0, 1, 0.5, 1, 0.001), text("FM Volume"),
rslider bounds(80, 268, 60, 60), channel("FreqMultiple"), range(0, 880, 100, 1, 0.001), text("Freq. Mul."),  
rslider bounds(142, 268, 60, 60), channel("ModMultiple"), range(0, 100, 5, 1, 0.001), text("Mod. Mul."),  
rslider bounds(204, 268, 60, 60), channel("Harmonicity"), range(0, 1, 0.5, 1, 0.001), text("Depth"),
</Cabbage>

<CsoundSynthesizer>
<CsOptions>
-+rtmidi=NULL -Ma --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>

<CsInstruments>
; Initialize the global variables. 
sr = 44100 ;Sample Rate
ksmps = 32 ; number of samples in each control cycle
nchnls = 2 ;# of channels
0dbfs = 1  ;Decibels betwen 0 and 1

;instrument will be triggered by keyboard widget
instr 1

gkMainVolume chnget "MainVolume"
kAddVol chnget "AdditiveVolume"

iAttack chnget "Attack"
iDecay chnget "Decay"
iSustain chnget "Sustain"
iRelease chnget "Release"
aEnv madsr iAttack, iDecay, iSustain, iRelease

aFundamentalSig poscil p5, p4, 1;high precision oscillator referencing a function table (GEN10 below) and the score
	
kP2 chnget "Partial2Strength" 
kP3 chnget "Partial3Strength"
kP4 chnget "Partial4Strength"
kP5 chnget "Partial5Strength"
kP6 chnget "Partial6Strength"
kP7 chnget "Partial7Strength"
		
aP2 poscil p5*kP2, p4*2, 1; frequencies for partials
aP3 poscil p5*kP3, p4*3, 1
aP4 poscil p5*kP4, p4*4, 1
aP5 poscil p5*kP5, p4*5, 1; frequencies for partials
aP6 poscil p5*kP6, p4*6, 1
aP7 poscil p5*kP7, p4*7, 1
	
aAddSig = (aFundamentalSig+aP2+aP3+aP4+aP5+aP6+aP7) * 0.07 * aEnv

outs aAddSig*kAddVol*gkMainVolume, aAddSig*kAddVol*gkMainVolume
endin

instr 2

kFMVol chnget "FMVolume"
 kAmp = p5
  kStartingFreq = p4 ; the Carrier Frequency 
  kCarrierFreqMultiply chnget "FreqMultiple"; change the Carrier Frequency by multiplying
  kModulatorFreqMultiply chnget "ModMultiple"; the Modulator Frequency as a multiple of the Carrier
  kHarmonicity chnget "Harmonicity"; also known as Modulation Index; the depth of the Modulator
  iFTable = 1

  aFMsig foscil kAmp, kStartingFreq, kCarrierFreqMultiply, kModulatorFreqMultiply,  kHarmonicity, iFTable
  outs aFMsig*gkMainVolume, aFMsig*gkMainVolume

endin

</CsInstruments>

<CsScore>
f0 z
f1 0 4096 10 1  ;Sine wave ;GEN10 function  
</CsScore>

</CsoundSynthesizer>

First point of order, welcome to the forum! Second point of order, can you remember to please format your code. I’ve gone ahead and reformatted your message so it’s easier to read :wink:

With regards to your message, by default, Csound can only trigger one instrument from a single midi channel. In the case of Cabage, this mean instr 1 will be triggered by messages send to MIDI channel 1. In your case, why not just include the code for instr 2 in instr 1. Problem solved.

If you don’t fancy that approach you can use the subinstr opcode[1], which will let you call one instrument from another one. Or you can put your instrument code into UDOs, and then call each of them from within your instrument 1 code block. Let us know if you get stuck :+1:

[1] I’ve noticed some CPU issues with subinstr so it might be worth doing a few tests before deciding to use it.

Thank you so much for your help Rory - apologies for not formatting my code. I did what you suggested and included the code for instr 2 in instr 1 and I now have audio output for both with separate Vol. control. The FM part isn’t sounding as it should but goes to show it’s hard to spot your own mistakes. Thanks you so much for your help!

P.s I’ve yet to use subinstr

If you can’t figure it out get back to us.

Hey Rory - Thanks again for your help - all working together smoothly now. I put a separate vol. control on each one which helps. Can you perhaps point me in the direction of a good, very simple reverb tutorial that I could look at? I’d like to have reverb on all three synths together if it’s simple enough to do :slight_smile:

It is simple to do. The best is to route the output from each of your synths to a single reverb instrument. Putting reverb into each synth will lead to more CPU usage so should be avoided. You could do something like this:

instr 1
   ;synth code
   outs a1, a2
   chnmix a1, "SynthOutL"
   chnmix a2, "SynthOutR"
endin

instr 2
   ;synth code
   outs a1, a2
   chnmix a1, "SynthOutL"
   chnmix a2, "SynthOutR"
endin

instr 3
   ;synth code
   outs a1, a2
   chnmix a1, "SynthOutL"
   chnmix a2, "SynthOutR"
endin

instr Reverb
   aL chnget "SynthOutL"
   aR chnget "SynthOutR"
   aRevL, aRevR reverbsc aL, aR, .6, 10000
   outs aRevL, aRevR
   chnclear "SynthOutL"
   chnclear "SynthOutL"
endin

Don’t forget to start the reverb instrument via the score:

i"Reverb" 0 z