// soundtrack.jsx — Cinematic procedural soundtrack for the Vokki film.
// All audio synthesized in-browser via Web Audio API. No external files.
//
// Arrangement (24s):
//   0-3   Intro:    pad swells in, vinyl crackle, opening chime
//   3-7   Walker:   lo-fi hip-hop beat (kick/snare/hat) + warm bass walk + Rhodes-y melody
//   7-11  Reader:   beat continues, glassy bell motif highlights words
//   11-15 Save:     beat continues, satisfying coin-up sparkles on each tap
//   15-19 Factory:  beat builds, mechanical clicks layered, riser into…
//   19-24 Outro:    beat drops, big sustained chord, sparkle, fade to silence

const SOUND_ENABLED_KEY = 'vokki-film:sound:v2';

// ─── Music data ────────────────────────────────────────────────────────────
// Cmaj7 → Am7 → Fmaj7 → G — classic four-chord loop, one bar = 1.5s (80 BPM).
const CHORDS = [
  { root: 'C',  notes: [60, 64, 67, 71] }, // Cmaj7
  { root: 'A',  notes: [57, 60, 64, 67] }, // Am7
  { root: 'F',  notes: [53, 57, 60, 64] }, // Fmaj7
  { root: 'G',  notes: [55, 59, 62, 65] }, // G
];

const BEAT = 0.375;   // quarter note at 80 BPM = 0.75; we use 8th notes = 0.375
const BAR  = BEAT * 4; // 1.5s

// Bass walk (one note per beat across the bar, follows chord roots)
const BASS_LINE = [
  [36, 40, 43, 40], // C
  [33, 36, 40, 36], // A
  [29, 33, 36, 33], // F
  [31, 35, 38, 35], // G
];

// Lead melody — simple, hummable, syncopated. Notes given as [midi, beats]
// where beats is duration in 8ths.
const LEAD = [
  [72, 1], [76, 1], [79, 2],  // C E G
  [76, 1], [72, 1], [69, 2],  // E C A
  [69, 1], [72, 1], [77, 2],  // A C F
  [74, 1], [71, 1], [67, 2],  // D B G
];

const midiToHz = (m) => 440 * Math.pow(2, (m - 69) / 12);

// ─── Core hook ─────────────────────────────────────────────────────────────
function useSoundtrack({ time, duration, playing }) {
  const [muted, setMuted] = React.useState(() => {
    try { return localStorage.getItem(SOUND_ENABLED_KEY) === 'off'; }
    catch { return false; }
  });
  const [armed, setArmed] = React.useState(false);

  const ctxRef = React.useRef(null);
  const masterRef = React.useRef(null);
  const reverbSendRef = React.useRef(null);
  const padRef = React.useRef(null);
  const noiseRef = React.useRef(null);

  const lastEighthRef = React.useRef(-1);
  const lastChimeRef = React.useRef(-1);

  const ensureCtx = React.useCallback(() => {
    if (ctxRef.current) return ctxRef.current;
    const AC = window.AudioContext || window.webkitAudioContext;
    if (!AC) return null;
    const ctx = new AC();

    // Master
    const master = ctx.createGain();
    master.gain.value = 0;

    // Master compressor for cohesion
    const comp = ctx.createDynamicsCompressor();
    comp.threshold.value = -18;
    comp.ratio.value = 4;
    comp.attack.value = 0.005;
    comp.release.value = 0.2;

    master.connect(comp);
    comp.connect(ctx.destination);

    // Reverb (algorithmic — convolver with synthetic IR)
    const conv = ctx.createConvolver();
    conv.buffer = makeReverbIR(ctx, 2.4, 2.5);
    const wet = ctx.createGain();
    wet.gain.value = 0.35;
    conv.connect(wet);
    wet.connect(master);

    const reverbSend = ctx.createGain();
    reverbSend.gain.value = 1;
    reverbSend.connect(conv);

    ctxRef.current = ctx;
    masterRef.current = master;
    reverbSendRef.current = reverbSend;

    // Vinyl crackle (continuous, very quiet)
    noiseRef.current = makeVinyl(ctx, master);

    // Pad (4-voice, lowpass-modulated)
    padRef.current = makePad(ctx, master, reverbSend);

    return ctx;
  }, []);

  // Arm on first gesture
  React.useEffect(() => {
    if (armed) return;
    const onGesture = () => {
      const ctx = ensureCtx();
      if (ctx && ctx.state === 'suspended') ctx.resume();
      setArmed(true);
    };
    window.addEventListener('pointerdown', onGesture, { once: true });
    window.addEventListener('keydown', onGesture, { once: true });
    return () => {
      window.removeEventListener('pointerdown', onGesture);
      window.removeEventListener('keydown', onGesture);
    };
  }, [armed, ensureCtx]);

  // Master volume + scene-aware ducking
  React.useEffect(() => {
    const ctx = ctxRef.current;
    const master = masterRef.current;
    if (!ctx || !master) return;
    const target = (muted || !playing || !armed) ? 0 : 0.32;
    master.gain.cancelScheduledValues(ctx.currentTime);
    master.gain.linearRampToValueAtTime(target, ctx.currentTime + 0.4);
  }, [muted, playing, armed]);

  // Update pad chord per scene + dynamics
  React.useEffect(() => {
    const ctx = ctxRef.current;
    if (!ctx || !padRef.current) return;

    // Pick chord based on time within 1.5s bar of the global loop
    const barIdx = Math.floor(time / BAR) % CHORDS.length;
    const chord = CHORDS[barIdx];
    padRef.current.setChord(chord.notes, ctx.currentTime + 0.1);

    // Filter brightness rises in build sections
    let cutoff = 600;
    if (time < 3) cutoff = 500 + time * 80;          // intro swell
    else if (time < 7) cutoff = 800;                 // walker
    else if (time < 11) cutoff = 1200;               // reader brighter
    else if (time < 15) cutoff = 1100;               // save
    else if (time < 19) cutoff = 700 + (time - 15) * 200; // factory build
    else cutoff = 1600;                              // outro full
    padRef.current.setCutoff(cutoff, ctx.currentTime + 0.4);

    // Pad amplitude per scene
    let padGain = 0.0;
    if (time < 3) padGain = 0.1 * (time / 3);        // fade in
    else if (time < 19) padGain = 0.14;              // beat-section bed
    else padGain = 0.28 - 0.28 * Math.max(0, (time - 22.5) / 1.5); // big then fade
    padRef.current.setGain(Math.max(0, padGain), ctx.currentTime + 0.3);
  }, [time]);

  // Sequencer: trigger drums/bass/lead on each 8th note
  React.useEffect(() => {
    if (!playing || muted || !armed) return;
    const ctx = ctxRef.current;
    const master = masterRef.current;
    const reverb = reverbSendRef.current;
    if (!ctx || !master) return;

    // Quantize to 8th-note grid
    const eighthIdx = Math.floor(time / BEAT);
    if (eighthIdx === lastEighthRef.current) {
      // Still emit one-shot scene events below
    } else {
      lastEighthRef.current = eighthIdx;

      // Beat section: 3..19 (drums/bass/lead)
      if (time >= 3 && time < 19) {
        const localBeat = eighthIdx % 8; // 8 eighths per bar
        const barIdx = Math.floor(time / BAR) % CHORDS.length;

        // ── Drums ──
        // Kick on 1, 3 (eighth idx 0, 4)
        if (localBeat === 0 || localBeat === 4) kick(ctx, master, 0.32);
        // Snare on 2, 4 (eighth idx 2, 6)
        if (localBeat === 2 || localBeat === 6) snare(ctx, master, reverb, 0.18);
        // Hat on every 8th, slight swing
        const hatGain = (localBeat % 2 === 0) ? 0.06 : 0.04;
        hat(ctx, master, hatGain);

        // ── Bass: one note per quarter (every 2 eighths) ──
        if (localBeat % 2 === 0) {
          const bassNote = BASS_LINE[barIdx][localBeat / 2];
          bass(ctx, master, midiToHz(bassNote), 0.22);
        }

        // ── Lead melody: only in walker (3-7) and outro build (15-19) ──
        if (time >= 3 && time < 7) {
          // Play the lead arp aligned to bar
          const arpIdx = eighthIdx % LEAD.length;
          const [note, dur] = LEAD[arpIdx];
          rhodes(ctx, master, reverb, midiToHz(note), 0.15, BEAT * dur * 0.9);
        }

        // ── Reader scene: glassy bell on every quarter ──
        if (time >= 7 && time < 11 && localBeat % 2 === 0) {
          const chord = CHORDS[barIdx].notes;
          const f = midiToHz(chord[(eighthIdx / 2) % chord.length] + 12);
          bell(ctx, master, reverb, f, 0.08, 1.4);
        }

        // ── Factory build: rising filter sweep + extra perc ──
        if (time >= 17 && time < 19 && localBeat % 1 === 0) {
          hat(ctx, master, 0.05);
        }
      }
    }

    // ─── One-shot scene events (timestamp-based) ───
    const events = [
      { t: 0.2,  fn: () => chime(ctx, master, reverb, [523, 659, 784, 1047], 0.18, 2.6) },
      { t: 3.0,  fn: () => kick(ctx, master, 0.42) },           // beat drop
      { t: 7.0,  fn: () => bell(ctx, master, reverb, 1318, 0.14, 2.0) },
      { t: 11.0, fn: () => bell(ctx, master, reverb, 1568, 0.14, 2.0) },
      { t: 11.7, fn: () => sparkle(ctx, master, reverb, 1760) },
      { t: 12.6, fn: () => sparkle(ctx, master, reverb, 1976) },
      { t: 13.5, fn: () => sparkle(ctx, master, reverb, 2349) },
      { t: 15.0, fn: () => bell(ctx, master, reverb, 1175, 0.14, 2.0) },
      { t: 17.5, fn: () => riser(ctx, master, 1.4) },
      { t: 18.9, fn: () => crash(ctx, master, reverb, 0.3) },
      { t: 19.0, fn: () => chord(ctx, master, reverb, [60, 64, 67, 71, 76], 0.32, 4.5) },
      { t: 22.0, fn: () => chime(ctx, master, reverb, [784, 988, 1175, 1568], 0.16, 2.6) },
    ];
    for (const e of events) {
      // Trigger if we just crossed it within this frame window
      if (time >= e.t && time < e.t + 0.06 && lastChimeRef.current < e.t) {
        lastChimeRef.current = e.t;
        e.fn();
      }
    }
    // Reset on scrub-back
    if (lastChimeRef.current > time + 0.5) lastChimeRef.current = -1;
  }, [time, playing, muted, armed]);

  return { muted, setMuted, armed };
}

// ─── Synth voices ──────────────────────────────────────────────────────────

function makeReverbIR(ctx, seconds = 2.4, decay = 2.5) {
  const rate = ctx.sampleRate;
  const len = rate * seconds;
  const buf = ctx.createBuffer(2, len, rate);
  for (let ch = 0; ch < 2; ch++) {
    const data = buf.getChannelData(ch);
    for (let i = 0; i < len; i++) {
      data[i] = (Math.random() * 2 - 1) * Math.pow(1 - i / len, decay);
    }
  }
  return buf;
}

function makeVinyl(ctx, dest) {
  const bufSize = ctx.sampleRate * 2;
  const buf = ctx.createBuffer(1, bufSize, ctx.sampleRate);
  const data = buf.getChannelData(0);
  for (let i = 0; i < bufSize; i++) {
    // Sparse pop noise + pink-ish hiss
    const pop = Math.random() < 0.0006 ? (Math.random() - 0.5) * 0.6 : 0;
    data[i] = (Math.random() - 0.5) * 0.04 + pop;
  }
  const src = ctx.createBufferSource();
  src.buffer = buf;
  src.loop = true;
  const hp = ctx.createBiquadFilter();
  hp.type = 'highpass';
  hp.frequency.value = 800;
  const gain = ctx.createGain();
  gain.gain.value = 0.06;
  src.connect(hp);
  hp.connect(gain);
  gain.connect(dest);
  src.start();
  return { src, gain };
}

function makePad(ctx, dest, reverb) {
  const filter = ctx.createBiquadFilter();
  filter.type = 'lowpass';
  filter.frequency.value = 600;
  filter.Q.value = 1.5;
  const gain = ctx.createGain();
  gain.gain.value = 0;
  filter.connect(gain);
  gain.connect(dest);
  // Send to reverb
  const send = ctx.createGain();
  send.gain.value = 0.5;
  filter.connect(send);
  send.connect(reverb);

  const voices = [];
  for (let i = 0; i < 4; i++) {
    const osc1 = ctx.createOscillator();
    const osc2 = ctx.createOscillator();
    osc1.type = 'sawtooth';
    osc2.type = 'sawtooth';
    osc1.detune.value = -7;
    osc2.detune.value = 7;
    const vGain = ctx.createGain();
    vGain.gain.value = 0.2;
    osc1.connect(vGain); osc2.connect(vGain);
    vGain.connect(filter);
    osc1.start(); osc2.start();
    voices.push({ osc1, osc2, vGain });
  }

  return {
    setChord(midiNotes, when) {
      midiNotes.forEach((n, i) => {
        if (!voices[i]) return;
        const f = midiToHz(n);
        voices[i].osc1.frequency.linearRampToValueAtTime(f, when);
        voices[i].osc2.frequency.linearRampToValueAtTime(f, when);
      });
    },
    setCutoff(hz, when) {
      filter.frequency.linearRampToValueAtTime(hz, when);
    },
    setGain(g, when) {
      gain.gain.linearRampToValueAtTime(g, when);
    },
  };
}

function kick(ctx, dest, peak = 0.32) {
  const now = ctx.currentTime;
  const osc = ctx.createOscillator();
  osc.type = 'sine';
  osc.frequency.setValueAtTime(150, now);
  osc.frequency.exponentialRampToValueAtTime(40, now + 0.16);
  const gain = ctx.createGain();
  gain.gain.setValueAtTime(peak, now);
  gain.gain.exponentialRampToValueAtTime(0.0001, now + 0.28);
  // Click transient
  const click = ctx.createOscillator();
  click.type = 'square';
  click.frequency.value = 1200;
  const cg = ctx.createGain();
  cg.gain.setValueAtTime(0.06, now);
  cg.gain.exponentialRampToValueAtTime(0.0001, now + 0.01);
  click.connect(cg); cg.connect(dest);
  osc.connect(gain); gain.connect(dest);
  osc.start(now); osc.stop(now + 0.3);
  click.start(now); click.stop(now + 0.02);
}

function snare(ctx, dest, reverb, peak = 0.18) {
  const now = ctx.currentTime;
  // Noise burst
  const len = ctx.sampleRate * 0.2;
  const buf = ctx.createBuffer(1, len, ctx.sampleRate);
  const data = buf.getChannelData(0);
  for (let i = 0; i < len; i++) data[i] = (Math.random() - 0.5) * 2;
  const src = ctx.createBufferSource();
  src.buffer = buf;
  const bp = ctx.createBiquadFilter();
  bp.type = 'bandpass';
  bp.frequency.value = 1800;
  bp.Q.value = 0.7;
  const gain = ctx.createGain();
  gain.gain.setValueAtTime(peak, now);
  gain.gain.exponentialRampToValueAtTime(0.0001, now + 0.18);
  src.connect(bp); bp.connect(gain); gain.connect(dest);
  // Reverb send
  const rs = ctx.createGain(); rs.gain.value = 0.3;
  gain.connect(rs); rs.connect(reverb);
  // Body tone
  const tone = ctx.createOscillator();
  tone.type = 'triangle';
  tone.frequency.value = 200;
  const tg = ctx.createGain();
  tg.gain.setValueAtTime(0.08, now);
  tg.gain.exponentialRampToValueAtTime(0.0001, now + 0.1);
  tone.connect(tg); tg.connect(dest);
  src.start(now); tone.start(now); tone.stop(now + 0.12);
}

function hat(ctx, dest, peak = 0.05) {
  const now = ctx.currentTime;
  const len = ctx.sampleRate * 0.06;
  const buf = ctx.createBuffer(1, len, ctx.sampleRate);
  const data = buf.getChannelData(0);
  for (let i = 0; i < len; i++) data[i] = (Math.random() - 0.5) * 2;
  const src = ctx.createBufferSource();
  src.buffer = buf;
  const hp = ctx.createBiquadFilter();
  hp.type = 'highpass';
  hp.frequency.value = 7000;
  const gain = ctx.createGain();
  gain.gain.setValueAtTime(peak, now);
  gain.gain.exponentialRampToValueAtTime(0.0001, now + 0.05);
  src.connect(hp); hp.connect(gain); gain.connect(dest);
  src.start(now);
}

function bass(ctx, dest, freq, peak = 0.22) {
  const now = ctx.currentTime;
  const osc = ctx.createOscillator();
  osc.type = 'triangle';
  osc.frequency.value = freq;
  // Sub
  const sub = ctx.createOscillator();
  sub.type = 'sine';
  sub.frequency.value = freq;
  const lp = ctx.createBiquadFilter();
  lp.type = 'lowpass';
  lp.frequency.value = 400;
  const gain = ctx.createGain();
  gain.gain.setValueAtTime(0, now);
  gain.gain.linearRampToValueAtTime(peak, now + 0.01);
  gain.gain.exponentialRampToValueAtTime(0.0001, now + 0.4);
  osc.connect(lp); sub.connect(lp); lp.connect(gain); gain.connect(dest);
  osc.start(now); sub.start(now);
  osc.stop(now + 0.42); sub.stop(now + 0.42);
}

function rhodes(ctx, dest, reverb, freq, peak = 0.12, dur = 0.6) {
  const now = ctx.currentTime;
  const osc = ctx.createOscillator();
  osc.type = 'sine';
  osc.frequency.value = freq;
  const osc2 = ctx.createOscillator();
  osc2.type = 'sine';
  osc2.frequency.value = freq * 2;
  const tine = ctx.createGain();
  tine.gain.setValueAtTime(peak * 0.4, now);
  tine.gain.exponentialRampToValueAtTime(0.0001, now + 0.06);
  osc2.connect(tine); tine.connect(dest);
  const lp = ctx.createBiquadFilter();
  lp.type = 'lowpass';
  lp.frequency.value = 1800;
  const gain = ctx.createGain();
  gain.gain.setValueAtTime(0, now);
  gain.gain.linearRampToValueAtTime(peak, now + 0.005);
  gain.gain.exponentialRampToValueAtTime(0.0001, now + dur);
  osc.connect(lp); lp.connect(gain); gain.connect(dest);
  // Reverb
  const rs = ctx.createGain(); rs.gain.value = 0.35;
  gain.connect(rs); rs.connect(reverb);
  osc.start(now); osc2.start(now);
  osc.stop(now + dur + 0.05); osc2.stop(now + 0.1);
}

function bell(ctx, dest, reverb, freq, peak = 0.1, dur = 1.6) {
  const now = ctx.currentTime;
  const o1 = ctx.createOscillator();
  o1.type = 'sine'; o1.frequency.value = freq;
  const o2 = ctx.createOscillator();
  o2.type = 'sine'; o2.frequency.value = freq * 2.756; // inharmonic
  const o3 = ctx.createOscillator();
  o3.type = 'sine'; o3.frequency.value = freq * 5.404;
  const g = ctx.createGain();
  g.gain.setValueAtTime(peak, now);
  g.gain.exponentialRampToValueAtTime(0.0001, now + dur);
  const g2 = ctx.createGain(); g2.gain.value = 0.3;
  const g3 = ctx.createGain(); g3.gain.value = 0.1;
  o1.connect(g); o2.connect(g2); g2.connect(g); o3.connect(g3); g3.connect(g);
  g.connect(dest);
  const rs = ctx.createGain(); rs.gain.value = 0.5;
  g.connect(rs); rs.connect(reverb);
  o1.start(now); o2.start(now); o3.start(now);
  o1.stop(now + dur); o2.stop(now + dur); o3.stop(now + dur);
}

function chime(ctx, dest, reverb, freqs, peak = 0.12, dur = 2.0) {
  freqs.forEach((f, i) => setTimeout(() => bell(ctx, dest, reverb, f, peak, dur), i * 70));
}

function sparkle(ctx, dest, reverb, baseFreq) {
  // Quick rising ladder of bells
  const ladder = [1, 1.25, 1.5, 2];
  ladder.forEach((m, i) => setTimeout(() => bell(ctx, dest, reverb, baseFreq * m, 0.08, 1.0), i * 50));
}

function riser(ctx, dest, dur = 1.4) {
  const now = ctx.currentTime;
  // Filtered noise sweeping up
  const len = ctx.sampleRate * dur;
  const buf = ctx.createBuffer(1, len, ctx.sampleRate);
  const data = buf.getChannelData(0);
  for (let i = 0; i < len; i++) data[i] = (Math.random() - 0.5) * 2;
  const src = ctx.createBufferSource();
  src.buffer = buf;
  const bp = ctx.createBiquadFilter();
  bp.type = 'bandpass';
  bp.frequency.setValueAtTime(400, now);
  bp.frequency.exponentialRampToValueAtTime(8000, now + dur);
  bp.Q.value = 4;
  const gain = ctx.createGain();
  gain.gain.setValueAtTime(0, now);
  gain.gain.linearRampToValueAtTime(0.18, now + dur * 0.9);
  gain.gain.linearRampToValueAtTime(0, now + dur);
  src.connect(bp); bp.connect(gain); gain.connect(dest);
  src.start(now);
}

function crash(ctx, dest, reverb, peak = 0.25) {
  const now = ctx.currentTime;
  const len = ctx.sampleRate * 1.6;
  const buf = ctx.createBuffer(1, len, ctx.sampleRate);
  const data = buf.getChannelData(0);
  for (let i = 0; i < len; i++) data[i] = (Math.random() - 0.5) * 2 * Math.pow(1 - i / len, 1.5);
  const src = ctx.createBufferSource();
  src.buffer = buf;
  const hp = ctx.createBiquadFilter();
  hp.type = 'highpass';
  hp.frequency.value = 4000;
  const gain = ctx.createGain();
  gain.gain.value = peak;
  src.connect(hp); hp.connect(gain); gain.connect(dest);
  const rs = ctx.createGain(); rs.gain.value = 0.5;
  gain.connect(rs); rs.connect(reverb);
  src.start(now);
}

function chord(ctx, dest, reverb, midiNotes, peak = 0.3, dur = 4.0) {
  midiNotes.forEach((n, i) => {
    setTimeout(() => {
      const freq = midiToHz(n);
      const now = ctx.currentTime;
      const o1 = ctx.createOscillator();
      const o2 = ctx.createOscillator();
      o1.type = 'sawtooth'; o2.type = 'sawtooth';
      o1.frequency.value = freq; o2.frequency.value = freq;
      o1.detune.value = -8; o2.detune.value = 8;
      const lp = ctx.createBiquadFilter();
      lp.type = 'lowpass'; lp.frequency.value = 2000;
      const g = ctx.createGain();
      g.gain.setValueAtTime(0, now);
      g.gain.linearRampToValueAtTime(peak / midiNotes.length, now + 0.08);
      g.gain.linearRampToValueAtTime(0.0001, now + dur);
      o1.connect(lp); o2.connect(lp); lp.connect(g); g.connect(dest);
      const rs = ctx.createGain(); rs.gain.value = 0.4;
      g.connect(rs); rs.connect(reverb);
      o1.start(now); o2.start(now);
      o1.stop(now + dur + 0.05); o2.stop(now + dur + 0.05);
    }, i * 25);
  });
}

// ─── Mute UI ───────────────────────────────────────────────────────────────
function MuteButton({ muted, onToggle, armed }) {
  const [hover, setHover] = React.useState(false);
  return (
    <button
      onClick={onToggle}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      title={!armed ? 'Click anywhere to enable sound' : muted ? 'Unmute' : 'Mute'}
      style={{
        position: 'fixed',
        top: 16, right: 16,
        zIndex: 10000,
        padding: '8px 14px',
        background: hover ? 'rgba(40,40,40,0.95)' : 'rgba(20,20,20,0.85)',
        border: '1px solid rgba(255,255,255,0.18)',
        borderRadius: 999,
        color: '#f3ede0',
        cursor: 'pointer',
        display: 'flex', alignItems: 'center', gap: 8,
        fontSize: 14,
        fontFamily: 'JetBrains Mono, monospace',
        letterSpacing: '0.06em',
        backdropFilter: 'blur(6px)',
      }}
    >
      <span style={{ fontSize: 16 }}>{!armed ? '🔈' : muted ? '🔇' : '🎵'}</span>
      <span>{!armed ? 'TAP TO ARM' : muted ? 'OFF' : 'ON'}</span>
    </button>
  );
}

function SoundtrackInner() {
  const tl = useTimeline();
  const { muted, setMuted, armed } = useSoundtrack(tl);
  return <MuteButton muted={muted} onToggle={() => setMuted(m => !m)} armed={armed} />;
}

Object.assign(window, { useSoundtrack, MuteButton, SoundtrackInner });
