<!-- SS · part 15 -->
ation();
    E.comp = new Tone.Compressor(-16, 3);
    E.limiter = new Tone.Limiter(-1).connect(E.master);
    E.comp.connect(E.limiter);
    E.verb = new Tone.Reverb({ decay: 2.4, wet: 1 }); E.verbSend = new Tone.Gain(0.22); E.verbSend.connect(E.verb); E.verb.connect(E.comp);
    ['drums', 'bass', 'chords', 'lead'].forEach(function (t) {
      var c = new Tone.Channel({ volume: S.vols[t], mute: !!S.mutes[t] }).connect(E.comp);
      if (t === 'chords' || t === 'lead') c.connect(E.verbSend);
      E.ch[t] = c;
    });
    E.voxBus = new Tone.Channel({ volume: Number($('#ss-vvol').value) || 0 }).connect(E.comp);
    E.recorder = (typeof MediaRecorder !== 'undefined') ? new Tone.Recorder() : null;
    if (E.recorder) E.master.connect(E.recorder);
    setSound('drums', S.sounds.drums); setSound('bass', S.sounds.bass); setSound('chords', S.sounds.chords); setSound('lead', S.sounds.lead);
    T.bpm.value = S.bpm; T.swing = S.swing; T.swingSubdivision = '16n';
    var idx = []; for (var i = 0; i < STEPS; i++) idx.push(i);
    E.seq = new Tone.Sequence(function (time, step) {
      var P = S.patterns;
      if (step === 0 && E.started) E.bar++;
      E.started = true;
      ['kick', 'snare', 'hat'].forEach(function (r) { if (P.drums[r][step]) E.inst.drums.play(r, time, r === 'hat' ? (step % 4 === 0 ? 0.8 : 0.5) : 0.95); });
      var b = P.bass[step]; if (b) E.inst.bass.triggerAttackRelease(b, '8n', time, 0.9);
      var c = P.chords[step]; if (c) { var notes = chordNotes(c); if (notes) { var len = 1; for (var k = step + 1; k < STEPS && !P.chords[k]; k++) len++; E.inst.chords.triggerAttackRelease(notes, Tone.Time('16n').toSeconds() * Math.min(len, 8), time, 0.6); } }
      var l = P.lead[step]; if (l) E.inst.lead.triggerAttackRelease(l, '16n', time, 0.7);
      var bar = E.bar;
      Tone.getDraw().schedule(function () { drawPlayhead(step, bar); }, time);
    }, idx, '16n');
    E.seq.start(0);
    return E;
  }
  function setSound(track, kind) {
    S.sounds[track] = kind; save();
    if (!E) return;
    if (E.inst[track]) { try { E.inst[track].releaseAll && E.inst[track].releaseAll(); } catch (e) {} try { E.inst[track].dispose(); } catch (e) {} }
    E.inst[track] = track === 'drums' ? makeDrums(kind, E.ch.drums) : makeSynth(track, kind, E.ch[track]);
  }
  var playing = false;
  function checkUnlock() {
    var need = !window.Tone || Tone.getContext().state !== 'running';
    $('#ss-unlock').hidden = !need;
  }
  function unlock() {
    if (!window.Tone) return Promise.reject(new Error('no Tone'));
    return Tone.start().then(function () { buildEngine(); checkUnlock(); });
  }
  $('#ss-unlock-btn').addEventListener('click', function () { unlock().then(function () { toast('Sound is on.'); }, function () { toast('Could not start audio.'); }); });
  function start() {
    return unlock().then(function () {
      var T = E.T; T.stop(); T.position = 0; E.bar = 0; E.started = false;
      scheduleVox();
      T.start('+0.08'); playing = true; setPlayButtons();
    });
  }
  function stop() {
    if (!E) return; E.T.stop(); playing = false; setPlayButtons(); drawPlayhead(-1, 0);
  }
  function setPlayButtons() {
    $('#ss-play').textContent = playing ? '■ Stop' : '▶ Play';
    $('#ss-vplay').textContent = playing ? '■ Stop' : '▶ Play with beat';
  }
  $('#ss-play').addEventListener('click', function () { if (playing) stop(); else start().catch(function () { toast('Tap again to start audio.'); }); });
  $('#ss-vplay').addEventListener('click', function () {
    if (playing) return stop();
    if (!S.voxClips || !S.voxClips.length) toast('No vocals rendered yet — playing the beat.');
    start().catch(function () { toast('Tap again to start audio.'); });
  });
  var lastCol = -1;
  function drawPlayhead(step, bar) {
    if (lastCol >= 0) $$('.ss-step[data-i="' + lastCol + '"]').forEach(function (c) { c.classList.remove('now'); });
    lastCol = step;
    if (step >= 0) { $$('.ss-step[data-i="' + step + '"]').forEach(function (c) { c.classList.add('now'); }); $('#ss-pos').textContent = 'bar ' + (bar + 1); }
    else $('#ss-pos').textContent = 'bar 1';
  }

  // ---------------------------------------------------------------- STUDIO UI
  var keySel = $('#ss-key'); keySel.innerHTML = KEYS.map(function (k) { return '<option>' + k + '</option>'; }).join('');
  function penOptions(track) {
    if (track === 'bass') return scaleNotes(S.key, [1, 2]).concat([]);
    if (track === 'lead') return scaleNotes(S.key, [4, 5]);
    var ch = (S.chords || []).slice(); diatonicChords(S.key).forEach(function (c) { if (ch.indexOf(c) < 0) ch.push(c); }); return ch;
  }
  var TRACKS = [['drums', 'Drums'], ['bass', 'Bass'], ['chords', 'Chords'], ['lead', 'Lead']];
  function stepBtn(i, on, label) { return '<button type="button" class="ss-step' + (on ? ' on' : '') + (i % 4 === 0 ? ' q' : '') + '" data-i="' + i + '" aria-label="step ' + (i + 1) + '">' + esc(label || '') + '</button>'; }
  function renderTracks() {
    