feat(sound): trance, industrial, detroit morceaux
CI build oscope-of / build-check (push) Has been cancelled

Add 3 new concert morceaux (09-11) to the data_only setlist.
09_trance_pluck: plucky 16th arp, arm-height filter, speed density.
10_industrial: distorted stab + rumble, speed drive, ropen noise.
11_detroit: warm detuned pad triad, string stab on rspeed, hat.
All three headless-tested: 20/20 assertions OK, zero SC errors.
This commit is contained in:
L'électron rare
2026-06-27 20:36:45 +02:00
parent 0d467da088
commit 24613cd809
4 changed files with 214 additions and 0 deletions
+3
View File
@@ -175,6 +175,9 @@ Routine({
"morceaux/06_hard_rave.scd",
"morceaux/07_dub_chords.scd",
"morceaux/08_dub_space.scd",
"morceaux/09_trance_pluck.scd",
"morceaux/10_industrial.scd",
"morceaux/11_detroit.scd",
].do { |f| (~base ++ f).load; 0.1.wait; };
s.sync;
@@ -0,0 +1,67 @@
// Trance Pluck -- arpege 16e plucky hypnotique + sub gate + kick soft.
// Bras hauts (ry/ly) -> ouvre le filtre pluck ; vitesse corps -> densite arp
// (16e a haute vitesse, 8e a basse vitesse). ~ccHarmony[\phrase] choisit la phrase.
(
SynthDef(\cc_pluck_pluck, { |out=0, freq=440, cutoff=2000, amp=0.3, pan=0|
var env = EnvGen.kr(Env.perc(0.002, 0.18), doneAction: 2);
var fenv = EnvGen.kr(Env([cutoff * 3.0, cutoff], [0.05], \exp)).clip(80, 8000);
var sig = (Saw.ar(freq.clip(50, 1200)) + Saw.ar(freq.clip(50, 1200) * 1.007)) * 0.5;
sig = RLPF.ar(sig, fenv, 0.25);
sig = sig * env;
Out.ar(out, Pan2.ar(sig, pan.clip(-1, 1)) * amp);
}).add;
SynthDef(\cc_pluck_sub, { |out=0, freq=55, amp=0.0, gate=1|
var sig = SinOsc.ar(freq.clip(20, 100));
sig = sig * EnvGen.kr(Env.asr(0.3, 1, 0.5), gate, doneAction: 2);
Out.ar(out, Pan2.ar(sig, 0) * amp.lag(0.3));
}).add;
SynthDef(\cc_pluck_kick, { |out=0, amp=0.5|
var env = EnvGen.kr(Env.perc(0.001, 0.28), doneAction: 2);
var fenv = EnvGen.kr(Env([150, 45], [0.07], \exp));
var sig = SinOsc.ar(fenv) * env;
Out.ar(out, Pan2.ar(sig, 0) * amp);
}).add;
~concertAdd.((
name: "Trance Pluck", style: \trance,
start: { |ctx|
ctx[\phrases] = [
[0, 2, 3, 5],
[0, 2, 4, 7],
[0, 3, 5, 7],
[0, 2, 3, 7]
];
ctx[\pat] = ctx[\phrases][0];
ctx[\step] = 0;
ctx[\cut] = 1800;
ctx[\dens] = 2;
ctx[\sub] = Synth(\cc_pluck_sub, [\freq, ~ccNote.(0, -1).midicps, \amp, 0.20]);
},
update: { |ctx, pose|
var hf = pose[\hands];
var hiAvg = (1 - (((hf[\ry] ? 1) + (hf[\ly] ? 1)) * 0.5)).clip(0, 1);
ctx[\cut] = hiAvg.linexp(0, 1, 400, 5000);
ctx[\dens] = ((pose[\kin][\speed] ? 0) > 0.3).if({ 1 }, { 2 });
},
tick: { |ctx, pose, beat|
var sixteenth = (0.25 / ~ccCtlDur).round.max(1);
var quarter = (1.0 / ~ccCtlDur).round.max(1);
ctx[\pat] = ctx[\phrases].wrapAt(~ccHarmony[\phrase] ? 0);
if(pose[\hasBody]) {
if((beat % quarter) == 0) { Synth(\cc_pluck_kick, [\amp, 0.55]) };
if((beat % sixteenth) == 0) {
if(((ctx[\step] ? 0) % (ctx[\dens] ? 2)) == 0) {
var deg = ctx[\pat].wrapAt(ctx[\step] ? 0);
var note = ~ccNote.(deg, 0);
Synth(\cc_pluck_pluck, [\freq, note.midicps,
\cutoff, (ctx[\cut] ? 1800).clip(200, 6000),
\amp, 0.28, \pan, 0.3.rand2]);
};
ctx[\step] = (ctx[\step] ? 0) + 1;
};
};
},
stop: { |ctx| ctx[\sub] !? { |s| s.set(\gate, 0) } },
));
"[morceau] Trance Pluck loaded".postln;
)
@@ -0,0 +1,69 @@
// Industrial -- stab metallique distordu (saw/pulse + BPF reso + tanh) +
// rafale bruit + kick dur + rumble gate. Vitesse corps -> drive + amp rumble ;
// ecart bras D (ropen) -> quantite bruit sur l'offbeat ; pitch stab -> ~ccNote.
(
SynthDef(\cc_indust_stab, { |out=0, freq=220, drive=2.5, amp=0.3, pan=0|
var env = EnvGen.kr(Env.perc(0.003, 0.20), doneAction: 2);
var sig = (Saw.ar(freq.clip(40, 880)) + (Pulse.ar(freq.clip(40, 880) * 0.5, 0.4) * 0.5)) * 0.4;
sig = BPF.ar(sig, (freq.clip(40, 880) * 2.0).clip(80, 8000), 0.4) * 3.0;
sig = (sig * drive.clip(1.0, 6.0)).tanh;
sig = sig * env;
Out.ar(out, Pan2.ar(sig, pan.clip(-1, 1)) * amp);
}).add;
SynthDef(\cc_indust_noise, { |out=0, amp=0.2, pan=0|
var env = EnvGen.kr(Env.perc(0.001, 0.08), doneAction: 2);
var sig = HPF.ar(WhiteNoise.ar, 4000) * env;
Out.ar(out, Pan2.ar(sig, pan.clip(-1, 1)) * amp);
}).add;
SynthDef(\cc_indust_kick, { |out=0, amp=0.7|
var env = EnvGen.kr(Env.perc(0.001, 0.30), doneAction: 2);
var fenv = EnvGen.kr(Env([160, 40], [0.06], \exp));
var sig = (SinOsc.ar(fenv) * env * 3.0).tanh;
Out.ar(out, Pan2.ar(sig, 0) * amp);
}).add;
SynthDef(\cc_indust_rumble, { |out=0, amp=0.0, gate=1|
var sig = (BPF.ar(PinkNoise.ar, 55, 0.4) * 5.0) + (SinOsc.ar(38) * 0.3);
sig = sig.tanh;
sig = sig * EnvGen.kr(Env.asr(0.4, 1, 0.4), gate, doneAction: 2);
Out.ar(out, Pan2.ar(sig, 0) * amp.lag(0.3));
}).add;
~concertAdd.((
name: "Industrial", style: \industrial,
start: { |ctx|
ctx[\rumble] = Synth(\cc_indust_rumble, [\amp, 0.0]);
ctx[\drive] = 2.0;
ctx[\noiseAmt] = 0.0;
ctx[\stabDeg] = 0;
},
update: { |ctx, pose|
var hf = pose[\hands];
var speed = (pose[\kin][\speed] ? 0);
ctx[\drive] = speed.linlin(0, 0.6, 1.5, 5.5);
ctx[\noiseAmt] = (hf[\ropen] ? 0.5);
ctx[\stabDeg] = [0, 0, 3, 5].wrapAt(~ccHarmony[\phrase] ? 0);
ctx[\rumble].set(\amp, speed.linlin(0, 0.6, 0.0, 0.28));
},
tick: { |ctx, pose, beat|
var quarter = (1.0 / ~ccCtlDur).round.max(1);
var half = (2.0 / ~ccCtlDur).round.max(1);
var eighth = (0.5 / ~ccCtlDur).round.max(1);
if(pose[\hasBody]) {
if((beat % quarter) == 0) {
Synth(\cc_indust_kick, [\amp, 0.70]);
};
if((beat % half) == 0) {
var note = ~ccNote.(ctx[\stabDeg] ? 0, 0);
Synth(\cc_indust_stab, [\freq, note.midicps,
\drive, (ctx[\drive] ? 2.0).clip(1.0, 6.0),
\amp, 0.32, \pan, 0.2.rand2]);
};
if(((beat % eighth) == (eighth div: 2)) and: { (ctx[\noiseAmt] ? 0) > 0.3 }) {
Synth(\cc_indust_noise, [\amp, (ctx[\noiseAmt] ? 0) * 0.40, \pan, 0.5.rand2]);
};
};
},
stop: { |ctx| ctx[\rumble] !? { |s| s.set(\gate, 0) } },
));
"[morceau] Industrial loaded".postln;
)
@@ -0,0 +1,75 @@
// Detroit -- pad chord chaud detune (triade 0/2/4, gate) + stab cordes +
// kick clean + hat offbeat. Bras D (rspeed) -> trigger stab + note ;
// bras G hauteur (ly) -> filtre chord ; ~ccHarmony[\pad] -> bright/dark cutoff.
(
SynthDef(\cc_detro_pad, { |out=0, freq1=110, freq2=138, freq3=165, cutoff=800, amp=0.0, gate=1|
var sig = Saw.ar(freq1.clip(40, 800)) + Saw.ar(freq1.clip(40, 800) * 1.006)
+ Saw.ar(freq2.clip(40, 800)) + Saw.ar(freq2.clip(40, 800) * 1.006)
+ Saw.ar(freq3.clip(40, 800)) + Saw.ar(freq3.clip(40, 800) * 1.006);
sig = sig * 0.10;
sig = RLPF.ar(sig, cutoff.clip(200, 6000), 0.5);
sig = sig * EnvGen.kr(Env.asr(1.5, 1, 2), gate, doneAction: 2);
Out.ar(out, Pan2.ar(sig, 0) * amp.lag(1.0));
}).add;
SynthDef(\cc_detro_stab, { |out=0, freq=220, amp=0.25, pan=0|
var env = EnvGen.kr(Env.perc(0.01, 0.35), doneAction: 2);
var vib = SinOsc.kr(5.0) * 3.0;
var sig = (Saw.ar(freq.clip(60, 880) + vib) + Saw.ar((freq.clip(60, 880) + vib) * 1.008)) * 0.5;
sig = RLPF.ar(sig, 3000, 0.5) * env;
Out.ar(out, Pan2.ar(sig, pan.clip(-1, 1)) * amp);
}).add;
SynthDef(\cc_detro_kick, { |out=0, amp=0.6|
var env = EnvGen.kr(Env.perc(0.001, 0.40), doneAction: 2);
var fenv = EnvGen.kr(Env([140, 40], [0.10], \exp));
var sig = SinOsc.ar(fenv) * env;
Out.ar(out, Pan2.ar(sig, 0) * amp);
}).add;
SynthDef(\cc_detro_hat, { |out=0, amp=0.15, pan=0|
var env = EnvGen.kr(Env.perc(0.001, 0.06), doneAction: 2);
var sig = HPF.ar(WhiteNoise.ar, 7000) * env;
Out.ar(out, Pan2.ar(sig, pan.clip(-1, 1)) * amp);
}).add;
~concertAdd.((
name: "Detroit", style: \techno,
start: { |ctx|
var f1 = ~ccNote.(0, 0).midicps;
var f2 = ~ccNote.(2, 0).midicps;
var f3 = ~ccNote.(4, 0).midicps;
ctx[\pad] = Synth(\cc_detro_pad, [\freq1, f1, \freq2, f2, \freq3, f3,
\cutoff, 800, \amp, 0.18]);
ctx[\cut] = 800.0;
ctx[\lastStab] = 0.0;
},
update: { |ctx, pose|
var hf = pose[\hands];
var pad = (~ccHarmony[\pad] ? \dark);
var base = (pad == \bright).if({ 900 }, { 350 });
var lyOpen = (1 - (hf[\ly] ? 1)).clip(0, 1);
var tgt = base + (lyOpen * 2500);
var rsp = (hf[\rspeed] ? 0);
ctx[\cut] = ctx[\cut] + ((tgt - ctx[\cut]) * 0.07);
ctx[\pad].set(\cutoff, ctx[\cut].clip(200, 6000));
if(rsp > 0.15) {
if((thisThread.seconds - (ctx[\lastStab] ? 0)) > 0.15) {
var stabNote = ~ccNote.([0, 2, 4, 7].wrapAt(~ccHarmony[\phrase] ? 0), 1);
ctx[\lastStab] = thisThread.seconds;
Synth(\cc_detro_stab, [\freq, stabNote.midicps,
\amp, 0.22, \pan, ((hf[\rx] ? 0.5) * 2 - 1)]);
};
};
},
tick: { |ctx, pose, beat|
var quarter = (1.0 / ~ccCtlDur).round.max(1);
var eighth = (0.5 / ~ccCtlDur).round.max(1);
if(pose[\hasBody]) {
if((beat % quarter) == 0) { Synth(\cc_detro_kick, [\amp, 0.60]) };
if((beat % eighth) == (eighth div: 2)) {
Synth(\cc_detro_hat, [\amp, 0.18, \pan, 0.3.rand2]);
};
};
},
stop: { |ctx| ctx[\pad] !? { |s| s.set(\gate, 0) } },
));
"[morceau] Detroit loaded".postln;
)