( SynthDef(\prophet5style, { |out=0, freq=440, amp=0.5, detune=0, osc1Wave=0, osc2Wave=1, filterCutoff=600, filterResonance=0.5, attack=0.1, decay=1, sustain=0.7, release=0.3, lfoRate=0.5, lfoDepth=0.5, lfoFreq=1, lfoWave=1, filterModDepth=0.3| // Oscillators var osc1, osc2, lfo, env, filter, filteredSignal, drySignal; // Oscillator 1 & 2: Waveforms and detuning osc1 = Select.ar(osc1Wave, [SinOsc.ar(freq), Saw.ar(freq), Pulse.ar(freq, 0.5)]); osc2 = Select.ar(osc2Wave, [SinOsc.ar(freq + detune), Saw.ar(freq + detune), Pulse.ar(freq + detune, 0.5)]); // Envelope env = EnvGen.kr(Env.perc(attack, decay, sustain, release), doneAction: 2); // LFO for modulation (filter or other params) lfo = SinOsc.kr(lfoRate, 0, lfoDepth); // Filter // filter = osc1 + osc2; filter = BPF.ar(osc1 + osc2, filterCutoff, filterResonance); filteredSignal = filter * env; // Modulate filter with LFO filteredSignal = filteredSignal * (1 + lfo * filterModDepth); // Dry signal (unfiltered) drySignal = (osc1 + osc2) * env; // Output mixed signal Out.ar(out, (filteredSignal + drySignal).dup * amp); }).add; ) MIDIClient.init; MIDIIn.connectAll; x = Synth(\prophet5style); // Mapping MIDI CCs to synth parameters ( ~midiMap = { |num, val| var osc1Wave, osc2Wave, release, cutoff, resonance; // Conditional mappings for parameters osc1Wave = num == 1 ifTrue: { val.linlin(0, 127, 0, 2).round } ifFalse: { 0 }; osc2Wave = num == 2 ifTrue: { val.linlin(0, 127, 0, 2).round } ifFalse: { 0 }; release = num == 8 ifTrue: { val.linlin(0, 127, 0.01, 3) } ifFalse: { 0.3 }; cutoff = num == 74 ifTrue: { val.linlin(0, 127, 20, 2000) } ifFalse: { 1000 }; resonance = num == 71 ifTrue: { val.linlin(0, 127, 0, 1) } ifFalse: { 0.5 }; // Return a dictionary with mapped parameters ^( \osc1Wave -> osc1Wave, \osc2Wave -> osc2Wave, \release -> release, \cutoff -> cutoff, \resonance -> resonance ); }; ) // Use the midi map to update synth parameters MIDIIn.control = { |num, val| var mappedParams = ~midiMap.(num, val); Synth(\prophet5styleModular, mappedParams); };