Skip to content

Instantly share code, notes, and snippets.

@nasedil
Last active May 2, 2023 18:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nasedil/0d46f5b1864bc3a810419b314c09fc25 to your computer and use it in GitHub Desktop.
Save nasedil/0d46f5b1864bc3a810419b314c09fc25 to your computer and use it in GitHub Desktop.
cleanup and add some comments
(
// marimba-style synthesizer
~synthGen = {|n=25, prefix=\fokyxiqa, numHarm = 13|
var synthNames = Array(n);
n.do{|i|
var synthName = (prefix ++ i.asString).asSymbol;
synthNames = synthNames.add(synthName);
SynthDef(synthName, {|
freq = 440,
attack = 0.01,
release = 1.0,
distort = 0.0,
detuneMax=0.15
lowHarm = 2,
highHarm = 41,
harmMul = 1.3,
harmLen = 1.0,
amp = 1,
pan = 0,
out = 0
|
var sig;
var partial, detune, distortMul, ampEnv;
detune = Rand(detuneMax.neg, detuneMax).midiratio;
sig = SinOsc.ar(freq * detune, 2pi.rand);
ampEnv = EnvGen.kr(Env.perc(attack, release), doneAction: 2);
sig = sig * ampEnv;
numHarm.do({
var pfact = IRand(lowHarm, highHarm);
detune = Rand(detuneMax.neg, detuneMax).midiratio;
partial = SinOsc.ar(freq * detune * pfact, 2pi.rand);
partial = partial * EnvGen.kr(
Env.perc(attack, release),
levelScale: pfact.reciprocal * harmMul.rand,
timeScale: harmLen.rand * pfact.reciprocal,
);
sig = sig + partial;
});
distortMul = 1 + (distort * ampEnv);
sig = (sig * distortMul).clip(-2, 2);
sig = HPF.ar(sig, 20);
sig = LPF.ar(sig, 16000);
sig = Pan2.ar(sig, pan, amp);
Out.ar(out, sig);
}).add;
};
synthNames;
};
// reverb generator
~reverbGen = {|n=15, prefix=\fokyxiqa|
var synthNames = Array(n);
n.do{|i|
var synthName = (prefix ++ i.asString).asSymbol;
synthNames = synthNames.add(synthName);
SynthDef(synthName, {|
in,
mix = 1,
out = 0
|
var sig = In.ar(in, 2);
sig = FreeVerb2.ar(
sig[0], sig[1],
mix: mix,
room: 1.0.rand,
damp: 1.0.rand,
);
Out.ar(out, sig);
}).add;
};
synthNames;
}
)
(
// make reverb and synth defs
~synthNames = ~synthGen.value(130);
~reverbNames = ~reverbGen.value(130, prefix: \jumisevu);
)
(
// create reverbs and busses
~reverbSynths = Array(~reverbNames.size);
~reverbBusses = Array(~reverbNames.size);
~reverbNames.do{|item|
~reverbBusses = ~reverbBusses.add(Bus.audio(s, 2));
~reverbSynths = ~reverbSynths.add(Synth(item, [
in: ~reverbBusses.last,
out: 0,
], s, \addToTail));
};
)
(
// setup reverb parameters
~reverbSynths.do{|item|
item.set(\mix, 0.4.rand);
};
)
(
// create tuning
~tuning = Tuning.et(13);
~scale = Scale.new(#[0, 3, 5, 8, 10], 13, ~tuning);
)
(
// play some music
Pdef(\hihymive, Pbind(*[
out: Pshuf(~reverbBusses.wrapExtend(9), inf),
instrument: Pshuf(~synthNames.wrapExtend(9), inf),
db: -9,
pan: Pwhite(-0.5, 0.5),
dur: 1/3,
attack: Pwhite(0.01, 0.02),
release: Pwhite(0.8, 1.0),
scale: Pn(~scale),
octave: 2,
degree: Pn(Pshuf((0..8), 3), inf),
])).quant_(3).play;
Pdef(\pafajyry, Pbind(*[
out: Pshuf(~reverbBusses.wrapExtend(15), inf),
instrument: Pshuf(~synthNames.wrapExtend(15), inf),
db: -19,
pan: Pwhite(-0.3, 0.3),
dur: 1/5,
attack: Pwhite(0.01, 0.02),
release: Pwhite(0.3, 0.5),
scale: Pn(~scale),
octave: 4,
degree: Pn(Pshuf((0..14), 2), inf),
])).quant_(3).play;
Pdef(\liwarypo, Pbind(*[
out: Pshuf(~reverbBusses.wrapExtend(5), inf),
instrument: Pshuf(~synthNames.wrapExtend(5), inf),
db: -28,
pan: Pwhite(-0.2, 0.2),
dur: 3/5,
offset: 1/10,
attack: Pwhite(0.005, 0.01),
release: Pwhite(0.1, 0.2),
scale: Pn(~scale),
octave: 8,
degree: Pn(Pshuf((0..4), 4), inf),
])).quant_(3).play;
)
////
TempoClock.tempo = 1;
~emergingVals = {|n, c, arr| Pseq(n.collect{|i| Pn(Pshuf(arr.wrapExtend(i+1), c), c)}, 1)};
~emergingNotes = {|n, c| Pseq(n.collect{|i| Pn(Pshuf((0..i), c), c)}, 1)};
~emergingNotes.(5, 1).asStream.all.size/60/1
~emergingNotes.(11, 2).asStream.all.size/60/2
~emergingNotes.(13, 3).asStream.all.size/60/3
~emergingNotes.(15, 4).asStream.all.size/60/4
~emergingNotes.(11, 5).asStream.all.size/60/5
~emergingVals.(5, 1, ~reverbBusses).asStream.all.size
~emergingNotes.(5, 1).asStream.all.size
(
// play some music
~tenydedi = Pbind(*[
out: ~emergingVals.(5, 1, ~reverbBusses),
instrument: ~emergingVals.(5, 1, ~synthNames),
db: -3,
pan: Pwhite(-0.2, 0.2!4),
dur: 1,
attack: Pwhite(0.01, 0.02),
release: Pwhite(0.8, 1.0),
scale: Pn(~scale),
octave: 1,
degree: ~emergingNotes.(5, 1),
timingOffset: Plprand(0, 0.003!4),
]);
Pdef(\tenydedi, ~tenydedi).quant_(1).play;
~nohagygu = Pbind(*[
out: ~emergingVals.(10, 2, ~reverbBusses),
instrument: ~emergingVals.(10, 2, ~synthNames),
db: -9,
pan: Pwhite(-0.2, 0.2!4),
dur: 1/2,
attack: Pwhite(0.01, 0.02),
release: Pwhite(0.8, 1.0),
scale: Pn(~scale),
octave: 2,
degree: ~emergingNotes.(10, 2),
timingOffset: Plprand(0, 0.003!4),
]);
Pdef(\nohagygu, ~nohagygu).quant_(1).play;
~hahuqefy = Pbind(*[
out: ~emergingVals.(9, 3, ~reverbBusses),
instrument: ~emergingVals.(9, 3, ~synthNames),
db: -18,
pan: Pwhite(-0.4, 0.4!4),
dur: 1/3,
attack: Pwhite(0.01, 0.02),
release: Pwhite(0.5, 0.9),
scale: Pn(~scale),
octave: 3,
degree: ~emergingNotes.(9, 3),
timingOffset: Plprand(0, 0.003!4),
]);
Pdef(\hahuqefy, ~hahuqefy).quant_(1).play;
~tymaroso = Pbind(*[
out: ~emergingVals.(15, 4, ~reverbBusses),
instrument: ~emergingVals.(15, 4, ~synthNames),
db: -28,
pan: Pwhite(-0.6, 0.6!4),
dur: 1/4,
attack: Pwhite(0.01, 0.02),
release: Pwhite(0.4, 0.7),
scale: Pn(~scale),
octave: 5,
degree: ~emergingNotes.(15, 4),
timingOffset: Plprand(0, 0.003!4),
]);
Pdef(\tymaroso, ~tymaroso).quant_(1).play;
~rekyhabe = Pbind(*[
out: ~emergingVals.(11, 5, ~reverbBusses),
instrument: ~emergingVals.(11, 5, ~synthNames),
db: -45,
pan: Pwhite(-0.7, 0.7!4),
dur: 1/5,
attack: Pwhite(0.01, 0.02),
release: Pwhite(0.3, 0.5),
scale: Pn(~scale),
octave: 7,
degree: ~emergingNotes.(11, 5),
timingOffset: Plprand(0, 0.003!4),
]);
Pdef(\rekyhabe, ~rekyhabe).quant_(1).play;
~nyhoweni = Ptpar([
0, ~tenydedi,
6, ~nohagygu,
20, ~hahuqefy,
32, ~tymaroso,
62, ~rekyhabe,
], 1);
Pdef(\test, ~nyhoweni).quant_(1).play;
)
//// more higher-level beats generator
(
TempoClock.tempo = 1/4;
~beatGenerator = {|depth=1, dur=1, degree=0, db=0, attack=0.07, release=0.7, chance=0.6, weights=#[10, 1]|
var beat = [[dur, degree, db, attack, release]];
weights = weights.normalizeSum;
(depth-1).do{|i|
var newBeat = [];
beat.do{|hit, j|
chance.coin.if {
var divider = Array.series(weights.size, 2).wchoose(weights);
var newHit = [
hit[0] / divider,
hit[1] + 1,
db - (3 * i),
attack / (i+1),
release / (i+1),
];
divider.do{
newBeat = newBeat.add(newHit)
};
} {newBeat = newBeat.add(hit)};
};
beat = newBeat;
};
beat;
};
~beatQogamocy = ~beatGenerator.(5);
~qogamocy = Pbind(*[
out: Pshuf(~reverbBusses.wrapExtend(~beatQogamocy.size), inf),
instrument: Pshuf(~synthNames.wrapExtend(~beatQogamocy.size), inf),
pan: [-0.2, 0.2],
scale: Pn(~scale),
octave: 2,
#[\dur, \degree, \db, \attack, \release]: Pseq(
~beatQogamocy, inf,
),
timingOffset: 0,
]);
Pdef(\qogamocy, ~qogamocy).quant_(1).play;
~beatJocenyne = ~beatGenerator.(6);
~jocenyne = Pbind(*[
out: Pshuf(~reverbBusses.wrapExtend(~beatJocenyne.size), inf),
instrument: Pshuf(~synthNames.wrapExtend(~beatJocenyne.size), inf),
pan: [-0.4, -0.4],
scale: Pn(~scale),
octave: 3,
#[\dur, \degree, \db, \attack, \release]: Pseq(
~beatJocenyne, inf,
),
timingOffset: 0,
]);
Pdef(\jocenyne, ~jocenyne).quant_(1).play;
~beatCocewary = ~beatGenerator.(7, db: -3);
~cocewary = Pbind(*[
out: Pshuf(~reverbBusses.wrapExtend(~beatCocewary.size), inf),
instrument: Pshuf(~synthNames.wrapExtend(~beatCocewary.size), inf),
pan: [-0.6, 0.6],
scale: Pn(~scale),
octave: 4,
#[\dur, \degree, \db, \attack, \release]: Pseq(
~beatCocewary, inf,
),
timingOffset: 0,
]);
Pdef(\cocewary, ~cocewary).quant_(1).play;
~beatSicilaqe = ~beatGenerator.(7, 2, db: -6, chance: 0.5);
~sicilaqe = Pbind(*[
out: Pshuf(~reverbBusses.wrapExtend(~beatSicilaqe.size), inf),
instrument: Pshuf(~synthNames.wrapExtend(~beatSicilaqe.size), inf),
pan: [-0.8, 0.8],
scale: Pn(~scale),
octave: 5,
#[\dur, \degree, \db, \attack, \release]: Pseq(
~beatSicilaqe, inf,
),
timingOffset: 0,
]);
Pdef(\sicilaqe, ~sicilaqe).quant_(2).play;
)
(
~beatGytuzowi = ~beatGenerator.(7, 1, db: -16, attack: 0.05, release: 0.7, chance: 0.5, weights: #[3, 1]);
~beatGytuzowi.size.postln;
~gytuzowi = Pbind(*[
out: Pshuf(~reverbBusses.wrapExtend(~beatGytuzowi.size), inf),
instrument: \dyti, //Pshuf(~synthNames.wrapExtend(~beatGytuzowi.size), inf),
legato: Pshuf(Array.fill(~beatGytuzowi.size, {rrand(0.2, 0.9)}), inf),
pan: [-0.9, 0.9],
scale: Pn(~scale),
octave: Prand([6], inf),
#[\dur, \degree, \db, \attack, \release]: Pseq(
~beatGytuzowi, inf,
),
timingOffset: 0,
]);
Pdef(\gytuzowi, ~gytuzowi).quant_(1).play;
~beatMazywaqo = ~beatGenerator.(7, 2, db: -14, attack: 0.05, release: 0.5, chance: 0.6, weights: #[3, 1]);
~beatMazywaqo.size.postln;
~mazywaqo = Pbind(*[
out: Pshuf(~reverbBusses.wrapExtend(~beatMazywaqo.size), inf),
instrument: \dyti,
legato: Pshuf(Array.fill(~beatMazywaqo.size, {rrand(0.2, 0.9)}), inf),
pan: [-0.9, 0.9],
scale: Pn(~scale),
octave: Prand([7], inf),
#[\dur, \degree, \db, \attack, \release]: Pseq(
~beatMazywaqo, inf,
),
timingOffset: 0,
]);
Pdef(\mazywaqo, ~mazywaqo).quant_(2).play;
)
(
[
~beatQogamocy,
~beatJocenyne,
~beatCocewary,
~beatSicilaqe,
~beatGytuzowi,
].writeArchive(Document.current.dir +/+ "dyxisija.beats");
)
Pdef.all.do{|i| i.stop};
//// make combined beats
(
~makeBeat = {|
depth=1,
weights=#[11, 10, 1],
dur=1,
degree=0,
db=0,
attack=0.07,
release=0.7
|
var beat = [[dur, degree, db, attack, release]];
weights = weights.normalizeSum;
(depth-1).do{|i|
var newBeat = [];
beat.do{|hit|
var divider = Array.series(weights.size, 1).wchoose(weights);
var newHit = [
hit[0] / divider,
hit[1] + min(1, divider-1),
hit[2] - (3 * min(1, divider-1)),
hit[3] * max(0.7, 2-divider),
hit[4] * max(0.7, 2-divider),
];
divider.do{
newBeat = newBeat.add(newHit)
};
};
beat = newBeat;
};
beat;
};
~repeat = {|arr, n=1|
(arr!n).reshape(*(arr.shape *.s [n, 1, 1, 1, 1, 1]));
};
~makeCombinedBeat = {|
db = -3
|
var beat = [];
beat = (beat
++ ~repeat.(~makeBeat.(7, dur: 1, db: db), 3)
++ ~repeat.(~makeBeat.(7, dur: 1, db: db), 1)
);
};
~makeBeatPat = {|
pan = 0,
octave = 4,
db = -3
|
var beat = ~makeCombinedBeat.(db: db);
Pbind(*[
out: Pshuf(~reverbBusses.wrapExtend(beat.size), inf),
instrument: Pshuf(~synthNames.wrapExtend(beat.size), inf),
pan: [pan.neg, pan],
scale: Pn(~scale),
octave: octave,
distort: 0,
detuneMax: 0.1,
lowHarm: 2,
highHarm: 51,
harmMul: 1.3,
harmLen: 1.0,
#[\dur, \degree, \db, \attack, \release]: Pseq(
beat, inf,
),
timingOffset: 0,
]);
};
)
(
thisThread.randSeed = 10300;
Pdef(2, ~makeBeatPat.(0.1, 2, -3)).quant_(4).play;
Pdef(3, ~makeBeatPat.(0.2, 3, -5)).quant_(4).play;
Pdef(4, ~makeBeatPat.(0.35, 4, -12)).quant_(4).play;
Pdef(5, ~makeBeatPat.(0.5, 5, -18)).quant_(4).play;
Pdef(6, ~makeBeatPat.(0.75, 6, -30)).quant_(4).play;
Pdef(7, ~makeBeatPat.(0.9, 7, -39)).quant_(4).play;
)
(
// play indefinite song
~task.stop;
TempoClock.tempo = 1/4;
~bar = 0;
~task = Task({{
thisThread.randSeed = 20300 + ~bar;
~bar = ~bar + 1;
~bar.postln;
thisThread.clock.beats.postln;
~song = Ppar([
~makeBeatPat.(0.1, 2, -3),
~makeBeatPat.(0.2, 3, -5),
~makeBeatPat.(0.35, 4, -12),
~makeBeatPat.(0.5, 5, -18),
~makeBeatPat.(0.75, 6, -30),
~makeBeatPat.(0.9, 7, -39),
], 1);
Pdef(\song, ~song).quant_(4).play;
4.wait;
}.loop}, TempoClock.default).start;
)
//// testing synth and scale on midi-keyboard
~kedifu = MidiRemote25SL();
(
~synthChooser = {
~synthNames.choose
};
~kedifu.mod_{|v|
~distort = v*10;
};
~keyParams = {|freq, v|
[
attack: 0.05 * (freq.cpsoct**(-0.5)),
release: 1.0 * (freq.cpsoct**(-0.9)),
distort: ~distort,
detuneMax: 0.05,
lowHarm: 2,
highHarm: (91 * (freq.cpsoct**(-0.6))).round,
harmMul: 1.3,
harmLen: 1.0,
out: ~reverbBusses.choose,
];
};
)
(
~keys = KeySynth(~kedifu, ~synthChooser, 12/13, true, {|f,v|~keyParams.(f,v)}, 0.3,
onlyWhite: true, scale: ~scale);
)
~keys.synthName = \dyti;
////
s.record(bus: 0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment