Technotronic - Move This (Bass)

Technotronic - Move This (Bass)

Log in to post a comment.

ditty.bpm = 45; // Technotronic suele estar en ~124 BPM

// --- Synth: onda cuadrada simple (como en squareWave) ---
const technotronicBass = synth.def((phase, env, tick, options) => {
  const wave = Math.sin(phase) >= 0 ? 1 : -1;
  return wave * env.value * 0.7; // volumen equilibrado
});

// --- Notas convertidas de vec3 a array [start, midi, end] ---
// Nota: ignoramos la línea con (0.00000,0.0,0.00000) (silencio)
const notes = [
  [0.00000,22.0,0.18750], [0.00000,29.0,0.18750],
  [0.25000,22.0,0.43750], [0.25000,29.0,0.43750],
  [0.50000,22.0,0.62500], [0.50000,29.0,0.62500],
  [0.68750,19.0,0.81250], [0.68750,26.0,0.81250],
  [0.87500,19.0,1.06250], [0.87500,26.0,1.06250],
  [1.06250,15.0,1.18750], [1.06250,22.0,1.18750],
  [1.18750,17.0,1.31250], [1.18750,24.0,1.31250],
  [1.37500,17.0,1.50000], [1.37500,24.0,1.50000],
  [1.56250,17.0,1.62500], [1.56250,24.0,1.62500],
  [1.68750,17.0,1.87500], [1.68750,24.0,1.87500],
  [1.87500,19.0,2.00000], [1.87500,26.0,2.00000],
  [2.00000,22.0,2.12500], [2.00000,29.0,2.12500],
  [2.12500,24.0,2.25000], [2.12500,31.0,2.25000],
  [2.25000,22.0,2.43750], [2.25000,29.0,2.43750],
  [2.50000,22.0,2.62500], [2.50000,29.0,2.62500],
  [2.68750,22.0,2.81250], [2.68750,29.0,2.81250],
  [2.81250,19.0,2.93750], [2.81250,26.0,2.93750],
  [3.00000,19.0,3.18750], [3.00000,26.0,3.18750],
  [3.18750,15.0,3.31250], [3.18750,22.0,3.31250],
  [3.31250,17.0,3.43750], [3.31250,24.0,3.43750],
  [3.50000,17.0,3.62500], [3.50000,24.0,3.62500],
  [3.68750,17.0,3.75000], [3.68750,24.0,3.75000],
  [3.81250,17.0,4.00000], [3.81250,24.0,4.00000],
  [3.96875,19.0,4.09375], [3.96875,26.0,4.09375],
  [4.09375,22.0,4.21875], [4.09375,29.0,4.21875],
  [4.21875,19.0,4.34375], [4.21875,26.0,4.34375],
  [4.34375,22.0,4.46875], [4.34375,29.0,4.46875],
  [4.53125,22.0,4.65625], [4.53125,29.0,4.65625],
  [4.71875,22.0,4.84375], [4.71875,29.0,4.84375],
  [4.84375,19.0,4.96875], [4.84375,26.0,4.96875],
  [5.03125,19.0,5.21875], [5.03125,26.0,5.21875],
  [5.21875,15.0,5.34375], [5.21875,22.0,5.34375],
  [5.34375,17.0,5.46875], [5.34375,24.0,5.46875],
  [5.53125,17.0,5.65625], [5.53125,24.0,5.65625],
  [5.71875,17.0,5.78125], [5.71875,24.0,5.78125],
  [5.84375,17.0,6.03125], [5.84375,24.0,6.03125],
  [6.00000,19.0,6.12500], [6.00000,26.0,6.12500],
  [6.12500,22.0,6.25000], [6.12500,29.0,6.25000],
  [6.25000,24.0,6.37500], [6.25000,31.0,6.37500],
  [6.37500,22.0,6.50000], [6.37500,29.0,6.50000],
  [6.56250,22.0,6.68750], [6.56250,29.0,6.68750],
  [6.75000,22.0,6.87500], [6.75000,29.0,6.87500],
  [6.87500,19.0,7.00000], [6.87500,26.0,7.00000],
  [7.06250,19.0,7.25000], [7.06250,26.0,7.25000],
  [7.25000,15.0,7.37500], [7.25000,22.0,7.37500],
  [7.31250,46.0,7.37500],
  [7.37500,17.0,7.50000], [7.37500,24.0,7.50000],
  [7.56250,17.0,7.68750], [7.56250,24.0,7.68750],
  [7.68750,46.0,7.75000],
  [7.75000,17.0,7.81250], [7.75000,24.0,7.81250], [7.75000,46.0,7.81250],
  [7.87500,17.0,8.06250], [7.87500,24.0,8.06250], [7.87500,46.0,8.06250],
  [8.03125,19.0,8.15625], [8.03125,26.0,8.15625],
  [8.15625,22.0,8.28125], [8.15625,29.0,8.28125], [8.15625,46.0,8.21875],
  [8.28125,19.0,8.40625], [8.28125,26.0,8.40625],
  [8.40625,22.0,8.53125], [8.40625,29.0,8.53125],
  [8.40625,41.0,8.90625], [8.40625,46.0,9.40625],
  [8.59375,22.0,8.71875], [8.59375,29.0,8.71875],
  [8.78125,22.0,8.90625], [8.78125,29.0,8.90625], [8.78125,46.0,8.84375],
  [8.90625,19.0,9.03125], [8.90625,26.0,9.03125], [8.90625,49.0,9.09375],
  [9.09375,19.0,9.28125], [9.09375,26.0,9.28125], [9.09375,48.0,9.21875]
];

// Agrupar por tiempo de inicio (para reproducir acordes simultáneos)
const events = {};
notes.forEach(([start, midi, end]) => {
  if (midi === 0) return; // ignorar notas silenciosas
  if (!events[start]) events[start] = [];
  events[start].push({ midi, duration: end - start });
});

const times = Object.keys(events)
  .map(t => parseFloat(t))
  .sort((a, b) => a - b);

// --- Loop principal ---
loop(() => {
  let currentTime = 0;
  
  for (const t of times) {
    if (t > currentTime) {
      sleep(t - currentTime);
      currentTime = t;
    }
    
    events[t].forEach(note => {
      technotronicBass.play(note.midi+48, {
        duration: note.duration,
        attack: 0.01,
        release: 0.08,
        amp: 0.85
      });
    });
  }
  
  // Completar el loop (Technotronic suele repetir cada 8 beats)
  const last = times[times.length - 1] || 0;
  if (last < 8) {
    sleep(8 - last);
  }
}, { name: "Technotronic - Move This (Bass)" });