{"version":3,"file":"eight-bit-audio.215ec2d8.mjs","sources":["../../../../../../src/lib/eight-bit-processor.worklet.js?url","../../../../../../src/lib/eight-bit-audio.js"],"sourcesContent":["export default \"data:application/javascript;base64,LyoqCiAqIEF1ZGlvV29ya2xldCBwcm9jZXNzb3IgZm9yIHJlYWx0aW1lIDgtYml0IC8gY2hpcHR1bmUgZWZmZWN0cy4KICogTG9hZGVkIHZpYSBhdWRpb0NvbnRleHQuYXVkaW9Xb3JrbGV0LmFkZE1vZHVsZSgpLgogKi8KY2xhc3MgRWlnaHRCaXRQcm9jZXNzb3IgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3IgewoJc3RhdGljIGdldCBwYXJhbWV0ZXJEZXNjcmlwdG9ycygpIHsKCQlyZXR1cm4gWwoJCQl7IG5hbWU6ICdiaXREZXB0aCcsIGRlZmF1bHRWYWx1ZTogOCwgbWluVmFsdWU6IDEsIG1heFZhbHVlOiAxNiB9LAoJCQl7IG5hbWU6ICdzYW1wbGVSYXRlJywgZGVmYXVsdFZhbHVlOiAxMTAyNSwgbWluVmFsdWU6IDIwMDAsIG1heFZhbHVlOiA0ODAwMCB9LAoJCQl7IG5hbWU6ICdtaXgnLCBkZWZhdWx0VmFsdWU6IDEsIG1pblZhbHVlOiAwLCBtYXhWYWx1ZTogMSB9LAoJCQl7IG5hbWU6ICdlbmFibGVkJywgZGVmYXVsdFZhbHVlOiAxLCBtaW5WYWx1ZTogMCwgbWF4VmFsdWU6IDEgfQoJCV07Cgl9CgoJY29uc3RydWN0b3IoKSB7CgkJc3VwZXIoKTsKCQl0aGlzLnBoYXNlciA9IDA7CgkJdGhpcy5sYXN0U2FtcGxlID0gWzAsIDBdOwoJfQoKCXByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CgkJY29uc3QgaW5wdXQgPSBpbnB1dHNbMF07CgkJY29uc3Qgb3V0cHV0ID0gb3V0cHV0c1swXTsKCgkJaWYgKCFpbnB1dD8ubGVuZ3RoIHx8ICFvdXRwdXQ/Lmxlbmd0aCkgcmV0dXJuIHRydWU7CgoJCWNvbnN0IGJpdERlcHRoID0gcGFyYW1ldGVycy5iaXREZXB0aFswXTsKCQljb25zdCB0YXJnZXRSYXRlID0gcGFyYW1ldGVycy5zYW1wbGVSYXRlWzBdOwoJCWNvbnN0IG1peCA9IHBhcmFtZXRlcnMubWl4WzBdOwoJCWNvbnN0IGVuYWJsZWQgPSBwYXJhbWV0ZXJzLmVuYWJsZWRbMF0gPj0gMC41OwoKCQljb25zdCBzdGVwcyA9IE1hdGgucG93KDIsIGJpdERlcHRoKTsKCQljb25zdCBzdGVwID0gdGFyZ2V0UmF0ZSAvIHNhbXBsZVJhdGU7CgoJCWZvciAobGV0IGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgb3V0cHV0Lmxlbmd0aDsgY2hhbm5lbCsrKSB7CgkJCWNvbnN0IGlucHV0Q2hhbm5lbCA9IGlucHV0W2NoYW5uZWxdID8/IGlucHV0WzBdOwoJCQljb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0W2NoYW5uZWxdOwoKCQkJaWYgKCFpbnB1dENoYW5uZWwgfHwgIW91dHB1dENoYW5uZWwpIGNvbnRpbnVlOwoKCQkJbGV0IHBoYXNlciA9IHRoaXMucGhhc2VyOwoJCQlsZXQgbGFzdFNhbXBsZSA9IHRoaXMubGFzdFNhbXBsZVtjaGFubmVsXSA/PyAwOwoKCQkJZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXRDaGFubmVsLmxlbmd0aDsgaSsrKSB7CgkJCQljb25zdCBkcnkgPSBpbnB1dENoYW5uZWxbaV07CgoJCQkJaWYgKCFlbmFibGVkIHx8IG1peCA8PSAwKSB7CgkJCQkJb3V0cHV0Q2hhbm5lbFtpXSA9IGRyeTsKCQkJCQljb250aW51ZTsKCQkJCX0KCgkJCQlwaGFzZXIgKz0gc3RlcDsKCQkJCWlmIChwaGFzZXIgPj0gMSkgewoJCQkJCXBoYXNlciAtPSAxOwoJCQkJCWxhc3RTYW1wbGUgPSBkcnk7CgkJCQl9CgoJCQkJbGV0IGNydXNoZWQgPSBNYXRoLmZsb29yKGxhc3RTYW1wbGUgKiBzdGVwcykgLyBzdGVwczsKCQkJCWNydXNoZWQgPSBNYXRoLm1heCgtMSwgTWF0aC5taW4oMSwgY3J1c2hlZCkpOwoKCQkJCW91dHB1dENoYW5uZWxbaV0gPSBkcnkgKiAoMSAtIG1peCkgKyBjcnVzaGVkICogbWl4OwoJCQl9CgoJCQl0aGlzLmxhc3RTYW1wbGVbY2hhbm5lbF0gPSBsYXN0U2FtcGxlOwoJCX0KCgkJdGhpcy5waGFzZXIgPSBwaGFzZXI7CgkJcmV0dXJuIHRydWU7Cgl9Cn0KCnJlZ2lzdGVyUHJvY2Vzc29yKCdlaWdodC1iaXQtcHJvY2Vzc29yJywgRWlnaHRCaXRQcm9jZXNzb3IpOwo=\"","import workletUrl from \"./eight-bit-processor.worklet.js?url\";\n\n/** @typedef {'subtle' | 'retro' | 'gameboy' | 'nes' | 'arcade'} EightBitPreset */\n\n/** @type {Record<EightBitPreset, { bitDepth: number; sampleRate: number; mix: number }>} */\nexport const PRESETS = {\n  subtle: { bitDepth: 12, sampleRate: 22050, mix: 0.5 },\n  retro: { bitDepth: 8, sampleRate: 16000, mix: 0.85 },\n  gameboy: { bitDepth: 6, sampleRate: 8192, mix: 1 },\n  nes: { bitDepth: 4, sampleRate: 11025, mix: 1 },\n  arcade: { bitDepth: 3, sampleRate: 8000, mix: 1 },\n};\n\nconst DEFAULT_SETTINGS = {\n  bitDepth: 8,\n  sampleRate: 16000,\n  mix: 0.85,\n  volume: 0.15,\n  enabled: false,\n};\n\n/**\n * Encode an AudioBuffer to a 16-bit PCM WAV Blob.\n * @param {AudioBuffer} buffer\n * @returns {Blob}\n */\nexport function encodeWav(buffer) {\n  const numChannels = buffer.numberOfChannels;\n  const sampleRate = buffer.sampleRate;\n  const bitsPerSample = 16;\n  const bytesPerSample = bitsPerSample / 8;\n  const blockAlign = numChannels * bytesPerSample;\n  const dataLength = buffer.length * blockAlign;\n  const arrayBuffer = new ArrayBuffer(44 + dataLength);\n  const view = new DataView(arrayBuffer);\n\n  const writeString = (offset, str) => {\n    for (let i = 0; i < str.length; i++)\n      view.setUint8(offset + i, str.charCodeAt(i));\n  };\n\n  writeString(0, \"RIFF\");\n  view.setUint32(4, 36 + dataLength, true);\n  writeString(8, \"WAVE\");\n  writeString(12, \"fmt \");\n  view.setUint32(16, 16, true);\n  view.setUint16(20, 1, true);\n  view.setUint16(22, numChannels, true);\n  view.setUint32(24, sampleRate, true);\n  view.setUint32(28, sampleRate * blockAlign, true);\n  view.setUint16(32, blockAlign, true);\n  view.setUint16(34, bitsPerSample, true);\n  writeString(36, \"data\");\n  view.setUint32(40, dataLength, true);\n\n  const channels = Array.from({ length: numChannels }, (_, i) =>\n    buffer.getChannelData(i),\n  );\n  let offset = 44;\n\n  for (let i = 0; i < buffer.length; i++) {\n    for (let channel = 0; channel < numChannels; channel++) {\n      const sample = Math.max(-1, Math.min(1, channels[channel][i]));\n      view.setInt16(\n        offset,\n        sample < 0 ? sample * 0x8000 : sample * 0x7fff,\n        true,\n      );\n      offset += 2;\n    }\n  }\n\n  return new Blob([arrayBuffer], { type: \"audio/wav\" });\n}\n\n/**\n * Apply 8-bit crush to an AudioBuffer (offline, non-realtime).\n * @param {AudioBuffer} buffer\n * @param {{ bitDepth?: number; sampleRate?: number; mix?: number; enabled?: boolean }} settings\n * @returns {AudioBuffer}\n */\nexport function crushBuffer(buffer, settings = {}) {\n  const { bitDepth, sampleRate, mix, enabled } = {\n    ...DEFAULT_SETTINGS,\n    ...settings,\n  };\n\n  if (!enabled || mix <= 0) return buffer;\n\n  const steps = Math.pow(2, bitDepth);\n  const step = sampleRate / buffer.sampleRate;\n  const output = new AudioBuffer({\n    length: buffer.length,\n    numberOfChannels: buffer.numberOfChannels,\n    sampleRate: buffer.sampleRate,\n  });\n\n  for (let channel = 0; channel < buffer.numberOfChannels; channel++) {\n    const input = buffer.getChannelData(channel);\n    const out = output.getChannelData(channel);\n    let phaser = 0;\n    let lastSample = 0;\n\n    for (let i = 0; i < input.length; i++) {\n      const dry = input[i];\n\n      phaser += step;\n      if (phaser >= 1) {\n        phaser -= 1;\n        lastSample = dry;\n      }\n\n      let crushed = Math.floor(lastSample * steps) / steps;\n      crushed = Math.max(-1, Math.min(1, crushed));\n      out[i] = dry * (1 - mix) + crushed * mix;\n    }\n  }\n\n  return output;\n}\n\n/**\n * Browser plugin for loading MP3s and applying 8-bit / chiptune effects.\n */\nexport class EightBitAudio {\n  /** @type {AudioContext | null} */\n  #context = null;\n\n  /** @type {ArrayBuffer | null} */\n  #rawArrayBuffer = null;\n\n  /** @type {AudioBuffer | null} */\n  #sourceBuffer = null;\n\n  /** @type {AudioBufferSourceNode | null} */\n  #sourceNode = null;\n\n  /** @type {AudioWorkletNode | null} */\n  #workletNode = null;\n\n  /** @type {GainNode | null} */\n  #gainNode = null;\n\n  #workletReady = false;\n  #loop = false;\n\n  /** @type {HTMLAudioElement | null} */\n  #audioElement = null;\n\n  /** @type {string | null} */\n  #objectUrl = null;\n\n  /** @type {ReturnType<typeof setTimeout> | null} */\n  #refreshTimer = null;\n\n  /** @type {typeof DEFAULT_SETTINGS} */\n  settings = { ...DEFAULT_SETTINGS };\n\n  /**\n   * @param {Partial<typeof DEFAULT_SETTINGS>} [initialSettings]\n   */\n  constructor(initialSettings = {}) {\n    this.settings = { ...DEFAULT_SETTINGS, ...initialSettings };\n  }\n\n  async #ensureContext() {\n    if (!this.#context) {\n      this.#context = new AudioContext();\n    }\n\n    return this.#context;\n  }\n\n  async #ensureWorklet() {\n    if (this.#workletReady) return true;\n\n    const context = await this.#ensureContext();\n\n    try {\n      await context.audioWorklet.addModule(workletUrl);\n      this.#workletReady = true;\n      return true;\n    } catch (error) {\n      console.warn(\n        \"EightBitAudio: worklet unavailable, using offline crush fallback.\",\n        error,\n      );\n      return false;\n    }\n  }\n\n  async #decodeSourceBuffer() {\n    if (!this.#rawArrayBuffer) {\n      throw new Error(\"No audio data loaded.\");\n    }\n\n    const context = await this.#ensureContext();\n    this.#sourceBuffer = await context.decodeAudioData(\n      this.#rawArrayBuffer.slice(0),\n    );\n    return this.#sourceBuffer;\n  }\n\n  /**\n   * Bind a native HTMLAudioElement for reliable autoplay playback.\n   * @param {HTMLAudioElement | null} element\n   */\n  bindAudioElement(element) {\n    this.#audioElement = element;\n  }\n\n  async #getProcessedUrl() {\n    const blob = await this.exportWav();\n    if (this.#objectUrl) URL.revokeObjectURL(this.#objectUrl);\n    this.#objectUrl = URL.createObjectURL(blob);\n    return this.#objectUrl;\n  }\n\n  #applyElementVolume() {\n    if (this.#audioElement) {\n      this.#audioElement.volume = this.settings.volume;\n    }\n  }\n\n  async prepareElement() {\n    if (!this.#audioElement || !this.#sourceBuffer) {\n      throw new Error(\"Bind an audio element and load a track first.\");\n    }\n\n    const url = await this.#getProcessedUrl();\n    this.#audioElement.src = url;\n    this.#audioElement.loop = true;\n    this.#audioElement.preload = \"auto\";\n    this.#applyElementVolume();\n  }\n\n  /**\n   * Prepare the crushed track on the bound audio element and autoplay.\n   */\n  async tryAutoplay() {\n    if (!this.#audioElement) {\n      throw new Error(\"No audio element bound.\");\n    }\n\n    await this.prepareElement();\n    await this.#audioElement.play();\n  }\n\n  async #refreshElementPlayback() {\n    const element = this.#audioElement;\n    if (!element || !this.#sourceBuffer) return;\n\n    const wasPlaying = !element.paused;\n    const currentTime = element.currentTime;\n    await this.prepareElement();\n    element.currentTime = currentTime;\n\n    if (wasPlaying) {\n      try {\n        await element.play();\n      } catch {\n        // autoplay policy may block resume\n      }\n    }\n  }\n\n  /**\n   * Call synchronously inside a click/tap handler to satisfy autoplay policy.\n   */\n  resumeFromGesture() {\n    if (!this.#context) {\n      this.#context = new AudioContext();\n    }\n\n    void this.#context.resume();\n  }\n\n  /**\n   * Load an MP3 (or any browser-decodable audio) from a File.\n   * @param {File | Blob} file\n   */\n  async load(file) {\n    this.#rawArrayBuffer = await file.arrayBuffer();\n    return this.#decodeSourceBuffer();\n  }\n\n  /**\n   * Fetch audio bytes without starting playback.\n   * @param {string} url\n   */\n  async loadFromUrl(url) {\n    const response = await fetch(url);\n    if (!response.ok)\n      throw new Error(`Failed to fetch audio: ${response.status}`);\n    this.#rawArrayBuffer = await response.arrayBuffer();\n    return this.#decodeSourceBuffer();\n  }\n\n  /**\n   * Update effect settings. Applies immediately during playback.\n   * @param {Partial<typeof DEFAULT_SETTINGS>} next\n   */\n  updateSettings(next) {\n    const wasPlaying = this.isPlaying;\n    const loop = this.#loop;\n\n    this.settings = { ...this.settings, ...next };\n    this.#applyElementVolume();\n    this.#applyWorkletParams();\n    this.#applyVolume();\n\n    if (this.#audioElement && this.#sourceBuffer) {\n      if (this.#refreshTimer) clearTimeout(this.#refreshTimer);\n      this.#refreshTimer = setTimeout(() => {\n        void this.#refreshElementPlayback();\n      }, 250);\n      return;\n    }\n\n    if (wasPlaying && !this.#workletReady) {\n      void this.start({ loop });\n    }\n  }\n\n  /**\n   * Apply a named preset.\n   * @param {EightBitPreset} preset\n   */\n  setPreset(preset) {\n    const values = PRESETS[preset];\n    if (!values) throw new Error(`Unknown preset: ${preset}`);\n    this.updateSettings({ ...values, enabled: true });\n  }\n\n  #getPlaybackBuffer() {\n    if (!this.#sourceBuffer) {\n      throw new Error(\"Load an audio file before playing.\");\n    }\n\n    if (this.#workletReady) return this.#sourceBuffer;\n\n    return crushBuffer(this.#sourceBuffer, this.settings);\n  }\n\n  #applyWorkletParams() {\n    if (!this.#workletNode) return;\n    const { bitDepth, sampleRate, mix, enabled } = this.settings;\n    this.#workletNode.parameters.get(\"bitDepth\").value = bitDepth;\n    this.#workletNode.parameters.get(\"sampleRate\").value = sampleRate;\n    this.#workletNode.parameters.get(\"mix\").value = mix;\n    this.#workletNode.parameters.get(\"enabled\").value = enabled ? 1 : 0;\n  }\n\n  #applyVolume() {\n    if (!this.#gainNode) return;\n    this.#gainNode.gain.value = this.settings.volume;\n  }\n\n  #buildGraph() {\n    if (!this.#context || !this.#sourceBuffer) {\n      throw new Error(\"Load an audio file before playing.\");\n    }\n\n    this.stop();\n\n    this.#sourceNode = this.#context.createBufferSource();\n    this.#sourceNode.buffer = this.#getPlaybackBuffer();\n    this.#gainNode = this.#context.createGain();\n\n    if (this.#workletReady) {\n      this.#workletNode = new AudioWorkletNode(\n        this.#context,\n        \"eight-bit-processor\",\n      );\n      this.#sourceNode.connect(this.#workletNode);\n      this.#workletNode.connect(this.#gainNode);\n      this.#applyWorkletParams();\n    } else {\n      this.#sourceNode.connect(this.#gainNode);\n    }\n\n    this.#gainNode.connect(this.#context.destination);\n    this.#applyVolume();\n  }\n\n  /**\n   * Start playback with 8-bit processing (non-blocking).\n   * @param {{ loop?: boolean }} [options]\n   */\n  async start(options = {}) {\n    const { loop = false } = options;\n    this.#loop = loop;\n\n    const context = await this.#ensureContext();\n\n    if (context.state === \"suspended\") {\n      await context.resume();\n    }\n\n    this.#buildGraph();\n\n    this.#sourceNode.loop = loop;\n    this.#sourceNode.onended = () => {\n      if (!this.#sourceNode?.loop) this.stop();\n    };\n    this.#sourceNode.start(0);\n  }\n\n  /**\n   * Play the loaded track and resolve when finished.\n   * @param {{ loop?: boolean }} [options]\n   */\n  async play(options = {}) {\n    const { loop = false } = options;\n    await this.start({ loop });\n\n    if (loop) return;\n\n    return new Promise((resolve) => {\n      if (!this.#sourceNode) {\n        resolve();\n        return;\n      }\n\n      this.#sourceNode.onended = () => {\n        this.stop();\n        resolve();\n      };\n    });\n  }\n\n  /** Stop current playback. */\n  stop() {\n    if (this.#sourceNode) {\n      try {\n        this.#sourceNode.stop();\n      } catch {\n        // already stopped\n      }\n      this.#sourceNode.disconnect();\n      this.#sourceNode = null;\n    }\n\n    if (this.#workletNode) {\n      this.#workletNode.disconnect();\n      this.#workletNode = null;\n    }\n\n    if (this.#gainNode) {\n      this.#gainNode.disconnect();\n      this.#gainNode = null;\n    }\n  }\n\n  /**\n   * Render the full track with current settings and return a WAV Blob.\n   * @returns {Promise<Blob>}\n   */\n  async exportWav() {\n    if (!this.#sourceBuffer)\n      throw new Error(\"Load an audio file before exporting.\");\n\n    const crushed = crushBuffer(this.#sourceBuffer, this.settings);\n    return encodeWav(crushed);\n  }\n\n  /**\n   * Trigger a browser download of the processed WAV.\n   * @param {string} [filename]\n   */\n  async download(filename = \"8bit-track.wav\") {\n    const blob = await this.exportWav();\n    const url = URL.createObjectURL(blob);\n    const anchor = document.createElement(\"a\");\n    anchor.href = url;\n    anchor.download = filename;\n    anchor.click();\n    URL.revokeObjectURL(url);\n  }\n\n  /** @returns {boolean} */\n  get isPlaying() {\n    if (this.#audioElement) return !this.#audioElement.paused;\n    return this.#sourceNode !== null;\n  }\n\n  /** @returns {boolean} */\n  get needsUnlock() {\n    return this.#context?.state === \"suspended\";\n  }\n\n  /** @returns {boolean} */\n  get isLoaded() {\n    return this.#sourceBuffer !== null;\n  }\n\n  /** @returns {number | null} Duration in seconds. */\n  get duration() {\n    return this.#sourceBuffer?.duration ?? null;\n  }\n\n  /** Release audio resources. */\n  destroy() {\n    this.stop();\n\n    if (this.#audioElement) {\n      this.#audioElement.pause();\n      this.#audioElement.removeAttribute(\"src\");\n    }\n\n    if (this.#refreshTimer) clearTimeout(this.#refreshTimer);\n    if (this.#objectUrl) URL.revokeObjectURL(this.#objectUrl);\n\n    this.#context?.close();\n    this.#context = null;\n    this.#sourceBuffer = null;\n    this.#rawArrayBuffer = null;\n    this.#audioElement = null;\n    this.#objectUrl = null;\n    this.#workletReady = false;\n  }\n}\n"],"names":["workletUrl","PRESETS","DEFAULT_SETTINGS","encodeWav","buffer","numChannels","sampleRate","bitsPerSample","bytesPerSample","blockAlign","dataLength","arrayBuffer","view","writeString","offset","str","i","channels","_","channel","sample","crushBuffer","settings","bitDepth","mix","enabled","steps","step","output","input","out","phaser","lastSample","dry","crushed","_context","_rawArrayBuffer","_sourceBuffer","_sourceNode","_workletNode","_gainNode","_workletReady","_loop","_audioElement","_objectUrl","_refreshTimer","_ensureContext","ensureContext_fn","_ensureWorklet","ensureWorklet_fn","_decodeSourceBuffer","decodeSourceBuffer_fn","_getProcessedUrl","getProcessedUrl_fn","_applyElementVolume","applyElementVolume_fn","_refreshElementPlayback","refreshElementPlayback_fn","_getPlaybackBuffer","getPlaybackBuffer_fn","_applyWorkletParams","applyWorkletParams_fn","_applyVolume","applyVolume_fn","_buildGraph","buildGraph_fn","EightBitAudio","initialSettings","__privateAdd","__publicField","element","__privateSet","__privateGet","url","__privateMethod","file","response","next","wasPlaying","loop","preset","values","options","context","_a","resolve","filename","blob","anchor","error","currentTime"],"mappings":"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"}