<!-- SS · part 22 -->
    d.hat = keep(new Tone.NoiseSynth({ noise: { type: 'white' }, envelope: { attack: 0.001, decay: 0.02, sustain: 0 }, volume: -6 }).connect(hp2));
      d.kickNote = 'C2';
    } else { // 808
      d.kick = keep(new Tone.MembraneSynth({ pitchDecay: 0.06, octaves: 8, envelope: { attack: 0.001, decay: 0.6, sustain: 0.01, release: 0.4 } }).connect(out));
      var sf = keep(new Tone.Filter(1800, 'bandpass').connect(out));
      d.snare = keep(new Tone.NoiseSynth({ noise: { type: 'white' }, envelope: { attack: 0.001, decay: 0.2, sustain: 0 }, volume: 6 }).connect(sf));
      var hp3 = keep(new Tone.Filter(7500, 'highpass').connect(out));
      d.hat = keep(new Tone.NoiseSynth({ noise: { type: 'white' }, envelope: { attack: 0.001, decay: 0.05, sustain: 0 }, volume: -4 }).connect(hp3));
      d.kickNote = 'A0';
    }
    d.dispose = function () { nodes.forEach(function (n) { try { n.dispose(); } catch (e) {} }); };
    d.play = function (row, time, vel) {
      if (row === 'kick') d.kick.triggerAttackRelease(d.kickNote, '8n', time, vel);
      else d[row].triggerAttackRelease(row === 'hat' ? '32n' : '16n', time, vel);
    };
    return d;
  }
  function makeSynth(track, kind, out) {
    var s;
    if (track === 'bass') {
      if (kind === 'Saw') s = new Tone.MonoSynth({ oscillator: { type: 'sawtooth' }, filter: { Q: 2, type: 'lowpass' }, envelope: { attack: 0.005, decay: 0.2, sustain: 0.5, release: 0.2 }, filterEnvelope: { attack: 0.001, decay: 0.15, sustain: 0.2, baseFrequency: 120, octaves: 3 } });
      else if (kind === 'FM') s = new Tone.FMSynth({ harmonicity: 1, modulationIndex: 6, envelope: { attack: 0.005, decay: 0.3, sustain: 0.4, release: 0.2 } });
      else s = new Tone.Synth({ oscillator: { type: 'sine' }, envelope: { attack: 0.005, decay: 0.4, sustain: 0.6, release: 0.3 }, volume: 4 });
    } else if (track === 'chords') {
      if (kind === 'Keys') s = new Tone.PolySynth(Tone.FMSynth, { harmonicity: 3, modulationIndex: 2, envelope: { attack: 0.005, decay: 0.8, sustain: 0.2, release: 0.8 } });
      else if (kind === 'Pluck') s = new Tone.PolySynth(Tone.Synth, { oscillator: { type: 'triangle' }, envelope: { attack: 0.002, decay: 0.25, sustain: 0, release: 0.2 } });
      else s = new Tone.PolySynth(Tone.Synth, { oscillator: { type: 'fatsawtooth', count: 3, spread: 20 }, envelope: { attack: 0.3, decay: 0.4, sustain: 0.7, release: 1.2 }, volume: -6 });
      s.maxPolyphony = 16;
    } else {
      if (kind === 'Square') s = new Tone.Synth({ oscillator: { type: 'square' }, envelope: { attack: 0.005, decay: 0.15, sustain: 0.3, release: 0.15 }, volume: -6 });
      else if (kind === 'Bell') s = new Tone.FMSynth({ harmonicity: 3.01, modulationIndex: 12, envelope: { attack: 0.001, decay: 1.2, sustain: 0, release: 1 }, modulationEnvelope: { attack: 0.001, decay: 0.6, sustain: 0, release: 0.5 } });
      else s = new Tone.MonoSynth({ oscillator: { type: 'sawtooth' }, filter: { Q: 1, type: 'lowpass' }, envelope: { attack: 0.01, decay: 0.2, sustain: 0.4, release: 0.25 }, filterEnvelope: { attack: 0.01, decay: 0.2, sustain: 0.4, baseFrequency: 600, octaves: 2.5 }, volume: -4 });
    }
    s.connect(out);
    return s;
  }
  function buildEngine() {
    if (E) return E;
    if (!window.Tone) { toast('Audio engine failed to load. Reload the page.'); return null; }
    var T = Tone.getTransport();
    E = { T: T, ch: {}, inst: {}, step: 0, bar: 0, players: [], voxBus: null };
    E.master = new Tone.Gain(0.9).toDestination();
    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 (n