Analog Oscillators for SuperDirt / TidalCycles

SynthDef Factory + Batch Instantiation (Analog-modeling)

(
~makeAnalogDirtSynth = { |name, waveFunc|
	SynthDef(name, { |out, sustain=1, pan, accelerate, freq=440, speed=1, gain=1, decay=0,
        coarse=0, fine=0, width=0.5, detune=0, harmonic=1, sync=1, phaseOffset=0, phaseRand=0|

        var env, baseFreq, syncFreq, startPhase, phase, sig, trig;

        env = EnvGen.ar(Env.pairs([[0,0],[0.05,1],[0.2,1-decay],[0.95,1-decay],[1,0]], -3), timeScale:sustain, doneAction: Done.freeSelf);

        baseFreq = ((harmonic > 0) * (freq * DirtFreqScale.kr(speed, accelerate, sustain) - 1) + 1);
        baseFreq = baseFreq * harmonic * ((coarse + (fine * 0.01)).midiratio) + detune;
        baseFreq = baseFreq.clip(20, 20000);

        syncFreq = baseFreq * sync.max(1);
		
		trig = Impulse.kr(0);
		startPhase = (phaseOffset + Rand(0, phaseRand)).wrap(0, 1);
		phase = Phasor.ar(trig, syncFreq * SampleDur.ir, 0, 1, resetPos: startPhase);

        sig = waveFunc.value(phase, width.clip(0.001, 0.999));

        Out.ar(out, DirtPan.ar(sig * gain, ~dirt.numChannels, pan, env));
    }).add;
};

[
    \sine,   { |p|      (p * 2pi).sin },
    \cosine, { |p|      ((p * 2pi) + 0.5pi).sin },
    \saw,    { |p|      (p * 2) - 1 },
    \isaw,   { |p|      1 - (p * 2) },
    \sq,     { |p, w|   (p - w).sign },
    \tri,    { |p, w|
        var rising = p / w;
        var falling = (1 - p) / (1 - w);
        (p <.ar w).if(rising, falling) * 2 - 1;
    }
].pairsDo { |name, func| ~makeAnalogDirtSynth.value(name, func) };
)

Variables

-- Analog Synth Parameters
let coarse = pF "coarse"
    fine = pF "fine"
    width = pF "width"
    sync = pF "sync"
    harmonic = pF "harmonic"
    phaseOffset = pF "phaseOffset"
    phaseRand = pF "phaseRand"

Usage

d1 $ n "0"
   # s "<sine cosine saw isaw sq tri>"

d1 $ n "0*4"
   # sound "<sq tri>"
   # width "0.01 0.25 0.5 0.99"

d1 $ n "0"
   # sound "sq"
   # phaseOffset "<0.1 0.5 0.9>"

d1 $ n "0"
   # sound "sq"
   # phaseRand "0.5"

d1 $ n "0"
   # s "sq"
   # coarse "<-12 -6 0 6 12>"
   # fine "<-100 0 100>"

d1 $ n "0"
   # s "sine"
   # harmonic "2"

d1 $ n "0"
   # s "sine"
   # sync "4"

d1 $ n "0"
   # s "sine"
   # detune "159"
1 Like