# Primitive FM synth

**URL:** <https://forum.cabbageaudio.com/t/primitive-fm-synth/3185>\
**Category:** Cabbage recipes\
**Created:** [7 April 2022 11:33 UTC](https://forum.cabbageaudio.com/t/primitive-fm-synth/3185 "2022-04-07T11:33:04Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![spruitje](https://forum.cabbageaudio.com/letter_avatar_proxy/v4/letter/s/5fc32e/32.png) [@spruitje](https://forum.cabbageaudio.com/u/spruitje)\
**Post date:** [7 April 2022 11:33 UTC](https://forum.cabbageaudio.com/t/primitive-fm-synth/3185/1 "2022-04-07T11:33:05Z")

</div>

This is my first Cabbage synth. I like to share it with the forum (and with the World ;-)). Everybody may do with it as they please. Comments about possible improvements or anything else are welcome. I want to learn more about building useful and fun Cabbage instrument plugins, and learning by doing seems to be a pleasant way to do so. Here it is:

```
<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) 
rslider bounds(460, 300, 80, 80) channel("fintun") range(-0.1, 0.1, 0, 1, 0.001) colour(255, 0, 0, 255) text("Fine-tuning") 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"
  kFintun chnget "fintun"

  kRat = kFreqrat + kFintun
  aModulatorSin poscil p5, p4*kRat, giSin
  aModulatorSaw poscil p5, p4*kRat, giSaw
  aModulatorSqu poscil p5, p4*kRat, giSqu
  aModulatorTri poscil p5, p4*kRat, giTri
  aModulatorImp poscil p5, p4*kRat, 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>
```

---

<div class="post-metadata">

**Author:** ![rorywalsh](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/rorywalsh/32/165_2.png) [@rorywalsh](https://forum.cabbageaudio.com/u/rorywalsh)\
**Post date:** [7 April 2022 14:02 UTC](https://forum.cabbageaudio.com/t/primitive-fm-synth/3185/2 "2022-04-07T14:02:01Z")

</div>

Thanks for sharing. I’m always impressed by the range of sounds FM gives.

---

<div class="post-metadata">

**Author:** ![spruitje](https://forum.cabbageaudio.com/letter_avatar_proxy/v4/letter/s/5fc32e/32.png) [@spruitje](https://forum.cabbageaudio.com/u/spruitje)\
**Post date:** [8 April 2022 08:50 UTC](https://forum.cabbageaudio.com/t/primitive-fm-synth/3185/3 "2022-04-08T08:50:59Z")

</div>

This is the GUI:

 ![GUI](https://forum.cabbageaudio.com/uploads/default/original/2X/e/e68ddfd3c34422edc0183c1fb18c2e2b4a0d5ba7.png)

---

<div class="post-metadata">

**Author:** ![RZorn](https://forum.cabbageaudio.com/user_avatar/forum.cabbageaudio.com/rzorn/32/2611_2.png) [@RZorn](https://forum.cabbageaudio.com/u/RZorn)\
**Post date:** [9 April 2022 07:26 UTC](https://forum.cabbageaudio.com/t/primitive-fm-synth/3185/4 "2022-04-09T07:26:59Z")

</div>

Really nice. I am not working with FM normally and it is a great help to see the waveform and spectrum immediately showing the effect of the controls. Great instrument to learn and experiment!

---

<div class="post-metadata">

**Author:** ![spruitje](https://forum.cabbageaudio.com/letter_avatar_proxy/v4/letter/s/5fc32e/32.png) [@spruitje](https://forum.cabbageaudio.com/u/spruitje)\
**Post date:** [9 April 2022 10:22 UTC](https://forum.cabbageaudio.com/t/primitive-fm-synth/3185/5 "2022-04-09T10:22:42Z")

</div>

Thank you for your comment! Building the instrument was a great learning experience for me, and seeing others happily using it is a great motivation to build some more.
