Sorry for my late input into a thread that bears my name.
I think you spotted that it’s best if the amplitude of the input oscillator is a constant 1 for
powershape otherwise the sound will disappear if shape amount is high. You can apply an amplitude envelope after the powershaping.
Below is my own quick version of a synth using this opcode.
PowershapeSynth.csd (1.9 KB)
Aliasing is indeed a problem as higher notes are played. My solution here was to use keyboard scaling to suppress the shaping amount as higher and higher notes are played.
If shape amount changes quickly - e.g. by using an envelope as I am doing here - then
ksmps will need to be low to prevent quantisation artefacts. A better solution would be to place powershape in a UDO with its own local
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
; 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
; 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