From 24613cd8091273446ed4af3506a939efdc4754b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=27=C3=A9lectron=20rare?= <108685187+electron-rare@users.noreply.github.com> Date: Sat, 27 Jun 2026 20:36:45 +0200 Subject: [PATCH] feat(sound): trance, industrial, detroit morceaux 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. --- sound_algo/data_only/boot.scd | 3 + .../data_only/morceaux/09_trance_pluck.scd | 67 +++++++++++++++++ .../data_only/morceaux/10_industrial.scd | 69 +++++++++++++++++ sound_algo/data_only/morceaux/11_detroit.scd | 75 +++++++++++++++++++ 4 files changed, 214 insertions(+) create mode 100644 sound_algo/data_only/morceaux/09_trance_pluck.scd create mode 100644 sound_algo/data_only/morceaux/10_industrial.scd create mode 100644 sound_algo/data_only/morceaux/11_detroit.scd diff --git a/sound_algo/data_only/boot.scd b/sound_algo/data_only/boot.scd index 6bf9bfc..9bb942e 100644 --- a/sound_algo/data_only/boot.scd +++ b/sound_algo/data_only/boot.scd @@ -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; diff --git a/sound_algo/data_only/morceaux/09_trance_pluck.scd b/sound_algo/data_only/morceaux/09_trance_pluck.scd new file mode 100644 index 0000000..1dcba16 --- /dev/null +++ b/sound_algo/data_only/morceaux/09_trance_pluck.scd @@ -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; +) diff --git a/sound_algo/data_only/morceaux/10_industrial.scd b/sound_algo/data_only/morceaux/10_industrial.scd new file mode 100644 index 0000000..bb92468 --- /dev/null +++ b/sound_algo/data_only/morceaux/10_industrial.scd @@ -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; +) diff --git a/sound_algo/data_only/morceaux/11_detroit.scd b/sound_algo/data_only/morceaux/11_detroit.scd new file mode 100644 index 0000000..bd03dce --- /dev/null +++ b/sound_algo/data_only/morceaux/11_detroit.scd @@ -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; +)