hey,
yet another question about Pmono…
short: how do one use Pmono
and MIDI
?
long:
For composing with patterns ive exchanged everything based on Pbind
with Pmono
lately because most of the SynthDefs im writing have continous LFOs which should not be retriggered on every new note event and it gives me the additional opportunity to modulate the triggers in the SynthDef and it is also a better way to transform functions to SynthDefs in the process of writing instruments in SC imo. Im doing multichannel expansion with Ppar
and Pmono
via Patterns and chaining all the different parameters with Pdefn
and using external Control Envelopes or LFOs to modulate some of the parameters + additional Fx Synths using PbindFx
from https://github.com/dkmayer/miSCellaneous_lib with a custom function for data sharing between source and fx which all in all works quite well.
like this for example:
(
Pdefn(\durs, Pbind(\dur, [0.5, 0.667]));
Pdefn(\notes, Pbind(\freq, [68, 68]));
Pdefn(\slopes, Pbind(\slope, [-5, -15]));
Pdefn(\fltRanges, Pbind(\fltRange, [4000, 8000]));
Pdefn(\inharmonics, Pbind(\inharmonic, [0.05, 0.05]));
//Pdefn(\sustains, Pbind(\sustain, Pfunc { |ev| ev[\gainEnv].duration }));
Pdefn(\times, Pbind(\time, Pfunc { |ev| ev.use { ~sustain.value } / thisThread.clock.tempo }));
Pdef(\gabor,
Ppar({|i|
Pmono(\gabor,
\trig, Pwhite(0.5, 1.0),
\dur, Pkey(\dur).collect(_[i]),
\freq, Pkey(\freq).collect(_[i]),
\inharmonic, Pkey(\inharmonic).collect(_[i]),
\atk, 0.01,
\rel, 0.5,
\gainEnv, Pfunc{|e|
Env([0,0,1,0], [0, e.atk, e.rel], \lin)
},
\sustain, Pfunc { |ev| ev[\gainEnv].duration },
\time, Pkey(\time),
// Bandpass Filter
\slope, Pkey(\slope).collect(_[i]),
\fltRange, Pkey(\fltRange).collect(_[i]),
\cutoff, ~bus[\ctrl][i].asMap,
\fAtk, 0.5,
\fRel, 0.01,
\freqEnv, Pfunc{|e|
Env([0,1,2,1],[0, 0.5, 0.01], \lin)
},
\amp, 0.30,
\out, i,
\group, ~mainGrp,
\cleanupDelay, Pkey(\sustain),
\fxOrder, [1]
)
} !2) <> Pdefn(\notes) <> Pdefn(\durs) <> Pdefn(\fltRanges) <> Pdefn(\slopes) <> Pdefn(\times) <> Pdefn(\inharmonics);
);
Pdef(\comb_fx,
Ppar({|i|
Pbind(
\fx, \combL,
\mix, 0.5,
\amp, 1,
\delStereoRatio, 0.9,
\delHz, 0.05,
\delMin, 0.1,
\delMax, Pkey(\delMin) + 0.01,
\decay, 0.25,
\cleanupDelay, Pkey(\decay)
)
} !2)
);
Pdef(\gabor_fx, ~pbindFx.(\gabor, \comb_fx));
)
///////////Control Envelope///////////
(
Pdef(\ctrlEnv,
Ppar({|i|
Pmono(\ctrlEnvMono,
\trig, Pwhite(0.5, 1.0),
\dur, Pkey(\dur).collect(_[i]),
\ctrlEnv, Pfunc{|e|
Env([0.0001, 0.0125, 2, 0.0125], [0.0001, 0.3, 0.2], \exp)
},
\sustain, Pfunc { |ev| ev[\ctrlEnv].duration },
\time, Pkey(\time),
\out, ~bus[\ctrl][i],
\group, ~ctrlGrp,
)
} !2) <> Pdefn(\durs) <> Pdefn(\times);
);
)
(
Pdef(\gabor_ctrl,
Ptpar([
0, Pdef(\gabor),
0.0001, Pdef(\ctrlEnv)
])
).play(t, quant:1);
)
Pdef(\gabor_ctrl).stop;
///////////LFOs///////////
(
x = { Out.kr(~bus[\ctrl][0], LFTri.ar(1).linexp(-1, 1, 0.0125, 2)) }.play;
y = { Out.kr(~bus[\ctrl][1], LFTri.ar(2).linexp(-1, 1, 0.0125, 1)) }.play;
Pdef(\gabor).play(t, quant:1);
)
(
Pdef(\gabor).stop;
x.free;
y.free;
)
For a midi based composition im working on right now, i would like to record the rhythms for some Pdef(...(Ppar(...Pmono,...)!n);
combinations created by a L-System based fractional System ive build and a somehow not really widely used Pulse Divider Pattern class PSPdiv
from https://github.com/dkmayer/miSCellaneous_lib (yet some other issues) to the DAW. compose / arrange / edit everything in the DAW, send the MIDI Data back to SC for playing the SynthDefs and record the multichannel Audio in the DAW.
something like this (simplified version of my Pmono
approach):
(
var ixa, shaper;
ixa = { |freq, in, index|
var phase, waveform, sig;
phase = Phasor.ar(Impulse.ar(0), freq / SampleRate.ir, 0, 1);
waveform = (phase % 0.5 * 2pi).sin * (2 * (phase % 0.5 < 0.25) - 1);
waveform = waveform + (2 * (phase % 0.5 >= 0.25));
waveform = waveform + (2 * (phase >= 0.5));
sig = (waveform + (in * index)).fold2;
sig;
};
shaper = {|in, mix, amount|
var k, shaped;
k = 2 * amount / (1 - amount);
shaped = (1 + k) * in / (1 + (k * in.abs));
shaped = XFade2.ar(in, shaped, mix);
};
SynthDef(\bass, {
arg index=1, iScale=5;
var trig = \trig.tr(1);
var trigMod = LFNoise0.ar(8).round;
var sig, gainEnv, iEnv, mod;
var low, mid, high;
var lowFreq, highFreq;
iEnv = EnvGen.ar(Env([0, index, index * iScale, index], [0.0001, 5, 1], \lin), trig);
gainEnv = EnvGen.ar(Env([0, 1, 1, 0], [0, \atk.kr(0.2), \rel.kr(0.01)], \curve.kr(-5)), (trig * trigMod).abs);
mod = Sweep.ar(trig * trigMod, [51.913, 726.783]);
sig = ixa.(51.913, ((mod * 2pi) + (pi/3)).wrap(-pi, pi), iEnv);
sig = (sig * [2, 0.05]).mean;
lowFreq = 207.652;
highFreq = 1038.26;
low = LPF.ar(LPF.ar(sig, lowFreq), lowFreq);
sig = sig - low;
mid = LPF.ar(LPF.ar(sig, highFreq), highFreq);
high = sig - mid;
// lows
low = low + PitchShift.ar(low, 0.2, 2);
low = shaper.(low, 1, \amount.kr(0.2));
// highs
high = (high * \boost.kr(3).dbamp).tanh;
sig = low + mid + high;
sig = sig * gainEnv * \amp.kr(0.25);
sig = MidEQ.ar(sig, 13289.75, 0.7, 8);
sig = LeakDC.ar(sig);
sig = Limiter.ar(sig);
Out.ar(\out.kr(0), sig);
}).add;
)
///////////////////// chain Pdefn(\durs) to Pmono //////////////////////
(
Pdefn(\durs, Pbind(\dur, 0.2));
Pdef(\bass,
Ppar({ |i|
Pmono(\bass,
\dur, Pkey(\dur).poll,
\atk, 0.2,
\rel, 0.01,
\curve, -5,
\amount, 0.2,
\index, Pwhite(0.0,0.03),
\boost, 3,
\trig, Pwhite(0.5, 1.0, inf),
\amp, 0.15,
\out, i,
)
} !2 ) <> Pdefn(\durs)
);
)
Pdef(\bass).play;
Pdef(\bass).stop;
////////// PSPdiv ///////////////////////
(
~bass = { |durs|
Ppar({ |i|
Pmono(\bass,
\dur, Pseq(durs).poll,
\atk, 0.2,
\rel, 0.01,
\curve, -5,
\smooth, 0.5,
\index, Pwhite(0.0,0.03),
\boost, 3,
\trig, Pwhite(0.5, 1.0, inf),
\amp, 0.15,
\out, i,
)
} !2 )
};
~pulse = 1;
~div = 5;
~divBase = 1;
~divType = \seq;
Pdef(\rhythms,
PSPdiv(
PL(\pulse),
~bass,
PL(\div),
PL(\divBase),
PL(\divType)
),
);
)
Pdef(\rhythms).play;
Pdef(\rhythms).stop;
Ive set up everything with JACKRouter (audio) and loopMIDI (midi). I can receive and send multichannel MIDI Data from / to Ableton Live using the MIDISynth
class from this thread: Video Tutorials on MIDI based music production with Supercollider, jackd and DAW - #10 by droptableuser and also record multichannel audio in the DAW from SC.
But i dont know how i can use this setup based on Pmono
+ the MIDISynth
Class to record / playback MIDI in the DAW.
Its working with the MIDISynth
class setup playing and recording MIDI from a Pbind
. But whats about Pmono
and MIDI
?
Do i have to exchange everything again?
Pbind example with the MIDISynth
Class:
/////////////////////////////////////////////
// create a synth
(
SynthDef(\sine, {
var freq = \freq.kr(220);
var gate = \gate.kr(1);
var sig = SinOsc.ar(freq);
var aeg = Env.adsr(
\atk.kr(0.01),
\dec.kr(0.3),
\suslevel.kr(0.5),
\rel.kr(1),
curve:\curve.kr(-4)
).ar(gate:gate, doneAction:Done.freeSelf);
sig = Splay.ar(sig) * aeg * \amp.kr(0.3) * \vel.kr(1);
Out.ar(\out.kr(0), sig);
}).add
)
/////////////////////////////////////////////
// show ui
n = NdefMixer(Server.default)
ProxyMeter.addMixer(n)
/////////////////////////////////////////////
// connect midi
MIDIClient.init()
MIDIIn.connectAll()
/////////////////////////////////////////////
// midi synth setup (see class below)
MidiSynth(\m1).synth(\sine) // primes the ndef with specified synth
MidiSynth(\m1).note(noteChan:2).cc(ctrl:[\rel, \sat], ccNum:[0, 1], ccChan:0)
/////////////////////////////////////////////
// test with pattern
m = MIDIOut.newByName("IAC Driver", "Bus 1") // or whatever
(
Pdef(\midi,
Pbind(
\type, \midi,
\midiout, m,
\chan, 2,
\degree, Pseq([0, 1, 3, 5].pyramid(2), inf),
\scale, Scale.dorian,
\dur, 0.5,
\octave, Pseq([ 6, 5, 5, 6, 5, 5, 6, 5 ], inf),
\legato, 0.2,
\tempo, 1,
\amp, 1)
)
)
Pdef(\midi).play
Pdef(\midi).stop
some frustrations:
sorry for the long read and the possibility of confusion. I really cant find a way to have an universal approach of composing music using SC for creating initial ideas with patterns and playing back SynthDefs but arrange everything based on midi notes in the DAW (i dont want to use recorded audio in the composing process, imo it is very unflexible). any ideas?
thanks a lot merry xmas