form caption("Powershape Synth") size(500, 180), colour(58, 110, 182), pluginid("def1")
rslider bounds(5,5,70,70), channel("att"), range(0.001,2,0.05,0.5), text("Att.")
rslider bounds(75,5,70,70), channel("dec"), range(0.001,2,1,0.5), text("Dec.")
rslider bounds(145,5,70,70), channel("rel"), range(0.001,2,0.1,0.5), text("Rel.")
rslider bounds(215,5,70,70), channel("amt"), range(1,5000,1000), text("Amount")
rslider bounds(285,5,70,70), channel("dtn"), range(0,50,1,0.5), text("Detune")
rslider bounds(355,5,70,70), channel("semi"), range(-24,0,-12,1,1), text("Semitone")
keyboard bounds(5,80, 490, 95)
-n -d -+rtmidi=NULL -M0 -m0d --midi-key-cps=4 --midi-velocity-amp=5
ksmps = 2 ; ksmps needs to be low if kShape will be changing quickly
nchnls = 2
0dbfs = 1
giScl ftgen 0,0,128,-5,500,96,0.01,32,0.00001 ; keyboard scaling. MIDI notes are mapped to values in this table
instr 1
; shape amount attack and release times
iAtt chnget "att"
iDec chnget "dec"
iRel chnget "rel"
iAmt chnget "amt"
kDtn chnget "dtn"
kSemi chnget "semi"
; read MIDI note number
iNum notnum
; read a keyboard scaling value. High numbers greater than 1 for low notes, low numbers close to zero
iScl table iNum, giScl
; envelope peak is dictated by velcity and and keyboard scaling value
kShape expseg 1, iAtt, 1+(iAmt*p5^3*iScl), iDec, 1, 1, 1
; create two oscillators. NB amplitude must be 1
a1 poscil 1, p4*cent(kDtn)
a2 poscil 1, p4*cent(-kDtn)*semitone(kSemi)
; powershape both oscillators
a1 powershape a1, kShape
a2 powershape a2, kShape
; amplitude envelope
aEnv expsegr 1, iRel, 0.001
aMix = (a1 + a2) * aEnv * p5 * 0.5
outs aMix, aMix
endin
f0 z