// "Heroes" de Bowie - Recréation avec l'intro iconique et la montée épique
ditty.bpm = 123;
// SYNTHÉ LEAD ICONIQUE (le riff d'intro caractéristique)
const heroLead = synth.def((phase, env, tick) => {
const osc1 = Math.sin(phase * Math.PI * 2);
const osc2 = Math.sin(phase * Math.PI * 2 * 1.01); // Légèrement désaccordé
return (osc1 + osc2) * 0.3 * env.value;
}, { attack: 0.02, release: 0.4 });
// BASSE PROFONDE avec sub
const deepBass = synth.def((phase, env) => {
const sub = Math.sin(phase * Math.PI * 2);
const harmonics = Math.sin(phase * Math.PI * 4) * 0.3;
return (sub + harmonics) * env.value * 0.6;
}, { attack: 0.01, release: 0.25 });
// PAD ATMOSPHÉRIQUE (les nappes de synthé)
const atmosphere = synth.def((phase, env) => {
const saw1 = 2 * ((phase * 1.0) % 1) - 1;
const saw2 = 2 * ((phase * 1.007) % 1) - 1;
return (saw1 + saw2) * 0.15 * env.value;
}, { attack: 0.8, decay: 0.3, sustain: 0.7, release: 2.0 });
// KICK puissant
const kick = synth.def((phase, env, tick) => {
return Math.sin(phase * Math.PI * 2 * (2 - tick * 8)) * env.value;
}, { attack: 0.005, release: 0.3 });
// SNARE avec du punch
const snare = synth.def((phase, env) => {
const noise = Math.random() * 2 - 1;
const tone = Math.sin(phase * Math.PI * 2 * 200);
return (noise * 0.7 + tone * 0.3) * env.value;
}, { attack: 0.001, release: 0.12 });
// HI-HAT ouvert
const openHat = synth.def((phase, env) => {
return (Math.random() * 2 - 1) * env.value * 0.25;
}, { attack: 0.001, release: 0.4 });
// LE RIFF D'INTRO ICONIQUE (la mélodie qui ouvre la chanson)
loop((loopCount) => {
// Le motif caractéristique: D - D - E - D
heroLead.play(D4, { duration: 0.375, amp: 0.5 });
sleep(0.5);
heroLead.play(D4, { duration: 0.375, amp: 0.4 });
sleep(0.5);
heroLead.play(E4, { duration: 0.375, amp: 0.6 });
sleep(0.5);
heroLead.play(D4, { duration: 0.75, amp: 0.5 });
sleep(1);
// Variation
heroLead.play(D4, { duration: 0.375, amp: 0.5 });
sleep(0.5);
heroLead.play(E4, { duration: 0.375, amp: 0.4 });
sleep(0.5);
heroLead.play(G4, { duration: 0.75, amp: 0.6 });
sleep(1);
heroLead.play(D4, { duration: 0.75, amp: 0.4 });
sleep(1);
}, { amp: 0.9 });
// LIGNE DE BASSE (suit la progression D - G - D - G - A)
loop((loopCount) => {
deepBass.play(D2, { duration: 0.75 });
sleep(1);
deepBass.play(D2, { duration: 0.5 });
sleep(1);
deepBass.play(G2, { duration: 0.75 });
sleep(1);
deepBass.play(G2, { duration: 0.5 });
sleep(1);
deepBass.play(D2, { duration: 0.75 });
sleep(1);
deepBass.play(D2, { duration: 0.5 });
sleep(1);
deepBass.play(G2, { duration: 0.75 });
sleep(0.5);
deepBass.play(A2, { duration: 0.75 });
sleep(1.5);
}, { amp: 0.85 });
// NAPPES DE SYNTHÉ (l'atmosphère dense)
loop((loopCount) => {
// Accord de D
atmosphere.play(D3, { duration: 8, pan: -0.3 });
atmosphere.play(Fs3, { duration: 8, pan: 0 });
atmosphere.play(A3, { duration: 8, pan: 0.3 });
sleep(4);
// Accord de G
atmosphere.play(G3, { duration: 8, pan: -0.2 });
atmosphere.play(B3, { duration: 8, pan: 0.1 });
atmosphere.play(D4, { duration: 8, pan: 0.4 });
sleep(4);
}, { amp: (loopCount) => Math.min(loopCount * 0.15, 0.6) });
// BATTERIE - Kick sur les temps forts
loop((loopCount) => {
if (loopCount > 0) {
kick.play(C1, { amp: 1.0 });
sleep(1);
kick.play(C1, { amp: 0.7 });
sleep(1);
kick.play(C1, { amp: 0.9 });
sleep(1);
kick.play(C1, { amp: 0.7 });
sleep(1);
} else {
sleep(4);
}
});
// BATTERIE - Snare sur les backbeats
loop((loopCount) => {
if (loopCount > 0) {
sleep(1);
snare.play(D3, { amp: 0.8 });
sleep(1);
snare.play(D3, { amp: 0.6 });
sleep(1);
snare.play(D3, { amp: 0.85 });
sleep(1);
} else {
sleep(4);
}
});
// BATTERIE - Hi-hat pour le groove
loop((loopCount) => {
if (loopCount > 1) {
openHat.play(Fs5, { duration: 0.3 });
sleep(0.5);
openHat.play(Fs5, { duration: 0.2, amp: 0.6 });
sleep(0.5);
} else {
sleep(1);
}
});
// MÉLODIE SECONDAIRE (entre après la montée)
loop((loopCount) => {
if (loopCount > 3) {
// Phrase mélodique inspirée du refrain
heroLead.play(A4, { duration: 0.75, pan: 0.2, amp: 0.4 });
sleep(1);
heroLead.play(B4, { duration: 0.75, pan: -0.2, amp: 0.4 });
sleep(1);
heroLead.play(D5, { duration: 1.5, pan: 0, amp: 0.5 });
sleep(2);
heroLead.play(Cs5, { duration: 0.75, pan: 0.2, amp: 0.4 });
sleep(1);
heroLead.play(B4, { duration: 0.75, pan: -0.2, amp: 0.4 });
sleep(1);
heroLead.play(A4, { duration: 1.5, pan: 0, amp: 0.45 });
sleep(2);
} else {
sleep(8);
}
});