// ==========================================================
// KATONIK - "Lagoon Tribe Ritual" (Afro Tech & Deep Acid)
// 124 BPM - Structure évolutive sur 128 mesures
// ==========================================================
ditty.bpm = 124;
// 1. HORLOGE GLOBALE & GESTION DES PHASES DU MORCEAU
// 0-16: Intro Percussions & Clave
// 16-32: Entrée Marimba & Shakers denses
// 32-64: Entrée Bassline Acid TB-03 + Kick plein
// 64-80: Montée Polyrythmique & Chords
// 80-96: Grand Break Tribal (sans kick, sweeps & marimba)
// 96-128: Drop Final Puissant (Plein arrangement)
// 2. KICK AFRO-DEEP (Attaque ronde et punch subby)
const deepKick = synth.def((phase, env, tick) => {
let f = 135 * Math.exp(-tick * 28) + 40;
let click = (Math.random() * 2 - 1) * Math.exp(-tick * 90) * 0.2;
return (Math.sin(phase * f) + click) * env.value;
}, { attack: 0.001, release: 0.38 });
loop((tick) => {
let bar = Math.floor(tick / 4) % 128;
let isBreak = (bar >= 80 && bar < 96);
if (!isBreak) {
deepKick.play(36, { amp: 1.05 });
}
sleep(1);
});
// 3. SECTION RYTHMIQUE AFRO : CLAVE, CONGAS & WOODBLOCKS
const woodClave = synth.def((phase, env) => {
let f = 980;
return Math.sin(phase * f) * env.value;
}, { attack: 0.001, release: 0.04 });
const conga = synth.def((phase, env, tick, opt) => {
let f = (opt.pitch || 220) * Math.exp(-tick * 12);
return Math.sin(phase * f) * env.value;
}, { attack: 0.002, release: 0.16 });
const afroShaker = synth.def((phase, env) => {
return (Math.random() * 2 - 1) * env.value;
}, { attack: 0.001, release: 0.035 });
// Clave Africaine traditionnelle (pattern 16 pas syncopé)
const clavePat = [1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0];
loop((tick) => {
let step = tick % 16;
if (clavePat[step]) {
woodClave.play(72, { amp: step === 0 ? 0.6 : 0.35 });
}
sleep(0.25);
});
// Congas polyrythmiques (Low / Mid / High)
loop((tick) => {
let bar = Math.floor(tick / 16) % 128;
if (bar < 8) { sleep(0.25); return; }
let step = tick % 16;
if (step === 3 || step === 11) conga.play(40, { pitch: 180, amp: 0.6 }); // Low
if (step === 6 || step === 14) conga.play(40, { pitch: 260, amp: 0.75 }); // High Slap
if (step === 8 || step === 15) conga.play(40, { pitch: 220, amp: 0.5 }); // Open
sleep(0.25);
});
// Shaker fluide et dansant avec dynamique ternaire
loop((tick) => {
let bar = Math.floor(tick / 16) % 128;
let step = tick % 16;
let amp = (step % 2 === 1) ? 0.3 : 0.12;
if (step === 6 || step === 14) amp = 0.45;
if (bar >= 4) {
afroShaker.play(80, { amp: amp });
}
sleep(0.25);
});
// 4. MARIMBA SYNTHÉTIQUE TROPICAL (Mélodie pentatonique)
const marimba = synth.def((phase, env, tick) => {
let f1 = Math.sin(phase * 1.0);
let f2 = Math.sin(phase * 3.01) * 0.35;
let f3 = Math.sin(phase * 5.02) * 0.15;
return (f1 + f2 + f3) * env.value;
}, { attack: 0.003, release: 0.35 });
const pentaScale = [60, 63, 65, 67, 70, 72, 75, 77]; // Eb Pentatonique
const marimbaMelody = [0, 2, 4, 3, 0, 5, 4, 2, 1, 3, 2, 0, 4, 3, 2, 1];
loop((tick) => {
let bar = Math.floor(tick / 16) % 128;
if (bar < 16) { sleep(0.5); return; }
let step = tick % 16;
if (step % 2 === 0 || step === 7 || step === 11) {
let note = pentaScale[marimbaMelody[step] % pentaScale.length];
marimba.play(note, { amp: 0.45 });
}
sleep(0.25);
});
// 5. BASSE ACID TB-03 HYPNOTIQUE & MODULÉE
const acidBass = synth.def((phase, env, tick, opt) => {
let raw = (phase % 1) * 2 - 1;
let sat = Math.tanh(raw * 2.2);
let cut = (opt.cutoff || 0.4) * env.value;
return sat * cut * env.value;
}, { attack: 0.004, release: 0.2 });
const bassNotes = [36, 36, 39, 36, 41, 43, 36, 46, 36, 39, 41, 36, 43, 46, 48, 39];
loop((tick) => {
let bar = Math.floor(tick / 16) % 128;
// La basse commence à la mesure 32 et s'arrête pendant le grand break (80-96)
if (bar < 32 || (bar >= 80 && bar < 96)) {
sleep(0.25);
return;
}
let step = tick % 16;
let n = bassNotes[step];
let isAccent = (step === 0 || step === 5 || step === 8 || step === 12);
// Évolution lente du cutoff sur 32 mesures
let slowEvolution = 0.3 + 0.55 * (0.5 + 0.5 * Math.sin(bar * 0.2));
let cutoff = isAccent ? Math.min(1.0, slowEvolution + 0.4) : slowEvolution;
acidBass.play(n, {
cutoff: cutoff,
amp: isAccent ? 0.95 : 0.55,
release: isAccent ? 0.32 : 0.12
});
sleep(0.25);
});
// 6. ACCORDS PROFONDS & AMBIANCE LAGON
const deepPad = synth.def((phase, env) => {
let v1 = Math.sin(phase * 1.0);
let v2 = Math.sin(phase * 1.006);
return (v1 + v2) * 0.5 * env.value;
}, { attack: 1.2, release: 2.0 });
const chordProg = [
[48, 55, 60, 63], // Cm7
[46, 53, 58, 61], // Bbm7
[44, 51, 56, 60], // Abmaj7
[46, 53, 58, 63] // Bbsus4
];
loop((tick) => {
let bar = Math.floor(tick / 8) % 128;
if (bar >= 64) {
let chord = chordProg[bar % chordProg.length];
chord.forEach(n => deepPad.play(n, { amp: 0.28, duration: 6 }));
}
sleep(8);
});