rlo-engine 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/README.md +493 -0
  2. package/dist/AudioEffects.d.ts +16 -0
  3. package/dist/AudioEffects.d.ts.map +1 -0
  4. package/dist/AudioEffects.js +41 -0
  5. package/dist/AudioEffects.js.map +1 -0
  6. package/dist/Instruments/Analog/AnalogSynthBase.d.ts +22 -0
  7. package/dist/Instruments/Analog/AnalogSynthBase.d.ts.map +1 -0
  8. package/dist/Instruments/Analog/AnalogSynthBase.js +30 -0
  9. package/dist/Instruments/Analog/AnalogSynthBase.js.map +1 -0
  10. package/dist/Instruments/Analog/BassSynth.d.ts +14 -0
  11. package/dist/Instruments/Analog/BassSynth.d.ts.map +1 -0
  12. package/dist/Instruments/Analog/BassSynth.js +25 -0
  13. package/dist/Instruments/Analog/BassSynth.js.map +1 -0
  14. package/dist/Instruments/Analog/ChiptuneSynth.d.ts +14 -0
  15. package/dist/Instruments/Analog/ChiptuneSynth.d.ts.map +1 -0
  16. package/dist/Instruments/Analog/ChiptuneSynth.js +19 -0
  17. package/dist/Instruments/Analog/ChiptuneSynth.js.map +1 -0
  18. package/dist/Instruments/Analog/FMSynth.d.ts +15 -0
  19. package/dist/Instruments/Analog/FMSynth.d.ts.map +1 -0
  20. package/dist/Instruments/Analog/FMSynth.js +23 -0
  21. package/dist/Instruments/Analog/FMSynth.js.map +1 -0
  22. package/dist/Instruments/Analog/FormantSynth.d.ts +14 -0
  23. package/dist/Instruments/Analog/FormantSynth.d.ts.map +1 -0
  24. package/dist/Instruments/Analog/FormantSynth.js +26 -0
  25. package/dist/Instruments/Analog/FormantSynth.js.map +1 -0
  26. package/dist/Instruments/Analog/LeadSynth.d.ts +13 -0
  27. package/dist/Instruments/Analog/LeadSynth.d.ts.map +1 -0
  28. package/dist/Instruments/Analog/LeadSynth.js +21 -0
  29. package/dist/Instruments/Analog/LeadSynth.js.map +1 -0
  30. package/dist/Instruments/Analog/OrganSynth.d.ts +13 -0
  31. package/dist/Instruments/Analog/OrganSynth.d.ts.map +1 -0
  32. package/dist/Instruments/Analog/OrganSynth.js +24 -0
  33. package/dist/Instruments/Analog/OrganSynth.js.map +1 -0
  34. package/dist/Instruments/Analog/PadSynth.d.ts +14 -0
  35. package/dist/Instruments/Analog/PadSynth.d.ts.map +1 -0
  36. package/dist/Instruments/Analog/PadSynth.js +22 -0
  37. package/dist/Instruments/Analog/PadSynth.js.map +1 -0
  38. package/dist/Instruments/Analog/ReeseBassSynth.d.ts +14 -0
  39. package/dist/Instruments/Analog/ReeseBassSynth.d.ts.map +1 -0
  40. package/dist/Instruments/Analog/ReeseBassSynth.js +22 -0
  41. package/dist/Instruments/Analog/ReeseBassSynth.js.map +1 -0
  42. package/dist/Instruments/Analog/StringSynth.d.ts +13 -0
  43. package/dist/Instruments/Analog/StringSynth.d.ts.map +1 -0
  44. package/dist/Instruments/Analog/StringSynth.js +19 -0
  45. package/dist/Instruments/Analog/StringSynth.js.map +1 -0
  46. package/dist/Instruments/Analog/WoodwindSynth.d.ts +14 -0
  47. package/dist/Instruments/Analog/WoodwindSynth.d.ts.map +1 -0
  48. package/dist/Instruments/Analog/WoodwindSynth.js +35 -0
  49. package/dist/Instruments/Analog/WoodwindSynth.js.map +1 -0
  50. package/dist/Instruments/CoreSynthBase.d.ts +29 -0
  51. package/dist/Instruments/CoreSynthBase.d.ts.map +1 -0
  52. package/dist/Instruments/CoreSynthBase.js +91 -0
  53. package/dist/Instruments/CoreSynthBase.js.map +1 -0
  54. package/dist/Instruments/Decay/AdditiveSynth.d.ts +15 -0
  55. package/dist/Instruments/Decay/AdditiveSynth.d.ts.map +1 -0
  56. package/dist/Instruments/Decay/AdditiveSynth.js +24 -0
  57. package/dist/Instruments/Decay/AdditiveSynth.js.map +1 -0
  58. package/dist/Instruments/Decay/BrassSynth.d.ts +13 -0
  59. package/dist/Instruments/Decay/BrassSynth.d.ts.map +1 -0
  60. package/dist/Instruments/Decay/BrassSynth.js +29 -0
  61. package/dist/Instruments/Decay/BrassSynth.js.map +1 -0
  62. package/dist/Instruments/Decay/ChromaticPercussionSynth.d.ts +15 -0
  63. package/dist/Instruments/Decay/ChromaticPercussionSynth.d.ts.map +1 -0
  64. package/dist/Instruments/Decay/ChromaticPercussionSynth.js +23 -0
  65. package/dist/Instruments/Decay/ChromaticPercussionSynth.js.map +1 -0
  66. package/dist/Instruments/Decay/DecaySynthBase.d.ts +23 -0
  67. package/dist/Instruments/Decay/DecaySynthBase.d.ts.map +1 -0
  68. package/dist/Instruments/Decay/DecaySynthBase.js +35 -0
  69. package/dist/Instruments/Decay/DecaySynthBase.js.map +1 -0
  70. package/dist/Instruments/Decay/ElectricGuitarSynth.d.ts +15 -0
  71. package/dist/Instruments/Decay/ElectricGuitarSynth.d.ts.map +1 -0
  72. package/dist/Instruments/Decay/ElectricGuitarSynth.js +31 -0
  73. package/dist/Instruments/Decay/ElectricGuitarSynth.js.map +1 -0
  74. package/dist/Instruments/Decay/EthnicSynth.d.ts +15 -0
  75. package/dist/Instruments/Decay/EthnicSynth.d.ts.map +1 -0
  76. package/dist/Instruments/Decay/EthnicSynth.js +21 -0
  77. package/dist/Instruments/Decay/EthnicSynth.js.map +1 -0
  78. package/dist/Instruments/Decay/GuitarSynth.d.ts +14 -0
  79. package/dist/Instruments/Decay/GuitarSynth.d.ts.map +1 -0
  80. package/dist/Instruments/Decay/GuitarSynth.js +23 -0
  81. package/dist/Instruments/Decay/GuitarSynth.js.map +1 -0
  82. package/dist/Instruments/Decay/KarplusSynth.d.ts +10 -0
  83. package/dist/Instruments/Decay/KarplusSynth.d.ts.map +1 -0
  84. package/dist/Instruments/Decay/KarplusSynth.js +34 -0
  85. package/dist/Instruments/Decay/KarplusSynth.js.map +1 -0
  86. package/dist/Instruments/Decay/PianoSynth.d.ts +14 -0
  87. package/dist/Instruments/Decay/PianoSynth.d.ts.map +1 -0
  88. package/dist/Instruments/Decay/PianoSynth.js +32 -0
  89. package/dist/Instruments/Decay/PianoSynth.js.map +1 -0
  90. package/dist/Instruments/Decay/SlapBassSynth.d.ts +15 -0
  91. package/dist/Instruments/Decay/SlapBassSynth.d.ts.map +1 -0
  92. package/dist/Instruments/Decay/SlapBassSynth.js +28 -0
  93. package/dist/Instruments/Decay/SlapBassSynth.js.map +1 -0
  94. package/dist/Instruments/ISynthInstrument.d.ts +16 -0
  95. package/dist/Instruments/ISynthInstrument.d.ts.map +1 -0
  96. package/dist/Instruments/ISynthInstrument.js +2 -0
  97. package/dist/Instruments/ISynthInstrument.js.map +1 -0
  98. package/dist/Instruments/InstrumentFactory.d.ts +2 -0
  99. package/dist/Instruments/InstrumentFactory.d.ts.map +1 -0
  100. package/dist/Instruments/InstrumentFactory.js +4 -0
  101. package/dist/Instruments/InstrumentFactory.js.map +1 -0
  102. package/dist/Instruments/Speciality/DrumSynth.d.ts +11 -0
  103. package/dist/Instruments/Speciality/DrumSynth.d.ts.map +1 -0
  104. package/dist/Instruments/Speciality/DrumSynth.js +61 -0
  105. package/dist/Instruments/Speciality/DrumSynth.js.map +1 -0
  106. package/dist/Instruments/Speciality/SoundEffectsSynth.d.ts +12 -0
  107. package/dist/Instruments/Speciality/SoundEffectsSynth.d.ts.map +1 -0
  108. package/dist/Instruments/Speciality/SoundEffectsSynth.js +27 -0
  109. package/dist/Instruments/Speciality/SoundEffectsSynth.js.map +1 -0
  110. package/dist/Instruments/Synthesizer.d.ts +15 -0
  111. package/dist/Instruments/Synthesizer.d.ts.map +1 -0
  112. package/dist/Instruments/Synthesizer.js +27 -0
  113. package/dist/Instruments/Synthesizer.js.map +1 -0
  114. package/dist/RLO-Player.d.ts +298 -0
  115. package/dist/RLO-Player.d.ts.map +1 -0
  116. package/dist/RLO-Player.js +724 -0
  117. package/dist/RLO-Player.js.map +1 -0
  118. package/dist/RLO-Transpiler.d.ts +22 -0
  119. package/dist/RLO-Transpiler.d.ts.map +1 -0
  120. package/dist/RLO-Transpiler.js +133 -0
  121. package/dist/RLO-Transpiler.js.map +1 -0
  122. package/dist/compiler.d.ts +40 -0
  123. package/dist/compiler.d.ts.map +1 -0
  124. package/dist/compiler.js +268 -0
  125. package/dist/compiler.js.map +1 -0
  126. package/dist/crush.d.ts +9 -0
  127. package/dist/crush.d.ts.map +1 -0
  128. package/dist/crush.js +20 -0
  129. package/dist/crush.js.map +1 -0
  130. package/dist/index.d.ts +36 -0
  131. package/dist/index.d.ts.map +1 -0
  132. package/dist/index.js +59 -0
  133. package/dist/index.js.map +1 -0
  134. package/dist/midi-parser.d.ts +10 -0
  135. package/dist/midi-parser.d.ts.map +1 -0
  136. package/dist/midi-parser.js +130 -0
  137. package/dist/midi-parser.js.map +1 -0
  138. package/dist/rlo-engine.min.js +655 -0
  139. package/dist/rlo-engine.min.js.map +1 -0
  140. package/dist/rlo-engine.min.umd.js +2 -0
  141. package/dist/rlo-engine.min.umd.js.map +1 -0
  142. package/dist/types.d.ts +16 -0
  143. package/dist/types.d.ts.map +1 -0
  144. package/dist/types.js +7 -0
  145. package/dist/types.js.map +1 -0
  146. package/dist/vite.config.d.ts +7 -0
  147. package/dist/vite.config.d.ts.map +1 -0
  148. package/dist/vite.config.js +244 -0
  149. package/dist/vite.config.js.map +1 -0
  150. package/dist/vite.config.js13k.d.ts +7 -0
  151. package/dist/vite.config.js13k.d.ts.map +1 -0
  152. package/dist/vite.config.js13k.js +72 -0
  153. package/dist/vite.config.js13k.js.map +1 -0
  154. package/package.json +50 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rlo-engine.min.js","sources":["../Instruments/Synthesizer.ts","../AudioEffects.ts","../RLO-Transpiler.ts","../RLO-Player.ts","../Instruments/CoreSynthBase.ts","../Instruments/Decay/DecaySynthBase.ts","../Instruments/Decay/PianoSynth.ts","../Instruments/Decay/ChromaticPercussionSynth.ts","../Instruments/Analog/AnalogSynthBase.ts","../Instruments/Analog/OrganSynth.ts","../Instruments/Decay/GuitarSynth.ts","../Instruments/Decay/ElectricGuitarSynth.ts","../Instruments/Analog/BassSynth.ts","../Instruments/Analog/StringSynth.ts","../Instruments/Decay/BrassSynth.ts","../Instruments/Analog/WoodwindSynth.ts","../Instruments/Analog/LeadSynth.ts","../Instruments/Analog/PadSynth.ts","../Instruments/Speciality/SoundEffectsSynth.ts","../Instruments/Decay/EthnicSynth.ts","../Instruments/Speciality/DrumSynth.ts","../Instruments/Analog/FMSynth.ts","../Instruments/Decay/AdditiveSynth.ts","../Instruments/Decay/KarplusSynth.ts","../Instruments/Analog/ReeseBassSynth.ts","../Instruments/Analog/FormantSynth.ts","../Instruments/Analog/ChiptuneSynth.ts","../Instruments/Decay/SlapBassSynth.ts","../index.ts"],"sourcesContent":["import { ISynthInstrument } from \"./ISynthInstrument.js\";\r\n\r\n/**\r\n * Handles routing and synthesis of different instrument types.\r\n */\r\nexport class Synthesizer {\r\n private _ctx: AudioContext;\r\n private _masterGain: GainNode;\r\n private _instruments: ISynthInstrument[];\r\n\r\n constructor(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n instruments: ISynthInstrument[],\r\n ) {\r\n this._ctx = ctx;\r\n this._masterGain = masterGain;\r\n this._instruments = instruments;\r\n }\r\n\r\n /**\r\n * Routes the note to the correct instrument synthesis method.\r\n */\r\n public _playNote(\r\n instrumentId: number,\r\n time: number,\r\n freq: number,\r\n duration: number,\r\n velocity: number,\r\n ): void {\r\n /** Key Tracking: High frequency waveforms carry significantly more perceived energy.\r\n * Gently rolling off the velocity of high notes prevents them from piercing the mix and distorting.\r\n * We also apply a 0.6 global headroom multiplier to prevent 30+ note crescendos from clipping. */\r\n const keyTrackVel = velocity * 0.6 * Math.min(1, 1600 / freq);\r\n\r\n const instrument = this._instruments[instrumentId] || this._instruments[0];\r\n\r\n if ((globalThis as any).DEBUG_MIDI) {\r\n console.log(\r\n `[MIDI Debug] Instr ID: ${instrumentId} | Class: ${instrument?.constructor.name || \"Unknown\"} | Freq: ${freq.toFixed(2)}Hz | Vel: ${velocity.toFixed(2)} | Dur: ${duration.toFixed(2)}s | Time: ${time.toFixed(2)}s`,\r\n );\r\n }\r\n\r\n if (instrument) {\r\n instrument._playNote(\r\n this._ctx,\r\n this._masterGain,\r\n time,\r\n freq,\r\n duration,\r\n keyTrackVel,\r\n );\r\n }\r\n }\r\n}\r\n","export type ReverbMode = \"concert\" | \"studio\";\r\n\r\n/**\r\n * Utility class for generating programmatic audio effects.\r\n */\r\nexport class AudioEffects {\r\n private static _cachedConcert: AudioBuffer | null = null;\r\n private static _cachedStudio: AudioBuffer | null = null;\r\n\r\n /**\r\n * Generates a mathematical impulse response for a Convolution Reverb node.\r\n * @param {AudioContext} ctx - The active AudioContext.\r\n * @param {ReverbMode} mode - The type of acoustic space to simulate.\r\n * @returns {AudioBuffer} The synthesized reverb impulse buffer.\r\n */\r\n public static _generateReverb(\r\n ctx: AudioContext,\r\n mode: ReverbMode = \"studio\",\r\n ): AudioBuffer {\r\n if (mode === \"concert\" && this._cachedConcert) return this._cachedConcert;\r\n if (mode === \"studio\" && this._cachedStudio) return this._cachedStudio;\r\n\r\n const isStudio = mode === \"studio\";\r\n const length =\r\n ctx.sampleRate *\r\n (isStudio ? 0.2 : 1.5); /** 0.2s for Studio, 1.5s for Concert */\r\n const decay = isStudio ? 8 : 4; /** Exponential decay factor */\r\n\r\n const impulse = ctx.createBuffer(2, length, ctx.sampleRate);\r\n for (let i = 0; i < 2; i++) {\r\n const channel = impulse.getChannelData(i);\r\n let lastOut = 0;\r\n for (let j = 0; j < length; j++) {\r\n /** Simple lowpass filter to absorb harsh high frequencies in the tail */\r\n const noise = Math.random() * 2 - 1;\r\n lastOut = lastOut + 0.3 * (noise - lastOut);\r\n /** True exponential acoustic decay multiplied by a linear fade to ensure 0 at the tail */\r\n channel[j] =\r\n lastOut * Math.exp(-decay * (j / length)) * (1 - j / length);\r\n }\r\n }\r\n\r\n // Cache the newly generated impulse\r\n return isStudio\r\n ? (this._cachedStudio = impulse)\r\n : (this._cachedConcert = impulse);\r\n }\r\n}\r\n","import { RloData } from \"./types.js\";\r\n\r\ndeclare const __ENABLE_TRANSPILER__: boolean;\r\nconst hasTranspiler =\r\n typeof __ENABLE_TRANSPILER__ !== \"undefined\" ? __ENABLE_TRANSPILER__ : true;\r\n\r\n/**\r\n * Universal translator for handling RLO data formats.\r\n * Converts between Human AoS (Array of Structures), Intermediate SoA (Structure of Arrays),\r\n * and highly compressed binary buffers.\r\n */\r\nexport class RLOTranspiler {\r\n /** Converts standard interleaved JSON into Delta-Timed Structure of Arrays */\r\n static _encodeToSoA(humanJson: RloData, fullRangeFreq: boolean = false) {\r\n if (!hasTranspiler) return null as unknown as typeof soa;\r\n const N = humanJson.notes.length / 5;\r\n const f = fullRangeFreq ? new Float32Array(N) : new Uint8Array(N);\r\n const t = new Uint16Array(N);\r\n const d = new Uint16Array(N);\r\n const v = new Uint8Array(N);\r\n const i = new Uint8Array(N);\r\n\r\n let lastRoundedTime = 0;\r\n for (let n = 0, ptr = 0; n < N; n++, ptr += 5) {\r\n const time = humanJson.notes[ptr + 1];\r\n const freq = humanJson.notes[ptr];\r\n if (fullRangeFreq) {\r\n f[n] = freq;\r\n } else {\r\n // Map the frequency in Hz back down to a 1-byte 0-255 index\r\n f[n] =\r\n freq > 0\r\n ? Math.max(\r\n 0,\r\n Math.min(255, Math.round(12 * Math.log2(freq / 440) + 69)),\r\n )\r\n : 0;\r\n }\r\n\r\n const roundedTime = Math.max(0, Math.round(time * 1000));\r\n t[n] = Math.min(65535, roundedTime - lastRoundedTime); // Clamp to Uint16 max to prevent wraparound\r\n d[n] = Math.min(\r\n 65535,\r\n Math.max(0, Math.round(humanJson.notes[ptr + 2] * 1000)),\r\n );\r\n v[n] = Math.max(\r\n 0,\r\n Math.min(255, Math.round(humanJson.notes[ptr + 3] * 255)),\r\n );\r\n i[n] = humanJson.notes[ptr + 4];\r\n lastRoundedTime += t[n]; // Add the clamped delta to accurately track absolute encoded time\r\n }\r\n\r\n const soa = {\r\n durationSecs: humanJson.durationSecs,\r\n f,\r\n t,\r\n d,\r\n v,\r\n i,\r\n };\r\n return soa;\r\n }\r\n\r\n /** Tightly packs the Delta-Timed SoA into a memory-aligned ArrayBuffer */\r\n static _encodeToBinary(\r\n humanJson: RloData,\r\n fullRangeFreq: boolean = false,\r\n ): ArrayBuffer {\r\n if (!hasTranspiler) return new ArrayBuffer(0);\r\n const isLittleEndian = new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;\r\n const soa = this._encodeToSoA(humanJson, fullRangeFreq);\r\n const N = soa.f.length;\r\n\r\n // Arrays: Time(2*N) + Dur(2*N) + Freq(1*N or 4*N) + Vel(1*N) + Inst(1*N)\r\n const bytesPerNote = fullRangeFreq ? 10 : 7;\r\n const buffer = new ArrayBuffer(12 + bytesPerNote * N);\r\n const view = new DataView(buffer);\r\n\r\n view.setUint8(0, 82);\r\n view.setUint8(1, 76);\r\n view.setUint8(2, 79);\r\n view.setUint8(3, fullRangeFreq ? 70 : 50); // 'RLOF' for Float32, 'RLO2' for Uint8\r\n view.setFloat32(4, soa.durationSecs, true);\r\n view.setUint32(8, N, true);\r\n\r\n if (isLittleEndian) {\r\n new Uint16Array(buffer, 12, N).set(soa.t);\r\n new Uint16Array(buffer, 12 + 2 * N, N).set(soa.d);\r\n if (fullRangeFreq) {\r\n new Float32Array(buffer, 12 + 4 * N, N).set(soa.f as Float32Array);\r\n }\r\n } else {\r\n // Explicitly write multi-byte values as Little-Endian using DataView\r\n // to ensure cross-platform compatibility (avoiding native endianness issues of TypedArrays)\r\n for (let n = 0; n < N; n++) {\r\n view.setUint16(12 + n * 2, soa.t[n], true);\r\n view.setUint16(12 + 2 * N + n * 2, soa.d[n], true);\r\n if (fullRangeFreq) {\r\n view.setFloat32(12 + 4 * N + n * 4, (soa.f as Float32Array)[n], true);\r\n }\r\n }\r\n }\r\n\r\n if (fullRangeFreq) {\r\n new Uint8Array(buffer, 12 + 8 * N, N).set(soa.v);\r\n new Uint8Array(buffer, 12 + 9 * N, N).set(soa.i);\r\n } else {\r\n new Uint8Array(buffer, 12 + 4 * N, N).set(soa.f as Uint8Array);\r\n new Uint8Array(buffer, 12 + 5 * N, N).set(soa.v);\r\n new Uint8Array(buffer, 12 + 6 * N, N).set(soa.i);\r\n }\r\n\r\n return buffer;\r\n }\r\n\r\n /** Reconstructs a high-speed runtime object directly from the binary buffer */\r\n static _decodeBinary(buffer: ArrayBuffer): RloData {\r\n if (!hasTranspiler) return { durationSecs: 0, notes: [] };\r\n const view = new DataView(buffer);\r\n const magic = String.fromCharCode(\r\n view.getUint8(0),\r\n view.getUint8(1),\r\n view.getUint8(2),\r\n view.getUint8(3),\r\n );\r\n if (magic !== \"RLO2\" && magic !== \"RLOF\")\r\n throw new Error(\"Invalid RLO Binary format. Please recompile tracks.\");\r\n const isFullRange = magic === \"RLOF\";\r\n\r\n const durationSecs = view.getFloat32(4, true);\r\n const N = view.getUint32(8, true);\r\n\r\n // Single-byte arrays are endian-agnostic\r\n const f8 = isFullRange ? null : new Uint8Array(buffer, 12 + 4 * N, N);\r\n const v = new Uint8Array(buffer, 12 + (isFullRange ? 8 : 5) * N, N);\r\n const i = new Uint8Array(buffer, 12 + (isFullRange ? 9 : 6) * N, N);\r\n\r\n const notes: number[] = new Array(N * 5);\r\n let currentTime = 0;\r\n\r\n for (let n = 0, ptr = 0; n < N; n++, ptr += 5) {\r\n // Read multi-byte values explicitly as Little-Endian\r\n const tn = view.getUint16(12 + n * 2, true);\r\n const dn = view.getUint16(12 + 2 * N + n * 2, true);\r\n const fn = isFullRange\r\n ? view.getFloat32(12 + 4 * N + n * 4, true)\r\n : f8![n];\r\n\r\n currentTime += tn / 1000;\r\n notes[ptr] = isFullRange\r\n ? fn\r\n : fn > 0\r\n ? 440 * Math.pow(2, (fn - 69) / 12)\r\n : 0;\r\n notes[ptr + 1] = currentTime;\r\n notes[ptr + 2] = dn / 1000;\r\n notes[ptr + 3] = v[n] / 255;\r\n notes[ptr + 4] = i[n];\r\n }\r\n\r\n return { durationSecs, notes };\r\n }\r\n}\r\n","import { RloData } from \"./types.js\";\r\nimport { Synthesizer } from \"./Instruments/Synthesizer.js\";\r\nimport { AudioEffects, ReverbMode } from \"./AudioEffects.js\";\r\nimport { RLOTranspiler } from \"./RLO-Transpiler.js\"; // Corrected import path\r\nimport { ISynthInstrument } from \"./Instruments/ISynthInstrument.js\";\r\n\r\nexport { RLOTranspiler };\r\nexport type { ISynthInstrument };\r\n\r\n/**\r\n * A dummy synthesizer that does absolutely nothing.\r\n * Useful for completely muting specific MIDI IDs in an instrument map.\r\n */\r\nexport const SilentSynth: ISynthInstrument = {\r\n _playNote: () => {},\r\n};\r\n\r\n/** Configuration options for playing sequences/music. */\r\nexport interface PlaySequenceOptions {\r\n loop?: boolean;\r\n fadeInTime?: number;\r\n playbackRate?: number;\r\n volume?: number;\r\n}\r\n\r\n/** Configuration options for playing single Sound Effects. */\r\nexport interface SFXOptions {\r\n velocity?: number;\r\n timeOffset?: number;\r\n}\r\n\r\n/** Configuration for a standard ADSR volume envelope. */\r\nexport interface ADSREnvelope {\r\n attack?: number;\r\n decay?: number;\r\n sustain?: number;\r\n release?: number;\r\n peak?: number;\r\n}\r\n\r\n/**\r\n * Syntactic sugar for applying a standard ADSR envelope to a Web Audio GainNode.\r\n * @param gainParam The AudioParam (e.g., gainNode.gain) to animate.\r\n * @param now The physical start time of the sound.\r\n * @param duration The total held duration of the note.\r\n * @param opts ADSR configuration object.\r\n */\r\nexport function applyEnvelope(\r\n gainParam: AudioParam,\r\n now: number,\r\n duration: number,\r\n opts: ADSREnvelope,\r\n): void {\r\n const a = opts.attack ?? 0.05;\r\n const d = opts.decay ?? 0.1;\r\n const s = opts.sustain ?? 0.8;\r\n const r = opts.release ?? 0.1;\r\n const peak = opts.peak ?? 1.0;\r\n\r\n gainParam.setValueAtTime(0, now);\r\n const realDur = Math.max(0, duration);\r\n\r\n if (realDur <= a) {\r\n const partialPeak = peak * (realDur / (a || 1));\r\n gainParam.linearRampToValueAtTime(partialPeak, now + realDur * 0.5);\r\n gainParam.linearRampToValueAtTime(0, now + realDur);\r\n } else if (realDur <= a + d) {\r\n gainParam.linearRampToValueAtTime(peak, now + a);\r\n gainParam.linearRampToValueAtTime(0, now + realDur);\r\n } else {\r\n gainParam.linearRampToValueAtTime(peak, now + a);\r\n gainParam.linearRampToValueAtTime(peak * s, now + a + d);\r\n const releaseStart = Math.max(now + a + d, now + realDur - r);\r\n gainParam.setValueAtTime(peak * s, releaseStart);\r\n gainParam.linearRampToValueAtTime(0, now + realDur);\r\n }\r\n}\r\n\r\n/** Flag injected by build tools to enable or disable string note parsing. */\r\ndeclare const __ENABLE_NOTE_PARSER__: boolean;\r\nconst hasNoteParser =\r\n typeof __ENABLE_NOTE_PARSER__ !== \"undefined\" ? __ENABLE_NOTE_PARSER__ : true;\r\n\r\n/**\r\n * Converts a musical note string (e.g., 'C4', 'F#5') to its frequency in Hz.\r\n * If a number is provided, it is returned as-is.\r\n */\r\nexport function Note(pitch: string | number): number {\r\n if (typeof pitch === \"number\") return pitch;\r\n if (!hasNoteParser) return 0;\r\n const match = pitch.match(/^([a-gA-G])([#b]?)(\\d)$/);\r\n if (!match) return 0;\r\n const offsets: Record<string, number> = {\r\n C: -9,\r\n D: -7,\r\n E: -5,\r\n F: -4,\r\n G: -2,\r\n A: 0,\r\n B: 2,\r\n };\r\n const [, note, accidental, octave] = match;\r\n let semitone = offsets[note.toUpperCase()];\r\n if (accidental === \"#\") semitone++;\r\n if (accidental === \"b\") semitone--;\r\n semitone += (parseInt(octave, 10) - 4) * 12;\r\n return Number((440 * Math.pow(2, semitone / 12)).toFixed(2));\r\n}\r\n\r\n/** A fluent, chainable builder for creating RloData sequences procedurally. */\r\nexport class RLOSequenceBuilder {\r\n private _notes: number[] = [];\r\n private _duration: number = 0;\r\n\r\n public addNote(opts: {\r\n instrument: number;\r\n pitch: string | number;\r\n duration: number;\r\n time?: number;\r\n velocity?: number;\r\n }): this {\r\n const time = opts.time !== undefined ? opts.time : this._duration;\r\n const freq = Note(opts.pitch);\r\n const vel = opts.velocity ?? 1.0;\r\n this._notes.push(freq, time, opts.duration, vel, opts.instrument);\r\n this._duration = Math.max(this._duration, time + opts.duration);\r\n return this;\r\n }\r\n public setDuration(secs: number): this {\r\n this._duration = secs;\r\n return this;\r\n }\r\n public compile(): RloData {\r\n return { durationSecs: this._duration, notes: this._notes };\r\n }\r\n}\r\n\r\n/** Flag injected by build tools (e.g., Vite) to enable or disable the transpiler (dead-code elimination). */\r\ndeclare const __ENABLE_TRANSPILER__: boolean;\r\nconst hasTranspiler =\r\n typeof __ENABLE_TRANSPILER__ !== \"undefined\" ? __ENABLE_TRANSPILER__ : true;\r\n\r\n/** Flag injected by build tools to enable or disable the RLOMusicPlayer features. */\r\ndeclare const __ENABLE_MUSIC_PLAYER__: boolean;\r\nconst hasMusicPlayer =\r\n typeof __ENABLE_MUSIC_PLAYER__ !== \"undefined\"\r\n ? __ENABLE_MUSIC_PLAYER__\r\n : true;\r\n\r\n/** Flag injected by build tools to enable or disable the RLOGameEngine features. */\r\ndeclare const __ENABLE_GAME_ENGINE__: boolean;\r\nconst hasGameEngine =\r\n typeof __ENABLE_GAME_ENGINE__ !== \"undefined\" ? __ENABLE_GAME_ENGINE__ : true;\r\n\r\n/** Flag injected by build tools to enable or disable the Web Worker metronome for background playback. */\r\ndeclare const __ENABLE_WORKER_METRONOME__: boolean;\r\nconst hasWorkerMetronome =\r\n typeof __ENABLE_WORKER_METRONOME__ !== \"undefined\"\r\n ? __ENABLE_WORKER_METRONOME__\r\n : false;\r\n\r\n/**\r\n * A \"dumb\" mapping mechanism for strict JS13K size-coding.\r\n * Bypasses the closest-match algorithm and explicitly assigns synths to individual IDs.\r\n * @param assignments An array of synthesizer modules and the exact MIDI IDs they should respond to.\r\n * @returns A fully populated array of 129 elements, with unassigned slots remaining null.\r\n */\r\nexport function createDirectMap(\r\n assignments: { synth: ISynthInstrument; ids: number[] }[],\r\n): ISynthInstrument[] {\r\n const mapArray = new Array(129).fill(null);\r\n assignments.forEach((a) => {\r\n a.ids.forEach((id) => (mapArray[id] = a.synth));\r\n });\r\n return mapArray;\r\n}\r\n\r\n/**\r\n * Mathematically maps instruments by MIDI ID, auto-falling back to the closest available synthesizer.\r\n * @param modules An array of synthesizer module configurations to map.\r\n * @returns A fully populated array of 129 synthesizer instruments.\r\n */\r\nexport function createInstrumentMap(\r\n modules: { synth: ISynthInstrument; start: number; end: number }[],\r\n): ISynthInstrument[] {\r\n const mapArray = new Array(129).fill(null);\r\n modules.forEach((m) => {\r\n for (let i = m.start; i <= m.end; i++) mapArray[i] = m.synth;\r\n });\r\n\r\n for (let i = 0; i < 129; i++) {\r\n if (mapArray[i] === null) {\r\n let closest = null;\r\n let minDiff = Infinity;\r\n for (let j = 0; j < 129; j++) {\r\n if (mapArray[j] !== null) {\r\n const diff = Math.abs(i - j);\r\n if (diff < minDiff) {\r\n minDiff = diff;\r\n closest = mapArray[j];\r\n }\r\n }\r\n }\r\n mapArray[i] = closest;\r\n }\r\n }\r\n return mapArray;\r\n}\r\n\r\n/**\r\n * Creates a new instrument map by merging custom synth overrides into an existing base map.\r\n * @param baseMap The base instrument map array.\r\n * @param overrides An array of synthesizer module configurations to override in the base map.\r\n * @returns A new array of synthesizer instruments with the overrides applied.\r\n */\r\nexport function extendInstrumentMap(\r\n baseMap: ISynthInstrument[],\r\n overrides: { synth: ISynthInstrument; start: number; end: number }[],\r\n): ISynthInstrument[] {\r\n const newMap = [...baseMap];\r\n overrides.forEach((m) => {\r\n for (let i = m.start; i <= m.end; i++) newMap[i] = m.synth;\r\n });\r\n return newMap;\r\n}\r\n\r\n/**\r\n * RLOCore: The bare-metal procedural sequencer.\r\n * Zero networking, zero master effects. Just pure math to audio waves.\r\n */\r\nexport class RLOCore {\r\n /** The Web Audio API context used for all audio operations. */\r\n protected _ctx: AudioContext;\r\n /** Indicates whether a sequence is currently playing. */\r\n protected _isPlaying: boolean = false;\r\n /** Stores the timer ID for the standard JavaScript timeout metronome. */\r\n protected _timer: ReturnType<typeof setTimeout> | null = null;\r\n /** Stores the Web Worker instance for accurate background metronome timing. */\r\n protected _workerTimer: Worker | null = null;\r\n /** Incremental ID to keep track of the current playback sequence and prevent overlapping schedules. */\r\n protected _sequenceId: number = 0;\r\n /** The current track playback time in seconds. */\r\n protected _trkT: number = 0;\r\n /** The total duration of the currently playing track in seconds. */\r\n protected _trkD: number = 0; // _currentTrackDuration\r\n /** Array of active audio nodes that need to be cleaned up when playback stops. */\r\n protected _activeNodes: AudioNode[] = [];\r\n /** The current global volume level (0.0 to 1.0). */\r\n protected _volume: number = 0.5;\r\n /** The target time to seek to on the next scheduling tick. */\r\n protected _seekTarget: number | null = null;\r\n\r\n /** The playback speed multiplier (1.0 is normal speed). */\r\n public playbackRate: number = 1.0;\r\n\r\n /** Array of synthesizers mapped to their corresponding MIDI instrument IDs. */\r\n protected _instrumentMap: ISynthInstrument[];\r\n /** The object URL for the Web Worker script, used for cleanup. */\r\n protected _workerUrl: string | null = null;\r\n\r\n /**\r\n * Initializes a new RLOCore instance.\r\n * @param audioContext The Web Audio API context.\r\n * @param instrumentMap The instrument routing map to use for synthesis.\r\n */\r\n constructor(\r\n audioContext: AudioContext,\r\n instrumentMap: ISynthInstrument[] = [],\r\n ) {\r\n this._ctx = audioContext;\r\n this._instrumentMap = instrumentMap;\r\n\r\n if (hasWorkerMetronome) {\r\n const blob = new Blob(\r\n [\r\n `\r\n let timerID = null;\r\n self.onmessage = function(e) {\r\n if (e.data === 'start') {\r\n if (timerID) clearInterval(timerID);\r\n timerID = setInterval(() => self.postMessage('tick'), 50);\r\n } else if (e.data === 'stop' && timerID) {\r\n clearInterval(timerID); timerID = null;\r\n }\r\n };\r\n `,\r\n ],\r\n { type: \"application/javascript\" },\r\n );\r\n this._workerUrl = URL.createObjectURL(blob);\r\n this._workerTimer = new Worker(this._workerUrl);\r\n }\r\n }\r\n\r\n /** Gets the current time of the audio context. */\r\n protected get _now(): number {\r\n return this._ctx.currentTime;\r\n }\r\n\r\n /**\r\n * Sets the global playback volume.\r\n * @param vol The volume level (0.0 to 1.0).\r\n */\r\n public setVolume(vol: number): void {\r\n this._volume = vol;\r\n }\r\n\r\n /**\r\n * Seeks the currently playing track to the specified time in seconds.\r\n * @param timeInSeconds The target time in seconds.\r\n */\r\n public seek(timeInSeconds: number): void {\r\n if (this._trkD > 0) {\r\n this._seekTarget = Math.max(0, timeInSeconds) % this._trkD;\r\n }\r\n }\r\n\r\n /** Stops playback and clears all scheduled audio nodes and timers. */\r\n public stop(): void {\r\n this._isPlaying = false;\r\n this._sequenceId++;\r\n if (this._timer) clearTimeout(this._timer);\r\n if (this._workerTimer) this._workerTimer.postMessage(\"stop\");\r\n\r\n const nodesToClean = this._activeNodes;\r\n this._activeNodes = [];\r\n\r\n nodesToClean.forEach((node) => {\r\n try {\r\n node.disconnect();\r\n } catch (e) {}\r\n });\r\n }\r\n\r\n /** Destroys the core engine, releasing memory and background workers. */\r\n public dispose(): void {\r\n this.stop();\r\n if (this._workerTimer) {\r\n this._workerTimer.terminate();\r\n this._workerTimer = null;\r\n }\r\n if (this._workerUrl) {\r\n URL.revokeObjectURL(this._workerUrl);\r\n this._workerUrl = null;\r\n }\r\n }\r\n\r\n /** Creates and returns a new GainNode. */\r\n protected _gain(): GainNode {\r\n return this._ctx.createGain();\r\n }\r\n\r\n /**\r\n * Applies a linear fade to an AudioParam over a specified duration.\r\n * @param gain The AudioParam to fade.\r\n * @param target The target value.\r\n * @param time The duration of the fade in seconds.\r\n */\r\n protected _fade(gain: AudioParam, target: number, time: number): void {\r\n gain.setValueAtTime(time > 0 ? 0 : target, this._now);\r\n if (time > 0) gain.linearRampToValueAtTime(target, this._now + time);\r\n }\r\n\r\n /** Creates a pre-configured DynamicsCompressorNode for mastering. */\r\n protected _comp(ctx: AudioContext = this._ctx): DynamicsCompressorNode {\r\n const c = ctx.createDynamicsCompressor();\r\n c.threshold.value = -24;\r\n c.knee.value = 12;\r\n c.ratio.value = 8;\r\n c.attack.value = 0.001;\r\n c.release.value = 0.25;\r\n return c;\r\n }\r\n\r\n /**\r\n * Sets up the master audio routing graph for this core.\r\n * @param fadeInTime Optional fade-in duration in seconds.\r\n * @returns An object containing the destination AudioNode.\r\n */\r\n protected _createRouting(fadeInTime: number = 0): { destination: AudioNode } {\r\n const gain = this._gain();\r\n this._fade(gain.gain, this._volume, fadeInTime);\r\n gain.connect(this._ctx.destination);\r\n this._activeNodes.push(gain);\r\n return { destination: gain };\r\n }\r\n\r\n /**\r\n * Plays a compiled RLO sequence.\r\n * @param track The compiled RloData to play.\r\n * @param loopOrOpts Whether the track should loop, or an Options Object.\r\n * @param fadeInTime Optional fade-in duration in seconds (default 0).\r\n */\r\n public playSequence(\r\n track: RloData,\r\n loopOrOpts: boolean | PlaySequenceOptions = true,\r\n oldFadeInTime: number = 0,\r\n ): void {\r\n let loop = true;\r\n let fadeInTime = oldFadeInTime;\r\n if (typeof loopOrOpts === \"object\") {\r\n loop = loopOrOpts.loop ?? true;\r\n fadeInTime = loopOrOpts.fadeInTime ?? 0;\r\n if (loopOrOpts.playbackRate !== undefined)\r\n this.playbackRate = loopOrOpts.playbackRate;\r\n if (loopOrOpts.volume !== undefined) this.setVolume(loopOrOpts.volume);\r\n } else {\r\n loop = loopOrOpts;\r\n }\r\n\r\n this.stop();\r\n if (this._ctx.state === \"suspended\") this._ctx.resume();\r\n\r\n this._isPlaying = true;\r\n const currentSequenceId = ++this._sequenceId;\r\n this._trkD = track.durationSecs;\r\n\r\n const { destination } = this._createRouting(fadeInTime);\r\n const synthesizer = new Synthesizer(\r\n this._ctx,\r\n destination as GainNode,\r\n this._instrumentMap,\r\n );\r\n\r\n const lookaheadTime = 0.5;\r\n this._trkT = -0.05 * this.playbackRate;\r\n let lastScheduleTime = this._now;\r\n let loopOffsetSecs = 0;\r\n let notePtr = 0;\r\n const notes = track.notes;\r\n const len = notes.length;\r\n\r\n const schedule = () => {\r\n if (!this._isPlaying || this._sequenceId !== currentSequenceId) return;\r\n const currentPhysicalTime = this._now;\r\n const deltaPhysical = currentPhysicalTime - lastScheduleTime;\r\n lastScheduleTime = currentPhysicalTime;\r\n\r\n if (this._seekTarget !== null) {\r\n this._trkT = this._seekTarget;\r\n loopOffsetSecs = 0;\r\n notePtr = 0;\r\n while (notePtr < len && notes[notePtr + 1] < this._seekTarget) {\r\n notePtr += 5;\r\n }\r\n this._seekTarget = null;\r\n } else {\r\n this._trkT += deltaPhysical * this.playbackRate;\r\n }\r\n\r\n const loopDurationSecs = track.durationSecs;\r\n\r\n while (notePtr < len) {\r\n const freq = notes[notePtr];\r\n const noteTime = notes[notePtr + 1];\r\n const noteDur = notes[notePtr + 2];\r\n const velocity = notes[notePtr + 3];\r\n const instrumentId = notes[notePtr + 4];\r\n\r\n const noteTrackTime = loopOffsetSecs + noteTime;\r\n\r\n if (noteTrackTime < this._trkT + lookaheadTime * this.playbackRate) {\r\n const notePhysicalTime =\r\n currentPhysicalTime +\r\n Math.max(0, (noteTrackTime - this._trkT) / this.playbackRate);\r\n synthesizer._playNote(\r\n instrumentId,\r\n notePhysicalTime,\r\n freq,\r\n noteDur / this.playbackRate,\r\n velocity,\r\n );\r\n notePtr += 5;\r\n } else {\r\n break;\r\n }\r\n }\r\n\r\n if (notePtr >= len) {\r\n if (loop) {\r\n notePtr = 0;\r\n loopOffsetSecs += loopDurationSecs;\r\n schedule();\r\n } else {\r\n if (this._workerTimer) this._workerTimer.postMessage(\"stop\");\r\n }\r\n return;\r\n }\r\n if (!this._workerTimer) {\r\n this._timer = setTimeout(schedule, 50);\r\n }\r\n };\r\n if (this._workerTimer) {\r\n this._workerTimer.onmessage = () => schedule();\r\n this._workerTimer.postMessage(\"start\");\r\n }\r\n schedule();\r\n }\r\n}\r\n\r\n/**\r\n * RLOMusicPlayer: The standard music player.\r\n * Includes network fetching, gzip decoding, convolution reverb, compression, and UI playback controls.\r\n */\r\nexport class RLOMusicPlayer extends RLOCore {\r\n /** The master volume control node. */\r\n private _masterGain: GainNode | null = null;\r\n /** The convolver node used for reverb effects. */\r\n private _reverb: ConvolverNode | null = null;\r\n /** The gain node controlling the wet/dry mix of the reverb effect. */\r\n private _fxGain: GainNode | null = null;\r\n /** A cache of recently loaded tracks to prevent redundant network requests. */\r\n private _trackCache: Map<string, RloData> = new Map();\r\n /** Event handler for pausing/resuming audio when the document visibility changes. */\r\n private _visibilityHandler!: () => void;\r\n /** The maximum number of tracks to store in the cache. */\r\n private _maxCacheSize: number = 20;\r\n /** The current acoustic space simulation mode. */\r\n private _reverbMode: ReverbMode = \"concert\";\r\n\r\n /**\r\n * Initializes a new RLOMusicPlayer instance with advanced effects and network capabilities.\r\n * @param audioContext The Web Audio API context.\r\n * @param instrumentMap Optional custom instrument map.\r\n */\r\n constructor(\r\n audioContext: AudioContext,\r\n instrumentMap: ISynthInstrument[] = [],\r\n ) {\r\n super(audioContext, instrumentMap);\r\n if (!hasMusicPlayer) return;\r\n\r\n AudioEffects._generateReverb(this._ctx, \"concert\");\r\n AudioEffects._generateReverb(this._ctx, \"studio\");\r\n\r\n this._visibilityHandler = () => {\r\n if (document.hidden) {\r\n this._ctx.suspend();\r\n } else if (this._isPlaying) {\r\n this._ctx.resume();\r\n }\r\n };\r\n\r\n // Only pause the AudioContext on tab hide if we AREN'T explicitly running in the background\r\n if (typeof document !== \"undefined\" && !hasWorkerMetronome) {\r\n document.addEventListener(\"visibilitychange\", this._visibilityHandler);\r\n }\r\n }\r\n\r\n /**\r\n * Changes the acoustic space simulation for the reverb effect.\r\n * @param mode 'concert' (large hall) or 'studio' (small room).\r\n */\r\n public setReverbMode(mode: ReverbMode): void {\r\n if (!hasMusicPlayer) return;\r\n this._reverbMode = mode;\r\n if (this._reverb && this._fxGain) {\r\n this._reverb.buffer = AudioEffects._generateReverb(this._ctx, mode);\r\n this._fxGain.gain.setTargetAtTime(\r\n mode === \"studio\" ? 0.05 : 0.2,\r\n this._now,\r\n 0.1,\r\n );\r\n }\r\n }\r\n\r\n /** Disposes the player, clearing caches and removing event listeners. */\r\n public dispose(): void {\r\n if (!hasMusicPlayer) return super.dispose();\r\n super.dispose();\r\n\r\n if (typeof document !== \"undefined\" && !hasWorkerMetronome) {\r\n document.removeEventListener(\"visibilitychange\", this._visibilityHandler);\r\n }\r\n this._trackCache.clear();\r\n }\r\n\r\n /**\r\n * Sets the playback volume, smoothly ramping to the target value.\r\n * @param vol The volume level (0.0 to 1.0).\r\n */\r\n public setVolume(vol: number): void {\r\n super.setVolume(vol);\r\n if (!hasMusicPlayer) return;\r\n if (this._masterGain) {\r\n this._masterGain.gain.setTargetAtTime(vol, this._now, 0.1);\r\n }\r\n }\r\n\r\n /** Returns the current playback time of the track in seconds. */\r\n public getCurrentTime(): number {\r\n if (!hasMusicPlayer) return 0;\r\n if (this._trkD === 0 || !this._isPlaying) return 0;\r\n return Math.max(0, this._trkT) % this._trkD;\r\n }\r\n\r\n /** Returns the total duration of the currently loaded track in seconds. */\r\n public getTotalDuration(): number {\r\n if (!hasMusicPlayer) return 0;\r\n return this._trkD;\r\n }\r\n\r\n /**\r\n * Overrides the core routing to include reverb, filtering, and mastering compression.\r\n * @param fadeInTime Optional fade-in duration in seconds.\r\n * @returns An object containing the destination AudioNode.\r\n */\r\n protected _createRouting(fadeInTime: number = 0): { destination: AudioNode } {\r\n if (!hasMusicPlayer) return super._createRouting(fadeInTime);\r\n this._reverb = this._ctx.createConvolver();\r\n this._reverb.buffer = AudioEffects._generateReverb(\r\n this._ctx,\r\n this._reverbMode,\r\n );\r\n this._masterGain = this._gain();\r\n this._activeNodes.push(this._reverb, this._masterGain);\r\n\r\n this._fade(this._masterGain.gain, this._volume, fadeInTime);\r\n\r\n this._fxGain = this._gain();\r\n this._fxGain.gain.value = this._reverbMode === \"studio\" ? 0.05 : 0.2;\r\n this._activeNodes.push(this._fxGain);\r\n\r\n const masterFilter = this._ctx.createBiquadFilter();\r\n masterFilter.type = \"lowpass\";\r\n masterFilter.frequency.value = Math.min(this._ctx.sampleRate / 2 - 1, 6500);\r\n this._activeNodes.push(masterFilter);\r\n\r\n const compressor = this._comp();\r\n this._activeNodes.push(compressor);\r\n\r\n this._masterGain\r\n .connect(masterFilter)\r\n .connect(compressor)\r\n .connect(this._ctx.destination);\r\n this._masterGain\r\n .connect(this._reverb)\r\n .connect(this._fxGain)\r\n .connect(masterFilter);\r\n\r\n return { destination: this._masterGain };\r\n }\r\n\r\n /**\r\n * Loads and plays a track from a URL, a JSON object, or an existing RloData object.\r\n * @param trackUrlOrData The URL to fetch, or the raw track data.\r\n * @param fadeInOrOpts Optional fade-in duration in seconds, or an Options Object.\r\n * @param oldLoop Whether to loop the track (default true).\r\n */\r\n public async play(\r\n trackUrlOrData: string | RloData,\r\n fadeInOrOpts: number | PlaySequenceOptions = 0,\r\n oldLoop: boolean = true,\r\n ): Promise<void> {\r\n if (!hasMusicPlayer) return;\r\n let track: RloData;\r\n\r\n let fadeInTime = 0;\r\n let optionsObj: PlaySequenceOptions = {};\r\n if (typeof fadeInOrOpts === \"object\") {\r\n fadeInTime = fadeInOrOpts.fadeInTime ?? 0;\r\n optionsObj = fadeInOrOpts;\r\n } else {\r\n fadeInTime = fadeInOrOpts;\r\n optionsObj = { fadeInTime, loop: oldLoop };\r\n }\r\n\r\n if (typeof trackUrlOrData === \"string\") {\r\n if (this._trackCache.has(trackUrlOrData)) {\r\n track = this._trackCache.get(trackUrlOrData)!;\r\n } else {\r\n const response = await fetch(trackUrlOrData);\r\n\r\n if (!hasTranspiler || trackUrlOrData.toLowerCase().endsWith(\".json\")) {\r\n const text = await response.text();\r\n track = JSON.parse(text);\r\n } else {\r\n const rawBuffer = await response.arrayBuffer();\r\n const view = new DataView(rawBuffer);\r\n // Check for 'RLO' magic bytes to see if the browser natively decompressed it\r\n const isDecompressed =\r\n view.byteLength >= 3 &&\r\n view.getUint8(0) === 82 &&\r\n view.getUint8(1) === 76 &&\r\n view.getUint8(2) === 79;\r\n\r\n if (isDecompressed) {\r\n track = RLOTranspiler._decodeBinary(rawBuffer);\r\n } else {\r\n const ds = new (window as any).DecompressionStream(\"gzip\");\r\n const writer = ds.writable.getWriter();\r\n writer.write(rawBuffer);\r\n writer.close();\r\n track = RLOTranspiler._decodeBinary(\r\n await new Response(ds.readable).arrayBuffer(),\r\n );\r\n }\r\n }\r\n this._trackCache.set(trackUrlOrData, track);\r\n\r\n if (this._trackCache.size > this._maxCacheSize) {\r\n const firstKey = this._trackCache.keys().next().value;\r\n if (firstKey) this._trackCache.delete(firstKey);\r\n }\r\n }\r\n } else {\r\n track = trackUrlOrData;\r\n }\r\n\r\n this.playSequence(track, optionsObj);\r\n }\r\n\r\n /** Stops playback and gently resets the master gain nodes. */\r\n public stop(): void {\r\n if (!hasMusicPlayer) return super.stop();\r\n if (this._masterGain) {\r\n const now = this._now;\r\n this._masterGain.gain.cancelScheduledValues(now);\r\n this._masterGain.gain.setValueAtTime(0, now);\r\n\r\n this._masterGain = null;\r\n this._fxGain = null;\r\n this._reverb = null;\r\n }\r\n super.stop();\r\n }\r\n}\r\n\r\n/**\r\n * RLOGameEngine: Built for instant action.\r\n * Features a persistent master routing bus so SFX can play over background music\r\n * without interrupting each other or causing clipping.\r\n */\r\nexport class RLOGameEngine extends RLOCore {\r\n /** The persistent master routing bus volume node. */\r\n private _masterGain!: GainNode;\r\n /** The dedicated routing bus for Sound Effects. */\r\n private _sfxGain!: GainNode;\r\n /** The dedicated routing bus for Background Music. */\r\n private _musicGain!: GainNode;\r\n /** A separate synthesizer instance strictly for playing non-blocking sound effects. */\r\n private _sfxSynthesizer!: Synthesizer;\r\n\r\n /**\r\n * Initializes a new RLOGameEngine instance tailored for dynamic real-time audio.\r\n * @param audioContext The Web Audio API context.\r\n * @param instrumentMap Optional custom instrument map.\r\n */\r\n constructor(\r\n audioContext: AudioContext,\r\n instrumentMap: ISynthInstrument[] = [],\r\n ) {\r\n super(audioContext, instrumentMap);\r\n if (!hasGameEngine) return;\r\n\r\n this._masterGain = this._gain();\r\n this._masterGain.gain.value = this._volume;\r\n\r\n const compressor = this._comp();\r\n\r\n this._masterGain.connect(compressor).connect(this._ctx.destination);\r\n\r\n this._musicGain = this._gain();\r\n this._musicGain.connect(this._masterGain);\r\n\r\n this._sfxGain = this._gain();\r\n this._sfxGain.connect(this._masterGain);\r\n this._sfxSynthesizer = new Synthesizer(\r\n this._ctx,\r\n this._sfxGain,\r\n this._instrumentMap,\r\n );\r\n }\r\n\r\n /**\r\n * Smoothly changes the master volume for all game audio.\r\n * @param vol The volume level (0.0 to 1.0).\r\n */\r\n public setVolume(vol: number): void {\r\n super.setVolume(vol);\r\n if (!hasGameEngine) return;\r\n this._masterGain.gain.setTargetAtTime(vol, this._now, 0.1);\r\n }\r\n\r\n /**\r\n * Smoothly changes the volume strictly for the background music routing bus.\r\n * @param vol The volume level (0.0 to 1.0).\r\n */\r\n public setMusicVolume(vol: number): void {\r\n if (!hasGameEngine) return;\r\n this._musicGain.gain.setTargetAtTime(vol, this._now, 0.1);\r\n }\r\n\r\n /**\r\n * Smoothly changes the volume strictly for the sound effects routing bus.\r\n * @param vol The volume level (0.0 to 1.0).\r\n */\r\n public setSFXVolume(vol: number): void {\r\n if (!hasGameEngine) return;\r\n this._sfxGain.gain.setTargetAtTime(vol, this._now, 0.1);\r\n }\r\n\r\n /**\r\n * Overrides the core routing to tap into the persistent master game bus.\r\n * @param fadeInTime Optional fade-in duration in seconds.\r\n * @returns An object containing the destination AudioNode.\r\n */\r\n protected _createRouting(fadeInTime: number = 0): { destination: AudioNode } {\r\n if (!hasGameEngine) return super._createRouting(fadeInTime);\r\n const musicGain = this._gain();\r\n musicGain.connect(this._musicGain);\r\n this._activeNodes.push(musicGain);\r\n\r\n this._fade(musicGain.gain, 1, fadeInTime);\r\n\r\n return { destination: musicGain };\r\n }\r\n\r\n /**\r\n * Plays a fire-and-forget sound effect dynamically at runtime.\r\n * @param instrumentId The General MIDI ID of the instrument to use (e.g., 128 for percussion).\r\n * @param freqOrNote The frequency in Hz, or a Note String (e.g. 'E4').\r\n * @param duration The duration of the sound effect in seconds.\r\n * @param velocityOrOpts The velocity (0.0 to 1.0), or an Options Object.\r\n * @param oldTimeOffset Optional delay in seconds before the sound effect plays.\r\n */\r\n public playSFX(\r\n instrumentId: number,\r\n freqOrNote: number | string,\r\n duration: number,\r\n velocityOrOpts: number | SFXOptions = 1.0,\r\n oldTimeOffset: number = 0,\r\n ) {\r\n if (!hasGameEngine) return;\r\n if (this._ctx.state === \"suspended\") this._ctx.resume();\r\n\r\n let velocity = 1.0;\r\n let timeOffset = oldTimeOffset;\r\n if (typeof velocityOrOpts === \"object\") {\r\n velocity = velocityOrOpts.velocity ?? 1.0;\r\n timeOffset = velocityOrOpts.timeOffset ?? 0;\r\n } else {\r\n velocity = velocityOrOpts;\r\n }\r\n this._sfxSynthesizer._playNote(\r\n instrumentId,\r\n this._now + timeOffset,\r\n Note(freqOrNote),\r\n duration,\r\n velocity,\r\n );\r\n }\r\n\r\n /**\r\n * Plays an entire compiled RLO sequence as a fire-and-forget sound effect.\r\n * Note: This bypasses the sequencer and schedules all notes instantly. Ideal for short, complex jingles.\r\n * @param track The compiled RloData to play.\r\n * @param timeOffset Optional delay in seconds before the sequence starts.\r\n */\r\n public playSFXSequence(track: RloData, timeOffset: number = 0): void {\r\n if (!hasGameEngine) return;\r\n if (this._ctx.state === \"suspended\") this._ctx.resume();\r\n\r\n const start = this._now + timeOffset;\r\n const n = track.notes;\r\n const len = n.length;\r\n\r\n for (let i = 0; i < len; i += 5) {\r\n this._sfxSynthesizer._playNote(\r\n n[i + 4],\r\n start + n[i + 1],\r\n n[i],\r\n n[i + 2],\r\n n[i + 3],\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Plays a background music track, routing it through the master game bus.\r\n * @param track The compiled RloData to play.\r\n * @param loopOrOpts Whether the track should loop indefinitely (default true), or an Options Object.\r\n * @param fadeInTime Optional fade-in duration in seconds (default 0).\r\n */\r\n public playMusic(\r\n track: RloData,\r\n loopOrOpts: boolean | PlaySequenceOptions = true,\r\n oldFadeInTime: number = 0,\r\n ): void {\r\n if (!hasGameEngine) return;\r\n let opts: boolean | PlaySequenceOptions = loopOrOpts;\r\n if (typeof loopOrOpts === \"object\" && loopOrOpts.volume !== undefined) {\r\n this.setMusicVolume(loopOrOpts.volume);\r\n opts = { ...loopOrOpts };\r\n delete (opts as PlaySequenceOptions).volume;\r\n }\r\n this.playSequence(track, opts, oldFadeInTime);\r\n }\r\n\r\n /** Stops the currently playing background music. SFX will continue to function. */\r\n public stopMusic(): void {\r\n super.stop();\r\n }\r\n}\r\n","import { ISynthInstrument } from \"./ISynthInstrument.js\";\r\n\r\ndeclare const __ENABLE_STRICT_GC__: boolean;\r\nconst hasStrictGC =\r\n typeof __ENABLE_STRICT_GC__ !== \"undefined\" ? __ENABLE_STRICT_GC__ : true;\r\n\r\nexport const enum Osc {\r\n Sine = 0,\r\n Square = 1,\r\n Sawtooth = 2,\r\n Triangle = 3,\r\n}\r\nexport const enum Filter {\r\n Lowpass = 0,\r\n Highpass = 1,\r\n Bandpass = 2,\r\n}\r\n\r\nexport abstract class CoreSynthBase implements ISynthInstrument {\r\n public abstract _playNote(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n time: number,\r\n freq: number,\r\n duration: number,\r\n velocity: number,\r\n ): void;\r\n\r\n public _osc(\r\n ctx: AudioContext,\r\n type: Osc,\r\n freq: number,\r\n dest?: AudioNode | AudioParam,\r\n ): OscillatorNode {\r\n const o = ctx.createOscillator();\r\n o.type = [\"sine\", \"square\", \"sawtooth\", \"triangle\"][type] as OscillatorType;\r\n if (freq) o.frequency.value = Math.min(22000, freq);\r\n if (dest) o.connect(dest as any);\r\n return o;\r\n }\r\n public _gain(\r\n ctx: AudioContext,\r\n val: number,\r\n dest?: AudioNode | AudioParam,\r\n ): GainNode {\r\n const g = ctx.createGain();\r\n g.gain.value = val;\r\n if (dest) g.connect(dest as any);\r\n return g;\r\n }\r\n public _filter(ctx: AudioContext, type: Filter): BiquadFilterNode {\r\n const f = ctx.createBiquadFilter();\r\n f.type = [\"lowpass\", \"highpass\", \"bandpass\"][type] as BiquadFilterType;\r\n return f;\r\n }\r\n public _pan(\r\n ctx: AudioContext,\r\n val: number,\r\n dest?: AudioNode,\r\n ): StereoPannerNode {\r\n const p = ctx.createStereoPanner();\r\n p.pan.value = val;\r\n if (dest) p.connect(dest);\r\n return p;\r\n }\r\n public _on(t: number, s: number, ...n: AudioScheduledSourceNode[]): void {\r\n n.forEach((x) => {\r\n x.start(t);\r\n x.stop(s);\r\n });\r\n }\r\n public _set(p: AudioParam, v: number, t: number): void {\r\n p.setValueAtTime(Math.min(22000, v), t);\r\n }\r\n public _lin(p: AudioParam, v: number, t: number): void {\r\n p.linearRampToValueAtTime(Math.min(22000, v), t);\r\n }\r\n public _exp(p: AudioParam, v: number, t: number): void {\r\n p.exponentialRampToValueAtTime(Math.min(22000, v), t);\r\n }\r\n\r\n public _transient(\r\n ctx: AudioContext,\r\n type: Osc,\r\n freq: number,\r\n dest: AudioNode,\r\n time: number,\r\n peak: number,\r\n dur: number,\r\n atk: number = 0,\r\n ): void {\r\n const g = this._gain(ctx, 0, dest);\r\n this._set(g.gain, atk > 0 ? 0 : peak, time);\r\n if (atk > 0) this._lin(g.gain, peak, time + atk);\r\n this._exp(g.gain, 0.001, time + dur);\r\n this._on(time, time + dur, this._osc(ctx, type, freq, g));\r\n }\r\n public _filterSweep(\r\n ctx: AudioContext,\r\n type: Filter,\r\n f1: number,\r\n f2: number,\r\n t1: number,\r\n dur: number,\r\n ): BiquadFilterNode {\r\n const f = this._filter(ctx, type);\r\n this._set(f.frequency, f1, t1);\r\n this._exp(f.frequency, f2, t1 + dur);\r\n return f;\r\n }\r\n public _stereoOsc(\r\n ctx: AudioContext,\r\n type: Osc,\r\n freq: number,\r\n detune: number,\r\n pan: number,\r\n dest: AudioNode,\r\n ): [OscillatorNode, OscillatorNode] {\r\n return [\r\n this._osc(ctx, type, freq, this._pan(ctx, -pan, dest)),\r\n this._osc(ctx, type, freq * detune, this._pan(ctx, pan, dest)),\r\n ];\r\n }\r\n public _lfo(\r\n ctx: AudioContext,\r\n freq: number,\r\n depth: number,\r\n time: number,\r\n fadeIn: number,\r\n stopTime: number,\r\n dest: AudioNode | AudioParam,\r\n delay: number = 0,\r\n ): GainNode {\r\n const g = this._gain(ctx, 0, dest);\r\n this._set(g.gain, 0, time);\r\n if (delay > 0) this._set(g.gain, 0, time + delay);\r\n this._lin(g.gain, depth, time + delay + fadeIn);\r\n this._on(time, stopTime, this._osc(ctx, Osc.Sine, freq, g));\r\n return g;\r\n }\r\n\r\n public _gc(\r\n ctx: AudioContext,\r\n time: number,\r\n stopTime: number,\r\n ...nodes: AudioNode[]\r\n ): void {\r\n if (hasStrictGC) {\r\n const gcOsc = ctx.createOscillator();\r\n gcOsc.onended = () => {\r\n nodes.forEach((n) => {\r\n try {\r\n n.disconnect();\r\n } catch (e) {}\r\n });\r\n };\r\n gcOsc.start(time);\r\n gcOsc.stop(stopTime);\r\n }\r\n }\r\n}\r\n","import { CoreSynthBase } from \"../CoreSynthBase.js\";\r\n\r\nexport type DecayCfg = { v: number; a: number; d: number; m: number };\r\n\r\n/**\r\n * Abstract base class for plucked, struck, and decaying synthesizers.\r\n * Handles GainNode creation, Nyquist safety limits, and decay volume envelopes.\r\n */\r\nexport abstract class DecaySynthBase extends CoreSynthBase {\r\n protected _c: DecayCfg = { v: 0.5, a: 0.02, d: 0.2, m: 4.0 };\r\n\r\n public _playNote(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n time: number,\r\n freq: number,\r\n duration: number,\r\n velocity: number,\r\n ): void {\r\n const gain = ctx.createGain();\r\n\r\n const c = this._cfg();\r\n const peakVol = Math.max(0.001, velocity * c.v);\r\n\r\n /** Physical strings/mallets stop vibrating quickly. Protects against stuck MIDI notes. */\r\n const safeDuration = Math.max(0.02, Math.min(duration, c.m));\r\n\r\n this._set(gain.gain, 0, time);\r\n this._lin(gain.gain, peakVol, time + c.a);\r\n\r\n this._applyDecay(gain.gain, peakVol, time, c.a, safeDuration, c.d);\r\n\r\n /** Pad the oscillator stop time slightly past the volume decay to prevent digital clicking */\r\n const stopTime = time + safeDuration + c.d + 0.1;\r\n\r\n const output = this._setupSynthesis(\r\n ctx,\r\n masterGain,\r\n gain,\r\n time,\r\n freq,\r\n velocity,\r\n safeDuration,\r\n stopTime,\r\n );\r\n\r\n const finalNode = output || gain;\r\n finalNode.connect(masterGain);\r\n this._gc(ctx, time, stopTime + 2.0, finalNode);\r\n }\r\n\r\n protected _cfg(): DecayCfg {\r\n return this._c;\r\n }\r\n\r\n /** Override this for complex envelopes (like electric guitar compression) */\r\n protected _applyDecay(\r\n gainParam: AudioParam,\r\n peakVol: number,\r\n time: number,\r\n attack: number,\r\n safeDuration: number,\r\n decayTail: number,\r\n ): void {\r\n this._exp(gainParam, 0.001, time + safeDuration + decayTail);\r\n }\r\n\r\n /**\r\n * Set up the specific oscillators and filters for this instrument.\r\n */\r\n protected abstract _setupSynthesis(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n safeDuration: number,\r\n stopTime: number,\r\n ): AudioNode | void;\r\n}\r\n","import { DecaySynthBase } from \"./DecaySynthBase.js\";\r\nimport { Osc, Filter } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Piano and similar percussive-melodic instruments.\r\n */\r\nexport class PianoSynth extends DecaySynthBase {\r\n protected _c = { v: 0.8, a: 0.015, d: 0.1, m: 5.0 };\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n safeDuration: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n /** Key-tracking the filter ensures high notes aren't artificially muffled or phase-distorted. Capped at Nyquist. */\r\n const filter = this._filterSweep(\r\n ctx,\r\n Filter.Lowpass,\r\n freq + 800 + velocity * 1000,\r\n freq + 200,\r\n time,\r\n Math.min(safeDuration, 1.0),\r\n );\r\n const osc1 = this._osc(ctx, Osc.Triangle, freq, gain);\r\n\r\n /** Slight inharmonicity stretching, strictly capped below Nyquist to prevent digital aliasing */\r\n const overtoneGain = this._gain(ctx, 0);\r\n const osc2 = this._osc(ctx, Osc.Sine, freq * 2.003, overtoneGain);\r\n const osc3 = this._osc(ctx, Osc.Sine, freq * 3.007, overtoneGain);\r\n\r\n /** Dynamically pan lower keys to the left ear, and higher keys to the right ear */\r\n const panner = this._pan(\r\n ctx,\r\n Math.max(-0.8, Math.min(0.8, (freq - 261.6) / 800)),\r\n );\r\n\r\n /** Sympathetic string resonance: metallic clangs decay much faster than the fundamental */\r\n this._set(overtoneGain.gain, 0, time);\r\n this._lin(overtoneGain.gain, Math.max(0.001, velocity * 0.15), time + 0.01);\r\n this._exp(overtoneGain.gain, 0.001, time + Math.min(safeDuration, 0.5));\r\n overtoneGain.connect(panner);\r\n\r\n /** Mechanical Hammer Thump: the physical impact of the wooden hammer on the strings */\r\n this._transient(\r\n ctx,\r\n Osc.Sine,\r\n 60,\r\n panner,\r\n time,\r\n Math.max(0.001, velocity * 0.4),\r\n 0.05,\r\n 0.005,\r\n );\r\n\r\n gain.connect(panner).connect(filter);\r\n\r\n this._on(time, stopTime, osc1, osc2, osc3);\r\n\r\n return filter;\r\n }\r\n}\r\n","import { DecaySynthBase } from \"./DecaySynthBase.js\";\r\nimport { Osc } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Chromatic Percussion (Bells, Marimba, Vibraphone).\r\n * Characterized by a pure tone with a very fast attack and immediate decay.\r\n */\r\nexport class ChromaticPercussionSynth extends DecaySynthBase {\r\n protected _c = { v: 0.7, a: 0.005, d: 0.5, m: 6.0 };\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n safeDuration: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n const osc = this._osc(ctx, Osc.Sine, 0, gain);\r\n this._set(osc.frequency, freq * 1.1, time);\r\n this._exp(osc.frequency, freq, time + 0.02);\r\n\r\n const overtoneGain = this._gain(ctx, 0, masterGain);\r\n this._set(overtoneGain.gain, Math.max(0.001, velocity * 0.25), time);\r\n this._exp(overtoneGain.gain, 0.001, time + safeDuration);\r\n const overtone = this._osc(ctx, Osc.Sine, freq * 2.76, overtoneGain);\r\n\r\n overtoneGain.connect(masterGain);\r\n\r\n this._on(time, stopTime, osc, overtone);\r\n }\r\n}\r\n","import { CoreSynthBase } from \"../CoreSynthBase.js\";\r\n\r\nexport type AnalogCfg = { v: number; a: number; r: number };\r\n\r\n/**\r\n * Abstract base class for sustained analog synthesizers.\r\n * Handles GainNode creation, Nyquist safety limits, and ADSR volume envelopes.\r\n */\r\nexport abstract class AnalogSynthBase extends CoreSynthBase {\r\n protected _c: AnalogCfg = { v: 0.5, a: 0.05, r: 0.1 };\r\n\r\n public _playNote(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n time: number,\r\n freq: number,\r\n duration: number,\r\n velocity: number,\r\n ): void {\r\n const gain = ctx.createGain();\r\n\r\n const c = this._cfg(duration);\r\n const peakVol = Math.max(0.001, velocity * c.v);\r\n\r\n this._set(gain.gain, 0, time);\r\n this._lin(gain.gain, peakVol, time + c.a);\r\n\r\n const sustainTime = Math.max(c.a, duration);\r\n this._set(gain.gain, peakVol, time + sustainTime);\r\n this._lin(gain.gain, 0.001, time + sustainTime + c.r);\r\n\r\n const stopTime = time + sustainTime + c.r;\r\n\r\n const output = this._setupSynthesis(\r\n ctx,\r\n gain,\r\n time,\r\n freq,\r\n velocity,\r\n sustainTime,\r\n c.r,\r\n stopTime,\r\n );\r\n\r\n const finalNode = output || gain;\r\n finalNode.connect(masterGain);\r\n this._gc(ctx, time, stopTime + 0.1, finalNode);\r\n }\r\n\r\n protected _cfg(d: number): AnalogCfg {\r\n return this._c;\r\n }\r\n\r\n /**\r\n * Set up the specific oscillators and filters for this instrument.\r\n * You must start() and stop() your own oscillators.\r\n * @returns The final audio node in the chain to connect to the master mix. If omitted, the base envelope gain is used.\r\n */\r\n protected abstract _setupSynthesis(\r\n ctx: AudioContext,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n sustainTime: number,\r\n releaseTime: number,\r\n stopTime: number,\r\n ): AudioNode | void;\r\n}\r\n","import { AnalogSynthBase, AnalogCfg } from \"./AnalogSynthBase.js\";\r\nimport { Osc } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Organs using additive sine waves.\r\n */\r\nexport class OrganSynth extends AnalogSynthBase {\r\n protected _c = { v: 0.4, a: 0.01, r: 0.05 };\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n sustainTime: number,\r\n releaseTime: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n const osc1 = this._osc(ctx, Osc.Sine, freq, gain);\r\n const gain2 = this._gain(ctx, 0.5, gain);\r\n const osc2 = this._osc(ctx, Osc.Sine, freq * 2, gain2);\r\n const gain3 = this._gain(ctx, 0.25, gain);\r\n const osc3 = this._osc(ctx, Osc.Sine, freq * 3, gain3);\r\n\r\n const rotaryNode = this._gain(ctx, 0.7);\r\n this._lfo(ctx, 6.5, 0.3, time, 0, stopTime, rotaryNode.gain);\r\n\r\n gain.connect(rotaryNode);\r\n\r\n this._transient(\r\n ctx,\r\n Osc.Square,\r\n 4000,\r\n rotaryNode,\r\n time,\r\n Math.max(0.001, velocity * 0.1),\r\n 0.015,\r\n );\r\n\r\n this._on(time, stopTime, osc1, osc2, osc3);\r\n\r\n return rotaryNode;\r\n }\r\n}\r\n","import { DecaySynthBase } from \"./DecaySynthBase.js\";\r\nimport { Osc, Filter } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Acoustic Guitars using a plucked sawtooth.\r\n */\r\nexport class GuitarSynth extends DecaySynthBase {\r\n protected _c = { v: 0.6, a: 0.02, d: 0.2, m: 4.0 };\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n safeDuration: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n /** Bright attack that quickly muffles as the acoustic string loses kinetic energy */\r\n const filter = this._filterSweep(\r\n ctx,\r\n Filter.Lowpass,\r\n 2000 + velocity * 1000,\r\n 200,\r\n time,\r\n safeDuration,\r\n );\r\n\r\n const osc = this._osc(ctx, Osc.Sawtooth, 0, gain);\r\n this._set(osc.frequency, freq * 1.02, time);\r\n this._exp(osc.frequency, freq, time + 0.05);\r\n\r\n gain.connect(filter);\r\n\r\n /** Plectrum Pluck: the sharp, plastic click of a pick striking a steel string */\r\n this._transient(\r\n ctx,\r\n Osc.Square,\r\n 3500,\r\n masterGain,\r\n time,\r\n Math.max(0.001, velocity * 0.25),\r\n 0.015,\r\n );\r\n\r\n this._on(time, stopTime, osc);\r\n\r\n return filter;\r\n }\r\n}\r\n","import { DecaySynthBase } from \"./DecaySynthBase.js\";\r\nimport { Osc, Filter } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Electric and Distorted Guitars.\r\n */\r\nexport class ElectricGuitarSynth extends DecaySynthBase {\r\n protected _c = { v: 0.5, a: 0.02, d: 0.2, m: 4.0 };\r\n\r\n protected _applyDecay(\r\n gainParam: AudioParam,\r\n peakVol: number,\r\n time: number,\r\n attack: number,\r\n safeDuration: number,\r\n decayTail: number,\r\n ): void {\r\n /** Compressed sustain mimicking an electric guitar amp */\r\n this._exp(\r\n gainParam,\r\n Math.max(0.001, peakVol * 0.4),\r\n time + Math.min(0.5, safeDuration),\r\n );\r\n this._exp(gainParam, 0.001, time + safeDuration + decayTail);\r\n }\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n safeDuration: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n const filter = this._filterSweep(\r\n ctx,\r\n Filter.Lowpass,\r\n 2500 + velocity * 1500,\r\n 600,\r\n time,\r\n safeDuration,\r\n );\r\n\r\n const [osc, osc2] = this._stereoOsc(ctx, Osc.Sawtooth, 0, 1, 0, gain);\r\n this._set(osc.frequency, freq * 1.02, time);\r\n this._exp(osc.frequency, freq, time + 0.05);\r\n this._set(osc2.frequency, freq * 1.022, time);\r\n this._exp(osc2.frequency, freq * 1.002, time + 0.05);\r\n\r\n const vibrato = this._lfo(\r\n ctx,\r\n 5.0,\r\n freq * 0.015,\r\n time,\r\n 0.2,\r\n stopTime,\r\n osc.frequency,\r\n 0.4,\r\n );\r\n vibrato.connect(osc2.frequency);\r\n\r\n gain.connect(filter);\r\n\r\n /** Heavy plectrum attack */\r\n this._transient(\r\n ctx,\r\n Osc.Square,\r\n 3500,\r\n masterGain,\r\n time,\r\n Math.max(0.001, velocity * 0.25),\r\n 0.015,\r\n );\r\n\r\n this._on(time, stopTime, osc, osc2);\r\n\r\n return filter;\r\n }\r\n}\r\n","import { DecaySynthBase } from \"../Decay/DecaySynthBase.js\";\r\nimport { Osc, Filter } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for deep Bass instruments using sawtooth waves.\r\n */\r\nexport class BassSynth extends DecaySynthBase {\r\n protected _c = { v: 0.8, a: 0.05, d: 0.1, m: 4.0 };\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n safeDuration: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n /** Deep envelope sweep for punchy, muffled bass attack. Capped safely below Nyquist. */\r\n const filter = this._filterSweep(\r\n ctx,\r\n Filter.Lowpass,\r\n 300 + velocity * 500,\r\n 100,\r\n time,\r\n safeDuration,\r\n );\r\n\r\n const osc = this._osc(ctx, Osc.Sawtooth, 0, gain);\r\n this._set(osc.frequency, freq * 0.92, time);\r\n this._exp(osc.frequency, freq, time + 0.04);\r\n\r\n const subGain = this._gain(ctx, 0.6, gain);\r\n const subOsc = this._osc(ctx, Osc.Sine, 0, subGain);\r\n this._set(subOsc.frequency, (freq / 2) * 0.92, time);\r\n this._exp(subOsc.frequency, freq / 2, time + 0.04);\r\n\r\n gain.connect(filter);\r\n\r\n this._on(time, stopTime, osc, subOsc);\r\n\r\n return filter;\r\n }\r\n}\r\n","import { AnalogSynthBase } from \"./AnalogSynthBase.js\";\r\nimport { Osc, Filter } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for String and Pad instruments using detuned oscillators.\r\n */\r\nexport class StringSynth extends AnalogSynthBase {\r\n protected _cfg(d: number): { v: number; a: number; r: number } {\r\n return { v: 0.3, a: d < 0.4 ? 0.05 : 0.2, r: d < 0.4 ? 0.1 : 0.5 };\r\n }\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n sustainTime: number,\r\n releaseTime: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n const [osc1, osc2] = this._stereoOsc(\r\n ctx,\r\n Osc.Sawtooth,\r\n freq,\r\n 1.005,\r\n 0.6,\r\n gain,\r\n );\r\n\r\n const lfo = this._lfo(\r\n ctx,\r\n 4.5,\r\n freq * 0.012,\r\n time,\r\n 0.3,\r\n stopTime,\r\n osc1.frequency,\r\n );\r\n lfo.connect(osc2.frequency);\r\n\r\n const filter = this._filterSweep(\r\n ctx,\r\n Filter.Lowpass,\r\n freq + 1200 + velocity * 1000,\r\n freq + 800,\r\n time,\r\n sustainTime + releaseTime,\r\n );\r\n\r\n gain.connect(filter);\r\n\r\n this._on(time, stopTime, osc1, osc2);\r\n\r\n return filter;\r\n }\r\n}\r\n","import { AnalogSynthBase } from \"../Analog/AnalogSynthBase.js\";\r\nimport { Osc, Filter } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Brass and Wind instruments with a slow filter envelope.\r\n */\r\nexport class BrassSynth extends AnalogSynthBase {\r\n protected _c = { v: 0.5, a: 0.1, r: 0.1 };\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n sustainTime: number,\r\n releaseTime: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n const osc = this._osc(ctx, Osc.Square, 0, gain);\r\n this._set(osc.frequency, freq * 0.95, time);\r\n this._exp(osc.frequency, freq, time + 0.05);\r\n\r\n const blareGain = this._gain(ctx, 0, gain);\r\n this._set(blareGain.gain, 0, time);\r\n this._lin(blareGain.gain, Math.max(0.001, velocity * 0.25), time + 0.05);\r\n this._exp(blareGain.gain, 0.001, time + 0.2);\r\n const blare = this._osc(ctx, Osc.Sawtooth, freq * 2, blareGain);\r\n\r\n const filter = this._filter(ctx, Filter.Lowpass);\r\n this._set(filter.frequency, freq + 400, time);\r\n this._lin(filter.frequency, freq + 1500 + velocity * 1000, time + 0.1);\r\n this._exp(filter.frequency, freq + 400, time + sustainTime + releaseTime);\r\n\r\n gain.connect(filter);\r\n this._on(time, stopTime, osc);\r\n this._on(time, time + 0.2, blare);\r\n\r\n return filter;\r\n }\r\n}\r\n","import { AnalogSynthBase } from \"./AnalogSynthBase.js\";\r\nimport { Osc, Filter } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Woodwinds and Pipes (Flute, Piccolo, Recorder, Ocarina).\r\n * Characterized by a pure, hollow, and breathy tone using sine and triangle waves.\r\n */\r\nexport class WoodwindSynth extends AnalogSynthBase {\r\n protected _c = { v: 0.7, a: 0.05, r: 0.1 };\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n sustainTime: number,\r\n releaseTime: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n /** Flutes are mostly a fundamental sine wave with a tiny bit of triangle for the \"chiff\" sound */\r\n const osc1 = this._osc(ctx, Osc.Sine, freq, gain);\r\n\r\n /** Triangle is mixed much lower just to provide a bit of upper harmonic texture */\r\n const triGain = this._gain(ctx, 0, gain);\r\n /** Breath transient: louder at attack, decaying to a whisper during sustain */\r\n this._set(triGain.gain, 0.3, time);\r\n this._exp(triGain.gain, 0.05, time + 0.2);\r\n const osc2 = this._osc(ctx, Osc.Triangle, freq, triGain);\r\n\r\n /** Lowpass filter to keep it extremely smooth and remove any digital sharpness */\r\n const filter = this._filter(ctx, Filter.Lowpass);\r\n this._set(filter.frequency, freq + 800, time);\r\n\r\n /** Diaphragm vibrato: blooms slowly after the initial breath attack */\r\n const vibrato = this._lfo(\r\n ctx,\r\n 5.5,\r\n freq * 0.015,\r\n time,\r\n 0.4,\r\n stopTime,\r\n osc1.frequency,\r\n );\r\n vibrato.connect(osc2.frequency);\r\n\r\n /** True Amplitude Modulation (Tremolo) pipelined from the diaphragm vibrato */\r\n const tremoloNode = this._gain(ctx, 1.0);\r\n const tremoloDepth = this._gain(ctx, 0.15, tremoloNode.gain);\r\n vibrato.connect(tremoloDepth);\r\n\r\n gain.connect(tremoloNode).connect(filter);\r\n\r\n this._on(time, stopTime, osc1, osc2);\r\n\r\n return filter;\r\n }\r\n}\r\n","import { AnalogSynthBase } from \"./AnalogSynthBase.js\";\r\nimport { Osc, Filter } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Synth Leads featuring an LFO Vibrato.\r\n */\r\nexport class LeadSynth extends AnalogSynthBase {\r\n protected _c = { v: 0.4, a: 0.05, r: 0.1 };\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n sustainTime: number,\r\n releaseTime: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n const osc = this._osc(ctx, Osc.Sawtooth, 0);\r\n this._set(osc.frequency, freq, time);\r\n\r\n this._lfo(ctx, 5, freq * 0.02, time, 0.2, stopTime, osc.frequency);\r\n\r\n const filter = this._filterSweep(\r\n ctx,\r\n Filter.Lowpass,\r\n freq,\r\n freq * 3,\r\n time,\r\n 0.05,\r\n );\r\n this._exp(filter.frequency, freq * 1.5, time + sustainTime);\r\n filter.Q.value = 3; /** Squelchy resonance */\r\n\r\n osc.connect(filter).connect(gain);\r\n\r\n this._on(time, stopTime, osc);\r\n }\r\n}\r\n","import { AnalogSynthBase } from \"./AnalogSynthBase.js\";\r\nimport { Osc, Filter } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Synth Pads (Warm, Choir, Halo, Bowed).\r\n * Characterized by slow attacks, slow releases, and evolving filter sweeps.\r\n */\r\nexport class PadSynth extends AnalogSynthBase {\r\n protected _cfg(d: number): { v: number; a: number; r: number } {\r\n return { v: 0.4, a: d < 0.4 ? 0.05 : 0.3, r: d < 0.4 ? 0.1 : 0.8 };\r\n }\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n sustainTime: number,\r\n releaseTime: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n const [osc1, osc2] = this._stereoOsc(\r\n ctx,\r\n Osc.Triangle,\r\n freq,\r\n 1.01,\r\n 0.7,\r\n gain,\r\n );\r\n\r\n const filter = this._filter(ctx, Filter.Lowpass);\r\n this._set(filter.frequency, freq + 400, time);\r\n this._lin(\r\n filter.frequency,\r\n freq + 1000 + velocity * 500,\r\n time + sustainTime,\r\n );\r\n\r\n this._lfo(ctx, 0.5, 10, time, 0, stopTime, osc2.frequency);\r\n this._lfo(ctx, 0.1, 400, time, 0, stopTime, filter.frequency);\r\n\r\n gain.connect(filter);\r\n\r\n this._on(time, stopTime, osc1, osc2);\r\n\r\n return filter;\r\n }\r\n}\r\n","import { CoreSynthBase, Osc } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Sound Effects and Sci-Fi Synths.\r\n * Features extreme frequency sweeping over the duration of the note.\r\n */\r\nexport class SoundEffectsSynth extends CoreSynthBase {\r\n /**\r\n * Plays an automated sweeping sci-fi sound effect.\r\n */\r\n public _playNote(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n time: number,\r\n freq: number,\r\n duration: number,\r\n velocity: number,\r\n ): void {\r\n const gain = this._gain(ctx, 0);\r\n const osc = this._osc(ctx, Osc.Sawtooth, 0, gain);\r\n\r\n /** Extreme pitch dive from fundamental down one full octave over the note's duration */\r\n this._set(osc.frequency, freq, time);\r\n this._exp(\r\n osc.frequency,\r\n Math.max(1, freq / 2),\r\n time + Math.max(0.05, duration),\r\n );\r\n\r\n /** Sci-Fi \"Laser Wobble\": fast sine-wave amplitude modulation (avoids scratchy clicking of square wave) */\r\n const stutterNode = this._gain(ctx, 0.5, masterGain);\r\n this._lfo(ctx, 15, 0.5, time, 0, time + duration + 0.2, stutterNode.gain);\r\n\r\n gain.connect(stutterNode);\r\n\r\n this._set(gain.gain, 0, time);\r\n this._lin(gain.gain, Math.max(0.001, velocity * 0.5), time + 0.05);\r\n this._exp(gain.gain, 0.001, time + duration + 0.2);\r\n\r\n this._on(time, time + duration + 0.2, osc);\r\n\r\n this._gc(ctx, time, time + duration + 0.3, gain, stutterNode);\r\n }\r\n}\r\n","import { DecaySynthBase } from \"./DecaySynthBase.js\";\r\nimport { Osc, Filter } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Ethnic instruments (Sitar, Shamisen, Koto).\r\n * Uses a bandpass filter over a square wave to emulate a hollow, plucked resonator.\r\n */\r\nexport class EthnicSynth extends DecaySynthBase {\r\n protected _c = { v: 0.6, a: 0.02, d: 0.1, m: 4.0 };\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n safeDuration: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n const osc = this._osc(ctx, Osc.Square, 0, gain);\r\n this._set(osc.frequency, freq * 1.05, time);\r\n this._exp(osc.frequency, freq, time + 0.08);\r\n\r\n const filter = this._filterSweep(\r\n ctx,\r\n Filter.Bandpass,\r\n freq * 2.5,\r\n freq,\r\n time,\r\n safeDuration,\r\n );\r\n filter.Q.value = 2;\r\n\r\n filter.connect(gain);\r\n\r\n this._on(time, stopTime, osc);\r\n }\r\n}\r\n","import { CoreSynthBase, Osc, Filter } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Percussion and Drum kits.\r\n */\r\nexport class DrumSynth extends CoreSynthBase {\r\n /** Cached white noise buffer to prevent massive memory allocations and GC spikes. */\r\n private static _cachedNoiseBuffer: AudioBuffer | null = null;\r\n\r\n private static _getNoiseBuffer(ctx: AudioContext): AudioBuffer {\r\n if (\r\n !DrumSynth._cachedNoiseBuffer ||\r\n DrumSynth._cachedNoiseBuffer.sampleRate !== ctx.sampleRate\r\n ) {\r\n const bufferSize = ctx.sampleRate * 1.0;\r\n const buffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate);\r\n const data = buffer.getChannelData(0);\r\n for (let i = 0; i < bufferSize; i++) data[i] = Math.random() * 2 - 1;\r\n DrumSynth._cachedNoiseBuffer = buffer;\r\n }\r\n return DrumSynth._cachedNoiseBuffer;\r\n }\r\n\r\n public _playNote(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n time: number,\r\n freq: number,\r\n duration: number,\r\n velocity: number,\r\n ): void {\r\n /** Standard MIDI maps specific frequencies to specific drum kit pieces */\r\n if (freq < 70) {\r\n const gain = this._gain(ctx, 0, masterGain);\r\n const osc = this._osc(ctx, Osc.Sine, 0, gain);\r\n\r\n this._set(osc.frequency, 150, time);\r\n this._exp(osc.frequency, 30, time + 0.1);\r\n this._set(gain.gain, Math.max(0.001, velocity * 1.5), time);\r\n this._exp(gain.gain, 0.001, time + 0.5);\r\n\r\n this._on(time, time + 0.5, osc);\r\n\r\n this._gc(ctx, time, time + 0.6, gain);\r\n } else {\r\n /** HI-HAT / SNARE (White Noise generation) */\r\n const isSnare = freq < 90;\r\n\r\n const noise = ctx.createBufferSource();\r\n noise.buffer = DrumSynth._getNoiseBuffer(ctx);\r\n const gain = this._gain(ctx, 0, masterGain);\r\n const filter = this._filter(\r\n ctx,\r\n isSnare ? Filter.Bandpass : Filter.Highpass,\r\n );\r\n const panner = this._pan(ctx, isSnare ? 0 : Math.random() * 0.6 - 0.3);\r\n\r\n filter.frequency.value = isSnare ? 1500 : 5000;\r\n\r\n this._set(gain.gain, Math.max(0.001, velocity), time);\r\n this._exp(gain.gain, 0.001, time + (isSnare ? 0.2 : 0.05));\r\n\r\n noise.connect(filter).connect(gain).connect(panner);\r\n this._on(time, time + (isSnare ? 0.2 : 0.05), noise);\r\n\r\n /** Add an extra body thwack tone if it is a snare */\r\n if (isSnare) {\r\n const snareOsc = this._osc(ctx, Osc.Triangle, 0, gain);\r\n /** Snare drum head tension: quick pitch drop when the stick hits the skin */\r\n this._set(snareOsc.frequency, 300, time);\r\n this._exp(snareOsc.frequency, 100, time + 0.1);\r\n this._on(time, time + 0.2, snareOsc);\r\n } else {\r\n /** 808 Cymbal Metallic Ring: TR-808 hi-hats contain high-pitched ringing square waves */\r\n this._transient(\r\n ctx,\r\n Osc.Square,\r\n 7000,\r\n panner,\r\n time,\r\n Math.max(0.001, velocity * 0.2),\r\n 0.05,\r\n );\r\n }\r\n\r\n this._gc(ctx, time, time + 0.4, filter, gain, panner);\r\n }\r\n }\r\n}\r\n","import { AnalogSynthBase, AnalogCfg } from \"./AnalogSynthBase.js\";\r\nimport { Osc } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for FM (Frequency Modulation).\r\n * Modulates a carrier sine wave with another sine wave to create glassy,\r\n * metallic overtones common in 1980s Electric Pianos and Bells.\r\n */\r\nexport class FMSynth extends AnalogSynthBase {\r\n protected _c = { v: 0.6, a: 0.01, r: 0.1 };\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n sustainTime: number,\r\n releaseTime: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n const carrier = this._osc(ctx, Osc.Sine, freq, gain);\r\n\r\n const modFreq = freq * 2; // 2:1 harmonic ratio for bell/epiano overtones\r\n const modDepth = modFreq * 4; // Modulation index (brightness)\r\n\r\n const modGain = this._gain(ctx, 0, carrier.frequency);\r\n this._set(modGain.gain, modDepth * velocity, time);\r\n this._exp(modGain.gain, 0.01, time + sustainTime); // Decay the harshness over time for a plucked feel\r\n\r\n const modulator = this._osc(ctx, Osc.Sine, modFreq, modGain);\r\n\r\n this._on(time, stopTime, carrier, modulator);\r\n }\r\n}\r\n","import { DecaySynthBase, DecayCfg } from \"./DecaySynthBase.js\";\r\nimport { Osc } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Inharmonic Additive bells/glass.\r\n * Stacks sine waves at non-integer multiples to create metallic, clanging overtones.\r\n */\r\nexport class AdditiveSynth extends DecaySynthBase {\r\n protected _c = { v: 0.6, a: 0.005, d: 0.5, m: 5.0 };\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n safeDuration: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n const ratios = [1.0, 2.76, 5.4, 8.9, 13.3];\r\n const decays = [1.0, 0.6, 0.4, 0.2, 0.1]; // Higher frequencies die out much faster\r\n\r\n ratios.forEach((ratio, i) => {\r\n const hFreq = freq * ratio;\r\n if (hFreq < 22000) {\r\n const peak = Math.max(0.001, velocity * (1 / (i + 1.5)));\r\n const dur = Math.max(0.1, safeDuration * decays[i]);\r\n this._transient(ctx, Osc.Sine, hFreq, gain, time, peak, dur, 0.005);\r\n }\r\n });\r\n }\r\n}\r\n","import { CoreSynthBase, Filter } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Karplus-Strong physical modeling.\r\n * Uses a noise burst fed into a tuned delay line with a feedback filter\r\n * to accurately simulate the physics of plucked strings (Acoustic Guitar, Harp).\r\n */\r\nexport class KarplusSynth extends CoreSynthBase {\r\n public _playNote(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n time: number,\r\n freq: number,\r\n duration: number,\r\n velocity: number,\r\n ): void {\r\n const delayTime = 1 / freq;\r\n\r\n // 1. The Plectrum (A microscopic burst of white noise)\r\n const burstBuffer = ctx.createBuffer(\r\n 1,\r\n Math.max(1, ctx.sampleRate * delayTime),\r\n ctx.sampleRate,\r\n );\r\n const data = burstBuffer.getChannelData(0);\r\n for (let i = 0; i < data.length; i++)\r\n data[i] = (Math.random() * 2 - 1) * velocity;\r\n\r\n const burst = ctx.createBufferSource();\r\n burst.buffer = burstBuffer;\r\n\r\n // 2. The String (A delay node exactly the length of the frequency)\r\n const delay = ctx.createDelay(delayTime);\r\n delay.delayTime.value = delayTime;\r\n\r\n // 3. The Body Damping (Lowpass filter inside the feedback loop to absorb high frequencies)\r\n const filter = this._filter(ctx, Filter.Lowpass);\r\n filter.frequency.value = Math.min(22000, freq * 6);\r\n\r\n // 4. The Tension (Feedback gain)\r\n const feedback = this._gain(ctx, 0.98); // Higher value = longer ring time\r\n\r\n burst.connect(delay).connect(filter).connect(feedback).connect(delay);\r\n\r\n const output = this._gain(ctx, 0, masterGain);\r\n this._set(output.gain, 1, time);\r\n this._exp(output.gain, 0.001, time + duration);\r\n\r\n delay.connect(output);\r\n this._on(time, time + duration, burst);\r\n\r\n this._gc(ctx, time, time + duration + 3.0, output, delay, filter, feedback);\r\n }\r\n}\r\n","import { AnalogSynthBase, AnalogCfg } from \"./AnalogSynthBase.js\";\r\nimport { Osc, Filter } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Reese/Wobble Bass.\r\n * Uses heavily detuned sawtooths and an LFO-driven lowpass filter.\r\n */\r\nexport class ReeseBassSynth extends AnalogSynthBase {\r\n protected _c = { v: 0.7, a: 0.05, r: 0.2 };\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n sustainTime: number,\r\n releaseTime: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n const filter = this._filter(ctx, Filter.Lowpass);\r\n this._set(filter.frequency, freq * 2, time);\r\n\r\n // Wobble LFO: syncs roughly to tempo (e.g. 1/8th notes ~4-8 Hz)\r\n this._lfo(ctx, 6, freq * 3, time, 0, stopTime, filter.frequency);\r\n\r\n // Deep, phasing detune\r\n const [osc1, osc2] = this._stereoOsc(\r\n ctx,\r\n Osc.Sawtooth,\r\n freq / 2,\r\n 1.015,\r\n 0.4,\r\n filter,\r\n );\r\n filter.connect(gain);\r\n this._on(time, stopTime, osc1, osc2);\r\n }\r\n}\r\n","import { AnalogSynthBase, AnalogCfg } from \"./AnalogSynthBase.js\";\r\nimport { Osc, Filter } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for Formant Choirs (Human Vox).\r\n * Uses parallel bandpass filters locked to specific \"vowel\" resonant frequencies.\r\n */\r\nexport class FormantSynth extends AnalogSynthBase {\r\n protected _c = { v: 0.8, a: 0.1, r: 0.4 };\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n sustainTime: number,\r\n releaseTime: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n const osc = this._osc(ctx, Osc.Sawtooth, freq);\r\n this._lfo(ctx, 5, freq * 0.015, time, 0.2, stopTime, osc.frequency);\r\n\r\n // Typical 'Ah' vowel formants: 730Hz, 1090Hz, 2440Hz\r\n [730, 1090, 2440].forEach((f) => {\r\n if (f < 22000) {\r\n const filter = this._filter(ctx, Filter.Bandpass);\r\n filter.frequency.value = f;\r\n filter.Q.value = 12; // High resonance to isolate the formant\r\n osc.connect(filter).connect(gain);\r\n }\r\n });\r\n\r\n this._on(time, stopTime, osc);\r\n }\r\n}\r\n","import { AnalogSynthBase, AnalogCfg } from \"./AnalogSynthBase.js\";\r\nimport { Osc } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for 8-bit Chiptune sounds.\r\n * Uses a raw square wave with a rapid pitch-drop \"blip\" attack.\r\n */\r\nexport class ChiptuneSynth extends AnalogSynthBase {\r\n protected _c = { v: 0.4, a: 0.005, r: 0.05 };\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n sustainTime: number,\r\n releaseTime: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n const osc = this._osc(ctx, Osc.Square, 0, gain);\r\n\r\n /** Classic tracker \"blip\" attack: starts one octave higher for a fraction of a second */\r\n this._set(osc.frequency, freq * 2, time);\r\n this._set(osc.frequency, freq, time + 0.02);\r\n\r\n this._on(time, stopTime, osc);\r\n }\r\n}\r\n","import { DecaySynthBase } from \"./DecaySynthBase.js\";\r\nimport { Osc, Filter } from \"../CoreSynthBase.js\";\r\n\r\n/**\r\n * Synthesizer strategy for 80s Slap Bass (DX7/Seinfeld style).\r\n * Characterized by a very snappy filter envelope and a metallic transient \"pop\".\r\n */\r\nexport class SlapBassSynth extends DecaySynthBase {\r\n protected _c = { v: 0.9, a: 0.005, d: 0.15, m: 3.0 }; // Ultra-fast attack for the slap\r\n\r\n protected _setupSynthesis(\r\n ctx: AudioContext,\r\n masterGain: GainNode,\r\n gain: GainNode,\r\n time: number,\r\n freq: number,\r\n velocity: number,\r\n safeDuration: number,\r\n stopTime: number,\r\n ): AudioNode | void {\r\n /** The \"Pop\" - An aggressive lowpass filter sweep that opens bright and snaps shut */\r\n const filter = this._filterSweep(\r\n ctx,\r\n Filter.Lowpass,\r\n freq * 8 + velocity * 3000, // Very bright on hard velocities\r\n freq + 100, // Quickly muffles down to the fundamental\r\n time,\r\n 0.1, // Snap duration\r\n );\r\n filter.Q.value = 3; // Adds a \"quack\" resonance to the slap\r\n\r\n /** The Body - Sawtooth for rich harmonics */\r\n const osc = this._osc(ctx, Osc.Sawtooth, freq, gain);\r\n\r\n /** The Sub - Deep sine wave an octave down to anchor the low end */\r\n const subOsc = this._osc(ctx, Osc.Sine, freq / 2, gain);\r\n\r\n /** The \"Thumb Slap\" - A quick, inharmonic metallic burst simulating the string hitting the fretboard */\r\n this._transient(\r\n ctx,\r\n Osc.Square,\r\n freq * 3.5,\r\n filter,\r\n time,\r\n Math.max(0.001, velocity * 0.4),\r\n 0.04,\r\n );\r\n\r\n gain.connect(filter);\r\n this._on(time, stopTime, osc, subOsc);\r\n\r\n return filter;\r\n }\r\n}\r\n","// AUTO-GENERATED BY VITE CONFIG\nimport { RLOCore as BaseCore, RLOMusicPlayer as BaseMusicPlayer, RLOGameEngine as BaseGameEngine, RLOTranspiler, createInstrumentMap, extendInstrumentMap, createDirectMap, SilentSynth, type ISynthInstrument } from './RLO-Player.js';\nimport { PianoSynth } from './Instruments/Decay/PianoSynth.js';\nimport { ChromaticPercussionSynth } from './Instruments/Decay/ChromaticPercussionSynth.js';\nimport { OrganSynth } from './Instruments/Analog/OrganSynth.js';\nimport { GuitarSynth } from './Instruments/Decay/GuitarSynth.js';\nimport { ElectricGuitarSynth } from './Instruments/Decay/ElectricGuitarSynth.js';\nimport { BassSynth } from './Instruments/Analog/BassSynth.js';\nimport { StringSynth } from './Instruments/Analog/StringSynth.js';\nimport { BrassSynth } from './Instruments/Decay/BrassSynth.js';\nimport { WoodwindSynth } from './Instruments/Analog/WoodwindSynth.js';\nimport { LeadSynth } from './Instruments/Analog/LeadSynth.js';\nimport { PadSynth } from './Instruments/Analog/PadSynth.js';\nimport { SoundEffectsSynth } from './Instruments/Speciality/SoundEffectsSynth.js';\nimport { EthnicSynth } from './Instruments/Decay/EthnicSynth.js';\nimport { DrumSynth } from './Instruments/Speciality/DrumSynth.js';\nimport { FMSynth } from './Instruments/Analog/FMSynth.js';\nimport { AdditiveSynth } from './Instruments/Decay/AdditiveSynth.js';\nimport { KarplusSynth } from './Instruments/Decay/KarplusSynth.js';\nimport { ReeseBassSynth } from './Instruments/Analog/ReeseBassSynth.js';\nimport { FormantSynth } from './Instruments/Analog/FormantSynth.js';\nimport { ChiptuneSynth } from './Instruments/Analog/ChiptuneSynth.js';\nimport { SlapBassSynth } from './Instruments/Decay/SlapBassSynth.js';\n\n// Export all synthesizers (including optional ones) for NPM users\nexport { PianoSynth, ChromaticPercussionSynth, OrganSynth, GuitarSynth, ElectricGuitarSynth, BassSynth, StringSynth, BrassSynth, WoodwindSynth, LeadSynth, PadSynth, SoundEffectsSynth, EthnicSynth, DrumSynth, FMSynth, AdditiveSynth, KarplusSynth, ReeseBassSynth, FormantSynth, ChiptuneSynth, SlapBassSynth };\n\nconst defaultMapModules = [\n { synth: new PianoSynth(), start: 0, end: 7 },\n { synth: new ChromaticPercussionSynth(), start: 8, end: 15 },\n { synth: new OrganSynth(), start: 16, end: 23 },\n { synth: new GuitarSynth(), start: 24, end: 26 },\n { synth: new ElectricGuitarSynth(), start: 27, end: 31 },\n { synth: new BassSynth(), start: 32, end: 39 },\n { synth: new StringSynth(), start: 40, end: 55 },\n { synth: new BrassSynth(), start: 56, end: 71 },\n { synth: new WoodwindSynth(), start: 72, end: 79 },\n { synth: new LeadSynth(), start: 83, end: 87 },\n { synth: new PadSynth(), start: 88, end: 95 },\n { synth: new SoundEffectsSynth(), start: 96, end: 103 },\n { synth: new SoundEffectsSynth(), start: 120, end: 127 },\n { synth: new EthnicSynth(), start: 104, end: 111 },\n { synth: new DrumSynth(), start: 112, end: 119 },\n { synth: new DrumSynth(), start: 128, end: 128 },\n];\nconst defaultMap = createInstrumentMap(defaultMapModules);\n\nconst retroMap = createInstrumentMap([\n { synth: new ChiptuneSynth(), start: 0, end: 127 },\n { synth: new DrumSynth(), start: 128, end: 128 }\n]);\n\nexport { RLOTranspiler, createInstrumentMap, extendInstrumentMap, createDirectMap, SilentSynth, defaultMap as MasterInstrumentMap, defaultMap as StandardInstrumentMap, retroMap as RetroInstrumentMap };\nexport class RLOCore extends BaseCore { constructor(ctx: AudioContext, customMap?: ISynthInstrument[]) { super(ctx, customMap || defaultMap); } }\nexport class RLOMusicPlayer extends BaseMusicPlayer { constructor(ctx: AudioContext, customMap?: ISynthInstrument[]) { super(ctx, customMap || defaultMap); } }\nexport class RLOGameEngine extends BaseGameEngine { constructor(ctx: AudioContext, customMap?: ISynthInstrument[]) { super(ctx, customMap || defaultMap); } }\n"],"names":["Synthesizer","ctx","masterGain","instruments","this","_ctx","_masterGain","_instruments","instrumentId","time","freq","duration","velocity","keyTrackVel","Math","min","instrument","globalThis","DEBUG_MIDI","_playNote","AudioEffects","mode","_cachedConcert","_cachedStudio","isStudio","length","sampleRate","decay","impulse","createBuffer","i","channel","getChannelData","lastOut","j","random","exp","RLOTranspiler","humanJson","fullRangeFreq","N","notes","f","Float32Array","Uint8Array","t","Uint16Array","d","v","lastRoundedTime","n","ptr","max","round","log2","roundedTime","durationSecs","isLittleEndian","buffer","soa","_encodeToSoA","ArrayBuffer","view","DataView","setUint8","setFloat32","setUint32","set","setUint16","magic","String","fromCharCode","getUint8","Error","isFullRange","getFloat32","getUint32","f8","Array","currentTime","tn","getUint16","dn","fn","pow","SilentSynth","createDirectMap","assignments","mapArray","fill","forEach","a","ids","id","synth","createInstrumentMap","modules","m","start","end","closest","minDiff","Infinity","diff","abs","extendInstrumentMap","baseMap","overrides","newMap","RLOCore$1","audioContext","instrumentMap","_isPlaying","_timer","_workerTimer","_sequenceId","_trkT","_trkD","_activeNodes","_volume","_seekTarget","playbackRate","_workerUrl","_instrumentMap","_now","vol","timeInSeconds","stop","clearTimeout","postMessage","nodesToClean","node","disconnect","e","dispose","terminate","URL","revokeObjectURL","createGain","gain","target","setValueAtTime","linearRampToValueAtTime","c","createDynamicsCompressor","threshold","value","knee","ratio","attack","release","fadeInTime","_gain","_fade","connect","destination","push","track","loopOrOpts","oldFadeInTime","loop","volume","setVolume","state","resume","currentSequenceId","_createRouting","synthesizer","lastScheduleTime","loopOffsetSecs","notePtr","len","schedule","currentPhysicalTime","deltaPhysical","loopDurationSecs","noteTime","noteDur","noteTrackTime","notePhysicalTime","setTimeout","onmessage","RLOCore","super","_reverb","_fxGain","_trackCache","Map","_maxCacheSize","_reverbMode","_generateReverb","_visibilityHandler","document","hidden","suspend","addEventListener","setTargetAtTime","removeEventListener","clear","getCurrentTime","createConvolver","masterFilter","createBiquadFilter","type","frequency","compressor","_comp","trackUrlOrData","fadeInOrOpts","oldLoop","optionsObj","has","get","response","fetch","toLowerCase","endsWith","text","JSON","parse","rawBuffer","arrayBuffer","byteLength","_decodeBinary","ds","window","DecompressionStream","writer","writable","getWriter","write","close","Response","readable","size","firstKey","keys","next","delete","playSequence","now","cancelScheduledValues","_musicGain","_sfxGain","_sfxSynthesizer","musicGain","freqOrNote","velocityOrOpts","oldTimeOffset","timeOffset","pitch","match","note","accidental","octave","semitone","C","D","E","F","G","A","B","toUpperCase","parseInt","toFixed","opts","setMusicVolume","stopMusic","Osc","Filter","CoreSynthBase","dest","o","createOscillator","val","g","p","createStereoPanner","pan","s","x","exponentialRampToValueAtTime","peak","dur","atk","_set","_lin","_exp","_on","_osc","f1","f2","t1","_filter","detune","_pan","depth","fadeIn","stopTime","delay","nodes","gcOsc","onended","DecaySynthBase","constructor","arguments","_c","_cfg","peakVol","safeDuration","_applyDecay","finalNode","_setupSynthesis","_gc","gainParam","decayTail","PianoSynth","filter","_filterSweep","Lowpass","osc1","Triangle","overtoneGain","osc2","Sine","osc3","panner","_transient","ChromaticPercussionSynth","osc","overtone","AnalogSynthBase","r","sustainTime","OrganSynth","releaseTime","gain2","gain3","rotaryNode","_lfo","Square","GuitarSynth","Sawtooth","ElectricGuitarSynth","_stereoOsc","BassSynth","subGain","subOsc","StringSynth","BrassSynth","blareGain","blare","WoodwindSynth","triGain","vibrato","tremoloNode","tremoloDepth","LeadSynth","Q","PadSynth","SoundEffectsSynth","stutterNode","EthnicSynth","Bandpass","DrumSynth","_cachedNoiseBuffer","bufferSize","data","isSnare","noise","createBufferSource","_getNoiseBuffer","Highpass","snareOsc","FMSynth","carrier","modFreq","modDepth","modGain","modulator","AdditiveSynth","decays","hFreq","KarplusSynth","delayTime","burstBuffer","burst","createDelay","feedback","output","ReeseBassSynth","FormantSynth","ChiptuneSynth","SlapBassSynth","defaultMap","retroMap","BaseCore","customMap","RLOMusicPlayer","BaseMusicPlayer","RLOGameEngine","BaseGameEngine"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ var t,s;t=this,s=function(t){class s{constructor(t,s,i){this.h=t,this.o=s,this.u=i}l(t,s,i,h,e){const n=.6*e*Math.min(1,1600/i),r=this.u[t]||this.u[0];globalThis.DEBUG_MIDI,r&&r.l(this.h,this.o,s,i,h,n)}}const i=class{static p(t,s="studio"){if("concert"===s&&this.M)return this.M;if("studio"===s&&this._)return this._;const i="studio"===s,h=t.sampleRate*(i?.2:1.5),e=i?8:4,n=t.createBuffer(2,h,t.sampleRate);for(let r=0;r<2;r++){const t=n.getChannelData(r);let s=0;for(let i=0;i<h;i++)s+=.3*(2*Math.random()-1-s),t[i]=s*Math.exp(i/h*-e)*(1-i/h)}return i?this._=n:this.M=n}};i.M=null,i._=null;let h=i;class e{static S(t,s=!1){const i=t.notes.length/5,h=s?new Float32Array(i):new Uint8Array(i),e=new Uint16Array(i),n=new Uint16Array(i),r=new Uint8Array(i),o=new Uint8Array(i);let a=0;for(let c=0,u=0;c<i;c++,u+=5){const i=t.notes[u+1],l=t.notes[u];h[c]=s?l:l>0?Math.max(0,Math.min(255,Math.round(12*Math.log2(l/440)+69))):0;const d=Math.max(0,Math.round(1e3*i));e[c]=Math.min(65535,d-a),n[c]=Math.min(65535,Math.max(0,Math.round(1e3*t.notes[u+2]))),r[c]=Math.max(0,Math.min(255,Math.round(255*t.notes[u+3]))),o[c]=t.notes[u+4],a+=e[c]}return{durationSecs:t.durationSecs,f:h,t:e,d:n,v:r,i:o}}static U(t,s=!1){const i=1===new Uint8Array(new Uint16Array([1]).buffer)[0],h=this.S(t,s),e=h.f.length,n=new ArrayBuffer(12+(s?10:7)*e),r=new DataView(n);if(r.setUint8(0,82),r.setUint8(1,76),r.setUint8(2,79),r.setUint8(3,s?70:50),r.setFloat32(4,h.durationSecs,!0),r.setUint32(8,e,!0),i)new Uint16Array(n,12,e).set(h.t),new Uint16Array(n,12+2*e,e).set(h.d),s&&new Float32Array(n,12+4*e,e).set(h.f);else for(let o=0;o<e;o++)r.setUint16(12+2*o,h.t[o],!0),r.setUint16(12+2*e+2*o,h.d[o],!0),s&&r.setFloat32(12+4*e+4*o,h.f[o],!0);return s?(new Uint8Array(n,12+8*e,e).set(h.v),new Uint8Array(n,12+9*e,e).set(h.i)):(new Uint8Array(n,12+4*e,e).set(h.f),new Uint8Array(n,12+5*e,e).set(h.v),new Uint8Array(n,12+6*e,e).set(h.i)),n}static R(t){const s=new DataView(t),i=String.fromCharCode(s.getUint8(0),s.getUint8(1),s.getUint8(2),s.getUint8(3));if("RLO2"!==i&&"RLOF"!==i)throw Error("Invalid RLO Binary format. Please recompile tracks.");const h="RLOF"===i,e=s.getFloat32(4,!0),n=s.getUint32(8,!0),r=h?null:new Uint8Array(t,12+4*n,n),o=new Uint8Array(t,12+(h?8:5)*n,n),a=new Uint8Array(t,12+(h?9:6)*n,n),c=Array(5*n);let u=0;for(let l=0,d=0;l<n;l++,d+=5){const t=s.getUint16(12+2*l,!0),i=s.getUint16(12+2*n+2*l,!0),e=h?s.getFloat32(12+4*n+4*l,!0):r[l];u+=t/1e3,c[d]=h?e:e>0?440*Math.pow(2,(e-69)/12):0,c[d+1]=u,c[d+2]=i/1e3,c[d+3]=o[l]/255,c[d+4]=a[l]}return{durationSecs:e,notes:c}}}function n(t){const s=Array(129).fill(null);t.forEach(t=>{for(let i=t.start;i<=t.end;i++)s[i]=t.synth});for(let i=0;i<129;i++)if(null===s[i]){let t=null,h=1/0;for(let e=0;e<129;e++)if(null!==s[e]){const n=Math.abs(i-e);n<h&&(h=n,t=s[e])}s[i]=t}return s}let r=class{constructor(t,s=[]){this.T=!1,this.N=null,this.V=null,this.j=0,this.O=0,this.L=0,this.q=[],this.k=.5,this.I=null,this.playbackRate=1,this.X=null,this.h=t,this.H=s}get J(){return this.h.currentTime}setVolume(t){this.k=t}seek(t){this.L>0&&(this.I=Math.max(0,t)%this.L)}stop(){this.T=!1,this.j++,this.N&&clearTimeout(this.N),this.V&&this.V.postMessage("stop");const t=this.q;this.q=[],t.forEach(t=>{try{t.disconnect()}catch(s){}})}dispose(){this.stop(),this.V&&(this.V.terminate(),this.V=null),this.X&&(URL.revokeObjectURL(this.X),this.X=null)}P(){return this.h.createGain()}$(t,s,i){t.setValueAtTime(i>0?0:s,this.J),i>0&&t.linearRampToValueAtTime(s,this.J+i)}K(t=this.h){const s=t.createDynamicsCompressor();return s.threshold.value=-24,s.knee.value=12,s.ratio.value=8,s.attack.value=.001,s.release.value=.25,s}W(t=0){const s=this.P();return this.$(s.gain,this.k,t),s.connect(this.h.destination),this.q.push(s),{destination:s}}playSequence(t,i=!0,h=0){let e=!0,n=h;"object"==typeof i?(e=i.loop??!0,n=i.fadeInTime??0,void 0!==i.playbackRate&&(this.playbackRate=i.playbackRate),void 0!==i.volume&&this.setVolume(i.volume)):e=i,this.stop(),"suspended"===this.h.state&&this.h.resume(),this.T=!0;const r=++this.j;this.L=t.durationSecs;const{destination:o}=this.W(n),a=new s(this.h,o,this.H);this.O=-.05*this.playbackRate;let c=this.J,u=0,l=0;const d=t.notes,p=d.length,y=()=>{if(!this.T||this.j!==r)return;const s=this.J,i=s-c;if(c=s,null!==this.I){for(this.O=this.I,u=0,l=0;l<p&&d[l+1]<this.I;)l+=5;this.I=null}else this.O+=i*this.playbackRate;const h=t.durationSecs;for(;l<p;){const t=d[l],i=d[l+1],h=d[l+2],e=d[l+3],n=d[l+4],r=u+i;if(!(r<this.O+.5*this.playbackRate))break;{const i=s+Math.max(0,(r-this.O)/this.playbackRate);a.l(n,i,t,h/this.playbackRate,e),l+=5}}l>=p?e?(l=0,u+=h,y()):this.V&&this.V.postMessage("stop"):this.V||(this.N=setTimeout(y,50))};this.V&&(this.V.onmessage=()=>y(),this.V.postMessage("start")),y()}},o=class extends r{constructor(t,s=[]){super(t,s),this.o=null,this.Y=null,this.Z=null,this.tt=new Map,this.st=20,this.it="concert",h.p(this.h,"concert"),h.p(this.h,"studio"),this.ht=()=>{document.hidden?this.h.suspend():this.T&&this.h.resume()},"undefined"!=typeof document&&document.addEventListener("visibilitychange",this.ht)}setReverbMode(t){this.it=t,this.Y&&this.Z&&(this.Y.buffer=h.p(this.h,t),this.Z.gain.setTargetAtTime("studio"===t?.05:.2,this.J,.1))}dispose(){super.dispose(),"undefined"!=typeof document&&document.removeEventListener("visibilitychange",this.ht),this.tt.clear()}setVolume(t){super.setVolume(t),this.o&&this.o.gain.setTargetAtTime(t,this.J,.1)}getCurrentTime(){return 0!==this.L&&this.T?Math.max(0,this.O)%this.L:0}getTotalDuration(){return this.L}W(t=0){this.Y=this.h.createConvolver(),this.Y.buffer=h.p(this.h,this.it),this.o=this.P(),this.q.push(this.Y,this.o),this.$(this.o.gain,this.k,t),this.Z=this.P(),this.Z.gain.value="studio"===this.it?.05:.2,this.q.push(this.Z);const s=this.h.createBiquadFilter();s.type="lowpass",s.frequency.value=Math.min(this.h.sampleRate/2-1,6500),this.q.push(s);const i=this.K();return this.q.push(i),this.o.connect(s).connect(i).connect(this.h.destination),this.o.connect(this.Y).connect(this.Z).connect(s),{destination:this.o}}async play(t,s=0,i=!0){let h,n=0,r={};if("object"==typeof s?(n=s.fadeInTime??0,r=s):(n=s,r={fadeInTime:n,loop:i}),"string"==typeof t)if(this.tt.has(t))h=this.tt.get(t);else{const s=await fetch(t);if(t.toLowerCase().endsWith(".json")){const t=await s.text();h=JSON.parse(t)}else{const t=await s.arrayBuffer(),i=new DataView(t);if(i.byteLength>=3&&82===i.getUint8(0)&&76===i.getUint8(1)&&79===i.getUint8(2))h=e.R(t);else{const s=new window.DecompressionStream("gzip"),i=s.writable.getWriter();i.write(t),i.close(),h=e.R(await new Response(s.readable).arrayBuffer())}}if(this.tt.set(t,h),this.tt.size>this.st){const t=this.tt.keys().next().value;t&&this.tt.delete(t)}}else h=t;this.playSequence(h,r)}stop(){if(this.o){const t=this.J;this.o.gain.cancelScheduledValues(t),this.o.gain.setValueAtTime(0,t),this.o=null,this.Z=null,this.Y=null}super.stop()}},a=class extends r{constructor(t,i=[]){super(t,i),this.o=this.P(),this.o.gain.value=this.k;const h=this.K();this.o.connect(h).connect(this.h.destination),this.et=this.P(),this.et.connect(this.o),this.nt=this.P(),this.nt.connect(this.o),this.rt=new s(this.h,this.nt,this.H)}setVolume(t){super.setVolume(t),this.o.gain.setTargetAtTime(t,this.J,.1)}setMusicVolume(t){this.et.gain.setTargetAtTime(t,this.J,.1)}setSFXVolume(t){this.nt.gain.setTargetAtTime(t,this.J,.1)}W(t=0){const s=this.P();return s.connect(this.et),this.q.push(s),this.$(s.gain,1,t),{destination:s}}playSFX(t,s,i,h=1,e=0){"suspended"===this.h.state&&this.h.resume();let n=1,r=e;"object"==typeof h?(n=h.velocity??1,r=h.timeOffset??0):n=h,this.rt.l(t,this.J+r,function(t){if("number"==typeof t)return t;const s=t.match(/^([a-gA-G])([#b]?)(\d)$/);if(!s)return 0;const[,i,h,e]=s;let n={C:-9,D:-7,E:-5,F:-4,G:-2,A:0,B:2}[i.toUpperCase()];return"#"===h&&n++,"b"===h&&n--,n+=12*(parseInt(e,10)-4),+(440*Math.pow(2,n/12)).toFixed(2)}(s),i,n)}playSFXSequence(t,s=0){"suspended"===this.h.state&&this.h.resume();const i=this.J+s,h=t.notes,e=h.length;for(let n=0;n<e;n+=5)this.rt.l(h[n+4],i+h[n+1],h[n],h[n+2],h[n+3])}playMusic(t,s=!0,i=0){let h=s;"object"==typeof s&&void 0!==s.volume&&(this.setMusicVolume(s.volume),h={...s},delete h.volume),this.playSequence(t,h,i)}stopMusic(){super.stop()}};var c=(t=>(t[t.Sine=0]="Sine",t[t.Square=1]="Square",t[t.Sawtooth=2]="Sawtooth",t[t.Triangle=3]="Triangle",t))(c||{}),u=(t=>(t[t.Lowpass=0]="Lowpass",t[t.Highpass=1]="Highpass",t[t.Bandpass=2]="Bandpass",t))(u||{});class l{ot(t,s,i,h){const e=t.createOscillator();return e.type=["sine","square","sawtooth","triangle"][s],i&&(e.frequency.value=Math.min(22e3,i)),h&&e.connect(h),e}P(t,s,i){const h=t.createGain();return h.gain.value=s,i&&h.connect(i),h}ct(t,s){const i=t.createBiquadFilter();return i.type=["lowpass","highpass","bandpass"][s],i}ut(t,s,i){const h=t.createStereoPanner();return h.pan.value=s,i&&h.connect(i),h}lt(t,s,...i){i.forEach(i=>{i.start(t),i.stop(s)})}dt(t,s,i){t.setValueAtTime(Math.min(22e3,s),i)}yt(t,s,i){t.linearRampToValueAtTime(Math.min(22e3,s),i)}ft(t,s,i){t.exponentialRampToValueAtTime(Math.min(22e3,s),i)}Mt(t,s,i,h,e,n,r,o=0){const a=this.P(t,0,h);this.dt(a.gain,o>0?0:n,e),o>0&&this.yt(a.gain,n,e+o),this.ft(a.gain,.001,e+r),this.lt(e,e+r,this.ot(t,s,i,a))}wt(t,s,i,h,e,n){const r=this.ct(t,s);return this.dt(r.frequency,i,e),this.ft(r.frequency,h,e+n),r}_t(t,s,i,h,e,n){return[this.ot(t,s,i,this.ut(t,-e,n)),this.ot(t,s,i*h,this.ut(t,e,n))]}St(t,s,i,h,e,n,r,o=0){const a=this.P(t,0,r);return this.dt(a.gain,0,h),o>0&&this.dt(a.gain,0,h+o),this.yt(a.gain,i,h+o+e),this.lt(h,n,this.ot(t,0,s,a)),a}vt(t,s,i,...h){{const e=t.createOscillator();e.onended=()=>{h.forEach(t=>{try{t.disconnect()}catch(s){}})},e.start(s),e.stop(i)}}}class d extends l{constructor(){super(...arguments),this.xt={v:.5,a:.02,d:.2,m:4}}l(t,s,i,h,e,n){const r=t.createGain(),o=this.gt(),a=Math.max(.001,n*o.v),c=Math.max(.02,Math.min(e,o.m));this.dt(r.gain,0,i),this.yt(r.gain,a,i+o.a),this.At(r.gain,a,i,o.a,c,o.d);const u=i+c+o.d+.1,l=this.bt(t,s,r,i,h,n,c,u)||r;l.connect(s),this.vt(t,i,u+2,l)}gt(){return this.xt}At(t,s,i,h,e,n){this.ft(t,.001,i+e+n)}}class p extends d{constructor(){super(...arguments),this.xt={v:.8,a:.015,d:.1,m:5}}bt(t,s,i,h,e,n,r,o){const a=this.wt(t,u.Lowpass,e+800+1e3*n,e+200,h,Math.min(r,1)),l=this.ot(t,c.Triangle,e,i),d=this.P(t,0),p=this.ot(t,c.Sine,2.003*e,d),y=this.ot(t,c.Sine,3.007*e,d),f=this.ut(t,Math.max(-.8,Math.min(.8,(e-261.6)/800)));return this.dt(d.gain,0,h),this.yt(d.gain,Math.max(.001,.15*n),h+.01),this.ft(d.gain,.001,h+Math.min(r,.5)),d.connect(f),this.Mt(t,c.Sine,60,f,h,Math.max(.001,.4*n),.05,.005),i.connect(f).connect(a),this.lt(h,o,l,p,y),a}}class y extends d{constructor(){super(...arguments),this.xt={v:.7,a:.005,d:.5,m:6}}bt(t,s,i,h,e,n,r,o){const a=this.ot(t,c.Sine,0,i);this.dt(a.frequency,1.1*e,h),this.ft(a.frequency,e,h+.02);const u=this.P(t,0,s);this.dt(u.gain,Math.max(.001,.25*n),h),this.ft(u.gain,.001,h+r);const l=this.ot(t,c.Sine,2.76*e,u);u.connect(s),this.lt(h,o,a,l)}}class f extends l{constructor(){super(...arguments),this.xt={v:.5,a:.05,r:.1}}l(t,s,i,h,e,n){const r=t.createGain(),o=this.gt(e),a=Math.max(.001,n*o.v);this.dt(r.gain,0,i),this.yt(r.gain,a,i+o.a);const c=Math.max(o.a,e);this.dt(r.gain,a,i+c),this.yt(r.gain,.001,i+c+o.r);const u=i+c+o.r,l=this.bt(t,r,i,h,n,c,o.r,u)||r;l.connect(s),this.vt(t,i,u+.1,l)}gt(t){return this.xt}}class M extends f{constructor(){super(...arguments),this.xt={v:.4,a:.01,r:.05}}bt(t,s,i,h,e,n,r,o){const a=this.ot(t,c.Sine,h,s),u=this.P(t,.5,s),l=this.ot(t,c.Sine,2*h,u),d=this.P(t,.25,s),p=this.ot(t,c.Sine,3*h,d),y=this.P(t,.7);return this.St(t,6.5,.3,i,0,o,y.gain),s.connect(y),this.Mt(t,c.Square,4e3,y,i,Math.max(.001,.1*e),.015),this.lt(i,o,a,l,p),y}}class w extends d{constructor(){super(...arguments),this.xt={v:.6,a:.02,d:.2,m:4}}bt(t,s,i,h,e,n,r,o){const a=this.wt(t,u.Lowpass,2e3+1e3*n,200,h,r),l=this.ot(t,c.Sawtooth,0,i);return this.dt(l.frequency,1.02*e,h),this.ft(l.frequency,e,h+.05),i.connect(a),this.Mt(t,c.Square,3500,s,h,Math.max(.001,.25*n),.015),this.lt(h,o,l),a}}class _ extends d{constructor(){super(...arguments),this.xt={v:.5,a:.02,d:.2,m:4}}At(t,s,i,h,e,n){this.ft(t,Math.max(.001,.4*s),i+Math.min(.5,e)),this.ft(t,.001,i+e+n)}bt(t,s,i,h,e,n,r,o){const a=this.wt(t,u.Lowpass,2500+1500*n,600,h,r),[l,d]=this._t(t,c.Sawtooth,0,1,0,i);return this.dt(l.frequency,1.02*e,h),this.ft(l.frequency,e,h+.05),this.dt(d.frequency,1.022*e,h),this.ft(d.frequency,1.002*e,h+.05),this.St(t,5,.015*e,h,.2,o,l.frequency,.4).connect(d.frequency),i.connect(a),this.Mt(t,c.Square,3500,s,h,Math.max(.001,.25*n),.015),this.lt(h,o,l,d),a}}class S extends d{constructor(){super(...arguments),this.xt={v:.8,a:.05,d:.1,m:4}}bt(t,s,i,h,e,n,r,o){const a=this.wt(t,u.Lowpass,300+500*n,100,h,r),l=this.ot(t,c.Sawtooth,0,i);this.dt(l.frequency,.92*e,h),this.ft(l.frequency,e,h+.04);const d=this.P(t,.6,i),p=this.ot(t,c.Sine,0,d);return this.dt(p.frequency,e/2*.92,h),this.ft(p.frequency,e/2,h+.04),i.connect(a),this.lt(h,o,l,p),a}}class v extends f{gt(t){return{v:.3,a:t<.4?.05:.2,r:t<.4?.1:.5}}bt(t,s,i,h,e,n,r,o){const[a,l]=this._t(t,c.Sawtooth,h,1.005,.6,s);this.St(t,4.5,.012*h,i,.3,o,a.frequency).connect(l.frequency);const d=this.wt(t,u.Lowpass,h+1200+1e3*e,h+800,i,n+r);return s.connect(d),this.lt(i,o,a,l),d}}class x extends f{constructor(){super(...arguments),this.xt={v:.5,a:.1,r:.1}}bt(t,s,i,h,e,n,r,o){const a=this.ot(t,c.Square,0,s);this.dt(a.frequency,.95*h,i),this.ft(a.frequency,h,i+.05);const l=this.P(t,0,s);this.dt(l.gain,0,i),this.yt(l.gain,Math.max(.001,.25*e),i+.05),this.ft(l.gain,.001,i+.2);const d=this.ot(t,c.Sawtooth,2*h,l),p=this.ct(t,u.Lowpass);return this.dt(p.frequency,h+400,i),this.yt(p.frequency,h+1500+1e3*e,i+.1),this.ft(p.frequency,h+400,i+n+r),s.connect(p),this.lt(i,o,a),this.lt(i,i+.2,d),p}}class m extends f{constructor(){super(...arguments),this.xt={v:.7,a:.05,r:.1}}bt(t,s,i,h,e,n,r,o){const a=this.ot(t,c.Sine,h,s),l=this.P(t,0,s);this.dt(l.gain,.3,i),this.ft(l.gain,.05,i+.2);const d=this.ot(t,c.Triangle,h,l),p=this.ct(t,u.Lowpass);this.dt(p.frequency,h+800,i);const y=this.St(t,5.5,.015*h,i,.4,o,a.frequency);y.connect(d.frequency);const f=this.P(t,1),M=this.P(t,.15,f.gain);return y.connect(M),s.connect(f).connect(p),this.lt(i,o,a,d),p}}class g extends f{constructor(){super(...arguments),this.xt={v:.4,a:.05,r:.1}}bt(t,s,i,h,e,n,r,o){const a=this.ot(t,c.Sawtooth,0);this.dt(a.frequency,h,i),this.St(t,5,.02*h,i,.2,o,a.frequency);const l=this.wt(t,u.Lowpass,h,3*h,i,.05);this.ft(l.frequency,1.5*h,i+n),l.Q.value=3,a.connect(l).connect(s),this.lt(i,o,a)}}class A extends f{gt(t){return{v:.4,a:t<.4?.05:.3,r:t<.4?.1:.8}}bt(t,s,i,h,e,n,r,o){const[a,l]=this._t(t,c.Triangle,h,1.01,.7,s),d=this.ct(t,u.Lowpass);return this.dt(d.frequency,h+400,i),this.yt(d.frequency,h+1e3+500*e,i+n),this.St(t,.5,10,i,0,o,l.frequency),this.St(t,.1,400,i,0,o,d.frequency),s.connect(d),this.lt(i,o,a,l),d}}class b extends l{l(t,s,i,h,e,n){const r=this.P(t,0),o=this.ot(t,c.Sawtooth,0,r);this.dt(o.frequency,h,i),this.ft(o.frequency,Math.max(1,h/2),i+Math.max(.05,e));const a=this.P(t,.5,s);this.St(t,15,.5,i,0,i+e+.2,a.gain),r.connect(a),this.dt(r.gain,0,i),this.yt(r.gain,Math.max(.001,.5*n),i+.05),this.ft(r.gain,.001,i+e+.2),this.lt(i,i+e+.2,o),this.vt(t,i,i+e+.3,r,a)}}class U extends d{constructor(){super(...arguments),this.xt={v:.6,a:.02,d:.1,m:4}}bt(t,s,i,h,e,n,r,o){const a=this.ot(t,c.Square,0,i);this.dt(a.frequency,1.05*e,h),this.ft(a.frequency,e,h+.08);const l=this.wt(t,u.Bandpass,2.5*e,e,h,r);l.Q.value=2,l.connect(i),this.lt(h,o,a)}}const R=class t extends l{static Ut(s){if(!t.Rt||t.Rt.sampleRate!==s.sampleRate){const i=1*s.sampleRate,h=s.createBuffer(1,i,s.sampleRate),e=h.getChannelData(0);for(let t=0;t<i;t++)e[t]=2*Math.random()-1;t.Rt=h}return t.Rt}l(s,i,h,e,n,r){if(e<70){const t=this.P(s,0,i),e=this.ot(s,c.Sine,0,t);this.dt(e.frequency,150,h),this.ft(e.frequency,30,h+.1),this.dt(t.gain,Math.max(.001,1.5*r),h),this.ft(t.gain,.001,h+.5),this.lt(h,h+.5,e),this.vt(s,h,h+.6,t)}else{const n=e<90,o=s.createBufferSource();o.buffer=t.Ut(s);const a=this.P(s,0,i),l=this.ct(s,n?u.Bandpass:u.Highpass),d=this.ut(s,n?0:.6*Math.random()-.3);if(l.frequency.value=n?1500:5e3,this.dt(a.gain,Math.max(.001,r),h),this.ft(a.gain,.001,h+(n?.2:.05)),o.connect(l).connect(a).connect(d),this.lt(h,h+(n?.2:.05),o),n){const t=this.ot(s,c.Triangle,0,a);this.dt(t.frequency,300,h),this.ft(t.frequency,100,h+.1),this.lt(h,h+.2,t)}else this.Mt(s,c.Square,7e3,d,h,Math.max(.001,.2*r),.05);this.vt(s,h,h+.4,l,a,d)}}};R.Rt=null;let T=R;class N extends f{constructor(){super(...arguments),this.xt={v:.4,a:.005,r:.05}}bt(t,s,i,h,e,n,r,o){const a=this.ot(t,c.Square,0,s);this.dt(a.frequency,2*h,i),this.dt(a.frequency,h,i+.02),this.lt(i,o,a)}}const F=n([{synth:new p,start:0,end:7},{synth:new y,start:8,end:15},{synth:new M,start:16,end:23},{synth:new w,start:24,end:26},{synth:new _,start:27,end:31},{synth:new S,start:32,end:39},{synth:new v,start:40,end:55},{synth:new x,start:56,end:71},{synth:new m,start:72,end:79},{synth:new g,start:83,end:87},{synth:new A,start:88,end:95},{synth:new b,start:96,end:103},{synth:new b,start:120,end:127},{synth:new U,start:104,end:111},{synth:new T,start:112,end:119},{synth:new T,start:128,end:128}]),V=n([{synth:new N,start:0,end:127},{synth:new T,start:128,end:128}]);t.AdditiveSynth=class extends d{constructor(){super(...arguments),this.xt={v:.6,a:.005,d:.5,m:5}}bt(t,s,i,h,e,n,r,o){const a=[1,.6,.4,.2,.1];[1,2.76,5.4,8.9,13.3].forEach((s,o)=>{const u=e*s;if(u<22e3){const s=Math.max(.001,n*(1/(o+1.5))),e=Math.max(.1,r*a[o]);this.Mt(t,c.Sine,u,i,h,s,e,.005)}})}},t.BassSynth=S,t.BrassSynth=x,t.ChiptuneSynth=N,t.ChromaticPercussionSynth=y,t.DrumSynth=T,t.ElectricGuitarSynth=_,t.EthnicSynth=U,t.FMSynth=class extends f{constructor(){super(...arguments),this.xt={v:.6,a:.01,r:.1}}bt(t,s,i,h,e,n,r,o){const a=this.ot(t,c.Sine,h,s),u=2*h,l=4*u,d=this.P(t,0,a.frequency);this.dt(d.gain,l*e,i),this.ft(d.gain,.01,i+n);const p=this.ot(t,c.Sine,u,d);this.lt(i,o,a,p)}},t.FormantSynth=class extends f{constructor(){super(...arguments),this.xt={v:.8,a:.1,r:.4}}bt(t,s,i,h,e,n,r,o){const a=this.ot(t,c.Sawtooth,h);this.St(t,5,.015*h,i,.2,o,a.frequency),[730,1090,2440].forEach(i=>{if(i<22e3){const h=this.ct(t,u.Bandpass);h.frequency.value=i,h.Q.value=12,a.connect(h).connect(s)}}),this.lt(i,o,a)}},t.GuitarSynth=w,t.KarplusSynth=class extends l{l(t,s,i,h,e,n){const r=1/h,o=t.createBuffer(1,Math.max(1,t.sampleRate*r),t.sampleRate),a=o.getChannelData(0);for(let u=0;u<a.length;u++)a[u]=(2*Math.random()-1)*n;const c=t.createBufferSource();c.buffer=o;const l=t.createDelay(r);l.delayTime.value=r;const d=this.ct(t,u.Lowpass);d.frequency.value=Math.min(22e3,6*h);const p=this.P(t,.98);c.connect(l).connect(d).connect(p).connect(l);const y=this.P(t,0,s);this.dt(y.gain,1,i),this.ft(y.gain,.001,i+e),l.connect(y),this.lt(i,i+e,c),this.vt(t,i,i+e+3,y,l,d,p)}},t.LeadSynth=g,t.MasterInstrumentMap=F,t.OrganSynth=M,t.PadSynth=A,t.PianoSynth=p,t.RLOCore=class extends r{constructor(t,s){super(t,s||F)}},t.RLOGameEngine=class extends a{constructor(t,s){super(t,s||F)}},t.RLOMusicPlayer=class extends o{constructor(t,s){super(t,s||F)}},t.RLOTranspiler=e,t.ReeseBassSynth=class extends f{constructor(){super(...arguments),this.xt={v:.7,a:.05,r:.2}}bt(t,s,i,h,e,n,r,o){const a=this.ct(t,u.Lowpass);this.dt(a.frequency,2*h,i),this.St(t,6,3*h,i,0,o,a.frequency);const[l,d]=this._t(t,c.Sawtooth,h/2,1.015,.4,a);a.connect(s),this.lt(i,o,l,d)}},t.RetroInstrumentMap=V,t.SilentSynth={l:()=>{}},t.SlapBassSynth=class extends d{constructor(){super(...arguments),this.xt={v:.9,a:.005,d:.15,m:3}}bt(t,s,i,h,e,n,r,o){const a=this.wt(t,u.Lowpass,8*e+3e3*n,e+100,h,.1);a.Q.value=3;const l=this.ot(t,c.Sawtooth,e,i),d=this.ot(t,c.Sine,e/2,i);return this.Mt(t,c.Square,3.5*e,a,h,Math.max(.001,.4*n),.04),i.connect(a),this.lt(h,o,l,d),a}},t.SoundEffectsSynth=b,t.StandardInstrumentMap=F,t.StringSynth=v,t.WoodwindSynth=m,t.createDirectMap=function(t){const s=Array(129).fill(null);return t.forEach(t=>{t.ids.forEach(i=>s[i]=t.synth)}),s},t.createInstrumentMap=n,t.extendInstrumentMap=function(t,s){const i=[...t];return s.forEach(t=>{for(let s=t.start;s<=t.end;s++)i[s]=t.synth}),i},Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})},"object"==typeof exports&&"undefined"!=typeof module?s(exports):"function"==typeof define&&define.amd?define(["exports"],s):s((t="undefined"!=typeof globalThis?globalThis:t||self).RLOEngine={});
2
+ //# sourceMappingURL=rlo-engine.min.umd.js.map