Cabbage Logo
Back to Cabbage Site

First primitive instrument

<Cabbage>
form caption("Primitive FM-synth") size(400, 300), guiMode("queue"), pluginId("def1")
keyboard bounds(12, 198, 381, 95)
rslider bounds(28, 16, 80, 80)   channel("att") range(0.001, 0.25, 0.1, 1, 0.001)  colour(255, 0, 0, 255)  text("Attack")  textColour(255, 245, 0, 255)
rslider bounds(116, 16, 80, 80)  channel("dec") range(0.001, 0.25, 0.1, 1, 0.001)  colour(255, 0, 0, 255)  text("Decay")   textColour(255, 245, 0, 255)
rslider bounds(212, 16, 80, 80)  channel("sus") range(0, 1, 0.7, 1, 0.001)         colour(255, 0, 0, 255)  text("Sustain") textColour(255, 245, 0, 255)
rslider bounds(304, 18, 80, 80)  channel("rel") range(0, 1, 0.1, 1, 0.001)         colour(255, 0, 0, 255)  text("Release") textColour(255, 245, 0, 255)
rslider bounds(28, 102, 80, 80)  channel("ampcar")  range(0, 1, 0.5, 1, 0.001)     colour(255, 0, 0, 255) text("Volume")     textColour(255, 255, 0, 255)
rslider bounds(114, 104, 80, 80) channel("ampmod")  range(0, 1, 0.5, 1, 0.001)     colour(255, 0, 0, 255) text("Amp of mod") textColour(255, 255, 0, 255)
rslider bounds(212, 104, 80, 80) channel("modind")  range(0, 1000, 500, 1, 0.001)  colour(255, 0, 0, 255) text("Mod index")  textColour(255, 255, 0, 255)
rslider bounds(304, 104, 80, 80) channel("freqrat") range(0, 5, 1, 1, 0.001)       colour(255, 0, 0, 255) text("Freq ratio") textColour(255, 255, 0, 255) 
</Cabbage>

<CsoundSynthesizer>

<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>

<CsInstruments>

sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1

instr 1

  iAtt chnget "att"
  iDec chnget "dec"
  iSus chnget "sus"
  iRel chnget "rel"

  iAmpc chnget "ampcar"
  iAmpm chnget "ampmod"
  iModi chnget "modind"
  iFrat chnget "freqrat"

  kres1 madsr iAtt, iDec, iSus, iRel
  aModulator poscil p5, p4*iFrat
  kres madsr iAtt, iDec, iSus, iRel
  aCarrier poscil p5, kres*(p4 + iModi*(iAmpm*kres1*aModulator))

  out kres*iAmpc*aCarrier, kres*iAmpc*aCarrier

endin

</CsInstruments>

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

</CsoundSynthesizer>

My very first primitive instrument. Any comments on how to improve it are welcome.

Nice. Have you considering making iAmpc, iAmmpm, iModi and iFrat k-rate so they can be changed over time?

Thank you. I have changed it now.

Can I change the wave form of the poscil opcode? I tried some values for “ifn” but am getting errors. The Manual says this:

ifn – (optional) function table number. This defaults to -1 which indicates a sinewave.

You can. You just need to define the table first.

Thanks! :slightly_smiling_face:

After some searching I found an explanation in EXAMPLE 03D04_Standard_waveforms_with_GEN10.csd on: https://flossmanual.csound.com/csound-language/function-tables

1 Like

I’m trying to add an oscilloscope to my synth and found something strange when attempting to do so. Apparently the scope works or not depending on where you place “–displays” in the line with CsOptions:


Is this a bug?

Sorry, I misread your first post. The problem is in the second line you have disabled displays using -d. If you remove that from the start of the second line it should work Ok.

Here is the current state of my program wherein I noticed the strange behavior:

<Cabbage>
form caption("Primitive FM-synth") size(600, 600), guiMode("queue"), pluginId("def1")

signaldisplay bounds(4, 6, 500, 300), colour("lime") displayType("waveform"), signalVariable("aOutput")

keyboard bounds(2, 525, 588, 75)

rslider bounds(100, 256, 80, 80)  channel("att")    range(0.001, 0.25, 0.1, 1, 0.001)  colour(255, 0, 0, 255) text("Attack")  textColour(255, 245, 0, 255)
rslider bounds(188, 256, 80, 80)  channel("dec")    range(0.001, 0.25, 0.1, 1, 0.001)  colour(255, 0, 0, 255) text("Decay")   textColour(255, 245, 0, 255)
rslider bounds(274, 256, 80, 80)  channel("sus")    range(0, 1, 0.7, 1, 0.001)         colour(255, 0, 0, 255) text("Sustain") textColour(255, 245, 0, 255)
rslider bounds(362, 256, 80, 80)  channel("rel")    range(0, 1, 0.1, 1, 0.001)         colour(255, 0, 0, 255) text("Release") textColour(255, 245, 0, 255)
rslider bounds(10, 256, 80, 80)   channel("ampcar") range(0, 1, 0.5, 1, 0.001)         colour(255, 0, 0, 255) text("Volume")  textColour(255, 255, 0, 255)

rslider bounds(486, 256, 80, 80)   channel("modind")  range(0, 1000, 500, 1, 0.001) colour(255, 0, 0, 255) text("Mod index")  textColour(255, 255, 0, 255)
rslider bounds(484, 358, 80, 80) channel("freqrat") range(0, 5, 1, 1, 0.001)      colour(255, 0, 0, 255) text("Freq ratio") textColour(255, 255, 0, 255) 

rslider bounds(10, 436, 80, 80)  channel("msin") range(0, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Sine")     textColour(255, 255, 0, 255) 
rslider bounds(100, 436, 80, 80) channel("msaw") range(0, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Saw")      textColour(255, 255, 0, 255)
rslider bounds(188, 436, 80, 80) channel("msqu") range(0, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Square")   textColour(255, 255, 0, 255)
rslider bounds(270, 436, 80, 80) channel("mtri") range(0, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Triangle") textColour(255, 255, 0, 255)
rslider bounds(362, 436, 80, 80) channel("mimp") range(0, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Impulse")  textColour(255, 255, 0, 255)
label bounds(412, 114, 80, 16)   channel("label10013") text("Modulator") colour(255, 255, 255, 255) fontColour(255, 0, 0, 255)

rslider bounds(8, 346, 80, 80)  channel("sin") range(0, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Sine")     textColour(255, 255, 0, 255) 
rslider bounds(100, 346, 80, 80) channel("saw") range(0, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Saw")      textColour(255, 255, 0, 255)
rslider bounds(188, 348, 80, 80) channel("squ") range(0, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Square")   textColour(255, 255, 0, 255)
rslider bounds(274, 346, 80, 80) channel("tri") range(0, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Triangle") textColour(255, 255, 0, 255)
rslider bounds(366, 348, 82, 80) channel("imp") range(0, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Impulse")  textColour(255, 255, 0, 255)
label bounds(412, 162, 80, 16)  channel("label10013") text("Carrier") colour(255, 255, 255, 128) fontColour(255, 0, 0, 255)

</Cabbage>

<CsoundSynthesizer>

<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d --midi-key-cps=4 --midi-velocity-amp=5 --displays
</CsOptions>

<CsInstruments>

sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1

instr 1

  giSin ftgen 0, 0, 2^10, 10, 1
  giSaw ftgen 0, 0, 2^10, 10, 1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9
  giSqu ftgen 0, 0, 2^10, 10, 1, 0, 1/3, 0, 1/5, 0, 1/7, 0, 1/9
  giTri ftgen 0, 0, 2^10, 10, 1, 0, -1/9, 0, 1/25, 0, -1/49, 0, 1/81
  giImp ftgen 0, 0, 2^10, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1

  iAtt chnget "att"
  iDec chnget "dec"
  iSus chnget "sus"
  iRel chnget "rel"

  kAmpc chnget "ampcar"
  kAmpm chnget "ampmod"
  kModi chnget "modind"
  kFrat chnget "freqrat"
  
  
  kMSin chnget "msin"
  kMSaw chnget "msaw"
  kMSqu chnget "msqu"
  kMTri chnget "mtri"
  kMImp chnget "mimp"
  
  
  kSin chnget "sin"
  kSaw chnget "saw"
  kSqu chnget "squ"
  kTri chnget "tri"
  kImp chnget "imp"
    
  kres1 madsr iAtt, iDec, iSus, iRel
  aModulatorSin poscil p5, p4*kFrat, giSin
  aModulatorSaw poscil p5, p4*kFrat, giSaw
  aModulatorSqu poscil p5, p4*kFrat, giSqu
  aModulatorTri poscil p5, p4*kFrat, giTri
  aModulatorImp poscil p5, p4*kFrat, giImp
  kres madsr iAtt, iDec, iSus, iRel
  aModulator = kMSin*aModulatorSin + kMSaw*aModulatorSaw + kMSqu*aModulatorSqu + kMTri*aModulatorTri + kMImp*aModulatorImp
  aCarSin poscil p5, kres*(p4 + kModi*(kres1*aModulator)), giSin
  
  kres1 madsr iAtt, iDec, iSus, iRel
  aModulatorSin poscil p5, p4*kFrat, giSin
  aModulatorSaw poscil p5, p4*kFrat, giSaw
  aModulatorSqu poscil p5, p4*kFrat, giSqu
  aModulatorTri poscil p5, p4*kFrat, giTri
  aModulatorImp poscil p5, p4*kFrat, giImp
  kres madsr iAtt, iDec, iSus, iRel
  aModulator = kMSin*aModulatorSin + kMSaw*aModulatorSaw + kMSqu*aModulatorSqu + kMTri*aModulatorTri + kMImp*aModulatorImp
  aCarSaw poscil p5, kres*(p4 + kModi*(kres1*aModulator)), giSaw 
  
  kres1 madsr iAtt, iDec, iSus, iRel
  aModulatorSin poscil p5, p4*kFrat, giSin
  aModulatorSaw poscil p5, p4*kFrat, giSaw
  aModulatorSqu poscil p5, p4*kFrat, giSqu
  aModulatorTri poscil p5, p4*kFrat, giTri
  aModulatorImp poscil p5, p4*kFrat, giImp
  kres madsr iAtt, iDec, iSus, iRel
  aModulator = kMSin*aModulatorSin + kMSaw*aModulatorSaw + kMSqu*aModulatorSqu + kMTri*aModulatorTri + kMImp*aModulatorImp 
  aCarSqu poscil p5, kres*(p4 + kModi*(kres1*aModulator)), giSqu
  
  kres1 madsr iAtt, iDec, iSus, iRel
  aModulatorSin poscil p5, p4*kFrat, giSin
  aModulatorSaw poscil p5, p4*kFrat, giSaw
  aModulatorSqu poscil p5, p4*kFrat, giSqu
  aModulatorTri poscil p5, p4*kFrat, giTri
  aModulatorImp poscil p5, p4*kFrat, giImp
  kres madsr iAtt, iDec, iSus, iRel
  aModulator = kMSin*aModulatorSin + kMSaw*aModulatorSaw + kMSqu*aModulatorSqu + kMTri*aModulatorTri + kMImp*aModulatorImp
  aCarTri poscil p5, kres*(p4 + kModi*(kAmpm*kres1*aModulator)), giTri
  
  kres1 madsr iAtt, iDec, iSus, iRel
  aModulatorSin poscil p5, p4*kFrat, giSin
  aModulatorSaw poscil p5, p4*kFrat, giSaw
  aModulatorSqu poscil p5, p4*kFrat, giSqu
  aModulatorTri poscil p5, p4*kFrat, giTri
  aModulatorImp poscil p5, p4*kFrat, giImp
  kres madsr iAtt, iDec, iSus, iRel
  aModulator = kMSin*aModulatorSin + kMSaw*aModulatorSaw + kMSqu*aModulatorSqu + kMTri*aModulatorTri + kMImp*aModulatorImp
  aCarImp poscil p5, kres*(p4 + kModi*(kres1*aModulator)), giImp
  aOutput = kres*kAmpc*(kSin*aCarSin + kSaw*aCarSaw + kSqu*aCarSqu + kTri*aCarTri + kImp*aCarImp) 
  
  out aOutput, aOutput
  
display aOutput, .1, 1 


endin





</CsInstruments>

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

</CsoundSynthesizer>

Remove the -d and it should work.

Sorry but removing the “-d” doesn’t help, and placing “–displays” at the end of the line does. I have no idea why this is happening…

-d removes all displays. So if that comes after the --display then it will stop the display from showing. At least that’s my take on it.

When I put “-d” after “–displays” then indeed the display disappears. But I found another problem with my code. It looks like the expression “-m0d” in the CsOptions that is causing the problem. After deleting “-m0d” the problem seems to be gone. I don’t know what “-m0d” means or where I got it from.

This disables certain messages from being printed. In Csound 6.16 this changes slightly be suppressing all output messages, which is not ideal. The situation has been fixed in 6.17. When you create a new instrument in Cabbage, it is automatically added to stop 100s of Csound output messages from bombarding the output console.

When I put -m0d before --displays then the display appears but not when -m0d comes after --displays. So I have now put -m0d before --displays and now all is well.

1 Like

I have made an improved version of my primitive synth:

<Cabbage>
form caption("Primitive FM-synth") size(800, 500), guiMode("queue"), pluginId("def1")

signaldisplay bounds(590, 30, 170, 140),   colour("lime"), displayType("waveform"),     signalVariable("aOutput")
signaldisplay bounds(590, 240, 170, 140),  colour("lime"), displayType("spectroscope"), signalVariable("aOutput")

keyboard bounds(20, 405, 750, 75)

rslider bounds(18, 30, 80, 80)   channel("vol")  range(0, 1, 0.5, 1, 0.001)          colour(255, 0, 0, 255) text("Volume")  textColour(255, 255, 0, 255)
rslider bounds(100, 30, 80, 80)  channel("att")  range(0.001, 0.25, 0.02, 1, 0.001)  colour(255, 0, 0, 255) text("Attack")  textColour(255, 245, 0, 255)
rslider bounds(180, 30, 80, 80)  channel("dec")  range(0.001, 0.25, 0.01, 1, 0.01)   colour(255, 0, 0, 255) text("Decay")   textColour(255, 245, 0, 255)
rslider bounds(260, 30, 80, 80)  channel("sus")  range(0, 1, 0.7, 1, 0.001)          colour(255, 0, 0, 255) text("Sustain") textColour(255, 245, 0, 255)
rslider bounds(340, 30, 80, 80)  channel("rel")  range(0, 1, 0.1, 1, 0.001)          colour(255, 0, 0, 255) text("Release") textColour(255, 245, 0, 255)

label bounds(20, 135, 400, 15) text("Carrier") colour(255, 255, 255, 225) fontColour(255, 0, 0, 255)

rslider bounds(20, 165, 80, 80)  channel("csin") range(0.001, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Sine")     textColour(255, 255, 0, 255) 
rslider bounds(100, 165, 80, 80) channel("csaw") range(0.001, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Saw")      textColour(255, 255, 0, 255)
rslider bounds(180, 165, 80, 80) channel("csqu") range(0.001, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Square")   textColour(255, 255, 0, 255)
rslider bounds(260, 165, 80, 80) channel("ctri") range(0.001, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Triangle") textColour(255, 255, 0, 255)
rslider bounds(340, 165, 80, 80) channel("cimp") range(0.001, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Impulse")  textColour(255, 255, 0, 255)

label bounds(20, 265, 400, 15) text("Modulator") colour(255, 255, 255, 255) fontColour(255, 0, 0, 255)

rslider bounds(20, 295, 80, 80)  channel("msin") range(0.001, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Sine")     textColour(255, 255, 0, 255) 
rslider bounds(100, 295, 80, 80) channel("msaw") range(0.001, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Saw")      textColour(255, 255, 0, 255)
rslider bounds(180, 295, 80, 80) channel("msqu") range(0.001, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Square")   textColour(255, 255, 0, 255)
rslider bounds(260, 295, 80, 80) channel("mtri") range(0.001, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Triangle") textColour(255, 255, 0, 255)
rslider bounds(340, 295, 80, 80) channel("mimp") range(0.001, 1, 0.2, 1, 0.001) colour(255, 0, 0, 255) text("Impulse")  textColour(255, 255, 0, 255)

rslider bounds(460, 30, 80, 80)  channel("modind")  range(0, 1000, 500, 1, 0.001) colour(255, 0, 0, 255) text("Mod. index")  textColour(255, 255, 0, 255)
rslider bounds(460, 165, 80, 80) channel("freqrat") range(0, 5, 1, 1, 0.001)      colour(255, 0, 0, 255) text("Freq. ratio") textColour(255, 255, 0, 255) 
</Cabbage>


<CsoundSynthesizer>

<CsOptions>
-m0d -n -+rtmidi=NULL -M0 --midi-key-cps=4 --midi-velocity-amp=5 --displays 
</CsOptions>

<CsInstruments>

sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1

instr 1
  giSin ftgen 0, 0, 2^10, 10, 1
  giSaw ftgen 0, 0, 2^10, 10, 1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9
  giSqu ftgen 0, 0, 2^10, 10, 1, 0, 1/3, 0, 1/5, 0, 1/7, 0, 1/9
  giTri ftgen 0, 0, 2^10, 10, 1, 0, -1/9, 0, 1/25, 0, -1/49, 0, 1/81
  giImp ftgen 0, 0, 2^10, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1

  kVol chnget "vol"
  iAtt chnget "att"
  iDec chnget "dec"
  iSus chnget "sus"
  iRel chnget "rel"
      
  kCSin chnget "csin"
  kCSaw chnget "csaw"
  kCSqu chnget "csqu"
  kCTri chnget "ctri"
  kCImp chnget "cimp"
  
  kMSin chnget "msin"
  kMSaw chnget "msaw"
  kMSqu chnget "msqu"
  kMTri chnget "mtri"
  kMImp chnget "mimp"

  kModind  chnget "modind"
  kFreqrat chnget "freqrat"

  aModulatorSin poscil p5, p4*kFreqrat, giSin
  aModulatorSaw poscil p5, p4*kFreqrat, giSaw
  aModulatorSqu poscil p5, p4*kFreqrat, giSqu
  aModulatorTri poscil p5, p4*kFreqrat, giTri
  aModulatorImp poscil p5, p4*kFreqrat, giImp
  
  kSumM = kMSin + kMSaw + kMSqu + kMTri + kMImp
  aModulator = (kMSin*aModulatorSin + kMSaw*aModulatorSaw + kMSqu*aModulatorSqu + kMTri*aModulatorTri + kMImp*aModulatorImp)/kSumM

  aCarrierSin poscil p5, p4 + kModind*aModulator, giSin
  aCarrierSaw poscil p5, p4 + kModind*aModulator, giSaw 
  aCarrierSqu poscil p5, p4 + kModind*aModulator, giSqu
  aCarrierTri poscil p5, p4 + kModind*aModulator, giTri
  aCarrierImp poscil p5, p4 + kModind*aModulator, giImp
 
  kADSR madsr iAtt, iDec, iSus, iRel
  kSumC =  kCSin + kCSaw + kCSqu + kCTri + kCImp
  aOutput = kADSR*kVol*(kCSin*aCarrierSin + kCSaw*aCarrierSaw + kCSqu*aCarrierSqu + kCTri*aCarrierTri + kCImp*aCarrierImp)/kSumC 

  out aOutput, aOutput
  display aOutput, .1, 1 
  dispfft aOutput, .1, 1024
endin

</CsInstruments>

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

</CsoundSynthesizer>

Is there any special place to present attempted Cabbage plugins?

There is a Cabbage recipes category. You could share it there :+1:

1 Like