spessasynth_lib 3.9.21 → 3.9.22
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.
- package/@types/externals/libvorbis/OggVorbisEncoder.min.d.ts +3 -0
- package/@types/sequencer/sequencer.d.ts +23 -13
- package/@types/sequencer/worklet_sequencer/sequencer_message.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +1 -1
- package/sequencer/sequencer.js +44 -1
- package/sequencer/worklet_sequencer/events.js +5 -0
- package/sequencer/worklet_sequencer/sequencer_message.js +3 -1
- package/sequencer/worklet_sequencer/song_control.js +0 -1
- package/sequencer/worklet_sequencer/worklet_sequencer.js +23 -2
- package/synthetizer/worklet_processor.min.js +2 -2
- package/synthetizer/worklet_processor.min.js.map +0 -7
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../utils/indexed_array.js", "../utils/other.js", "../midi_parser/midi_message.js", "worklet_system/message_protocol/worklet_message.js", "../utils/loggin.js", "synthetizer.js", "../utils/byte_functions/little_endian.js", "../utils/byte_functions/string.js", "../soundfont/read/riff_chunk.js", "../soundfont/read/generators.js", "../soundfont/read/modulators.js", "worklet_system/worklet_utilities/worklet_processor_channel.js", "../externals/stbvorbis_sync/stbvorbis_sync.min.js", "../soundfont/read/samples.js", "../soundfont/read/instruments.js", "../soundfont/read/zones.js", "../soundfont/read/presets.js", "../soundfont/write/igen.js", "../soundfont/write/sdta.js", "../soundfont/write/shdr.js", "../soundfont/write/imod.js", "../soundfont/write/ibag.js", "../soundfont/write/inst.js", "../soundfont/write/pgen.js", "../soundfont/write/pmod.js", "../soundfont/write/pbag.js", "../soundfont/write/phdr.js", "../soundfont/write/write.js", "../soundfont/soundfont.js", "worklet_system/message_protocol/handle_message.js", "worklet_system/worklet_methods/system_exclusive.js", "worklet_system/worklet_utilities/unit_converter.js", "worklet_system/worklet_utilities/volume_envelope.js", "worklet_system/worklet_utilities/lowpass_filter.js", "worklet_system/worklet_utilities/worklet_voice.js", "worklet_system/worklet_utilities/modulator_curves.js", "worklet_system/worklet_utilities/worklet_modulator.js", "worklet_system/worklet_methods/note_on.js", "worklet_system/worklet_methods/data_entry.js", "worklet_system/worklet_methods/note_off.js", "worklet_system/worklet_methods/controller_control.js", "worklet_system/message_protocol/message_sending.js", "worklet_system/worklet_methods/tuning_control.js", "worklet_system/worklet_methods/program_control.js", "worklet_system/worklet_methods/vibrato_control.js", "../sequencer/worklet_sequencer/sequencer_message.js", "../utils/byte_functions/big_endian.js", "../sequencer/worklet_sequencer/process_event.js", "../sequencer/worklet_sequencer/process_tick.js", "../sequencer/worklet_sequencer/play.js", "../midi_parser/midi_data.js", "../utils/byte_functions/variable_length_quantity.js", "../midi_parser/midi_loader.js", "../midi_parser/used_keys_loaded.js", "../sequencer/worklet_sequencer/song_control.js", "../sequencer/worklet_sequencer/events.js", "../sequencer/worklet_sequencer/worklet_sequencer.js", "worklet_system/worklet_methods/snapshot.js", "worklet_system/worklet_utilities/lfo.js", "worklet_system/worklet_utilities/modulation_envelope.js", "worklet_system/worklet_utilities/wavetable_oscillator.js", "worklet_system/worklet_utilities/stereo_panner.js", "worklet_system/worklet_methods/voice_control.js", "worklet_system/worklet_methods/reset_controllers.js", "worklet_system/main_processor.js", "worklet_system/worklet_processor.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * indexed_array.js\n * purpose: exteds Uint8Array with a currentIndex property\n */\n\nexport class IndexedByteArray extends Uint8Array\n{\n /**\n * Creates a new instance of an Uint8Array with a currentIndex property\n * @param args {any} same as for Uint8Array\n */\n constructor(args)\n {\n super(args);\n this.currentIndex = 0;\n }\n\n /**\n * The current index of the array\n * @type {number}\n */\n currentIndex;\n}\n\n\n/**\n * @param arrs {(IndexedByteArray|Uint8Array)[]}\n * @returns {IndexedByteArray|Uint8Array}\n */\nexport function combineArrays(arrs)\n{\n const length = arrs.reduce((sum, current) => sum + current.length, 0);\n const newArr = new IndexedByteArray(length);\n let offset = 0;\n for(const arr of arrs)\n {\n newArr.set(arr, offset);\n offset += arr.length;\n }\n return newArr;\n}", "/**\n * other.js\n * purpose: contains some useful functions that don't belong in any specific category\n */\n\n/**\n * Formats the given seconds to nice readable time\n * @param totalSeconds {number} time in seconds\n * @return {{seconds: number, minutes: number, time: string}}\n */\nexport function formatTime(totalSeconds) {\n totalSeconds = Math.floor(totalSeconds);\n let minutes = Math.floor(totalSeconds / 60);\n let seconds = Math.round(totalSeconds - (minutes * 60));\n return {\"minutes\": minutes, \"seconds\": seconds, \"time\": `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`}\n}\n\n/**\n * @param fileName {string}\n * @returns {string}\n */\nexport function formatTitle(fileName)\n{\n return fileName\n .trim()\n .replaceAll(\".mid\", \"\")\n .replaceAll(\".rmi\", \"\")\n .replaceAll(\"_\", \" \");\n}\n\n/**\n * Does what it says\n * @param arr {number[]}\n * @returns {string}\n */\nexport function arrayToHexString(arr) {\n let hexString = '';\n\n for (let i = 0; i < arr.length; i++) {\n const hex = arr[i].toString(16).padStart(2, '0').toUpperCase();\n hexString += hex;\n hexString += ' ';\n }\n\n return hexString;\n}\n\nexport const consoleColors = {\n warn: \"color: orange;\",\n unrecognized: \"color: red;\",\n info: \"color: aqua;\",\n recognized: \"color: lime\",\n value: \"color: yellow; background-color: black;\"\n}", "import {IndexedByteArray} from \"../utils/indexed_array.js\";\n\n/**\n * midi_message.js\n * purpose: contains enums for midi events and controllers and functions to parse them\n */\n\nexport class MidiMessage\n{\n /**\n * @param ticks {number}\n * @param byte {number} the message status byte\n * @param data {IndexedByteArray}\n */\n constructor(ticks, byte, data) {\n // absolute ticks from the start\n this.ticks = ticks;\n // message status byte (for meta it's the second byte)\n this.messageStatusByte = byte;\n /**\n * @type {IndexedByteArray}\n */\n this.messageData = data;\n }\n}\n\n/**\n * Gets the status byte's channel\n * @param statusByte\n * @returns {number} channel is -1 for system messages -2 for meta and -3 for sysex\n */\nexport function getChannel(statusByte) {\n const eventType = statusByte & 0xF0;\n const channel = statusByte & 0x0F;\n\n let resultChannel = channel;\n\n switch (eventType) {\n // midi (and meta and sysex headers)\n case 0x80:\n case 0x90:\n case 0xA0:\n case 0xB0:\n case 0xC0:\n case 0xD0:\n case 0xE0:\n break;\n\n case 0xF0:\n switch (channel) {\n case 0x0:\n resultChannel = -3;\n break;\n\n case 0x1:\n case 0x2:\n case 0x3:\n case 0x4:\n case 0x5:\n case 0x6:\n case 0x7:\n case 0x8:\n case 0x9:\n case 0xA:\n case 0xB:\n case 0xC:\n case 0xD:\n case 0xE:\n resultChannel = -1;\n break;\n\n case 0xF:\n resultChannel = -2;\n break;\n }\n break;\n\n default:\n resultChannel = -1;\n }\n\n return resultChannel;\n}\n\n// all the midi statuses dictionary\nexport const messageTypes = {\n noteOff: 0x80,\n noteOn: 0x90,\n polyPressure: 0xA0,\n controllerChange: 0xB0,\n programChange: 0xC0,\n channelPressure: 0xD0,\n pitchBend: 0xE0,\n systemExclusive: 0xF0,\n timecode: 0xF1,\n songPosition: 0xF2,\n songSelect: 0xF3,\n tuneRequest: 0xF6,\n clock: 0xF8,\n start: 0xFA,\n continue: 0xFB,\n stop: 0xFC,\n activeSensing: 0xFE,\n reset: 0xFF,\n sequenceNumber: 0x00,\n text: 0x01,\n copyright: 0x02,\n trackName: 0x03,\n instrumentName: 0x04,\n lyric: 0x05,\n marker: 0x06,\n cuePoint: 0x07,\n midiChannelPrefix: 0x20,\n midiPort: 0x21,\n endOfTrack: 0x2F,\n setTempo: 0x51,\n smpteOffset: 0x54,\n timeSignature: 0x58,\n keySignature: 0x59,\n sequenceSpecific: 0x7F\n};\n\n\n/**\n * Gets the event's status and channel from the status byte\n * @param statusByte {number} the status byte\n * @returns {{channel: number, status: number}} channel will be -1 for sysex and meta\n */\nexport function getEvent(statusByte) {\n const status = statusByte & 0xF0;\n const channel = statusByte & 0x0F;\n\n let eventChannel = -1;\n let eventStatus = statusByte;\n\n if (status >= 0x80 && status <= 0xE0) {\n eventChannel = channel;\n eventStatus = status;\n }\n\n return {\n status: eventStatus,\n channel: eventChannel\n };\n}\n\n\n/**\n * @enum {number}\n */\nexport const midiControllers = {\n bankSelect: 0,\n modulationWheel: 1,\n breathController: 2,\n footController: 4,\n portamentoTime: 5,\n dataEntryMsb: 6,\n mainVolume: 7,\n balance: 8,\n pan: 10,\n expressionController: 11,\n effectControl1: 12,\n effectControl2: 13,\n generalPurposeController1: 16,\n generalPurposeController2: 17,\n generalPurposeController3: 18,\n generalPurposeController4: 19,\n lsbForControl0BankSelect: 32,\n lsbForControl1ModulationWheel: 33,\n lsbForControl2BreathController: 34,\n lsbForControl4FootController: 36,\n lsbForControl5PortamentoTime: 37,\n lsbForControl6DataEntry: 38,\n lsbForControl7MainVolume: 39,\n lsbForControl8Balance: 40,\n lsbForControl10Pan: 42,\n lsbForControl11ExpressionController: 43,\n lsbForControl12EffectControl1: 44,\n lsbForControl13EffectControl2: 45,\n sustainPedal: 64,\n portamentoOnOff: 65,\n sostenutoPedal: 66,\n softPedal: 67,\n legatoFootswitch: 68,\n hold2Pedal: 69,\n soundVariation: 70,\n timbreHarmonicContent: 71,\n releaseTime: 72,\n attackTime: 73,\n brightness: 74,\n soundController6: 75,\n soundController7: 76,\n soundController8: 77,\n soundController9: 78,\n soundController10: 79,\n generalPurposeController5: 80,\n generalPurposeController6: 81,\n generalPurposeController7: 82,\n generalPurposeController8: 83,\n portamentoControl: 84,\n effects1Depth: 91,\n effects2Depth: 92,\n effects3Depth: 93,\n effects4Depth: 94,\n effects5Depth: 95,\n dataIncrement: 96,\n dataDecrement: 97,\n NRPNLsb: 98,\n NRPNMsb: 99,\n RPNLsb: 100,\n RPNMsb: 101,\n allSoundOff: 120,\n resetAllControllers: 121,\n localControlOnOff: 122,\n allNotesOff: 123,\n omniModeOff: 124,\n omniModeOn: 125,\n monoModeOn: 126,\n polyModeOn: 127\n};\n\n\n/**\n * @type {{\"11\": number, \"12\": number, \"13\": number, \"14\": number, \"8\": number, \"9\": number, \"10\": number}}\n */\nexport const dataBytesAmount = {\n 0x8: 2, // note off\n 0x9: 2, // note on\n 0xA: 2, // note at\n 0xB: 2, // cc change\n 0xC: 1, // pg change\n 0xD: 1, // channel aftertouch\n 0xE: 2 // pitch wheel\n};", "/**\n * @enum {number}\n * // NOTE: Every message needs a channel number (if not relevant or all, set to -1)\n * @property {number} noteOff - 0 -> midiNote<number>\n * @property {number} noteOn - 1 -> [midiNote<number>, velocity<number>, enableDebugging<boolean>]\n * @property {number} ccChange - 2 -> [ccNumber<number>, ccValue<number>, force<boolean>]\n * @property {number} programChange - 3 -> [programNumber<number>, userChange<boolean>]\n * @property {number} channelPressure - 4 -> pressure<number>\n * @property {number} polyPressure - 5 -> [midiNote<number>, pressure<number>]\n * @property {number} killNote - 6 -> midiNote<number>\n * @property {number} ccReset - 7 -> (no data) note: if channel is -1 then reset all channels\n * @property {number} setChannelVibrato - 8 -> {frequencyHz: number, depthCents: number, delaySeconds: number} note: if channel is -1 then stop all channels note 2: if rate is -1, it means locking\n * @property {number} reloadSoundFont - 9 -> (no data)\n * @property {number} stopAll - 10 -> force<number> (0 false, 1 true) note: if channel is -1 then stop all channels\n * @property {number} killNotes - 11 -> amount<number>\n * @property {number} muteChannel - 12 -> isMuted<boolean>\n * @property {number} addNewChannel - 13 -> (no data)\n * @property {number} customCcChange - 14 -> [ccNumber<number>, ccValue<number>]\n * @property {number} debugMessage - 15 -> (no data)\n * @property {number} systemExclusive - 16 -> message data <number[]> (without the F0 byte)\n * @property {number} setMasterParameter - 17 -> [parameter<masterParameterType>, value<number>]\n * @property {number} setDrums - 18 -> isDrums<boolean>\n * @property {number} pitchWheel - 19 -> [MSB<number>, LSB<number>]\n * @property {number} transpose - 20 -> [semitones<number>, force<boolean>] note: if channel is -1 then transpose all channels\n * @property {number} highPerformanceMode - 21 -> isOn<boolean>\n * @property {number} lockController - 22 -> [controllerNumber<number>, isLocked<boolean>]\n * @property {number} sequencerSpecific - 23 -> [messageType<WorkletSequencerMessageType> messageData<any>] note: refer to sequencer_message.js\n * @property {number} requestSynthesizerSnapshot - 24 -> (no data)\n * @property {number} setLogLevel - 25 -> [enableInfo<boolean>, enableWarning<boolean>, enableGroup<boolean>, enableTable<boolean>]\n */\nexport const workletMessageType = {\n noteOff: 0,\n noteOn: 1,\n ccChange: 2,\n programChange: 3,\n channelPressure: 4,\n polyPressure: 5,\n killNote: 6,\n ccReset: 7,\n setChannelVibrato: 8,\n reloadSoundFont: 9,\n stopAll: 10,\n killNotes: 11,\n muteChannel: 12,\n addNewChannel: 13,\n customcCcChange: 14,\n debugMessage: 15,\n systemExclusive: 16,\n setMasterParameter: 17,\n setDrums: 18,\n pitchWheel: 19,\n transpose: 20,\n highPerformanceMode: 21,\n lockController: 22,\n sequencerSpecific: 23,\n requestSynthesizerSnapshot: 24,\n setLogLevel: 25\n};\n\n/**\n * @enum {number}\n */\nexport const masterParameterType = {\n mainVolume: 0,\n masterPan: 1,\n voicesCap: 2,\n}\n\n\nexport const ALL_CHANNELS_OR_DIFFERENT_ACTION = -1;\n/**\n * @typedef {{\n * channelNumber: number\n * messageType: workletMessageType,\n * messageData: (\n * number[]\n * |boolean[]\n * |WorkletVoice[]\n * |number\n * |{sampleData: Float32Array, sampleID: number}\n * |{rate: number, depth: number, delay: number}\n * |boolean\n * |ArrayBuffer\n * |{messageType: WorkletSequencerMessageType, messageData: any}\n * )\n * }} WorkletMessage\n */\n\n/**\n * @typedef {Object} WorkletReturnMessage\n * @property {returnMessageType} messageType - the message's type\n * @property {{\n * eventName: string,\n * eventData: any\n * }|ChannelProperty[]\n * |PresetListElement[]\n * |string\n * |{messageType: WorkletSequencerReturnMessageType, messageData: any}\n * |SynthesizerSnapshot} messageData - the message's data\n *\n * 0 - channel properties -> [...<ChannelProperty>] see message_sending.js line 29\n * 1 - event call -> {eventName<string>, eventData:<the event's data>}\n * 2 - reported current time -> currentTime<number>\n * 3 - sequencer specific -> [messageType<WorkletSequencerReturnMessageType> messageData<any>] note: refer to sequencer_message.js\n * 4 - synthesizer snapshot -> snapshot<SynthesizerSnapshot> note: refer to snapshot.js\n * 5 - ready -> (no data)\n * 6 - soundfontError -> errorMessage<string>\n */\n\n/**\n * @enum {number}\n */\nexport const returnMessageType = {\n channelProperties: 0,\n eventCall: 1,\n reportedCurrentTime: 2,\n sequencerSpecific: 3,\n synthesizerSnapshot: 4,\n ready: 5,\n soundfontError: 6,\n}", "let ENABLE_INFO = true;\nlet ENABLE_WARN = true;\nlet ENABLE_GROUP = true;\nlet ENABLE_TABLE = true;\n\n/**\n * Enables or disables looging\n * @param enableInfo {boolean} - enables info\n * @param enableWarn {boolean} - enables warning\n * @param enableGroup {boolean} - enables groups\n * @param enableTable {boolean} - enables tables\n */\nexport function SpessaSynthLogging(enableInfo, enableWarn, enableGroup, enableTable)\n{\n ENABLE_INFO = enableInfo;\n ENABLE_WARN = enableWarn;\n ENABLE_GROUP = enableGroup;\n ENABLE_TABLE = enableTable;\n}\n\n/**\n * @param message {...any}\n */\nexport function SpessaSynthInfo(...message)\n{\n if(ENABLE_INFO)\n {\n console.info(...message);\n }\n}\n\n/**\n * @param message {...any}\n */\nexport function SpessaSynthWarn(...message)\n{\n if(ENABLE_WARN)\n {\n console.warn(...message);\n }\n}\n\nexport function SpessaSynthTable(...args)\n{\n if(ENABLE_TABLE)\n {\n console.table(...args);\n }\n}\n\n/**\n * @param message {...any} the message\n */\nexport function SpessaSynthGroup(...message)\n{\n if(ENABLE_GROUP)\n {\n console.group(...message);\n }\n}\n\n/**\n * @param message {...any} the message\n */\nexport function SpessaSynthGroupCollapsed(...message)\n{\n if(ENABLE_GROUP)\n {\n console.groupCollapsed(...message);\n }\n}\n\nexport function SpessaSynthGroupEnd()\n{\n if(ENABLE_GROUP)\n {\n console.groupEnd();\n }\n}", "import { IndexedByteArray } from '../utils/indexed_array.js'\nimport { consoleColors } from '../utils/other.js'\nimport { getEvent, messageTypes, midiControllers } from '../midi_parser/midi_message.js'\nimport { EventHandler } from './synth_event_handler.js'\nimport { FancyChorus } from './audio_effects/fancy_chorus.js'\nimport { getReverbProcessor } from './audio_effects/reverb.js'\nimport {\n ALL_CHANNELS_OR_DIFFERENT_ACTION, masterParameterType,\n returnMessageType,\n workletMessageType,\n} from './worklet_system/message_protocol/worklet_message.js'\nimport { SpessaSynthInfo, SpessaSynthWarn } from '../utils/loggin.js'\nimport { DEFAULT_EFFECTS_CONFIG } from './audio_effects/effects_config.js'\n\n\n/**\n * synthesizer.js\n * purpose: responds to midi messages and called functions, managing the channels and passing the messages to them\n */\n\n/**\n * @typedef {Object} StartRenderingDataConfig\n * @property {MIDI} parsedMIDI - the MIDI to render\n * @property {SynthesizerSnapshot} snapshot - the snapshot to apply\n * @property {boolean|undefined} oneOutput - if synth should use one output with 32 channels (2 audio channels for each midi channel). this disables chorus and reverb.\n */\n\nexport const WORKLET_PROCESSOR_NAME = \"spessasynth-worklet-system\";\n\nexport const VOICE_CAP = 450;\n\nexport const DEFAULT_PERCUSSION = 9;\nexport const MIDI_CHANNEL_COUNT = 16;\nexport const DEFAULT_SYNTH_MODE = \"gs\";\n\n/**\n * Creates a new instance of the SpessaSynth synthesizer\n * @param targetNode {AudioNode}\n * @param soundFontBuffer {ArrayBuffer} the soundfont file array buffer\n * @param enableEventSystem {boolean} enables the event system. Defaults to true\n * @param startRenderingData {StartRenderingDataConfig} if set, starts playing this immediately and restores the values\n * @param effectsConfig {EffectsConfig} optional configuration for the audio effects.\n */\nexport class Synthetizer {\n /**\n * Creates a new instance of the SpessaSynth synthesizer\n * @param targetNode {AudioNode}\n * @param soundFontBuffer {ArrayBuffer} the soundfont file array buffer\n * @param enableEventSystem {boolean} enables the event system. Defaults to true\n * @param startRenderingData {StartRenderingDataConfig} if set, starts playing this immediately and restores the values\n * @param effectsConfig {EffectsConfig} optional configuration for the audio effects.\n */\n constructor(targetNode,\n soundFontBuffer,\n enableEventSystem = true,\n startRenderingData = undefined,\n effectsConfig = DEFAULT_EFFECTS_CONFIG) {\n SpessaSynthInfo(\"%cInitializing SpessaSynth synthesizer...\", consoleColors.info);\n this.context = targetNode.context;\n const oneOutputMode = startRenderingData?.oneOutput === true;\n\n /**\n * Allows to set up custom event listeners for the synthesizer\n * @type {EventHandler}\n */\n this.eventHandler = new EventHandler();\n\n this._voiceCap = VOICE_CAP;\n\n /**\n * the new channels will have their audio sent to the moduled output by this constant.\n * what does that mean? e.g. if outputsAmount is 16, then channel's 16 audio will be sent to channel 0\n * @type {number}\n * @private\n */\n this._outputsAmount = MIDI_CHANNEL_COUNT;\n\n /**\n * the amount of midi channels\n * @type {number}\n */\n this.channelsAmount = this._outputsAmount;\n\n /**\n * Indicates if the synth is fully ready\n * @type {Promise<void>}\n */\n this.isReady = new Promise(resolve => this._resolveReady = resolve);\n\n\n /**\n * individual channel voices amount\n * @type {ChannelProperty[]}\n */\n this.channelProperties = [];\n for (let i = 0; i < this.channelsAmount; i++)\n {\n this.addNewChannel(false);\n }\n this.channelProperties[DEFAULT_PERCUSSION].isDrum = true;\n this._voicesAmount = 0;\n\n /**\n * For Black MIDI's - forces release time to 50ms\n * @type {boolean}\n */\n this._highPerformanceMode = false;\n\n // create a worklet processor\n let processorChannelCount = Array(this._outputsAmount + 2).fill(2);\n let processorOutputsCount = this._outputsAmount + 2;\n if(oneOutputMode)\n {\n processorOutputsCount = 1;\n processorChannelCount = [32];\n }\n\n // first two outputs: reverb, chorsu, the others are the channel outputs\n try {\n this.worklet = new AudioWorkletNode(this.context, WORKLET_PROCESSOR_NAME, {\n outputChannelCount: processorChannelCount,\n numberOfOutputs: processorOutputsCount,\n processorOptions: {\n midiChannels: this._outputsAmount,\n soundfont: soundFontBuffer,\n enableEventSystem: enableEventSystem,\n startRenderingData: startRenderingData\n }\n });\n }\n catch (e)\n {\n throw new Error(\"Could not create the audioWorklet. Did you forget to addModule()?\");\n }\n\n /**\n * @typedef {Object} PresetListElement\n * @property {string} presetName\n * @property {number} program\n * @property {number} bank\n *\n * used in \"presetlistchange\" event\n */\n\n // worklet sends us some data back\n this.worklet.port.onmessage = e => this.handleMessage(e.data);\n\n /**\n * @type {function(SynthesizerSnapshot)}\n * @private\n */\n this._snapshotCallback = undefined;\n\n /**\n * for the worklet sequencer's messages\n * @type {function(WorkletSequencerReturnMessageType, any)}\n */\n this.sequencerCallbackFunction = undefined;\n\n // add reverb\n if(effectsConfig.reverbEnabled && !oneOutputMode)\n {\n this.reverbProcessor = getReverbProcessor(this.context, effectsConfig.reverbImpulseResponse);\n this.reverbProcessor.connect(targetNode);\n this.worklet.connect(this.reverbProcessor, 0);\n }\n\n if(effectsConfig.chorusEnabled && !oneOutputMode)\n {\n this.chorusProcessor = new FancyChorus(targetNode, effectsConfig.chorusConfig);\n this.worklet.connect(this.chorusProcessor.input, 1);\n }\n\n if(oneOutputMode)\n {\n // one output mode: one output (duh)\n this.worklet.connect(targetNode, 0);\n }\n else\n {\n // connect all outputs to the output node\n for (let i = 2; i < this.channelsAmount + 2; i++)\n {\n this.worklet.connect(targetNode, i);\n }\n }\n\n // attach newchannel to keep track of channels count\n this.eventHandler.addEvent(\"newchannel\", \"synth-new-channel\", () => {\n this.channelsAmount++;\n });\n }\n\n /**\n * The maximum amount of voices allowed at once\n * @returns {number}\n */\n get voiceCap()\n {\n return this._voiceCap;\n }\n\n /**\n * The maximum amount of voices allowed at once\n * @param value {number}\n */\n set voiceCap(value)\n {\n this.post({\n messageType: workletMessageType.setMasterParameter,\n messageData: [masterParameterType.voicesCap, value]\n })\n this._voiceCap = value;\n }\n\n /**\n * For Black MIDI's - forces release time to 50ms\n * @param {boolean} value\n */\n set highPerformanceMode(value)\n {\n this._highPerformanceMode = value;\n\n }\n\n get highPerformanceMode()\n {\n return this._highPerformanceMode;\n }\n\n /**\n * Sets the SpessaSynth's log level\n * @param enableInfo {boolean} - enable info (verbose)\n * @param enableWarning {boolean} - enable warnings (unrecognized messages)\n * @param enableGroup {boolean} - enable groups (recomended)\n * @param enableTable {boolean} - enable table (debug message)\n */\n setLogLevel(enableInfo, enableWarning, enableGroup, enableTable)\n {\n this.post({\n channelNumber: -1,\n messageType: workletMessageType.setLogLevel,\n messageData: [enableInfo, enableWarning, enableGroup, enableTable]\n });\n }\n\n /**\n * Handles the messages received from the worklet\n * @param message {WorkletReturnMessage}\n * @private\n */\n handleMessage(message)\n {\n const messageData = message.messageData;\n switch (message.messageType)\n {\n case returnMessageType.channelProperties:\n /**\n * @type {ChannelProperty[]}\n */\n this.channelProperties = messageData;\n\n this._voicesAmount = this.channelProperties.reduce((sum, voices) => sum + voices.voicesAmount, 0);\n break;\n\n case returnMessageType.eventCall:\n this.eventHandler.callEvent(messageData.eventName, messageData.eventData);\n break;\n\n case returnMessageType.sequencerSpecific:\n if(this.sequencerCallbackFunction)\n {\n this.sequencerCallbackFunction(messageData.messageType, messageData.messageData);\n }\n break;\n\n case returnMessageType.synthesizerSnapshot:\n if(this._snapshotCallback)\n {\n this._snapshotCallback(messageData);\n }\n break;\n\n case returnMessageType.ready:\n this._resolveReady();\n break;\n\n case returnMessageType.soundfontError:\n SpessaSynthWarn(new Error(messageData));\n this.eventHandler.callEvent(\"soundfonterror\", messageData);\n }\n }\n\n /**\n * Gets a complete snapshot of the synthesizer, including controllers\n * @returns {Promise<SynthesizerSnapshot>}\n */\n async getSynthesizerSnapshot()\n {\n return new Promise(resolve => {\n this._snapshotCallback = s => {\n this._snapshotCallback = undefined;\n resolve(s);\n };\n this.post({\n messageType: workletMessageType.requestSynthesizerSnapshot,\n messageData: undefined,\n channelNumber: ALL_CHANNELS_OR_DIFFERENT_ACTION\n });\n });\n }\n\n /**\n * Adds a new channel to the synthesizer\n * @param postMessage {boolean} leave at true, set to false only at initialization\n */\n addNewChannel(postMessage = true)\n {\n this.channelProperties.push({\n voicesAmount: 0,\n pitchBend: 0,\n pitchBendRangeSemitones: 0,\n isMuted: false,\n isDrum: false\n });\n if(!postMessage)\n {\n return;\n }\n this.post({\n channelNumber: 0,\n messageType: workletMessageType.addNewChannel,\n messageData: null\n });\n }\n\n /**\n * @param channel {number}\n * @param value {{delay: number, depth: number, rate: number}}\n */\n setVibrato(channel, value)\n {\n this.post({\n channelNumber: channel,\n messageType: workletMessageType.setChannelVibrato,\n messageData: value\n });\n }\n\n /**\n * Connects the individual audio outputs to the given audio nodes. In the app it's used by the renderer.\n * @param audioNodes {AudioNode[]}\n */\n connectIndividualOutputs(audioNodes)\n {\n if(audioNodes.length !== this._outputsAmount)\n {\n throw new Error(`input nodes amount differs from the system's outputs amount!\n Expected ${this._outputsAmount} got ${audioNodes.length}`);\n }\n for (let outputNumber = 0; outputNumber < this._outputsAmount; outputNumber++) {\n // + 2 because chorus and reverb come first!\n this.worklet.connect(audioNodes[outputNumber], outputNumber + 2);\n }\n }\n\n /*\n * Prevents any further changes to the vibrato via NRPN messages and sets it to disabled\n */\n lockAndResetChannelVibrato()\n {\n // rate -1 disables, see worklet_message.js line 9\n // channel -1 is all\n this.setVibrato(ALL_CHANNELS_OR_DIFFERENT_ACTION, {depth: 0, rate: -1, delay: 0});\n }\n\n /**\n * A message for debugging\n */\n debugMessage()\n {\n SpessaSynthInfo(this);\n this.post({\n channelNumber: 0,\n messageType: workletMessageType.debugMessage,\n messageData: undefined\n });\n }\n\n /**\n * Starts playing a note\n * @param channel {number} usually 0-15: the channel to play the note\n * @param midiNote {number} 0-127 the key number of the note\n * @param velocity {number} 0-127 the velocity of the note (generally controls loudness)\n * @param enableDebugging {boolean} set to true to log technical details to console\n */\n noteOn(channel, midiNote, velocity, enableDebugging = false) {\n this.post({\n channelNumber: channel,\n messageType: workletMessageType.noteOn,\n messageData: [midiNote, velocity, enableDebugging]\n });\n }\n\n /**\n * Stops playing a note\n * @param channel {number} usually 0-15: the channel of the note\n * @param midiNote {number} 0-127 the key number of the note\n * @param force {boolean} instantly kills the note if true\n */\n noteOff(channel, midiNote, force = false) {\n if(force)\n {\n this.post({\n channelNumber: channel,\n messageType: workletMessageType.killNote,\n messageData: midiNote\n });\n }\n else {\n this.post({\n channelNumber: channel,\n messageType: workletMessageType.noteOff,\n messageData: midiNote\n });\n }\n }\n\n /**\n * Stops all notes\n * @param force {boolean} if we should instantly kill the note, defaults to false\n */\n stopAll(force=false) {\n this.post({\n channelNumber: ALL_CHANNELS_OR_DIFFERENT_ACTION,\n messageType: workletMessageType.stopAll,\n messageData: force ? 1 : 0\n });\n\n }\n\n /**\n * Changes the given controller\n * @param channel {number} usually 0-15: the channel to change the controller\n * @param controllerNumber {number} 0-127 the MIDI CC number\n * @param controllerValue {number} 0-127 the controller value\n * @param force {boolean} forces the controller change, even if it's locked or gm system is set and the cc is bank select\n */\n controllerChange(channel, controllerNumber, controllerValue, force=false)\n {\n controllerValue = Math.floor(controllerValue);\n controllerNumber = Math.floor(controllerNumber);\n this.post({\n channelNumber: channel,\n messageType: workletMessageType.ccChange,\n messageData: [controllerNumber, controllerValue, force]\n });\n }\n\n /**\n * Resets all controllers (for every channel)\n */\n resetControllers()\n {\n this.post({\n channelNumber: ALL_CHANNELS_OR_DIFFERENT_ACTION,\n messageType: workletMessageType.ccReset,\n messageData: undefined\n })\n }\n\n /**\n * Applies pressure to a given channel\n * @param channel {number} usually 0-15: the channel to change the controller\n * @param pressure {number} 0-127: the pressure to apply\n */\n channelPressure(channel, pressure)\n {\n this.post({\n channelNumber: channel,\n messageType: workletMessageType.channelPressure,\n messageData: pressure\n });\n }\n\n /**\n * Applies pressure to a given note\n * @param channel {number} usually 0-15: the channel to change the controller\n * @param midiNote {number} 0-127: the MIDI note\n * @param pressure {number} 0-127: the pressure to apply\n */\n polyPressure(channel, midiNote, pressure)\n {\n this.post({\n channelNumber: channel,\n messageType: workletMessageType.polyPressure,\n messageData: [midiNote, pressure]\n });\n }\n\n /**\n * @param data {WorkletMessage}\n */\n post(data)\n {\n this.worklet.port.postMessage(data);\n }\n\n /**\n * Sets the pitch of the given channel\n * @param channel {number} usually 0-15: the channel to change pitch\n * @param MSB {number} SECOND byte of the MIDI pitchWheel message\n * @param LSB {number} FIRST byte of the MIDI pitchWheel message\n */\n pitchWheel(channel, MSB, LSB)\n {\n this.post({\n channelNumber: channel,\n messageType: workletMessageType.pitchWheel,\n messageData: [MSB, LSB],\n });\n }\n\n /**\n * Transposes the synthetizer's pitch by given semitones amount (percussion channels do not get affected)\n * @param semitones {number} the semitones to transpose by. Can be a floating point number for more precision\n */\n transpose(semitones)\n {\n this.transposeChannel(ALL_CHANNELS_OR_DIFFERENT_ACTION, semitones, false);\n }\n\n /**\n * Transposes the channel by given amount of semitones\n * @param channel {number} the channel number\n * @param semitones {number} the transposition of the channel, can be a float\n * @param force {boolean} defaults to false, if true transposes the channel even if it's a drum channel\n */\n transposeChannel(channel, semitones, force=false)\n {\n this.post({\n channelNumber: channel,\n messageType: workletMessageType.transpose,\n messageData: [semitones, force]\n });\n }\n\n /**\n * Sets the main volume\n * @param volume {number} 0-1 the volume\n */\n setMainVolume(volume)\n {\n this.post({\n channelNumber: ALL_CHANNELS_OR_DIFFERENT_ACTION,\n messageType: workletMessageType.setMasterParameter,\n messageData: [masterParameterType.mainVolume, volume]\n });\n }\n\n /**\n * Sets the master stereo panning\n * @param pan {number} -1 to 1, the pan (-1 is left, 0 is midde, 1 is right)\n */\n setMasterPan(pan)\n {\n this.post({\n channelNumber: ALL_CHANNELS_OR_DIFFERENT_ACTION,\n messageType: workletMessageType.setMasterParameter,\n messageData: [masterParameterType.masterPan, pan]\n });\n }\n\n /**\n * Sets the channel's pitch bend range, in semitones\n * @param channel {number} usually 0-15: the channel to change\n * @param pitchBendRangeSemitones {number} the bend range in semitones\n */\n setPitchBendRange(channel, pitchBendRangeSemitones)\n {\n // set range\n this.controllerChange(channel, midiControllers.RPNMsb, 0);\n this.controllerChange(channel, midiControllers.dataEntryMsb, pitchBendRangeSemitones);\n\n // reset rpn\n this.controllerChange(channel, midiControllers.RPNMsb, 127);\n this.controllerChange(channel, midiControllers.RPNLsb, 127);\n this.controllerChange(channel, midiControllers.dataEntryMsb, 0);\n }\n\n /**\n * Changes the patch for a given channel\n * @param channel {number} usually 0-15: the channel to change\n * @param programNumber {number} 0-127 the MIDI patch number\n * @param userChange {boolean} indicates if the program change has been called by user. defaults to false\n */\n programChange(channel, programNumber, userChange=false)\n {\n this.post({\n channelNumber: channel,\n messageType: workletMessageType.programChange,\n messageData: [programNumber, userChange]\n })\n }\n\n /**\n * Causes the given midi channel to ignore controller messages for the given controller number\n * @param channel {number} usually 0-15: the channel to lock\n * @param controllerNumber {number} 0-127 MIDI CC number NOTE: -1 locks the preset\n * @param isLocked {boolean} true if locked, false if unlocked\n */\n lockController(channel, controllerNumber, isLocked)\n {\n this.post({\n channelNumber: channel,\n messageType: workletMessageType.lockController,\n messageData: [controllerNumber, isLocked]\n });\n }\n\n /**\n * Mutes or unmutes the given channel\n * @param channel {number} usually 0-15: the channel to lock\n * @param isMuted {boolean} indicates if the channel is muted\n */\n muteChannel(channel, isMuted)\n {\n this.post({\n channelNumber: channel,\n messageType: workletMessageType.muteChannel,\n messageData: isMuted\n });\n }\n\n /**\n * Reloads the sounfont.\n * @param soundFontBuffer {ArrayBuffer} the new soundfont file array buffer\n * @return {Promise<void>}\n */\n async reloadSoundFont(soundFontBuffer)\n {\n // copy and use transferable\n const bufferCopy = soundFontBuffer.slice(0);\n await new Promise(resolve => {\n this._resolveReady = resolve;\n this.worklet.port.postMessage({\n channelNumber: 0,\n messageType: workletMessageType.reloadSoundFont,\n messageData: bufferCopy\n }, [bufferCopy]);\n });\n }\n\n /**\n * Sends a MIDI Sysex message to the synthesizer\n * @param messageData {IndexedByteArray} the message's data (excluding the F0 byte, but including the F7 at the end)\n */\n systemExclusive(messageData)\n {\n this.post({\n channelNumber: ALL_CHANNELS_OR_DIFFERENT_ACTION,\n messageType: workletMessageType.systemExclusive,\n messageData: Array.from(messageData)\n });\n }\n\n /**\n * Toggles drums on a given channel\n * @param channel {number}\n * @param isDrum {boolean}\n */\n setDrums(channel, isDrum)\n {\n this.post({\n channelNumber: channel,\n messageType: workletMessageType.setDrums,\n messageData: isDrum\n });\n }\n\n /**\n * sends a raw MIDI message to the synthesizer\n * @param message {ArrayLike<number>} the midi message, each number is a byte\n */\n sendMessage(message)\n {\n // discard as soon as possible if high perf\n const statusByteData = getEvent(message[0]);\n\n\n // process the event\n switch (statusByteData.status)\n {\n case messageTypes.noteOn:\n const velocity = message[2];\n if(velocity > 0) {\n this.noteOn(statusByteData.channel, message[1], velocity);\n }\n else\n {\n this.noteOff(statusByteData.channel, message[1]);\n }\n break;\n\n case messageTypes.noteOff:\n this.noteOff(statusByteData.channel, message[1]);\n break;\n\n case messageTypes.pitchBend:\n this.pitchWheel(statusByteData.channel, message[2], message[1]);\n break;\n\n case messageTypes.controllerChange:\n this.controllerChange(statusByteData.channel, message[1], message[2]);\n break;\n\n case messageTypes.programChange:\n this.programChange(statusByteData.channel, message[1]);\n break;\n\n case messageTypes.polyPressure:\n this.polyPressure(statusByteData.channel, message[0], message[1]);\n break;\n\n case messageTypes.channelPressure:\n this.channelPressure(statusByteData.channel, message[1]);\n break;\n\n case messageTypes.systemExclusive:\n this.systemExclusive(new IndexedByteArray(message.slice(1)));\n break;\n\n case messageTypes.reset:\n this.stopAll(true);\n this.resetControllers();\n break;\n\n default:\n break;\n }\n }\n\n /**\n * @returns {number} the audioContext's current time\n */\n get currentTime()\n {\n return this.context.currentTime;\n }\n\n /**\n * @returns {number} the current amount of voices playing\n */\n get voicesAmount()\n {\n return this._voicesAmount;\n }\n\n reverbateEverythingBecauseWhyNot()\n {\n for (let i = 0; i < this.channelsAmount; i++) {\n this.controllerChange(i, midiControllers.effects1Depth, 127);\n }\n return \"That's the spirit!\";\n }\n}", "/**\n * Reads as little endian\n * @param dataArray {IndexedByteArray}\n * @param bytesAmount {number}\n * @returns {number}\n */\nexport function readBytesAsUintLittleEndian(dataArray, bytesAmount){\n let out = 0;\n for(let i = 0; i < bytesAmount; i++)\n {\n out |= (dataArray[dataArray.currentIndex++] << i * 8);\n }\n // make sure it stays unsigned\n return out >>> 0;\n}\n\n/**\n * Writes a number as little endian seems to also work for negative numbers so yay?\n * @param dataArray {IndexedByteArray}\n * @param number {number}\n * @param byteTarget {number}\n */\nexport function writeLittleEndian(dataArray, number, byteTarget)\n{\n for(let i = 0; i < byteTarget; i++)\n {\n dataArray[dataArray.currentIndex++] = (number >> (i * 8)) & 0xFF;\n }\n}\n\n/**\n * @param dataArray {IndexedByteArray}\n * @param word {number}\n */\nexport function writeWord(dataArray, word)\n{\n dataArray[dataArray.currentIndex++] = word & 0xFF;\n dataArray[dataArray.currentIndex++] = word >> 8;\n}\n\n/**\n * @param dataArray {IndexedByteArray}\n * @param dword {number}\n */\nexport function writeDword(dataArray, dword)\n{\n writeLittleEndian(dataArray, dword, 4);\n}\n\n/**\n * @param byte1 {number}\n * @param byte2 {number}\n * @returns {number}\n */\nexport function signedInt16(byte1, byte2){\n let val = (byte2 << 8) | byte1;\n if(val > 32767)\n {\n return val - 65536;\n }\n return val;\n}\n\n/**\n * @param byte {number}\n * @returns {number}\n */\nexport function signedInt8(byte) {\n if(byte > 127)\n {\n return byte - 256;\n }\n return byte;\n}", "import { IndexedByteArray } from '../indexed_array.js'\n\n/**\n * @param dataArray {IndexedByteArray}\n * @param bytes {number}\n * @param encoding {string} the textElement encoding\n * @param trimEnd {boolean} if we should trim once we reach an invalid byte\n * @returns {string}\n */\nexport function readBytesAsString(dataArray, bytes, encoding = undefined, trimEnd = true) {\n if (!encoding)\n {\n let finished = false\n let string = ''\n for (let i = 0; i < bytes; i++)\n {\n let byte = dataArray[dataArray.currentIndex++]\n if (finished)\n {\n continue\n }\n if (byte < 32 || byte > 127)\n {\n if (trimEnd)\n {\n finished = true\n continue\n }\n else\n {\n if (byte === 0)\n {\n finished = true;\n continue;\n }\n }\n }\n string += String.fromCharCode(byte)\n }\n return string\n }\n else\n {\n let byteBuffer = dataArray.slice(dataArray.currentIndex, dataArray.currentIndex + bytes)\n dataArray.currentIndex += bytes\n let decoder = new TextDecoder(encoding)\n return decoder.decode(byteBuffer.buffer)\n }\n}\n\n/**\n * @param string {string}\n * @param padLength {number}\n * @returns {IndexedByteArray}\n */\nexport function getStringBytes(string, padLength = 0)\n{\n let len = string.length;\n if(padLength > 0)\n {\n len = padLength;\n }\n const arr = new IndexedByteArray(len);\n writeStringAsBytes(arr, string, padLength);\n return arr;\n}\n\n/**\n * @param string {string}\n * @param outArray {IndexedByteArray}\n * @param padLength {number}\n * @returns {IndexedByteArray} modified IN PLACE\n */\nexport function writeStringAsBytes(outArray, string, padLength = 0)\n{\n if(padLength > 0)\n {\n if(string.length > padLength)\n {\n string = string.slice(0, padLength);\n }\n }\n for (let i = 0; i < string.length; i++)\n {\n outArray[outArray.currentIndex++] = string.charCodeAt(i);\n }\n\n // pad with zeros if needed\n if(padLength > string.length)\n {\n for (let i = 0; i < padLength - string.length; i++)\n {\n outArray[outArray.currentIndex++] = 0;\n }\n }\n return outArray\n}", "import { IndexedByteArray } from '../../utils/indexed_array.js'\nimport { readBytesAsUintLittleEndian, writeDword } from '../../utils/byte_functions/little_endian.js'\nimport { readBytesAsString, writeStringAsBytes } from '../../utils/byte_functions/string.js'\n\n/**\n * riff_chunk.js\n * reads a riff read and stores it as a class\n */\n\nexport class RiffChunk\n{\n /**\n * Creates a new riff read\n * @constructor\n * @param header {string}\n * @param size {number}\n * @param data {IndexedByteArray}\n */\n constructor(header, size, data) {\n this.header = header;\n this.size = size;\n this.chunkData = data;\n }\n\n}\n\n/**\n * @param dataArray {IndexedByteArray}\n * @param readData {boolean}\n * @param forceShift {boolean}\n * @returns {RiffChunk}\n */\nexport function readRIFFChunk(dataArray, readData = true, forceShift = false) {\n let header = readBytesAsString(dataArray, 4)\n\n let size = readBytesAsUintLittleEndian(dataArray, 4)\n let chunkData = undefined\n if (readData)\n {\n chunkData = new IndexedByteArray(size)\n chunkData.set(dataArray.slice(dataArray.currentIndex, dataArray.currentIndex + size))\n }\n if(readData || forceShift)\n {\n dataArray.currentIndex += size;\n }\n\n return new RiffChunk(header, size, chunkData)\n}\n\n/**\n * @param chunk {RiffChunk}\n * @param prepend {IndexedByteArray}\n * @returns {IndexedByteArray}\n */\nexport function writeRIFFChunk(chunk, prepend = undefined)\n{\n let size = 8 + chunk.size;\n if(chunk.size % 2 !== 0)\n {\n size++;\n }\n if(prepend)\n {\n size += prepend.length;\n }\n const array = new IndexedByteArray(size);\n // prepend data (for example type before the read)\n if(prepend)\n {\n array.set(prepend, array.currentIndex);\n array.currentIndex += prepend.length;\n }\n // write header\n writeStringAsBytes(array, chunk.header);\n // write size (excluding header and the size itself) and the prepend if specified\n writeDword(array, size - 8 - (prepend?.length || 0));\n // write data\n array.set(chunk.chunkData, array.currentIndex);\n return array;\n}", "import { IndexedByteArray } from '../../utils/indexed_array.js'\nimport { RiffChunk } from './riff_chunk.js'\nimport { signedInt16 } from '../../utils/byte_functions/little_endian.js'\n\n/**\n * generators.js\n * purpose: contains enums for generators and their limis parses reads soundfont generators, sums them and applies limits\n */\n\n/**\n * @enum {number}\n */\nexport const generatorTypes = {\n startAddrsOffset: 0, // sample control - moves sample start point\n endAddrOffset: 1, // sample control - moves sample end point\n startloopAddrsOffset: 2, // loop control - moves loop start point\n endloopAddrsOffset: 3, // loop control - moves loop end point\n startAddrsCoarseOffset: 4, // sample control - moves sample start point in 32767 increments\n modLfoToPitch: 5, // pitch modulation - modulation lfo pitch modulation in cents\n vibLfoToPitch: 6, // pitch modulation - vibrato lfo pitch modulation in cents\n modEnvToPitch: 7, // pitch modulation - modulation envelope pitch modulation in cents\n initialFilterFc: 8, // filter - lowpass filter cutoff in cents\n initialFilterQ: 9, // filter - lowpass filter resonance\n modLfoToFilterFc: 10, // filter modulation - modulation lfo lowpass filter cutoff in cents\n modEnvToFilterFc: 11, // filter modulation - modulation envelope lowpass filter cutoff in cents\n endAddrsCoarseOffset: 12, // ample control - moves sample end point in 32767 increments\n modLfoToVolume: 13, // modulation lfo - volume (tremolo), where 100 = 10dB\n unused1: 14,\n chorusEffectsSend: 15, // effect send - how much is sent to chorus 0 - 1000\n reverbEffectsSend: 16, // effect send - how much is sent to reverb 0 - 1000\n pan: 17, // panning - where -500 = left, 0 = center, 500 = right\n unused2: 18,\n unused3: 19,\n unused4: 20,\n delayModLFO: 21, // mod lfo - delay for mod lfo to start from zero (weird scale)\n freqModLFO: 22, // mod lfo - frequency of mod lfo, 0 = 8.176Hz, unit: f => 1200log2(f/8.176)\n delayVibLFO: 23, // vib lfo - delay for vibrato lfo to start from zero (weird scale)\n freqVibLFO: 24, // vib lfo - frequency of vibrato lfo, 0 = 8.176Hz, unit: f => 1200log2(f/8.176)\n delayModEnv: 25, // mod env - 0 = 1s declay till mod env starts\n attackModEnv: 26, // mod env - attack of mod env\n holdModEnv: 27, // mod env - hold of mod env\n decayModEnv: 28, // mod env - decay of mod env\n sustainModEnv: 29, // mod env - sustain of mod env\n releaseModEnv: 30, // mod env - release of mod env\n keyNumToModEnvHold: 31, // mod env - also modulating mod envelope hold with key number\n keyNumToModEnvDecay: 32, // mod env - also modulating mod envelope decay with key number\n delayVolEnv: 33, // vol env - delay of envelope from zero (weird scale)\n attackVolEnv: 34, // vol env - attack of envelope\n holdVolEnv: 35, // vol env - hold of envelope\n decayVolEnv: 36, // vol env - decay of envelope\n sustainVolEnv: 37, // vol env - sustain of envelope\n releaseVolEnv: 38, // vol env - release of envelope\n keyNumToVolEnvHold: 39, // vol env - key number to volume envelope hold\n keyNumToVolEnvDecay: 40, // vol env - key number to volume envelope decay\n instrument: 41, // zone - instrument index to use for preset zone\n reserved1: 42,\n keyRange: 43, // zone - key range for which preset / instrument zone is active\n velRange: 44, // zone - velocity range for which preset / instrument zone is active\n startloopAddrsCoarseOffset: 45, // ample control - moves sample loop start point in 32767 increments\n keyNum: 46, // zone - instrument only: always use this midi number (ignore what's pressed)\n velocity: 47, // zone - instrument only: always use this velocity (ignore what's pressed)\n initialAttenuation: 48, // zone - allows turning down the volume, 10 = -1dB\n reserved2: 49,\n endloopAddrsCoarseOffset: 50, // ample control - moves sample loop end point in 32767 increments\n coarseTune: 51, // tune - pitch offset in semitones\n fineTune: 52, // tune - pitch offset in cents\n sampleID: 53, // sample - instrument zone only: which sample to use\n sampleModes: 54, // sample - 0 = no loop, 1 = loop, 2 = reserved, 3 = loop and play till end in release phase\n reserved3: 55,\n scaleTuning: 56, // sample - the degree to which MIDI key number influences pitch, 100 = default\n exclusiveClass: 57, // sample - = cut = choke group\n overridingRootKey: 58, // sample - can override the sample's original pitch\n unused5: 59,\n endOper: 60 // end marker\n};\n\n/**\n * @type {{min: number, max: number, def: number}[]}\n */\nexport const generatorLimits = [];\n// offsets\ngeneratorLimits[generatorTypes.startAddrsOffset] = {min: 0, max: 32768, def: 0};\ngeneratorLimits[generatorTypes.endAddrOffset] = {min: -32768, max: 32768, def: 0};\ngeneratorLimits[generatorTypes.startloopAddrsOffset] = {min: -32768, max: 32768, def: 0};\ngeneratorLimits[generatorTypes.endloopAddrsOffset] = {min: -32768, max: 32768, def: 0};\ngeneratorLimits[generatorTypes.startAddrsCoarseOffset] = {min: 0, max: 32768, def: 0};\n\n// pitch influence\ngeneratorLimits[generatorTypes.modLfoToPitch] = {min: -12000, max: 12000, def: 0};\ngeneratorLimits[generatorTypes.vibLfoToPitch] = {min: -12000, max: 12000, def: 0};\ngeneratorLimits[generatorTypes.modEnvToPitch] = {min: -12000, max: 12000, def: 0};\n\n// lowpass\ngeneratorLimits[generatorTypes.initialFilterFc] = {min: 1500, max: 13500, def: 13500};\ngeneratorLimits[generatorTypes.initialFilterQ] = {min: 0, max: 960, def: 0};\ngeneratorLimits[generatorTypes.modLfoToFilterFc] = {min: -12000, max: 12000, def: 0};\ngeneratorLimits[generatorTypes.modEnvToFilterFc] = {min: -12000, max: 12000, def: 0};\n\ngeneratorLimits[generatorTypes.endAddrsCoarseOffset] = {min: -32768, max: 32768, def: 0};\n\ngeneratorLimits[generatorTypes.modLfoToVolume] = {min: -960, max: 960, def: 0};\n\n// effects, pan\ngeneratorLimits[generatorTypes.chorusEffectsSend] = {min: 0, max: 1000, def: 0};\ngeneratorLimits[generatorTypes.reverbEffectsSend] = {min: 0, max: 1000, def: 0};\ngeneratorLimits[generatorTypes.pan] = {min: -500, max: 500, def: 0};\n\n// lfo\ngeneratorLimits[generatorTypes.delayModLFO] = {min: -12000, max: 5000, def: -12000};\ngeneratorLimits[generatorTypes.freqModLFO] = {min: -16000, max: 4500, def: 0};\ngeneratorLimits[generatorTypes.delayVibLFO] = {min: -12000, max: 5000, def: -12000};\ngeneratorLimits[generatorTypes.freqVibLFO] = {min: -16000, max: 4500, def: 0};\n\n// mod env\ngeneratorLimits[generatorTypes.delayModEnv] = {min: -12000, max: 5000, def: -12000};\ngeneratorLimits[generatorTypes.attackModEnv] = {min: -12000, max: 8000, def: -12000};\ngeneratorLimits[generatorTypes.holdModEnv] = {min: -12000, max: 5000, def: -12000};\ngeneratorLimits[generatorTypes.decayModEnv] = {min: -12000, max: 8000, def: -12000};\ngeneratorLimits[generatorTypes.sustainModEnv] = {min: 0, max: 1000, def: 0};\ngeneratorLimits[generatorTypes.releaseModEnv] = {min: -12000, max: 8000, def: -12000};\n// keynum to mod env\ngeneratorLimits[generatorTypes.keyNumToModEnvHold] = {min: -1200, max: 1200, def: 0};\ngeneratorLimits[generatorTypes.keyNumToModEnvDecay] = {min: -1200, max: 1200, def: 0};\n\n// vol env\ngeneratorLimits[generatorTypes.delayVolEnv] = {min: -12000, max: 5000, def: -12000};\ngeneratorLimits[generatorTypes.attackVolEnv] = {min: -12000, max: 8000, def: -12000};\ngeneratorLimits[generatorTypes.holdVolEnv] = {min: -12000, max: 5000, def: -12000};\ngeneratorLimits[generatorTypes.decayVolEnv] = {min: -12000, max: 8000, def: -12000};\ngeneratorLimits[generatorTypes.sustainVolEnv] = {min: 0, max: 1440, def: 0};\ngeneratorLimits[generatorTypes.releaseVolEnv] = {min: -7200, max: 8000, def: -12000}; // prevent clicks\n// keynum to vol env\ngeneratorLimits[generatorTypes.keyNumToVolEnvHold] = {min: -1200, max: 1200, def: 0};\ngeneratorLimits[generatorTypes.keyNumToVolEnvDecay] = {min: -1200, max: 1200, def: 0};\n\ngeneratorLimits[generatorTypes.startloopAddrsCoarseOffset] = {min: -32768, max: 32768, def: 0};\ngeneratorLimits[generatorTypes.keyNum] = {min: -1, max: 127, def: -1};\ngeneratorLimits[generatorTypes.velocity] = {min: -1, max: 127, def: -1};\n\ngeneratorLimits[generatorTypes.initialAttenuation] = {min: -250, max: 1440, def: 0}; // soundblaster allows 10dB of gain (divide by 0.4)\n\ngeneratorLimits[generatorTypes.endloopAddrsCoarseOffset] = {min: -32768, max: 32768, def: 0};\n\ngeneratorLimits[generatorTypes.coarseTune] = {min: -120, max: 120, def: 0};\ngeneratorLimits[generatorTypes.fineTune] = {min: -99, max: 99, def: 0};\ngeneratorLimits[generatorTypes.scaleTuning] = {min: 0, max: 1200, def: 100};\ngeneratorLimits[generatorTypes.exclusiveClass] = {min: 0, max: 99999, def: 0};\ngeneratorLimits[generatorTypes.overridingRootKey] = {min: 0-1, max: 127, def: -1};\n\n\n/**\n * @param generatorType {number}\n * @param presetGens {Generator[]}\n * @param instrumentGens {Generator[]}\n */\nexport function addAndClampGenerator(generatorType, presetGens, instrumentGens)\n{\n const limits = generatorLimits[generatorType] || {min: 0, max: 32768, def: 0};\n let presetGen = presetGens.find(g => g.generatorType === generatorType);\n let presetValue = 0;\n if(presetGen)\n {\n presetValue = presetGen.generatorValue;\n }\n\n let instruGen = instrumentGens.find(g => g.generatorType === generatorType);\n let instruValue = limits.def;\n if(instruGen)\n {\n instruValue = instruGen.generatorValue;\n }\n return Math.max(limits.min, Math.min(limits.max, instruValue + presetValue));\n}\n\n\nexport class Generator{\n /**\n * Creates a generator\n * @param dataArray {IndexedByteArray}\n */\n constructor(dataArray) {\n // 4 bytes:\n // type, type, type, value\n const i = dataArray.currentIndex;\n /**\n * @type {generatorTypes}\n **/\n this.generatorType = (dataArray[i + 1] << 8) | dataArray[i];\n this.generatorValue = signedInt16(dataArray[i + 2], dataArray[i + 3]);\n dataArray.currentIndex += 4;\n }\n}\n\n/**\n * Reads the generator read\n * @param generatorChunk {RiffChunk}\n * @returns {Generator[]}\n */\nexport function readGenerators(generatorChunk)\n{\n let gens = [];\n while(generatorChunk.chunkData.length > generatorChunk.chunkData.currentIndex)\n {\n gens.push(new Generator(generatorChunk.chunkData));\n }\n if(gens.length > 1)\n {\n // remove terminal\n gens.pop();\n }\n return gens;\n}", "import {signedInt16, readBytesAsUintLittleEndian} from \"../../utils/byte_functions/little_endian.js\";\nimport { IndexedByteArray } from '../../utils/indexed_array.js';\nimport { generatorTypes } from './generators.js'\nimport { midiControllers } from '../../midi_parser/midi_message.js'\n\n/**\n * modulators.js\n * purpose: parses soundfont modulators and the source enums, also includes the default modulators list\n **/\nexport const modulatorSources = {\n noController: 0,\n noteOnVelocity: 2,\n noteOnKeyNum: 3,\n polyPressure: 10,\n channelPressure: 13,\n pitchWheel: 14,\n pitchWheelRange: 16,\n link: 127\n}\n\nexport const modulatorCurveTypes = {\n linear: 0,\n concave: 1,\n convex: 2,\n switch: 3\n}\n\n/**\n *\n * type, polarity, direction\n * @type {Float32Array[][][]}\n */\nexport const precomputedTransforms = [];\nfor (let i = 0; i < 4; i++) {\n precomputedTransforms.push([[], []]);\n}\n\nexport class Modulator{\n /**\n * Creates a modulator\n * @param dataArray {IndexedByteArray|{srcEnum: number, secSrcEnum: number, dest:number, amt: number, transform: number}}\n */\n constructor(dataArray) {\n if(dataArray.srcEnum)\n {\n this.modulatorSource = dataArray.srcEnum;\n /**\n * @type {generatorTypes}\n */\n this.modulatorDestination = dataArray.dest;\n this.modulationSecondarySrc = dataArray.secSrcEnum;\n this.transformAmount = dataArray.amt;\n this.transformType = dataArray.transform;\n }\n else\n {\n this.modulatorSource = readBytesAsUintLittleEndian(dataArray, 2);\n this.modulatorDestination = readBytesAsUintLittleEndian(dataArray, 2);\n this.transformAmount = signedInt16(dataArray[dataArray.currentIndex++], dataArray[dataArray.currentIndex++]);\n this.modulationSecondarySrc = readBytesAsUintLittleEndian(dataArray, 2);\n this.transformType = readBytesAsUintLittleEndian(dataArray, 2);\n }\n\n if(this.modulatorDestination > 58)\n {\n this.modulatorDestination = -1; // flag as invalid (for linked ones)\n }\n\n // decode the source\n this.sourcePolarity = this.modulatorSource >> 9 & 1;\n this.sourceDirection = this.modulatorSource >> 8 & 1;\n this.sourceUsesCC = this.modulatorSource >> 7 & 1;\n this.sourceIndex = this.modulatorSource & 127;\n this.sourceCurveType = this.modulatorSource >> 10 & 3;\n\n // decode the secondary source\n this.secSrcPolarity = this.modulationSecondarySrc >> 9 & 1;\n this.secSrcDirection = this.modulationSecondarySrc >> 8 & 1;\n this.secSrcUsesCC = this.modulationSecondarySrc >> 7 & 1;\n this.secSrcIndex = this.modulationSecondarySrc & 127;\n this.secSrcCurveType = this.modulationSecondarySrc >> 10 & 3;\n\n //this.precomputeModulatorTransform();\n }\n\n /**\n * Sums transform and creates a NEW modulator\n * @param modulator {Modulator}\n * @returns {Modulator}\n */\n sumTransform(modulator)\n {\n return new Modulator({\n srcEnum: this.modulatorSource,\n secSrcEnum: this.modulationSecondarySrc,\n dest: this.modulatorDestination,\n transform: this.transformType,\n amt: this.transformAmount + modulator.transformAmount\n });\n }\n\n /**\n * @returns {string}\n */\n debugString()\n {\n function getKeyByValue(object, value)\n {\n return Object.keys(object).find(key => object[key] === value);\n }\n\n let sourceString = getKeyByValue(modulatorCurveTypes, this.sourceCurveType);\n sourceString += this.sourcePolarity === 0 ? \" unipolar \" : \" bipolar \";\n sourceString += this.sourceDirection === 0 ? \"forwards \" : \"backwards \";\n if(this.sourceUsesCC)\n {\n sourceString += getKeyByValue(midiControllers, this.sourceIndex);\n }\n else\n {\n sourceString += getKeyByValue(modulatorSources, this.sourceIndex);\n }\n\n let secSrcString = getKeyByValue(modulatorCurveTypes, this.secSrcCurveType);\n secSrcString += this.secSrcPolarity === 0 ? \" unipolar \" : \" bipolar \";\n secSrcString += this.secSrcCurveType === 0 ? \"forwards \" : \"backwards \";\n if(this.secSrcUsesCC)\n {\n secSrcString += getKeyByValue(midiControllers, this.secSrcIndex);\n }\n else\n {\n secSrcString += getKeyByValue(modulatorSources, this.secSrcIndex);\n }\n return `Modulator:\n Source: ${sourceString}\n Secondary source: ${secSrcString}\n Destination: ${getKeyByValue(generatorTypes, this.modulatorDestination)}\n Trasform amount: ${this.transformAmount}\n Transform type: ${this.transformType}\n \\n\\n`;\n }\n}\n\nfunction getModSourceEnum(curveType, polarity, direction, isCC, index)\n{\n return (curveType << 10) | (polarity << 9) | (direction << 8) | (isCC << 7) | index;\n}\n\nconst DEFAULT_ATTENUATION_MOD_AMOUNT = 960;\nconst DEFAULT_ATTENUATION_MOD_CURVE_TYPE = modulatorCurveTypes.concave;\n\nexport const defaultModulators = [\n // vel to attenuation\n new Modulator({\n srcEnum: getModSourceEnum(DEFAULT_ATTENUATION_MOD_CURVE_TYPE, 0, 1, 0, modulatorSources.noteOnVelocity),\n dest: generatorTypes.initialAttenuation,\n amt: DEFAULT_ATTENUATION_MOD_AMOUNT,\n secSrcEnum: 0x0,\n transform: 0}),\n\n // mod wheel to vibrato\n new Modulator({srcEnum: 0x0081, dest: generatorTypes.vibLfoToPitch, amt: 50, secSrcEnum: 0x0, transform: 0}),\n\n // vol to attenuation\n new Modulator({\n srcEnum: getModSourceEnum(DEFAULT_ATTENUATION_MOD_CURVE_TYPE, 0, 1, 1, midiControllers.mainVolume),\n dest: generatorTypes.initialAttenuation,\n amt: DEFAULT_ATTENUATION_MOD_AMOUNT,\n secSrcEnum: 0x0,\n transform: 0}),\n\n // channel pressure to vibrato\n new Modulator({srcEnum: 0x000D, dest: generatorTypes.vibLfoToPitch, amt: 50, secSrcEnum: 0x0, transform: 0}),\n\n // pitch wheel to tuning\n new Modulator({srcEnum: 0x020E, dest: generatorTypes.fineTune, amt: 12700, secSrcEnum: 0x0010, transform: 0}),\n\n // pan to uhh, pan\n new Modulator({srcEnum: 0x028A, dest: generatorTypes.pan, amt: 1000, secSrcEnum: 0x0, transform: 0}),\n\n // expression to attenuation\n new Modulator({\n srcEnum: getModSourceEnum(DEFAULT_ATTENUATION_MOD_CURVE_TYPE, 0, 1, 1, midiControllers.expressionController),\n dest: generatorTypes.initialAttenuation,\n amt: DEFAULT_ATTENUATION_MOD_AMOUNT,\n secSrcEnum: 0x0,\n transform: 0\n }),\n\n // reverb effects to send\n // 1000 to align with the reverbSend (overriding it works anyways)\n new Modulator({srcEnum: 0x00DB, dest: generatorTypes.reverbEffectsSend, amt: 200, secSrcEnum: 0x0, transform: 0}),\n\n // chorus effects to send\n new Modulator({srcEnum: 0x00DD, dest: generatorTypes.chorusEffectsSend, amt: 200, secSrcEnum: 0x0, transform: 0}),\n\n // custom modulators heck yeah\n // poly pressure to vibrato\n new Modulator({\n srcEnum: getModSourceEnum(modulatorCurveTypes.linear, 0, 0, 0, modulatorSources.polyPressure),\n dest: generatorTypes.vibLfoToPitch,\n amt: 50,\n secSrcEnum: 0x0,\n transform: 0\n }),\n\n // cc 92 (tremolo) to modLFO volume\n new Modulator({\n srcEnum: getModSourceEnum(modulatorCurveTypes.linear, 0, 0, 1, midiControllers.effects2Depth), /*linear forward unipolar cc 92 */\n dest: generatorTypes.modLfoToVolume,\n amt: 24,\n secSrcEnum: 0x0, // no controller\n transform: 0\n }),\n\n // cc 72 (release time) to volEnv release\n new Modulator({\n srcEnum: getModSourceEnum(modulatorCurveTypes.linear, 1, 0, 1, midiControllers.releaseTime), // linear forward bipolar cc 72\n dest: generatorTypes.releaseVolEnv,\n amt: 1200,\n secSrcEnum: 0x0, // no controller\n transform: 0\n }),\n\n // cc 74 (brightness) to filterFc\n new Modulator({\n srcEnum: getModSourceEnum(modulatorCurveTypes.linear, 1, 0 , 1, midiControllers.brightness), // linear forwards bipolar cc 74\n dest: generatorTypes.initialFilterFc,\n amt: 4000,\n secSrcEnum: 0x0, // no controller\n transform: 0\n })\n];\n\n/**\n * Reads the modulator read\n * @param modulatorChunk {RiffChunk}\n * @returns {Modulator[]}\n */\nexport function readModulators(modulatorChunk)\n{\n let gens = [];\n while(modulatorChunk.chunkData.length > modulatorChunk.chunkData.currentIndex)\n {\n gens.push(new Modulator(modulatorChunk.chunkData));\n }\n return gens;\n}", "import { midiControllers } from '../../../midi_parser/midi_message.js'\nimport { modulatorSources } from '../../../soundfont/read/modulators.js'\n/**\n * @typedef {Object} WorkletProcessorChannel\n * @property {Int16Array} midiControllers - array of MIDI controller values + the values used by modulators as source (pitch bend, bend range etc.)\n * @property {boolean[]} lockedControllers - array indicating if a controller is locked\n * @property {Float32Array} customControllers - array of custom (not sf2) control values such as RPN pitch tuning, transpose, modulation depth, etc.\n *\n * @property {number} channelTransposeKeyShift - key shift of the channel\n * @property {boolean} holdPedal - indicates whether the hold pedal is active\n * @property {boolean} drumChannel - indicates whether the channel is a drum channel\n *\n * @property {dataEntryStates} dataEntryState - the current state of the data entry\n * @property {number} NRPCoarse - the current coarse value of the Non-Registered Parameter\n * @property {number} NRPFine - the current fine value of the Non-Registered Parameter\n * @property {number} RPValue - the current value of the Registered Parameter\n *\n * @property {Preset} preset - the channel's preset\n * @property {boolean} lockPreset - indicates whether the program on the channel is locked\n *\n * @property {boolean} lockVibrato - indicates whether the custom vibrato is locked\n * @property {Object} channelVibrato - vibrato settings for the channel\n * @property {number} channelVibrato.depth - depth of the vibrato effect (cents)\n * @property {number} channelVibrato.delay - delay before the vibrato effect starts (seconds)\n * @property {number} channelVibrato.rate - rate of the vibrato oscillation (Hz)\n\n * @property {boolean} isMuted - indicates whether the channel is muted\n * @property {WorkletVoice[]} voices - array of voices currently active on the channel\n * @property {WorkletVoice[]} sustainedVoices - array of voices that are sustained on the channel\n * @property {WorkletVoice[][][]} cachedVoices - first is midi note, second is velocity. output is an array of WorkletVoices\n */\n\n/**\n * @param sendEvent {boolean}\n * @this {SpessaSynthProcessor}\n */\nexport function createWorkletChannel(sendEvent = false)\n{\n /**\n * @type {WorkletProcessorChannel}\n */\n const channel = {\n midiControllers: new Int16Array(CONTROLLER_TABLE_SIZE),\n lockedControllers: Array(CONTROLLER_TABLE_SIZE).fill(false),\n customControllers: new Float32Array(CUSTOM_CONTROLLER_TABLE_SIZE),\n\n NRPCoarse: 0,\n NRPFine: 0,\n RPValue: 0,\n dataEntryState: dataEntryStates.Idle,\n\n voices: [],\n sustainedVoices: [],\n cachedVoices: [],\n preset: this.defaultPreset,\n\n channelTransposeKeyShift: 0,\n channelVibrato: {delay: 0, depth: 0, rate: 0},\n lockVibrato: false,\n holdPedal: false,\n isMuted: false,\n drumChannel: false,\n lockPreset: false,\n\n }\n for (let i = 0; i < 128; i++)\n {\n channel.cachedVoices.push([]);\n }\n this.workletProcessorChannels.push(channel);\n this.resetControllers(this.workletProcessorChannels.length - 1);\n this.sendChannelProperties();\n if(sendEvent)\n {\n this.callEvent(\"newchannel\", undefined);\n }\n}\n\nexport const NON_CC_INDEX_OFFSET = 128;\nexport const CONTROLLER_TABLE_SIZE = 147;\n// an array with preset default values so we can quickly use set() to reset the controllers\nexport const resetArray = new Int16Array(CONTROLLER_TABLE_SIZE).fill(0);\n// default values (the array is 14 bit so shift the 7 bit values by 7 bits)\nresetArray[midiControllers.mainVolume] = 100 << 7;\nresetArray[midiControllers.expressionController] = 127 << 7;\nresetArray[midiControllers.pan] = 64 << 7;\nresetArray[midiControllers.releaseTime] = 64 << 7;\nresetArray[midiControllers.brightness] = 64 << 7;\nresetArray[midiControllers.effects1Depth] = 40 << 7;\nresetArray[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel] = 8192;\nresetArray[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheelRange] = 2 << 7;\n\n/**\n * @enum {number}\n */\nexport const dataEntryStates = {\n Idle: 0,\n RPCoarse: 1,\n RPFine: 2,\n NRPCoarse: 3,\n NRPFine: 4,\n DataCoarse: 5,\n DataFine: 6\n};\n\n\nexport const customControllers = {\n channelTuning: 0, // cents, RPN for fine tuning\n channelTransposeFine: 1, // cents, only the decimal tuning, (e.g. transpose is 4.5, then shift by 4 keys + tune by 50 cents)\n modulationMultiplier: 2, // cents, set by moduldation depth RPN\n masterTuning: 3, // cents, set by system exclusive\n channelTuningSemitones: 4, // semitones, for RPN coarse tuning\n}\nexport const CUSTOM_CONTROLLER_TABLE_SIZE = Object.keys(customControllers).length;\nexport const customResetArray = new Float32Array(CUSTOM_CONTROLLER_TABLE_SIZE);\ncustomResetArray[customControllers.modulationMultiplier] = 1;\n", "export var stbvorbis=void 0!==stbvorbis?stbvorbis:{};let isReady=!1,readySolver;stbvorbis.isInitialized=new Promise(A=>readySolver=A);var atob=function(A){var I,g,B,E,Q,C,i,h=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\",o=\"\",G=0;A=A.replace(/[^A-Za-z0-9\\+\\/\\=]/g,\"\");do E=h.indexOf(A.charAt(G++)),Q=h.indexOf(A.charAt(G++)),C=h.indexOf(A.charAt(G++)),i=h.indexOf(A.charAt(G++)),I=E<<2|Q>>4,g=(15&Q)<<4|C>>2,B=(3&C)<<6|i,o+=String.fromCharCode(I),64!==C&&(o+=String.fromCharCode(g)),64!==i&&(o+=String.fromCharCode(B));while(G<A.length);return o};!function(){var A,I,g,B,E,Q,C,i,h,o,G,D,a,S,F,R,s,w,y,c,n,U,$=void 0!==$?$:{};$.wasmBinary=Uint8Array.from(atob(\"AGFzbQEAAAABpQEYYAJ/fwF/YAF/AGAAAX9gBH9/f38AYAAAYAN/f38Bf2ABfwF/YAJ/fwBgBn9/f39/fwF/YAR/f39/AX9gBX9/f39/AX9gB39/f39/f38Bf2AGf39/f39/AGAIf39/f39/f38Bf2AFf39/f38AYAd/f39/f39/AGADf39/AGABfwF9YAF9AX1gAnx/AXxgAnx/AX9gA3x8fwF8YAJ8fAF8YAF8AXwCngIPA2VudgZtZW1vcnkCAIACA2VudgV0YWJsZQFwAQQEA2Vudgl0YWJsZUJhc2UDfwADZW52DkRZTkFNSUNUT1BfUFRSA38AA2VudghTVEFDS1RPUAN/AANlbnYJU1RBQ0tfTUFYA38ABmdsb2JhbAhJbmZpbml0eQN8AANlbnYFYWJvcnQAAQNlbnYNZW5sYXJnZU1lbW9yeQACA2Vudg5nZXRUb3RhbE1lbW9yeQACA2VudhdhYm9ydE9uQ2Fubm90R3Jvd01lbW9yeQACA2Vudg5fX19hc3NlcnRfZmFpbAADA2VudgtfX19zZXRFcnJObwABA2VudgZfYWJvcnQABANlbnYWX2Vtc2NyaXB0ZW5fbWVtY3B5X2JpZwAFA3d2BgYCAQcHAQIBAQcBCAcFAAkGCQoHBgYGBgEFBgIBBgYKAAgLAAYGBgYGBgYBAAoMDAMGBQANCAoJAAwODA8OAQAGBgcEABAJEAERAAADBQwAAAMHBxIGAQAABwIFEwMOBw8HBgYQFAoVExYXFxcXFgQFBQYFAAYkB38BIwELfwEjAgt/ASMDC38BQQALfwFBAAt8ASMEC38BQQALB9MCFRBfX2dyb3dXYXNtTWVtb3J5AAgRX19fZXJybm9fbG9jYXRpb24AYwVfZnJlZQBfB19tYWxsb2MAXgdfbWVtY3B5AHkHX21lbXNldAB6BV9zYnJrAHsXX3N0Yl92b3JiaXNfanNfY2hhbm5lbHMAJhRfc3RiX3ZvcmJpc19qc19jbG9zZQAlFV9zdGJfdm9yYmlzX2pzX2RlY29kZQAoE19zdGJfdm9yYmlzX2pzX29wZW4AJBpfc3RiX3ZvcmJpc19qc19zYW1wbGVfcmF0ZQAnC2R5bkNhbGxfaWlpAHwTZXN0YWJsaXNoU3RhY2tTcGFjZQAMC2dldFRlbXBSZXQwAA8LcnVuUG9zdFNldHMAeAtzZXRUZW1wUmV0MAAOCHNldFRocmV3AA0Kc3RhY2tBbGxvYwAJDHN0YWNrUmVzdG9yZQALCXN0YWNrU2F2ZQAKCQoBACMACwR9VFl9Csb2A3YGACAAQAALGwEBfyMGIQEjBiAAaiQGIwZBD2pBcHEkBiABCwQAIwYLBgAgACQGCwoAIAAkBiABJAcLEAAjCEUEQCAAJAggASQJCwsGACAAJAsLBAAjCwsRACAABEAgABARIAAgABASCwvvBwEKfyAAQYADaiEHIAcoAgAhBQJAIAUEQCAAQfwBaiEEIAQoAgAhASABQQBKBEAgAEHwAGohCANAIAUgAkEYbGpBEGohCSAJKAIAIQEgAQRAIAgoAgAhAyAFIAJBGGxqQQ1qIQogCi0AACEGIAZB/wFxIQYgAyAGQbAQbGpBBGohAyADKAIAIQMgA0EASgRAQQAhAwNAIAEgA0ECdGohASABKAIAIQEgACABEBIgA0EBaiEDIAgoAgAhASAKLQAAIQYgBkH/AXEhBiABIAZBsBBsakEEaiEBIAEoAgAhBiAJKAIAIQEgAyAGSA0ACwsgACABEBILIAUgAkEYbGpBFGohASABKAIAIQEgACABEBIgAkEBaiECIAQoAgAhASACIAFODQMgBygCACEFDAAACwALCwsgAEHwAGohAyADKAIAIQEgAQRAIABB7ABqIQUgBSgCACECIAJBAEoEQEEAIQIDQAJAIAEgAkGwEGxqQQhqIQQgBCgCACEEIAAgBBASIAEgAkGwEGxqQRxqIQQgBCgCACEEIAAgBBASIAEgAkGwEGxqQSBqIQQgBCgCACEEIAAgBBASIAEgAkGwEGxqQaQQaiEEIAQoAgAhBCAAIAQQEiABIAJBsBBsakGoEGohASABKAIAIQEgAUUhBCABQXxqIQFBACABIAQbIQEgACABEBIgAkEBaiECIAUoAgAhASACIAFODQAgAygCACEBDAELCyADKAIAIQELIAAgARASCyAAQfgBaiEBIAEoAgAhASAAIAEQEiAHKAIAIQEgACABEBIgAEGIA2ohAyADKAIAIQEgAQRAIABBhANqIQUgBSgCACECIAJBAEoEQEEAIQIDQCABIAJBKGxqQQRqIQEgASgCACEBIAAgARASIAJBAWohAiAFKAIAIQcgAygCACEBIAIgB0gNAAsLIAAgARASCyAAQQRqIQIgAigCACEBIAFBAEoEQEEAIQEDQCAAQZQGaiABQQJ0aiEDIAMoAgAhAyAAIAMQEiAAQZQHaiABQQJ0aiEDIAMoAgAhAyAAIAMQEiAAQdgHaiABQQJ0aiEDIAMoAgAhAyAAIAMQEiABQQFqIQEgAigCACEDIAEgA0ghAyABQRBJIQUgBSADcQ0ACwtBACEBA0AgAEGgCGogAUECdGohAiACKAIAIQIgACACEBIgAEGoCGogAUECdGohAiACKAIAIQIgACACEBIgAEGwCGogAUECdGohAiACKAIAIQIgACACEBIgAEG4CGogAUECdGohAiACKAIAIQIgACACEBIgAEHACGogAUECdGohAiACKAIAIQIgACACEBIgAUEBaiEBIAFBAkcNAAsLGwAgAEHEAGohACAAKAIAIQAgAEUEQCABEF8LC3wBAX8gAEHUB2ohASABQQA2AgAgAEGAC2ohASABQQA2AgAgAEH4CmohASABQQA2AgAgAEGcCGohASABQQA2AgAgAEHVCmohASABQQA6AAAgAEH8CmohASABQQA2AgAgAEHUC2ohASABQQA2AgAgAEHYC2ohACAAQQA2AgAL8AQBB38jBiELIwZBEGokBiALQQhqIQcgC0EEaiEKIAshCCAAQSRqIQYgBiwAACEGAn8gBgR/IABBgAtqIQYgBigCACEGIAZBf0oEQCAFQQA2AgAgACABIAIQFgwCCyAAQRRqIQYgBiABNgIAIAEgAmohAiAAQRxqIQkgCSACNgIAIABB2ABqIQIgAkEANgIAIABBABAXIQkgCUUEQCAFQQA2AgBBAAwCCyAAIAcgCCAKEBghCSAJBEAgBygCACECIAgoAgAhCSAKKAIAIQggACACIAkgCBAaIQogByAKNgIAIABBBGohAiACKAIAIQggCEEASgRAQQAhAgNAIABBlAZqIAJBAnRqIQcgBygCACEHIAcgCUECdGohByAAQdQGaiACQQJ0aiEMIAwgBzYCACACQQFqIQIgAiAISA0ACwsgAwRAIAMgCDYCAAsgBSAKNgIAIABB1AZqIQAgBCAANgIAIAYoAgAhACAAIAFrDAILAkACQAJAAkACQCACKAIAIgNBIGsOBAECAgACCyACQQA2AgAgAEHUAGohAiAAEBkhAwJAIANBf0cEQANAIAIoAgAhAyADDQIgABAZIQMgA0F/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ACECIABBmAhqIQYgBigCACEHIAUgA2shCSAJIAdqIQkgAiAJSSEJIAIgB0khDSACIAdrIQJBACACIA0bIQIgAiADaiECIAIgBUohByAFIAIgBxshAiAJBEAgASACNgIAIAYoAgAhACAAIAJqIQAgBiAANgIAQQEMBgsLCyAAQfQKaiECIAIoAgAhAiADIB9rIQYgBiACaiEGIABBmAhqIQIgAiAGNgIAIAhBATYCAAwBBSAAQZgIaiECIAYNAQsMAQsgBCADayEDIAIoAgAhBCADIARqIQMgAiADNgIACyATKAIAIQIgAgRAIABByABqIQIgAigCACECIABB0ABqIQAgACgCACEAIAIgAEcEQEHTE0HEE0HkGkHnFBAECwsgASAFNgIAQQELIQAgHCQGIAALqAIBBX8gAEHoCmohBSAFKAIAIQICQCACQQBIBEBBACEABSACIAFIBEAgAUEYSgRAIABBGBAsIQIgAUFoaiEBIAAgARAsIQAgAEEYdCEAIAAgAmohACAADwsgAkUEQCAAQeQKaiECIAJBADYCAAsgAEHkCmohAwJAAkACQANAIAAQLiECIAJBf0YNASAFKAIAIQQgAiAEdCECIAMoAgAhBiAGIAJqIQIgAyACNgIAIAUgBEEIaiICNgIAIAIgAUgNAAwCAAsACyAFQX82AgBBACEADAQLIARBeEgEQEEAIQAMBAsLCyAAQeQKaiEEIAQoAgAhA0EBIAF0IQAgAEF/aiEAIAMgAHEhACADIAF2IQMgBCADNgIAIAIgAWshASAFIAE2AgALCyAAC40CAAJAIABBAEgEf0EABSAAQYCAAUgEQCAAQRBIBEAgAEGACGohACAALAAAIQAMAwsgAEGABEgEQCAAQQV2IQAgAEGACGohACAALAAAIQAgAEEFaiEABSAAQQp2IQAgAEGACGohACAALAAAIQAgAEEKaiEACwwCCyAAQYCAgAhIBH8gAEGAgCBIBH8gAEEPdiEAIABBgAhqIQAgACwAACEAIABBD2oFIABBFHYhACAAQYAIaiEAIAAsAAAhACAAQRRqCwUgAEGAgICAAkgEfyAAQRl2IQAgAEGACGohACAALAAAIQAgAEEZagUgAEEediEAIABBgAhqIQAgACwAACEAIABBHmoLCwshAAsgAAuiAQEDfyAAQdQKaiECIAIsAAAhAQJAAkAgAQ0AIABB3ApqIQEgASgCACEBIAEEQEF/IQMFIAAQLyEBIAEEQCACLAAAIQEgAQ0CQaEUQcQTQfYLQbUUEAQFQX8hAwsLDAELIAFBf2pBGHRBGHUhASACIAE6AAAgAEHsCmohASABKAIAIQIgAkEBaiECIAEgAjYCACAAEDAhACAAQf8BcSEDCyADC6wCAQd/IABB3ApqIQIgAigCACEBAkAgAUUEQCAAQdgKaiEEIAQoAgAhASABQX9GBEAgAEHQCGohASABKAIAIQEgAUF/aiEBIABB4ApqIQMgAyABNgIAIAAQMSEBIAFFBEAgAkEBNgIADAMLIABB0wpqIQEgASwAACEBIAFBAXEhASABBH8gBCgCAAUgAEEgEBUMAwshAQsgAUEBaiEHIAQgBzYCACAAQdQIaiABaiEDIAMsAAAhBiAGQf8BcSEDIAZBf0cEQCACQQE2AgAgAEHgCmohAiACIAE2AgALIABB0AhqIQEgASgCACEBIAcgAU4EQCAEQX82AgALIABB1ApqIQAgACwAACEBIAEEQEHFFEHEE0HoC0HaFBAEBSAAIAY6AAAgAyEFCwsLIAULUQEDfyAAQRRqIQMgAygCACEBIABBHGohAiACKAIAIQIgASACSQR/IAFBAWohACADIAA2AgAgASwAAAUgAEHUAGohACAAQQE2AgBBAAshACAACyABAX8gABAyIQEgAQR/IAAQMwUgAEEeEBVBAAshACAAC2ABAX8gABAwIQEgAUH/AXFBzwBGBEAgABAwIQEgAUH/AXFB5wBGBEAgABAwIQEgAUH/AXFB5wBGBEAgABAwIQAgAEH/AXFB0wBGIQAFQQAhAAsFQQAhAAsFQQAhAAsgAAvZAwEGfyAAEDAhAQJ/IAFB/wFxBH8gAEEfEBVBAAUgABAwIQEgAEHTCmohAiACIAE6AAAgABAjIQUgABAjIQIgABAjGiAAECMhASAAQcwIaiEDIAMgATYCACAAECMaIAAQMCEBIAFB/wFxIQEgAEHQCGohAyADIAE2AgAgAEHUCGohBCAAIAQgARAiIQEgAUUEQCAAQQoQFUEADAILIABB8ApqIQQgBEF+NgIAIAIgBXEhAQJAIAFBf0cEQCADKAIAIQEgAUEASgRAA0ACQCABQX9qIQIgAEHUCGogAmohBiAGLAAAIQYgBkF/Rw0AIAFBAUwNBCACIQEMAQsLIAQgAjYCACAAQfQKaiEBIAEgBTYCAAsLCyAAQdUKaiEBIAEsAAAhASABBEAgAygCACEDIANBAEoEf0EAIQJBACEBA0AgAEHUCGogAWohBCAELQAAIQQgBEH/AXEhBCACIARqIQIgAUEBaiEBIAEgA0gNAAsgAkEbagVBGwshASAAQShqIQIgAigCACECIAEgA2ohASABIAJqIQEgAEEsaiEDIAMgAjYCACAAQTBqIQIgAiABNgIAIABBNGohASABIAU2AgALIABB2ApqIQAgAEEANgIAQQELCyEAIAALowEBB38gAEHoCmohAyADKAIAIQECQCABQRlIBEAgAEHkCmohBCABRQRAIARBADYCAAsgAEHUCmohBSAAQdwKaiEGA0AgBigCACEBIAEEQCAFLAAAIQEgAUUNAwsgABAuIQIgAkF/Rg0CIAMoAgAhASACIAF0IQIgBCgCACEHIAcgAmohAiAEIAI2AgAgAUEIaiECIAMgAjYCACABQRFIDQALCwsLrQUBCX8gABA0IAFBIGohAiACKAIAIQUCQAJAIAVFIgNFDQAgAUGkEGohAiACKAIAIQIgAg0AQX8hAQwBCyABQQRqIQIgAigCACECAkACQCACQQhKBEAgAUGkEGohAyADKAIAIQMgAw0BBSADDQELDAELIABB5ApqIQggCCgCACEJIAkQOiEHIAFBrBBqIQIgAigCACECIAJBAUoEQCABQaQQaigCACEKQQAhAwNAIAJBAXYhBSAFIANqIQQgCiAEQQJ0aiEGIAYoAgAhBiAGIAdLIQYgAiAFayECIAMgBCAGGyEDIAUgAiAGGyECIAJBAUoNAAsFQQAhAwsgAUEXaiECIAIsAAAhAiACRQRAIAFBqBBqIQIgAigCACECIAIgA0ECdGohAiACKAIAIQMLIAFBCGohASABKAIAIQEgASADaiEBIAEtAAAhASABQf8BcSEBIABB6ApqIQIgAigCACEAIAAgAUgEf0EAIQBBfwUgACABayEAIAkgAXYhASAIIAE2AgAgAwshASACIAA2AgAMAQsgAUEXaiEDIAMsAAAhAyADBEBBgRVBxBNB6gxBjBUQBAsCQCACQQBKBEAgASgCCCEIIABB5ApqIQlBACEBA0ACQCAIIAFqIQMgAywAACEEIARB/wFxIQMgBEF/RwRAIAUgAUECdGoh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IwZBEGokBiACIQECfCAAvUIgiKdB/////wdxIgNB/MOk/wNJBHwgA0GewZryA0kEfEQAAAAAAADwPwUgAEQAAAAAAAAAABByCwUgACAAoSADQf//v/8HSw0BGgJAAkACQAJAIAAgARBuQQNxDgMAAQIDCyABKwMAIAErAwgQcgwECyABKwMAIAErAwhBARBwmgwDCyABKwMAIAErAwgQcpoMAgsgASsDACABKwMIQQEQcAsLIQAgAiQGIAALywEBA38jBiECIwZBEGokBiACIQECQCAAvUIgiKdB/////wdxIgNB/MOk/wNJBEAgA0GAgMDyA08EQCAARAAAAAAAAAAAQQAQcCEACwUgA0H//7//B0sEQCAAIAChIQAMAgsCQAJAAkACQAJAIAAgARBuQQNxDgMAAQIDCyABKwMAIAErAwhBARBwIQAMBQsgASsDACABKwMIEHIhAAwECyABKwMAIAErAwhBARBwmiEADAMLIAErAwAgASsDCBBymiEACwsLIAIkBiAAC5sDAwJ/AX4CfCAAvSIDQj+IpyEBAnwCfwJAIANCIIinQf////8HcSICQarGmIQESwR8IANC////////////AINCgICAgICAgPj/AFYEQCAADwsgAETvOfr+Qi6GQGQEQCAARAAAAAAAAOB/og8FIABE0rx63SsjhsBjIABEUTAt1RBJh8BjcUUNAkQAAAAAAAAAACIADwsABSACQcLc2P4DSwRAIAJBscXC/wNLDQIgAUEBcyABawwDCyACQYCAwPEDSwR8QQAhASAABSAARAAAAAAAAPA/oA8LCwwCCyAARP6CK2VHFfc/oiABQQN0QYATaisDAKCqCyEBIAAgAbciBEQAAOD+Qi7mP6KhIgAgBER2PHk17znqPaIiBaELIQQgACAEIAQgBCAEoiIAIAAgACAAIABE0KS+cmk3Zj6iRPFr0sVBvbu+oKJELN4lr2pWET+gokSTvb4WbMFmv6CiRD5VVVVVVcU/oKKhIgCiRAAAAAAAAABAIAChoyAFoaBEAAAAAAAA8D+gIQAgAUUEQCAADwsgACABEGULnwMDAn8BfgV8IAC9IgNCIIinIQECfyADQgBTIgIgAUGAgMAASXIEfyADQv///////////wCDQgBRBEBEAAAAAAAA8L8gACAAoqMPCyACRQRAIABEAAAAAAAAUEOi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mgDjqR0AXmGRAAgb5gCFmWUAoBRfAI1AaACA2P8AJ3NNAAYGMQDKVhUAyahzAHviYABrjMAAQcMSC11A+yH5PwAAAAAtRHQ+AAAAgJhG+DwAAABgUcx4OwAAAICDG/A5AAAAQCAlejgAAACAIoLjNgAAAAAd82k1AAAAAAAA4D8AAAAAAADgvwAAAAAAAPA/AAAAAAAA+D8AQagTCwgG0M9D6/1MPgBBuxMLigZAA7jiP09nZ1MuL3N0Yl92b3JiaXMuYwBmLT5hbGxvYy5hbGxvY19idWZmZXJfbGVuZ3RoX2luX2J5dGVzID09IGYtPnRlbXBfb2Zmc2V0AHZvcmJpc19kZWNvZGVfaW5pdGlhbABmLT5ieXRlc19pbl9zZWcgPiAwAGdldDhfcGFja2V0X3JhdwBmLT5ieXRlc19pbl9zZWcgPT0gMABuZXh0X3NlZ21lbnQAdm9yYmlzX2RlY29kZV9wYWNrZXRfcmVzdAAhYy0+c3BhcnNlAGNvZGVib29rX2RlY29kZV9zY2FsYXJfcmF3ACFjLT5zcGFyc2UgfHwgeiA8IGMtPnNvcnRlZF9lbnRyaWVzAGNvZGVib29rX2RlY29kZV9kZWludGVybGVhdmVfcmVwZWF0AHogPCBjLT5zb3J0ZWRfZW50cmllcwBjb2RlYm9va19kZWNvZGVfc3RhcnQAKG4gJiAzKSA9PSAwAGltZGN0X3N0ZXAzX2l0ZXIwX2xvb3AAMABnZXRfd2luZG93AGYtPnRlbXBfb2Zmc2V0ID09IGYtPmFsbG9jLmFsbG9jX2J1ZmZlcl9sZW5ndGhfaW5fYnl0ZXMAc3RhcnRfZGVjb2RlcgB2b3JiaXNjLT5zb3J0ZWRfZW50cmllcyA9PSAwAGNvbXB1dGVfY29kZXdvcmRzAHogPj0gMCAmJiB6IDwgMzIAbGVuW2ldID49IDAgJiYgbGVuW2ldIDwgMzIAYXZhaWxhYmxlW3ldID09IDAAayA9PSBjLT5zb3J0ZWRfZW50cmllcwBjb21wdXRlX3NvcnRlZF9odWZmbWFuAGMtPnNvcnRlZF9jb2Rld29yZHNbeF0gPT0gY29kZQBsZW4gIT0gTk9fQ09ERQBpbmNsdWRlX2luX3NvcnQAcG93KChmbG9hdCkgcisxLCBkaW0pID4gZW50cmllcwBsb29rdXAxX3ZhbHVlcwAoaW50KSBmbG9vcihwb3coKGZsb2F0KSByLCBkaW0pKSA8PSBlbnRyaWVzAOoPBG5hbWUB4g9+AAVhYm9ydAENZW5sYXJnZU1lbW9yeQIOZ2V0VG90YWxNZW1vcnkDF2Fib3J0T25DYW5ub3RHcm93TWVtb3J5BA5fX19hc3NlcnRfZmFpbAULX19fc2V0RXJyTm8GBl9hYm9ydAcWX2Vtc2NyaXB0ZW5fbWVtY3B5X2JpZwgQX19ncm93V2FzbU1lbW9yeQkKc3RhY2tBbGxvYwoJc3RhY2tTYXZlCwxzdGFja1Jlc3RvcmUME2VzdGFibGlzaFN0YWNrU3BhY2UNCHNldFRocmV3DgtzZXRUZW1wUmV0MA8LZ2V0VGVtcFJldDAQEV9zdGJfdm9yYmlzX2Nsb3NlEQ5fdm9yYmlzX2RlaW5pdBILX3NldHVwX2ZyZWUTGl9zdGJfdm9yYmlzX2ZsdXNoX3B1c2hkYXRhFCFfc3RiX3ZvcmJpc19kZWNvZGVfZnJhbWVfcHVzaGRhdGEVBl9lcnJvchYgX3ZvcmJpc19zZWFyY2hfZm9yX3BhZ2VfcHVzaGRhdGEXGF9pc193aG9sZV9wYWNrZXRfcHJlc2VudBgVX3ZvcmJpc19kZWNvZGVfcGFja2V0GQxfZ2V0OF9wYWNrZXQaFF92b3JiaXNfZmluaXNoX2ZyYW1lGxlfc3RiX3ZvcmJpc19vcGVuX3B1c2hkYXRhHAxfdm9yYmlzX2luaXQdDl9zdGFydF9kZWNvZGVyHg1fdm9yYmlzX2FsbG9jHxtfc3RiX3ZvcmJpc19nZXRfZmlsZV9vZmZzZXQgE19tYXliZV9zdGFydF9wYWNrZXQhDV9mbHVzaF9wYWNrZXQiBV9nZXRuIwZfZ2V0MzIkE19zdGJfdm9yYmlzX2pzX29wZW4lFF9zdGJfdm9yYmlzX2pzX2Nsb3NlJhdfc3RiX3ZvcmJpc19qc19jaGFubmVscycaX3N0Yl92b3JiaXNfanNfc2FtcGxlX3JhdGUoFV9zdGJfdm9yYmlzX2pzX2RlY29kZSkNX2NyYzMyX3VwZGF0ZSoWX3ZvcmJpc19kZWNvZGVfaW5pdGlhbCsaX3ZvcmJpc19kZWNvZGVfcGFja2V0X3Jlc3QsCV9nZXRfYml0cy0FX2lsb2cuEF9nZXQ4X3BhY2tldF9yYXcvDV9uZXh0X3NlZ21lbnQwBV9nZXQ4MQtfc3RhcnRfcGFnZTIQX2NhcHR1cmVfcGF0dGVybjMdX3N0YXJ0X3BhZ2Vfbm9fY2FwdHVyZXBhdHRlcm40DV9wcmVwX2h1ZmZtYW41G19jb2RlYm9va19kZWNvZGVfc2NhbGFyX3JhdzYOX3ByZWRpY3RfcG9pbnQ3D19kZWNvZGVfcmVzaWR1ZTgJX2RvX2Zsb29yOQ1faW52ZXJzZV9tZGN0OgxfYml0X3JldmVyc2U7EV9tYWtlX2Jsb2NrX2FycmF5PBJfc2V0dXBfdGVtcF9tYWxsb2M9JF9jb2RlYm9va19kZWNvZGVfZGVpbnRlcmxlYXZlX3JlcGVhdD4PX3Jlc2lkdWVfZGVjb2RlPxVfY29kZWJvb2tfZGVjb2RlX3N0ZXBAEF9jb2RlYm9va19kZWNvZGVBFl9jb2RlYm9va19kZWNvZGVfc3RhcnRCCl9kcmF3X2xpbmVDF19pbWRjdF9zdGVwM19pdGVyMF9sb29wRBlfaW1kY3Rfc3RlcDNfaW5uZXJfcl9sb29wRRlfaW1kY3Rfc3RlcDNfaW5uZXJfc19sb29wRh9faW1kY3Rfc3RlcDNfaW5uZXJfc19sb29wX2xkNjU0RwhfaXRlcl81NEgLX2dldF93aW5kb3dJEF92b3JiaXNfdmFsaWRhdGVKDV9zdGFydF9wYWNrZXRLBV9za2lwTAtfY3JjMzJfaW5pdE0NX3NldHVwX21hbGxvY04QX3NldHVwX3RlbXBfZnJlZU8SX2NvbXB1dGVfY29kZXdvcmRzUBdfY29tcHV0ZV9zb3J0ZWRfaHVmZm1hblEcX2NvbXB1dGVfYWNjZWxlcmF0ZWRfaHVmZm1hblIPX2Zsb2F0MzJfdW5wYWNrUw9fbG9va3VwMV92YWx1ZXNUDl9wb2ludF9jb21wYXJlVQpfbmVpZ2hib3JzVg9faW5pdF9ibG9ja3NpemVXCl9hZGRfZW50cnlYEF9pbmNsdWRlX2luX3NvcnRZD191aW50MzJfY29tcGFyZVoYX2NvbXB1dGVfdHdpZGRsZV9mYWN0b3JzWw9fY29tcHV0ZV93aW5kb3dcE19jb21wdXRlX2JpdHJldmVyc2VdB19zcXVhcmVeB19tYWxsb2NfBV9mcmVlYAhfcmVhbGxvY2ESX3RyeV9yZWFsbG9jX2NodW5rYg5fZGlzcG9zZV9jaHVua2MRX19fZXJybm9fbG9jYXRpb25kB19tZW1jbXBlB19zY2FsYm5mBl9xc29ydGcFX3NpZnRoBF9zaHJpCF90cmlua2xlagRfc2hsawVfcG50emwIX2FfY3R6X2xtBl9jeWNsZW4LX19fcmVtX3BpbzJvEV9fX3JlbV9waW8yX2xhcmdlcAZfX19zaW5xBl9sZGV4cHIGX19fY29zcwRfY29zdARfc2ludQRfZXhwdgRfbG9ndwRfcG93eAtydW5Qb3N0U2V0c3kHX21lbWNweXoHX21lbXNldHsFX3Nicmt8C2R5bkNhbGxfaWlpfQJiMA==\"),function(A){return A.charCodeAt(0)});var $=void 0!==$?$:{},e={};for(A in $)$.hasOwnProperty(A)&&(e[A]=$[A]);$.arguments=[],$.thisProgram=\"./this.program\",$.quit=function(A,I){throw I},$.preRun=[],$.postRun=[];var t=!1,k=!1,N=!1,r=!1;t=\"object\"==typeof window,k=\"function\"==typeof importScripts,N=\"object\"==typeof process&&\"function\"==typeof require&&!t&&!k,r=!t&&!N&&!k;var Y=\"\";function J(A){return $.locateFile?$.locateFile(A,Y):Y+A}N?(Y=__dirname+\"/\",$.read=function A(B,E){var Q;return I||(I=undefined),g||(g=undefined),B=g.normalize(B),Q=I.readFileSync(B),E?Q:Q.toString()},$.readBinary=function A(I){var g=$.read(I,!0);return g.buffer||(g=new Uint8Array(g)),_(g.buffer),g},process.argv.length>1&&($.thisProgram=process.argv[1].replace(/\\\\/g,\"/\")),$.arguments=process.argv.slice(2),\"undefined\"!=typeof module&&(/undefined!=$/),process.on(\"uncaughtException\",function(A){if(!(A instanceof II))throw A}),process.on(\"unhandledRejection\",function(A,I){process.exit(1)}),$.quit=function(A){process.exit(A)},$.inspect=function(){return\"[Emscripten Module object]\"}):r?(\"undefined\"!=typeof read&&($.read=function A(I){return read(I)}),$.readBinary=function A(I){var g;return\"function\"==typeof readbuffer?new Uint8Array(readbuffer(I)):(_(\"object\"==typeof(g=read(I,\"binary\"))),g)},\"undefined\"!=typeof scriptArgs?$.arguments=scriptArgs:\"undefined\"!=typeof arguments&&($.arguments=arguments),\"function\"==typeof quit&&($.quit=function(A){quit(A)})):(t||k)&&(t?document.currentScript&&(Y=document.currentScript.src):Y=self.location.href,Y=0!==Y.indexOf(\"blob:\")?Y.split(\"/\").slice(0,-1).join(\"/\")+\"/\":\"\",$.read=function A(I){var g=new XMLHttpRequest;return g.open(\"GET\",I,!1),g.send(null),g.responseText},k&&($.readBinary=function A(I){var g=new XMLHttpRequest;return g.open(\"GET\",I,!1),g.responseType=\"arraybuffer\",g.send(null),new Uint8Array(g.response)}),$.readAsync=function A(I,g,B){var E=new XMLHttpRequest;E.open(\"GET\",I,!0),E.responseType=\"arraybuffer\",E.onload=function A(){if(200==E.status||0==E.status&&E.response){g(E.response);return}B()},E.onerror=B,E.send(null)},$.setWindowTitle=function(A){document.title=A});var f=$.print||(\"undefined\"!=typeof console?console.log.bind(console):\"undefined\"!=typeof print?print:null),H=$.printErr||(\"undefined\"!=typeof printErr?printErr:\"undefined\"!=typeof console&&console.warn.bind(console)||f);for(A in e)e.hasOwnProperty(A)&&($[A]=e[A]);function L(A){var I=S;return S=S+A+15&-16,I}function M(A){var I=h[c>>2],g=I+A+15&-16;return(h[c>>2]=g,g>=AN&&!Ae())?(h[c>>2]=I,0):I}function d(A,I){return I||(I=16),A=Math.ceil(A/I)*I}function q(A){switch(A){case\"i1\":case\"i8\":return 1;case\"i16\":return 2;case\"i32\":case\"float\":return 4;case\"i64\":case\"double\":return 8;default:if(\"*\"===A[A.length-1])return 4;if(\"i\"!==A[0])return 0;var I=parseInt(A.substr(1));return _(I%8==0),I/8}}function K(A){K.shown||(K.shown={}),K.shown[A]||(K.shown[A]=1,H(A))}e=void 0;var l={\"f64-rem\":function(A,I){return A%I},debugger:function(){}},u=[];function b(A,I){for(var g=0,B=g;B<g+0;B++)if(!u[B])return u[B]=A,1+B;throw\"Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.\"}function X(A){u[A-1]=null}var m={};function Z(A,I){if(A){_(I),m[I]||(m[I]={});var g=m[I];return g[A]||(1===I.length?g[A]=function g(){return V(I,A)}:2===I.length?g[A]=function g(B){return V(I,A,[B])}:g[A]=function g(){return V(I,A,Array.prototype.slice.call(arguments))}),g[A]}}function x(A,I,g){return g?+(A>>>0)+4294967296*+(I>>>0):+(A>>>0)+4294967296*+(0|I)}function V(A,I,g){return g&&g.length?$[\"dynCall_\"+A].apply(null,[I].concat(g)):$[\"dynCall_\"+A].call(null,I)}var p=0,W=0;function _(A,I){A||IE(\"Assertion failed: \"+I)}function T(A){var I=$[\"_\"+A];return _(I,\"Cannot call unknown function \"+A+\", make sure it is exported\"),I}var v={stackSave:function(){IA()},stackRestore:function(){A9()},arrayToC:function(A){var I,g,B=A5(A.length);return I=A,g=B,E.set(I,g),B},stringToC:function(A){var I=0;if(null!=A&&0!==A){var g=(A.length<<2)+1;I=A5(g),Ai(A,I,g)}return I}},O={string:v.stringToC,array:v.arrayToC};function j(A,I,g,B,E){var Q=T(A),C=[],i=0;if(B)for(var h=0;h<B.length;h++){var o=O[g[h]];o?(0===i&&(i=IA()),C[h]=o(B[h])):C[h]=B[h]}var G,D=Q.apply(null,C);return D=(G=D,\"string\"===I?Ag(G):\"boolean\"===I?Boolean(G):G),0!==i&&A9(i),D}function P(A,I,g,B){switch(\"*\"===(g=g||\"i8\").charAt(g.length-1)&&(g=\"i32\"),g){case\"i1\":case\"i8\":E[A>>0]=I;break;case\"i16\":C[A>>1]=I;break;case\"i32\":h[A>>2]=I;break;case\"i64\":tempI64=[I>>>0,+Ax(tempDouble=I)>=1?tempDouble>0?(0|Ap(+A6(tempDouble/4294967296),4294967295))>>>0:~~+AV((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0,],h[A>>2]=tempI64[0],h[A+4>>2]=tempI64[1];break;case\"float\":G[A>>2]=I;break;case\"double\":D[A>>3]=I;break;default:IE(\"invalid type for setValue: \"+g)}}function z(A,I,g){switch(\"*\"===(I=I||\"i8\").charAt(I.length-1)&&(I=\"i32\"),I){case\"i1\":case\"i8\":return E[A>>0];case\"i16\":return C[A>>1];case\"i32\":case\"i64\":return h[A>>2];case\"float\":return G[A>>2];case\"double\":return D[A>>3];default:IE(\"invalid type for getValue: \"+I)}return null}function AA(A,I,g,B){\"number\"==typeof A?(i=!0,o=A):(i=!1,o=A.length);var C=\"string\"==typeof I?I:null;if(G=4==g?B:[\"function\"==typeof A8?A8:L,A5,L,M,][void 0===g?2:g](Math.max(o,C?1:I.length)),i){for(B=G,_((3&G)==0),D=G+(-4&o);B<D;B+=4)h[B>>2]=0;for(D=G+o;B<D;)E[B++>>0]=0;return G}if(\"i8\"===C)return A.subarray||A.slice?Q.set(A,G):Q.set(new Uint8Array(A),G),G;for(var i,o,G,D,a,S,F,R=0;R<o;){var s=A[R];if(0===(a=C||I[R])){R++;continue}\"i64\"==a&&(a=\"i32\"),P(G+R,s,a),F!==a&&(S=q(a),F=a),R+=S}return G}function AI(A){return F?A0?A8(A):M(A):L(A)}function Ag(A,I){if(0===I||!A)return\"\";for(var g,B,E,C=0,i=0;C|=B=Q[A+i>>0],(0!=B||I)&&(i++,!I||i!=I););I||(I=i);var h=\"\";if(C<128){for(;I>0;)E=String.fromCharCode.apply(String,Q.subarray(A,A+Math.min(I,1024))),h=h?h+E:E,A+=1024,I-=1024;return h}return g=A,function A(I,g){for(var B=g;I[B];)++B;if(B-g>16&&I.subarray&&AQ)return AQ.decode(I.subarray(g,B));for(var E,Q,C,i,h,o,G=\"\";;){if(!(E=I[g++]))return G;if(!(128&E)){G+=String.fromCharCode(E);continue}if(Q=63&I[g++],(224&E)==192){G+=String.fromCharCode((31&E)<<6|Q);continue}if(C=63&I[g++],(240&E)==224?E=(15&E)<<12|Q<<6|C:(i=63&I[g++],(248&E)==240?E=(7&E)<<18|Q<<12|C<<6|i:(h=63&I[g++],E=(252&E)==248?(3&E)<<24|Q<<18|C<<12|i<<6|h:(1&E)<<30|Q<<24|C<<18|i<<12|h<<6|(o=63&I[g++]))),E<65536)G+=String.fromCharCode(E);else{var D=E-65536;G+=String.fromCharCode(55296|D>>10,56320|1023&D)}}}(Q,g)}function AB(A){for(var I=\"\";;){var g=E[A++>>0];if(!g)return I;I+=String.fromCharCode(g)}}function AE(A,I){return function A(I,g,B){for(var Q=0;Q<I.length;++Q)E[g++>>0]=I.charCodeAt(Q);B||(E[g>>0]=0)}(A,I,!1)}var AQ=\"undefined\"!=typeof TextDecoder?new TextDecoder(\"utf8\"):void 0;function AC(A,I,g,B){if(!(B>0))return 0;for(var E=g,Q=g+B-1,C=0;C<A.length;++C){var i=A.charCodeAt(C);if(i>=55296&&i<=57343&&(i=65536+((1023&i)<<10)|1023&A.charCodeAt(++C)),i<=127){if(g>=Q)break;I[g++]=i}else if(i<=2047){if(g+1>=Q)break;I[g++]=192|i>>6,I[g++]=128|63&i}else if(i<=65535){if(g+2>=Q)break;I[g++]=224|i>>12,I[g++]=128|i>>6&63,I[g++]=128|63&i}else if(i<=2097151){if(g+3>=Q)break;I[g++]=240|i>>18,I[g++]=128|i>>12&63,I[g++]=128|i>>6&63,I[g++]=128|63&i}else if(i<=67108863){if(g+4>=Q)break;I[g++]=248|i>>24,I[g++]=128|i>>18&63,I[g++]=128|i>>12&63,I[g++]=128|i>>6&63,I[g++]=128|63&i}else{if(g+5>=Q)break;I[g++]=252|i>>30,I[g++]=128|i>>24&63,I[g++]=128|i>>18&63,I[g++]=128|i>>12&63,I[g++]=128|i>>6&63,I[g++]=128|63&i}}return I[g]=0,g-E}function Ai(A,I,g){return AC(A,Q,I,g)}function Ah(A){for(var I=0,g=0;g<A.length;++g){var B=A.charCodeAt(g);B>=55296&&B<=57343&&(B=65536+((1023&B)<<10)|1023&A.charCodeAt(++g)),B<=127?++I:B<=2047?I+=2:B<=65535?I+=3:B<=2097151?I+=4:B<=67108863?I+=5:I+=6}return I}var Ao=\"undefined\"!=typeof TextDecoder?new TextDecoder(\"utf-16le\"):void 0;function AG(A){for(var I=A,g=I>>1;C[g];)++g;if((I=g<<1)-A>32&&Ao)return Ao.decode(Q.subarray(A,I));for(var B=0,E=\"\";;){var i=C[A+2*B>>1];if(0==i)return E;++B,E+=String.fromCharCode(i)}}function AD(A,I,g){if(void 0===g&&(g=2147483647),g<2)return 0;for(var B=I,E=(g-=2)<2*A.length?g/2:A.length,Q=0;Q<E;++Q){var i=A.charCodeAt(Q);C[I>>1]=i,I+=2}return C[I>>1]=0,I-B}function Aa(A){return 2*A.length}function AS(A){for(var I=0,g=\"\";;){var B=h[A+4*I>>2];if(0==B)return g;if(++I,B>=65536){var E=B-65536;g+=String.fromCharCode(55296|E>>10,56320|1023&E)}else g+=String.fromCharCode(B)}}function AF(A,I,g){if(void 0===g&&(g=2147483647),g<4)return 0;for(var B=I,E=B+g-4,Q=0;Q<A.length;++Q){var C=A.charCodeAt(Q);if(C>=55296&&C<=57343&&(C=65536+((1023&C)<<10)|1023&A.charCodeAt(++Q)),h[I>>2]=C,(I+=4)+4>E)break}return h[I>>2]=0,I-B}function AR(A){for(var I=0,g=0;g<A.length;++g){var B=A.charCodeAt(g);B>=55296&&B<=57343&&++g,I+=4}return I}function As(A){var I=Ah(A)+1,g=A8(I);return g&&AC(A,E,g,I),g}function Aw(A){var I=Ah(A)+1,g=A5(I);return AC(A,E,g,I),g}function Ay(A){return A}function Ac(){var A,I=function A(){var I=Error();if(!I.stack){try{throw Error(0)}catch(g){I=g}if(!I.stack)return\"(no stack trace available)\"}return I.stack.toString()}();return $.extraStackTrace&&(I+=\"\\n\"+$.extraStackTrace()),(A=I).replace(/__Z[\\w\\d_]+/g,function(A){var I,g=I=A;return A===g?A:A+\" [\"+g+\"]\"})}function An(A,I){return A%I>0&&(A+=I-A%I),A}function AU(A){$.buffer=B=A}function A$(){$.HEAP8=E=new Int8Array(B),$.HEAP16=C=new Int16Array(B),$.HEAP32=h=new Int32Array(B),$.HEAPU8=Q=new Uint8Array(B),$.HEAPU16=i=new Uint16Array(B),$.HEAPU32=o=new Uint32Array(B),$.HEAPF32=G=new Float32Array(B),$.HEAPF64=D=new Float64Array(B)}function Ae(){var A=$.usingWasm?65536:16777216,I=2147483648-A;if(h[c>>2]>I)return!1;var g=AN;for(AN=Math.max(AN,16777216);AN<h[c>>2];)AN=AN<=536870912?An(2*AN,A):Math.min(An((3*AN+2147483648)/4,A),I);var B=$.reallocBuffer(AN);return B&&B.byteLength==AN?(AU(B),A$(),!0):(AN=g,!1)}a=S=R=s=w=y=c=0,F=!1,$.reallocBuffer||($.reallocBuffer=function(A){try{if(ArrayBuffer.transfer)I=ArrayBuffer.transfer(B,A);else{var I,g=E;I=new ArrayBuffer(A),new Int8Array(I).set(g)}}catch(Q){return!1}return!!Az(I)&&I});try{(n=Function.prototype.call.bind(Object.getOwnPropertyDescriptor(ArrayBuffer.prototype,\"byteLength\").get))(new ArrayBuffer(4))}catch(At){n=function(A){return A.byteLength}}var Ak=$.TOTAL_STACK||5242880,AN=$.TOTAL_MEMORY||16777216;function Ar(){return AN}function AY(A){for(;A.length>0;){var I=A.shift();if(\"function\"==typeof I){I();continue}var g=I.func;\"number\"==typeof g?void 0===I.arg?$.dynCall_v(g):$.dynCall_vi(g,I.arg):g(void 0===I.arg?null:I.arg)}}AN<Ak&&H(\"TOTAL_MEMORY should be larger than TOTAL_STACK, was \"+AN+\"! (TOTAL_STACK=\"+Ak+\")\"),$.buffer?B=$.buffer:(\"object\"==typeof WebAssembly&&\"function\"==typeof WebAssembly.Memory?($.wasmMemory=new WebAssembly.Memory({initial:AN/65536}),B=$.wasmMemory.buffer):B=new ArrayBuffer(AN),$.buffer=B),A$();var AJ=[],Af=[],AH=[],AL=[],AM=[],A0=!1,Ad=!1;function Aq(A){AJ.unshift(A)}function AK(A){Af.unshift(A)}function Al(A){AH.unshift(A)}function Au(A){AL.unshift(A)}function Ab(A){AM.unshift(A)}function AX(A,I,g){var B,Q;K(\"writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!\"),g&&(B=E[Q=I+Ah(A)]),Ai(A,I,1/0),g&&(E[Q]=B)}function Am(A,I,g){return A>=0?A:I<=32?2*Math.abs(1<<I-1)+A:Math.pow(2,I)+A}function AZ(A,I,g){if(A<=0)return A;var B=I<=32?Math.abs(1<<I-1):Math.pow(2,I-1);return A>=B&&(I<=32||A>B)&&(A=-2*B+A),A}var Ax=Math.abs,AV=Math.ceil,A6=Math.floor,Ap=Math.min,A7=0,A1=null,AW=null;function A_(A){return A}$.preloadedImages={},$.preloadedAudios={};var AT=\"data:application/octet-stream;base64,\";function A2(A){return String.prototype.startsWith?A.startsWith(AT):0===A.indexOf(AT)}!function A(){var I=\"main.wast\",g=\"main.wasm\",B=\"main.temp.asm.js\";A2(I)||(I=J(I)),A2(g)||(g=J(g)),A2(B)||(B=J(B));var E={global:null,env:null,asm2wasm:l,parent:$},Q=null;function C(A){return A}function i(){try{if($.wasmBinary)return new Uint8Array($.wasmBinary);if($.readBinary)return $.readBinary(g);throw\"both async and sync fetching of the wasm failed\"}catch(A){IE(A)}}$.asmPreload=$.asm;var h=$.reallocBuffer,o=function(A){A=An(A,$.usingWasm?65536:16777216);var I=$.buffer.byteLength;if($.usingWasm)try{var g=$.wasmMemory.grow((A-I)/65536);if(-1!==g)return $.buffer=$.wasmMemory.buffer;return null}catch(B){return null}};$.reallocBuffer=function(A){return\"asmjs\"===G?h(A):o(A)};var G=\"\";$.asm=function(A,I,B){var C;if(!(I=C=I).table){var h,o=$.wasmTableSize;void 0===o&&(o=1024);var G=$.wasmMaxTableSize;\"object\"==typeof WebAssembly&&\"function\"==typeof WebAssembly.Table?void 0!==G?I.table=new WebAssembly.Table({initial:o,maximum:G,element:\"anyfunc\"}):I.table=new WebAssembly.Table({initial:o,element:\"anyfunc\"}):I.table=Array(o),$.wasmTable=I.table}return I.memoryBase||(I.memoryBase=$.STATIC_BASE),I.tableBase||(I.tableBase=0),h=function A(I,B,C){if(\"object\"!=typeof WebAssembly)return H(\"no native wasm support detected\"),!1;if(!($.wasmMemory instanceof WebAssembly.Memory))return H(\"no native wasm Memory in use\"),!1;function h(A,I){if((Q=A.exports).memory){var g,B,E;g=Q.memory,B=$.buffer,g.byteLength<B.byteLength&&H(\"the new buffer in mergeMemory is smaller than the previous one. in native wasm, we should grow memory here\"),E=new Int8Array(B),new Int8Array(g).set(E),AU(g),A$()}$.asm=Q,$.usingWasm=!0,function A(I){if(A7--,$.monitorRunDependencies&&$.monitorRunDependencies(A7),0==A7&&(null!==A1&&(clearInterval(A1),A1=null),AW)){var g=AW;AW=null,g()}}(\"wasm-instantiate\")}B.memory=$.wasmMemory,E.global={NaN:NaN,Infinity:1/0},E[\"global.Math\"]=Math,E.env=B;if((A7++,$.monitorRunDependencies&&$.monitorRunDependencies(A7)),$.instantiateWasm)try{return $.instantiateWasm(E,h)}catch(o){return H(\"Module.instantiateWasm callback failed with error: \"+o),!1}function G(A){h(A.instance,A.module)}function D(A){(!$.wasmBinary&&(t||k)&&\"function\"==typeof fetch?fetch(g,{credentials:\"same-origin\"}).then(function(A){if(!A.ok)throw\"failed to load wasm binary file at '\"+g+\"'\";return A.arrayBuffer()}).catch(function(){return i()}):new Promise(function(A,I){A(i())})).then(function(A){return WebAssembly.instantiate(A,E)}).then(A).catch(function(A){H(\"failed to asynchronously prepare wasm: \"+A),IE(A)})}return $.wasmBinary||\"function\"!=typeof WebAssembly.instantiateStreaming||A2(g)||\"function\"!=typeof fetch?D(G):WebAssembly.instantiateStreaming(fetch(g,{credentials:\"same-origin\"}),E).then(G).catch(function(A){H(\"wasm streaming compile failed: \"+A),H(\"falling back to ArrayBuffer instantiation\"),D(G)}),{}}(A,I,B),_(h,\"no binaryen method succeeded.\"),h},$.asm}(),S=(a=1024)+4816,Af.push(),$.STATIC_BASE=a,$.STATIC_BUMP=4816;var Av=S;function AO(A){E[Av]=E[A],E[Av+1]=E[A+1],E[Av+2]=E[A+2],E[Av+3]=E[A+3]}function Aj(A){E[Av]=E[A],E[Av+1]=E[A+1],E[Av+2]=E[A+2],E[Av+3]=E[A+3],E[Av+4]=E[A+4],E[Av+5]=E[A+5],E[Av+6]=E[A+6],E[Av+7]=E[A+7]}function AP(A,I,g){var B=g>0?g:Ah(A)+1,E=Array(B),Q=AC(A,E,0,E.length);return I&&(E.length=Q),E}function A4(A){for(var I=[],g=0;g<A.length;g++){var B=A[g];B>255&&(B&=255),I.push(String.fromCharCode(B))}return I.join(\"\")}S+=16,c=L(4),w=(R=s=d(S))+Ak,y=d(w),h[c>>2]=y,F=!0,$.wasmTableSize=4,$.wasmMaxTableSize=4,$.asmGlobalArg={},$.asmLibraryArg={abort:IE,assert:_,enlargeMemory:Ae,getTotalMemory:Ar,abortOnCannotGrowMemory:function A(){IE(\"Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value \"+AN+\", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 \")},invoke_iii:function A(I,g,B){var E=IA();try{return $.dynCall_iii(I,g,B)}catch(Q){if(A9(E),\"number\"!=typeof Q&&\"longjmp\"!==Q)throw Q;$.setThrew(1,0)}},___assert_fail:function A(I,g,B,E){IE(\"Assertion failed: \"+Ag(I)+\", at: \"+[g?Ag(g):\"unknown filename\",B,E?Ag(E):\"unknown function\",])},___setErrNo:function A(I){return $.___errno_location&&(h[$.___errno_location()>>2]=I),I},_abort:function A(){$.abort()},_emscripten_memcpy_big:function A(I,g,B){return Q.set(Q.subarray(g,g+B),I),I},_llvm_floor_f64:A6,DYNAMICTOP_PTR:c,tempDoublePtr:Av,ABORT:p,STACKTOP:s,STACK_MAX:w};var A3=$.asm($.asmGlobalArg,$.asmLibraryArg,B);$.asm=A3,$.___errno_location=function(){return $.asm.___errno_location.apply(null,arguments)};var Az=$._emscripten_replace_memory=function(){return $.asm._emscripten_replace_memory.apply(null,arguments)};$._free=function(){return $.asm._free.apply(null,arguments)};var A8=$._malloc=function(){return $.asm._malloc.apply(null,arguments)};$._memcpy=function(){return $.asm._memcpy.apply(null,arguments)},$._memset=function(){return $.asm._memset.apply(null,arguments)},$._sbrk=function(){return $.asm._sbrk.apply(null,arguments)},$._stb_vorbis_js_channels=function(){return $.asm._stb_vorbis_js_channels.apply(null,arguments)},$._stb_vorbis_js_close=function(){return $.asm._stb_vorbis_js_close.apply(null,arguments)},$._stb_vorbis_js_decode=function(){return $.asm._stb_vorbis_js_decode.apply(null,arguments)},$._stb_vorbis_js_open=function(){return $.asm._stb_vorbis_js_open.apply(null,arguments)},$._stb_vorbis_js_sample_rate=function(){return $.asm._stb_vorbis_js_sample_rate.apply(null,arguments)},$.establishStackSpace=function(){return $.asm.establishStackSpace.apply(null,arguments)},$.getTempRet0=function(){return $.asm.getTempRet0.apply(null,arguments)},$.runPostSets=function(){return $.asm.runPostSets.apply(null,arguments)},$.setTempRet0=function(){return $.asm.setTempRet0.apply(null,arguments)},$.setThrew=function(){return $.asm.setThrew.apply(null,arguments)};var A5=$.stackAlloc=function(){return $.asm.stackAlloc.apply(null,arguments)},A9=$.stackRestore=function(){return $.asm.stackRestore.apply(null,arguments)},IA=$.stackSave=function(){return $.asm.stackSave.apply(null,arguments)};function II(A){this.name=\"ExitStatus\",this.message=\"Program terminated with exit(\"+A+\")\",this.status=A}function Ig(A){if(A=A||$.arguments,!(A7>0))!function A(){if($.preRun)for(\"function\"==typeof $.preRun&&($.preRun=[$.preRun]);$.preRun.length;)Aq($.preRun.shift());AY(AJ)}(),!(A7>0)&&($.calledRun||($.setStatus?($.setStatus(\"Running...\"),setTimeout(function(){setTimeout(function(){$.setStatus(\"\")},1),I()},1)):I()));function I(){!$.calledRun&&($.calledRun=!0,p||(A0||(A0=!0,AY(Af)),AY(AH),$.onRuntimeInitialized&&$.onRuntimeInitialized(),function A(){if($.postRun)for(\"function\"==typeof $.postRun&&($.postRun=[$.postRun]);$.postRun.length;)Ab($.postRun.shift());AY(AM)}()))}}function IB(A,I){(!I||!$.noExitRuntime||0!==A)&&($.noExitRuntime||(p=!0,W=A,s=U,AY(AL),Ad=!0,$.onExit&&$.onExit(A)),$.quit(A,new II(A)))}function IE(A){throw $.onAbort&&$.onAbort(A),void 0!==A?(f(A),H(A),A=JSON.stringify(A)):A=\"\",p=!0,W=1,\"abort(\"+A+\"). Build with -s ASSERTIONS=1 for more info.\"}if($.dynCall_iii=function(){return $.asm.dynCall_iii.apply(null,arguments)},$.asm=A3,$.ccall=j,$.cwrap=function A(I,g,B,E){var Q=(B=B||[]).every(function(A){return\"number\"===A});return\"string\"!==g&&Q&&!E?T(I):function(){return j(I,g,B,arguments,E)}},II.prototype=Error(),II.prototype.constructor=II,AW=function A(){$.calledRun||Ig(),$.calledRun||(AW=A)},$.run=Ig,$.abort=IE,$.preInit)for(\"function\"==typeof $.preInit&&($.preInit=[$.preInit]);$.preInit.length>0;)$.preInit.pop()();$.noExitRuntime=!0,Ig(),$.onRuntimeInitialized=()=>{isReady=!0,readySolver()},stbvorbis.decode=function(A){return function A(I){if(!isReady)throw Error(\"Not initialized\");var g={};function B(A){return new Int32Array($.HEAPU8.buffer,A,1)[0]}function E(A,I){var g=new ArrayBuffer(I*Float32Array.BYTES_PER_ELEMENT),B=new Float32Array(g);return B.set(new Float32Array($.HEAPU8.buffer,A,I)),B}g.open=$.cwrap(\"stb_vorbis_js_open\",\"number\",[]),g.close=$.cwrap(\"stb_vorbis_js_close\",\"void\",[\"number\"]),g.channels=$.cwrap(\"stb_vorbis_js_channels\",\"number\",[\"number\"]),g.sampleRate=$.cwrap(\"stb_vorbis_js_sample_rate\",\"number\",[\"number\"]),g.decode=$.cwrap(\"stb_vorbis_js_decode\",\"number\",[\"number\",\"number\",\"number\",\"number\",\"number\"]);var Q,C,i,h,o=g.open(),G=(Q=I,C=I.byteLength,i=$._malloc(C),(h=new Uint8Array($.HEAPU8.buffer,i,C)).set(new Uint8Array(Q,0,C)),h),D=$._malloc(4),a=$._malloc(4),S=g.decode(o,G.byteOffset,G.byteLength,D,a);if($._free(G.byteOffset),S<0)throw g.close(o),$._free(D),Error(\"stbvorbis decode failed: \"+S);for(var F=g.channels(o),R=Array(F),s=new Int32Array($.HEAPU32.buffer,B(D),F),w=0;w<F;w++)R[w]=E(s[w],S),$._free(s[w]);var y=g.sampleRate(o);return g.close(o),$._free(B(D)),$._free(D),{data:R,sampleRate:y,eof:!0,error:null}}(A)}}();", "import {RiffChunk} from \"./riff_chunk.js\";\nimport {IndexedByteArray} from \"../../utils/indexed_array.js\";\nimport { readBytesAsUintLittleEndian, signedInt8} from \"../../utils/byte_functions/little_endian.js\";\nimport { stbvorbis } from '../../externals/stbvorbis_sync/stbvorbis_sync.min.js'\nimport { SpessaSynthWarn } from '../../utils/loggin.js'\nimport { readBytesAsString } from '../../utils/byte_functions/string.js'\n\n/**\n * samples.js\n * purpose: parses soundfont samples, resamples if needed.\n * loads sample data, handles async loading of sf3 compressed samples\n */\n\nexport class BasicSample\n{\n /**\n * The basic representation of a soundfont sample\n * @param sampleName {string}\n * @param sampleRate {number}\n * @param samplePitch {number}\n * @param samplePitchCorrection {number}\n * @param sampleLink {number}\n * @param sampleType {number}\n * @param loopStart {number} relative to sample start\n * @param loopEnd {number} relative to sample start\n */\n constructor(\n sampleName,\n sampleRate,\n samplePitch,\n samplePitchCorrection,\n sampleLink,\n sampleType,\n loopStart,\n loopEnd\n )\n {\n /**\n * Sample's name\n * @type {string}\n */\n this.sampleName = sampleName;\n /**\n * Sample rate in Hz\n * @type {number}\n */\n this.sampleRate = sampleRate;\n /**\n * Original pitch of the sample as a MIDI note number\n * @type {number}\n */\n this.samplePitch = samplePitch;\n /**\n * Pitch correction, in cents. Can be negative\n * @type {number}\n */\n this.samplePitchCorrection = samplePitchCorrection;\n /**\n * Sample link, currently unused.\n * @type {number}\n */\n this.sampleLink = sampleLink;\n /**\n * Type of the sample, an enum\n * @type {number}\n */\n this.sampleType = sampleType;\n /**\n * Relative to start of the sample, bytes\n * @type {number}\n */\n this.sampleLoopStartIndex = loopStart;\n /**\n * Relative to start of the sample, in bytes\n * @type {number}\n */\n this.sampleLoopEndIndex = loopEnd;\n\n /**\n * Indicates if the sample is compressed\n * @type {boolean}\n */\n this.isCompressed = (sampleType & 0x10) > 0;\n\n /**\n * The compressed sample data if it was compressed by spessasynth\n * @type {Uint8Array}\n */\n this.compressedData = undefined;\n }\n\n /**\n * @returns {Uint8Array|IndexedByteArray}\n */\n getRawData()\n {\n const e = new Error(\"Not implemented\");\n e.name = \"NotImplementedError\";\n throw e;\n }\n\n /**\n * @param quality {number}\n * @param encodeVorbis {EncodeVorbisFunction}\n */\n compressSample(quality, encodeVorbis)\n {\n // no need to compress\n if(this.isCompressed)\n {\n return;\n }\n // compress, always mono!\n try {\n this.compressedData = encodeVorbis([this.getAudioData()], 1, this.sampleRate, quality);\n // flag as compressed\n this.sampleType |= 0x10;\n this.isCompressed = true;\n }\n catch (e)\n {\n SpessaSynthWarn(`Failed to compress ${this.sampleName}. Leaving as uncompressed!`);\n this.isCompressed = false;\n this.compressedData = undefined;\n this.sampleType &= -17;\n }\n\n }\n\n /**\n * @returns {Float32Array}\n */\n getAudioData()\n {\n const e = new Error(\"Not implemented\");\n e.name = \"NotImplementedError\";\n throw e;\n }\n}\n\nexport class Sample extends BasicSample\n{\n /**\n * Creates a sample\n * @param sampleName {string}\n * @param sampleStartIndex {number}\n * @param sampleEndIndex {number}\n * @param sampleLoopStartIndex {number}\n * @param sampleLoopEndIndex {number}\n * @param sampleRate {number}\n * @param samplePitch {number}\n * @param samplePitchCorrection {number}\n * @param sampleLink {number}\n * @param sampleType {number}\n * @param smplArr {IndexedByteArray}\n * @param sampleIndex {number} initial sample index when loading the sfont\n */\n constructor(sampleName,\n sampleStartIndex,\n sampleEndIndex,\n sampleLoopStartIndex,\n sampleLoopEndIndex,\n sampleRate,\n samplePitch,\n samplePitchCorrection,\n sampleLink,\n sampleType,\n smplArr,\n sampleIndex\n )\n {\n super(\n sampleName,\n sampleRate,\n samplePitch,\n samplePitchCorrection,\n sampleLink,\n sampleType,\n sampleLoopStartIndex - sampleStartIndex,\n sampleLoopEndIndex - sampleStartIndex\n );\n this.sampleName = sampleName\n // in bytes\n this.sampleStartIndex = sampleStartIndex;\n this.sampleEndIndex = sampleEndIndex;\n this.isSampleLoaded = false;\n this.sampleID = sampleIndex;\n this.useCount = 0;\n // in bytes\n this.sampleLength = this.sampleEndIndex - this.sampleStartIndex;\n this.sampleDataArray = smplArr;\n this.sampleData = new Float32Array(0);\n if(this.isCompressed)\n {\n // correct loop points\n this.sampleLoopStartIndex += this.sampleStartIndex;\n this.sampleLoopEndIndex += this.sampleStartIndex;\n this.sampleLength = 99999999; // set to 999999 before we decode it\n }\n\n }\n\n /**\n * Get raw data, whether it's compressed or not as we simply write it to the file\n * @return {Uint8Array}\n */\n getRawData()\n {\n const smplArr = this.sampleDataArray;\n if(this.isCompressed)\n {\n if(this.compressedData)\n {\n return this.compressedData;\n }\n const smplStart = smplArr.currentIndex;\n return smplArr.slice(this.sampleStartIndex / 2 + smplStart, this.sampleEndIndex / 2 + smplStart);\n }\n else\n {\n const dataStartIndex = smplArr.currentIndex;\n return smplArr.slice(dataStartIndex + this.sampleStartIndex, dataStartIndex + this.sampleEndIndex)\n }\n }\n\n /**\n * Decode binary vorbis into a float32 pcm\n */\n decodeVorbis()\n {\n if (this.sampleLength < 1)\n {\n // eos, do not do anything\n return;\n }\n // get the compressed byte stream\n const smplArr = this.sampleDataArray;\n const smplStart = smplArr.currentIndex;\n const buff = smplArr.slice(this.sampleStartIndex / 2 + smplStart, this.sampleEndIndex / 2 + smplStart);\n // reset array and being decoding\n this.sampleData = new Float32Array(0);\n /**\n * @type {{data: Float32Array[], error: (string|null), sampleRate: number, eof: boolean}}\n */\n const vorbis = stbvorbis.decode(buff.buffer);\n this.sampleData = vorbis.data[0];\n }\n\n /**\n * Loads the audio data and stores it for reuse\n * @returns {Float32Array} The audioData\n */\n getAudioData()\n {\n if (!this.isSampleLoaded)\n {\n // start loading data if not loaded\n return this.loadBufferData();\n }\n return this.sampleData;\n }\n\n /**\n * @returns {Float32Array}\n */\n loadUncompressedData()\n {\n if(this.isCompressed)\n {\n SpessaSynthWarn(\"Trying to load a compressed sample via loadUncompressedData()... aborting!\");\n return new Float32Array(0);\n }\n\n // read the sample data\n let audioData = new Float32Array(this.sampleLength / 2);\n const dataStartIndex = this.sampleDataArray.currentIndex;\n let convertedSigned16 = new Int16Array(\n this.sampleDataArray.slice(dataStartIndex + this.sampleStartIndex, dataStartIndex + this.sampleEndIndex)\n .buffer\n );\n\n // convert to float\n for(let i = 0; i < convertedSigned16.length; i++)\n {\n audioData[i] = convertedSigned16[i] / 32768;\n }\n\n this.sampleData = audioData;\n this.isSampleLoaded = true;\n return audioData;\n }\n\n /**\n * @returns {Float32Array}\n */\n loadBufferData()\n {\n if (this.sampleLength < 1)\n {\n // eos, do not do anything\n return new Float32Array(1);\n }\n\n if(this.isCompressed)\n {\n this.decodeVorbis();\n this.isSampleLoaded = true;\n return this.sampleData;\n }\n return this.loadUncompressedData();\n }\n}\n\n/**\n * Reads the generatorTranslator from the shdr read\n * @param sampleHeadersChunk {RiffChunk}\n * @param smplChunkData {IndexedByteArray}\n * @returns {Sample[]}\n */\nexport function readSamples(sampleHeadersChunk, smplChunkData)\n{\n /**\n * @type {Sample[]}\n */\n let samples = [];\n let index = 0;\n while(sampleHeadersChunk.chunkData.length > sampleHeadersChunk.chunkData.currentIndex)\n {\n const sample = readSample(index, sampleHeadersChunk.chunkData, smplChunkData);\n samples.push(sample);\n index++;\n }\n // remove EOS\n if (samples.length > 1)\n {\n samples.pop();\n }\n return samples;\n}\n\n/**\n * Reads it into a sample\n * @param index {number}\n * @param sampleHeaderData {IndexedByteArray}\n * @param smplArrayData {IndexedByteArray}\n * @returns {Sample}\n */\nfunction readSample(index, sampleHeaderData, smplArrayData) {\n\n // read the sample name\n let sampleName = readBytesAsString(sampleHeaderData, 20);\n\n // read the sample start index\n let sampleStartIndex = readBytesAsUintLittleEndian(sampleHeaderData, 4) * 2;\n\n // read the sample end index\n let sampleEndIndex = readBytesAsUintLittleEndian(sampleHeaderData, 4) * 2;\n\n // read the sample looping start index\n let sampleLoopStartIndex = readBytesAsUintLittleEndian(sampleHeaderData, 4) * 2;\n\n // read the sample looping end index\n let sampleLoopEndIndex = readBytesAsUintLittleEndian(sampleHeaderData, 4) * 2;\n\n // read the sample rate\n let sampleRate = readBytesAsUintLittleEndian(sampleHeaderData, 4);\n\n // read the original sample pitch\n let samplePitch = sampleHeaderData[sampleHeaderData.currentIndex++];\n if(samplePitch === 255)\n {\n // if it's 255, then default to 60\n samplePitch = 60;\n }\n\n // readt the sample pitch correction\n let samplePitchCorrection = signedInt8(sampleHeaderData[sampleHeaderData.currentIndex++]);\n\n\n // read the link to the other channel\n let sampleLink = readBytesAsUintLittleEndian(sampleHeaderData, 2);\n let sampleType = readBytesAsUintLittleEndian(sampleHeaderData, 2);\n\n\n\n return new Sample(sampleName,\n sampleStartIndex,\n sampleEndIndex,\n sampleLoopStartIndex,\n sampleLoopEndIndex,\n sampleRate,\n samplePitch,\n samplePitchCorrection,\n sampleLink,\n sampleType,\n smplArrayData,\n index);\n}", "import {RiffChunk} from \"./riff_chunk.js\";\nimport {InstrumentZone} from \"./zones.js\";\nimport {readBytesAsUintLittleEndian} from \"../../utils/byte_functions/little_endian.js\";\nimport { readBytesAsString } from '../../utils/byte_functions/string.js'\n\n/**\n * instrument.js\n * purpose: parses soundfont instrument and stores them as a class\n */\n\nexport class Instrument\n{\n /**\n * Creates an instrument\n * @param instrumentChunk {RiffChunk}\n */\n constructor(instrumentChunk)\n {\n this.instrumentName = readBytesAsString(instrumentChunk.chunkData, 20).trim();\n this.instrumentZoneIndex = readBytesAsUintLittleEndian(instrumentChunk.chunkData, 2);\n this.instrumentZonesAmount = 0;\n /**\n * @type {InstrumentZone[]}\n */\n this.instrumentZones = [];\n this._useCount = 0;\n }\n\n addUseCount()\n {\n this._useCount++;\n this.instrumentZones.forEach(z => z.useCount++);\n }\n\n removeUseCount()\n {\n this._useCount--;\n for(let i = 0; i < this.instrumentZones.length; i++)\n {\n if(this.safeDeleteZone(i))\n {\n i--;\n }\n }\n }\n\n /**\n * @returns {number}\n */\n get useCount()\n {\n return this._useCount;\n }\n\n deleteInstrument()\n {\n this.instrumentZones.forEach(z => z.deleteZone());\n this.instrumentZones.length = 0;\n }\n\n /**\n * @param index {number}\n * @returns {boolean} is the zone has been deleted\n */\n safeDeleteZone(index)\n {\n this.instrumentZones[index].useCount--;\n if(this.instrumentZones[index].useCount < 1)\n {\n this.deleteZone(index);\n return true;\n }\n return false;\n }\n\n /**\n * @param index {number}\n */\n deleteZone(index)\n {\n this.instrumentZones[index].deleteZone();\n this.instrumentZones.splice(index, 1);\n }\n\n /**\n * Loads all the instrument zones, given the amount\n * @param amount {number}\n * @param zones {InstrumentZone[]}\n */\n getInstrumentZones(amount, zones)\n {\n this.instrumentZonesAmount = amount;\n for(let i = this.instrumentZoneIndex; i < this.instrumentZonesAmount + this.instrumentZoneIndex; i++)\n {\n this.instrumentZones.push(zones[i]);\n }\n }\n}\n\n/**\n * Reads the instruments\n * @param instrumentChunk {RiffChunk}\n * @param instrumentZones {InstrumentZone[]}\n * @returns {Instrument[]}\n */\nexport function readInstruments(instrumentChunk, instrumentZones)\n{\n let instruments = [];\n while(instrumentChunk.chunkData.length > instrumentChunk.chunkData.currentIndex)\n {\n let instrument = new Instrument(instrumentChunk);\n if(instruments.length > 0)\n {\n let instrumentsAmount = instrument.instrumentZoneIndex - instruments[instruments.length - 1].instrumentZoneIndex;\n instruments[instruments.length - 1].getInstrumentZones(instrumentsAmount, instrumentZones);\n }\n instruments.push(instrument);\n }\n if(instruments.length > 1)\n {\n // remove EOI\n instruments.pop();\n }\n return instruments;\n}", "import {readBytesAsUintLittleEndian} from \"../../utils/byte_functions/little_endian.js\";\nimport {IndexedByteArray} from \"../../utils/indexed_array.js\";\nimport {RiffChunk} from \"./riff_chunk.js\";\nimport {Generator, generatorTypes} from \"./generators.js\";\nimport {Sample} from \"./samples.js\";\nimport {Instrument} from \"./instruments.js\";\nimport {Modulator} from \"./modulators.js\";\n\n/**\n * zones.js\n * purpose: reads instrumend and preset zones from soundfont and gets their respective samples and generators and modulators\n */\n\nexport class InstrumentZone {\n /**\n * Creates a zone (instrument)\n * @param dataArray {IndexedByteArray}\n * @param index {number}\n */\n constructor(dataArray, index)\n {\n this.generatorZoneStartIndex = readBytesAsUintLittleEndian(dataArray, 2);\n this.modulatorZoneStartIndex = readBytesAsUintLittleEndian(dataArray, 2);\n this.modulatorZoneSize = 0;\n this.generatorZoneSize = 0;\n this.zoneID = index;\n this.keyRange = {min: 0, max: 127};\n this.velRange = {min: 0, max: 127}\n this.isGlobal = true;\n this.useCount = 0;\n\n /**\n * @type {Generator[]}\n */\n this.generators = [];\n /**\n * @type {Modulator[]}\n */\n this.modulators = [];\n }\n\n deleteZone()\n {\n this.useCount--;\n if(this.isGlobal)\n {\n return;\n }\n this.sample.useCount--;\n }\n\n setZoneSize(modulatorZoneSize, generatorZoneSize)\n {\n this.modulatorZoneSize = modulatorZoneSize;\n this.generatorZoneSize = generatorZoneSize;\n }\n\n /**\n * grab the generators\n * @param generators {Generator[]}\n */\n getGenerators(generators)\n {\n for(let i = this.generatorZoneStartIndex; i < this.generatorZoneStartIndex + this.generatorZoneSize; i++)\n {\n this.generators.push(generators[i]);\n }\n }\n\n /**\n * grab the modulators\n * @param modulators {Modulator[]}\n */\n getModulators(modulators)\n {\n for(let i = this.modulatorZoneStartIndex; i < this.modulatorZoneStartIndex + this.modulatorZoneSize; i++)\n {\n this.modulators.push(modulators[i]);\n }\n }\n\n /**\n * Loads the zone's sample\n * @param samples {Sample[]}\n */\n getSample(samples)\n {\n let sampleID = this.generators.find(g => g.generatorType === generatorTypes.sampleID);\n if (sampleID)\n {\n this.sample = samples[sampleID.generatorValue];\n this.isGlobal = false;\n this.sample.useCount++;\n }\n }\n\n /**\n * Reads the keyRange of the zone\n */\n getKeyRange()\n {\n let range = this.generators.find(g => g.generatorType === generatorTypes.keyRange);\n if(range)\n {\n this.keyRange.min = range.generatorValue & 0x7F;\n this.keyRange.max = (range.generatorValue >> 8) & 0x7F;\n }\n }\n\n /**\n * reads the velolicty range of the zone\n */\n getVelRange()\n {\n let range = this.generators.find(g => g.generatorType === generatorTypes.velRange);\n if(range)\n {\n this.velRange.min = range.generatorValue & 0x7F;\n this.velRange.max = (range.generatorValue >> 8) & 0x7F;\n }\n }\n}\n\n/**\n * Reads the given instrument zone read\n * @param zonesChunk {RiffChunk}\n * @param instrumentGenerators {Generator[]}\n * @param instrumentModulators {Modulator[]}\n * @param instrumentSamples {Sample[]}\n * @returns {InstrumentZone[]}\n */\nexport function readInstrumentZones(zonesChunk, instrumentGenerators, instrumentModulators, instrumentSamples)\n{\n /**\n * @type {InstrumentZone[]}\n */\n let zones = [];\n let index = 0;\n while(zonesChunk.chunkData.length > zonesChunk.chunkData.currentIndex)\n {\n let zone = new InstrumentZone(zonesChunk.chunkData, index);\n if(zones.length > 0)\n {\n let modulatorZoneSize = zone.modulatorZoneStartIndex - zones[zones.length - 1].modulatorZoneStartIndex;\n let generatorZoneSize = zone.generatorZoneStartIndex - zones[zones.length - 1].generatorZoneStartIndex;\n zones[zones.length - 1].setZoneSize(modulatorZoneSize, generatorZoneSize);\n zones[zones.length - 1].getGenerators(instrumentGenerators);\n zones[zones.length - 1].getModulators(instrumentModulators);\n zones[zones.length - 1].getSample(instrumentSamples);\n zones[zones.length - 1].getKeyRange();\n zones[zones.length - 1].getVelRange();\n }\n zones.push(zone);\n index++;\n }\n if(zones.length > 1)\n {\n // remove terminal\n zones.pop();\n }\n return zones;\n}\n\nexport class\nPresetZone\n{\n /**\n * Creates a zone (preset)\n * @param dataArray {IndexedByteArray}\n * @param index {number}\n */\n constructor(dataArray, index) {\n this.generatorZoneStartIndex = readBytesAsUintLittleEndian(dataArray, 2);\n this.modulatorZoneStartIndex = readBytesAsUintLittleEndian(dataArray, 2);\n this.modulatorZoneSize = 0;\n this.generatorZoneSize = 0;\n this.zoneID = index;\n this.keyRange = {min: 0, max: 127};\n this.velRange = {min: 0, max: 127}\n this.isGlobal = true;\n /**\n * @type {Generator[]}\n */\n this.generators = [];\n /**\n * @type {Modulator[]}\n */\n this.modulators = [];\n }\n\n setZoneSize(modulatorZoneSize, generatorZoneSize)\n {\n this.modulatorZoneSize = modulatorZoneSize;\n this.generatorZoneSize = generatorZoneSize;\n }\n\n deleteZone()\n {\n if(this.isGlobal)\n {\n return;\n }\n this.instrument.removeUseCount();\n }\n\n /**\n * grab the generators\n * @param generators {Generator[]}\n */\n getGenerators(generators)\n {\n for(let i = this.generatorZoneStartIndex; i < this.generatorZoneStartIndex + this.generatorZoneSize; i++)\n {\n this.generators.push(generators[i]);\n }\n }\n\n /**\n * grab the modulators\n * @param modulators {Modulator[]}\n */\n getModulators(modulators)\n {\n for(let i = this.modulatorZoneStartIndex; i < this.modulatorZoneStartIndex + this.modulatorZoneSize; i++)\n {\n this.modulators.push(modulators[i]);\n }\n }\n\n /**\n * grab the instrument\n * @param instruments {Instrument[]}\n */\n getInstrument(instruments)\n {\n let instrumentID = this.generators.find(g => g.generatorType === generatorTypes.instrument);\n if(instrumentID)\n {\n this.instrument = instruments[instrumentID.generatorValue];\n this.instrument.addUseCount();\n this.isGlobal = false;\n }\n }\n\n /**\n * Reads the keyRange of the zone\n */\n getKeyRange()\n {\n let range = this.generators.find(g => g.generatorType === generatorTypes.keyRange);\n if(range)\n {\n this.keyRange.min = range.generatorValue & 0x7F;\n this.keyRange.max = (range.generatorValue >> 8) & 0x7F;\n }\n }\n\n /**\n * reads the velolicty range of the zone\n */\n getVelRange()\n {\n let range = this.generators.find(g => g.generatorType === generatorTypes.velRange);\n if(range)\n {\n this.velRange.min = range.generatorValue & 0x7F;\n this.velRange.max = (range.generatorValue >> 8) & 0x7F;\n }\n }\n}\n\n/**\n * Reads the given preset zone read\n * @param zonesChunk {RiffChunk}\n * @param presetGenerators {Generator[]}\n * @param instruments {Instrument[]}\n * @param presetModulators {Modulator[]}\n * @returns {PresetZone[]}\n */\nexport function readPresetZones(zonesChunk, presetGenerators, presetModulators, instruments)\n{\n /**\n * @type {PresetZone[]}\n */\n let zones = [];\n let index = 0;\n while(zonesChunk.chunkData.length > zonesChunk.chunkData.currentIndex)\n {\n let zone = new PresetZone(zonesChunk.chunkData, index);\n if(zones.length > 0)\n {\n let modulatorZoneSize = zone.modulatorZoneStartIndex - zones[zones.length - 1].modulatorZoneStartIndex;\n let generatorZoneSize = zone.generatorZoneStartIndex - zones[zones.length - 1].generatorZoneStartIndex;\n zones[zones.length - 1].setZoneSize(modulatorZoneSize, generatorZoneSize);\n zones[zones.length - 1].getGenerators(presetGenerators);\n zones[zones.length - 1].getModulators(presetModulators);\n zones[zones.length - 1].getInstrument(instruments);\n zones[zones.length - 1].getKeyRange();\n zones[zones.length - 1].getVelRange();\n }\n zones.push(zone);\n index++;\n }\n if(zones.length > 1)\n {\n // remove terminal\n zones.pop();\n }\n return zones;\n}", "import {RiffChunk} from \"./riff_chunk.js\";\nimport {PresetZone} from \"./zones.js\";\nimport {readBytesAsUintLittleEndian} from \"../../utils/byte_functions/little_endian.js\";\nimport {Sample} from \"./samples.js\";\nimport { Generator, generatorTypes } from './generators.js'\nimport { defaultModulators } from './modulators.js'\nimport { readBytesAsString } from '../../utils/byte_functions/string.js'\n\n/**\n * parses soundfont presets, also includes function for getting the generators and samples from midi note and velocity\n */\n\nexport class Preset {\n /**\n * Creates a preset\n * @param presetChunk {RiffChunk}\n */\n constructor(presetChunk)\n {\n this.presetName = readBytesAsString(presetChunk.chunkData, 20)\n .trim()\n .replace(/\\d{3}:\\d{3}/, \"\"); // remove those pesky \"000:001\"\n\n this.program = readBytesAsUintLittleEndian(presetChunk.chunkData, 2);\n this.bank = readBytesAsUintLittleEndian(presetChunk.chunkData, 2);\n this.presetZoneStartIndex = readBytesAsUintLittleEndian(presetChunk.chunkData, 2);\n this.presetZonesAmount = 0;\n /**\n * @type {PresetZone[]}\n */\n this.presetZones = [];\n\n /**\n * Stores already found getSamplesAndGenerators for reuse\n * @type {SampleAndGenerators[][][]}\n */\n this.foundSamplesAndGenerators = [];\n for(let i = 0; i < 128; i++)\n {\n this.foundSamplesAndGenerators[i] = [];\n }\n\n // read the dwords\n this.library = readBytesAsUintLittleEndian(presetChunk.chunkData, 4);\n this.genre = readBytesAsUintLittleEndian(presetChunk.chunkData, 4);\n this.morphology = readBytesAsUintLittleEndian(presetChunk.chunkData, 4);\n }\n\n /**\n * Loads all the preset zones, given the amount\n * @param amount {number}\n * @param zones {PresetZone[]}\n */\n getPresetZones(amount, zones)\n {\n this.presetZonesAmount = amount;\n for (let i = this.presetZoneStartIndex; i < this.presetZonesAmount + this.presetZoneStartIndex; i++)\n {\n this.presetZones.push(zones[i]);\n }\n }\n\n deletePreset()\n {\n this.presetZones.forEach(z => z.deleteZone());\n this.presetZones.length = 0;\n }\n\n /**\n * @param index {number}\n */\n deleteZone(index)\n {\n this.presetZones[index].deleteZone();\n this.presetZones.splice(index, 1);\n }\n\n /**\n * Preloads all samples (async)\n */\n preload(keyMin, keyMax)\n {\n for (let key = keyMin; key < keyMax + 1; key++)\n {\n for (let velocity = 0; velocity < 128; velocity++)\n {\n this.getSamplesAndGenerators(key, velocity).forEach(samandgen => {\n if(!samandgen.sample.isSampleLoaded)\n {\n samandgen.sample.getAudioData();\n }\n })\n }\n }\n }\n\n /**\n * Preloads a specific key/velocity combo\n * @param key {number}\n * @param velocity {number}\n */\n preloadSpecific(key, velocity)\n {\n this.getSamplesAndGenerators(key, velocity).forEach(samandgen => {\n if(!samandgen.sample.isSampleLoaded)\n {\n samandgen.sample.getAudioData();\n }\n })\n }\n\n /**\n * @typedef {{\n * instrumentGenerators: Generator[],\n * presetGenerators: Generator[],\n * modulators: Modulator[],\n * sample: Sample,\n * sampleID: number,\n * }} SampleAndGenerators\n */\n\n /**\n * Returns generatorTranslator and generators for given note\n * @param midiNote {number}\n * @param velocity {number}\n * @returns {SampleAndGenerators[]}\n */\n getSamplesAndGenerators(midiNote, velocity)\n {\n const memorized = this.foundSamplesAndGenerators[midiNote][velocity];\n if(memorized)\n {\n return memorized;\n }\n\n function isInRange(min, max, number) {\n return number >= min && number <= max;\n }\n\n /**\n * @param mod1 {Modulator}\n * @param mod2 {Modulator}\n * @returns {boolean}\n */\n function identicalMod(mod1, mod2)\n {\n return (mod1.modulatorSource === mod2.modulatorSource)\n && (mod1.modulatorDestination === mod2.modulatorDestination)\n && (mod1.modulationSecondarySrc === mod2.modulationSecondarySrc)\n && (mod1.transformType === mod2.transformType);\n }\n\n /**\n * @param main {Generator[]}\n * @param adder {Generator[]}\n */\n function addUnique(main, adder)\n {\n main.push(...adder.filter(g => !main.find(mg => mg.generatorType === g.generatorType)));\n }\n\n /**\n * @param main {Modulator[]}\n * @param adder {Modulator[]}\n */\n function addUniqueMods(main, adder)\n {\n main.push(...adder.filter(m => !main.find(mm => identicalMod(m, mm))));\n }\n\n /**\n * @type {SampleAndGenerators[]}\n */\n let parsedGeneratorsAndSamples = [];\n\n /**\n * global zone is always first, so it or nothing\n * @type {Generator[]}\n */\n let globalPresetGenerators = this.presetZones[0].isGlobal ? [...this.presetZones[0].generators] : [];\n\n let globalPresetModulators = this.presetZones[0].isGlobal ? [...this.presetZones[0].modulators] : [];\n\n // find the preset zones in range\n let presetZonesInRange = this.presetZones.filter(currentZone =>\n (\n isInRange(currentZone.keyRange.min, currentZone.keyRange.max, midiNote)\n &&\n isInRange(currentZone.velRange.min, currentZone.velRange.max, velocity)\n ) && !currentZone.isGlobal);\n\n presetZonesInRange.forEach(zone =>\n {\n let presetGenerators = zone.generators;\n let presetModulators = zone.modulators;\n /**\n * global zone is always first, so it or nothing\n * @type {Generator[]}\n */\n let globalInstrumentGenerators = zone.instrument.instrumentZones[0].isGlobal ? [...zone.instrument.instrumentZones[0].generators] : [];\n let globalInstrumentModulators = zone.instrument.instrumentZones[0].isGlobal ? [...zone.instrument.instrumentZones[0].modulators] : [];\n\n let instrumentZonesInRange = zone.instrument.instrumentZones\n .filter(currentZone =>\n (\n isInRange(currentZone.keyRange.min,\n currentZone.keyRange.max,\n midiNote)\n &&\n isInRange(currentZone.velRange.min,\n currentZone.velRange.max,\n velocity)\n ) && !currentZone.isGlobal\n );\n\n instrumentZonesInRange.forEach(instrumentZone =>\n {\n let instrumentGenerators = [...instrumentZone.generators];\n let instrumentModulators = [...instrumentZone.modulators];\n\n addUnique(presetGenerators, globalPresetGenerators);\n // add the unique global preset generators (local replace global(\n\n\n // add the unique global instrument generators (local replace global)\n addUnique(instrumentGenerators, globalInstrumentGenerators);\n\n addUniqueMods(presetModulators, globalPresetModulators);\n addUniqueMods(instrumentModulators, globalInstrumentModulators);\n\n // default mods\n addUniqueMods(instrumentModulators, defaultModulators);\n\n /**\n * sum preset modulators to instruments (amount) sf spec page 54\n * @type {Modulator[]}\n */\n const finalModulatorList = [...instrumentModulators];\n for(let i = 0; i < presetModulators.length; i++)\n {\n let mod = presetModulators[i];\n const identicalInstrumentModulator = finalModulatorList.findIndex(m => identicalMod(mod, m));\n if(identicalInstrumentModulator !== -1)\n {\n // sum the amounts (this makes a new modulator because otherwise it would overwrite the one in the soundfont!!!\n finalModulatorList[identicalInstrumentModulator] = finalModulatorList[identicalInstrumentModulator].sumTransform(mod);\n }\n else\n {\n finalModulatorList.push(mod);\n }\n }\n\n\n // combine both generators and add to the final result\n parsedGeneratorsAndSamples.push({\n instrumentGenerators: instrumentGenerators,\n presetGenerators: presetGenerators,\n modulators: finalModulatorList,\n sample: instrumentZone.sample,\n sampleID: instrumentZone.generators.find(g => g.generatorType === generatorTypes.sampleID).generatorValue\n });\n });\n });\n\n // save and return\n this.foundSamplesAndGenerators[midiNote][velocity] = parsedGeneratorsAndSamples;\n return parsedGeneratorsAndSamples;\n }\n}\n\n/**\n * Reads the presets\n * @param presetChunk {RiffChunk}\n * @param presetZones {PresetZone[]}\n * @returns {Preset[]}\n */\nexport function readPresets(presetChunk, presetZones)\n{\n /**\n * @type {Preset[]}\n */\n let presets = [];\n while(presetChunk.chunkData.length > presetChunk.chunkData.currentIndex)\n {\n let preset = new Preset(presetChunk);\n if(presets.length > 0)\n {\n let presetZonesAmount = preset.presetZoneStartIndex - presets[presets.length - 1].presetZoneStartIndex;\n presets[presets.length - 1].getPresetZones(presetZonesAmount, presetZones);\n }\n presets.push(preset);\n }\n // remove EOP\n if (presets.length > 1)\n {\n presets.pop();\n }\n return presets;\n}", "import { writeDword, writeWord } from '../../utils/byte_functions/little_endian.js'\nimport { IndexedByteArray } from '../../utils/indexed_array.js'\nimport { RiffChunk, writeRIFFChunk } from '../read/riff_chunk.js'\nimport { generatorTypes } from '../read/generators.js'\n\n/**\n * @this {SoundFont2}\n * @returns {IndexedByteArray}\n */\nexport function getIGEN()\n{\n // go through all instruments -> zones and write generators sequentially (add 4 for terminal)\n let igensize = 4;\n for(const inst of this.instruments)\n {\n igensize += inst.instrumentZones.reduce((sum, z) => {\n // clear sample and range generators before derermining the size\n z.generators = z.generators.filter(g =>\n g.generatorType !== generatorTypes.sampleID &&\n g.generatorType !== generatorTypes.keyRange &&\n g.generatorType !== generatorTypes.velRange\n );\n // add sample and ranges if needed\n // unshift vel then key ( to make key first) and instrument is last\n if(z.velRange.max !== 127 || z.velRange.min !== 0)\n {\n z.generators.unshift({\n generatorType: generatorTypes.velRange,\n generatorValue: z.velRange.max << 8 | z.velRange.min\n });\n }\n if(z.keyRange.max !== 127 || z.keyRange.min !== 0)\n {\n z.generators.unshift({\n generatorType: generatorTypes.keyRange,\n generatorValue: z.keyRange.max << 8 | z.keyRange.min\n });\n }\n if(!z.isGlobal)\n {\n // write sample\n z.generators.push({\n generatorType: generatorTypes.sampleID,\n generatorValue: this.samples.indexOf(z.sample)\n });\n }\n return z.generators.length * 4 + sum;\n }, 0);\n }\n const igendata = new IndexedByteArray(igensize);\n let igenIndex = 0;\n for(const instrument of this.instruments)\n {\n for (const instrumentZone of instrument.instrumentZones)\n {\n // set the start index here\n instrumentZone.generatorZoneStartIndex = igenIndex;\n for (const gen of instrumentZone.generators)\n {\n // name is deceptive, it works on negatives\n writeWord(igendata, gen.generatorType);\n writeWord(igendata, gen.generatorValue);\n igenIndex++;\n }\n }\n }\n // terminal generator, is zero\n writeDword(igendata, 0);\n\n return writeRIFFChunk(new RiffChunk(\n \"igen\",\n igendata.length,\n igendata\n ));\n}", "import { RiffChunk, writeRIFFChunk } from '../read/riff_chunk.js'\nimport { IndexedByteArray } from '../../utils/indexed_array.js'\nimport { SpessaSynthInfo } from '../../utils/loggin.js'\nimport { consoleColors } from '../../utils/other.js'\n\n/**\n * @this {SoundFont2}\n * @param smplStartOffsets {number[]}\n * @param smplEndOffsets {number[]}\n * @param compress {boolean}\n * @param quality {number}\n * @param vorbisFunc {EncodeVorbisFunction}\n * @returns {IndexedByteArray}\n */\nexport function getSDTA(smplStartOffsets, smplEndOffsets, compress, quality, vorbisFunc)\n{\n // write smpl: write int16 data of each sample linearly\n // get size (calling getAudioData twice doesn't matter since it gets cached)\n const sampleDatas = this.samples.map((s, i) => {\n if(compress)\n {\n s.compressSample(quality, vorbisFunc);\n }\n const r= s.getRawData();\n SpessaSynthInfo(`%cEncoded sample %c${i}. ${s.sampleName}%c of %c${this.samples.length}`,\n consoleColors.info,\n consoleColors.recognized,\n consoleColors.info,\n consoleColors.recognized);\n return r;\n });\n const smplSize = this.samples.reduce((total, s, i) => {\n return total + sampleDatas[i].length + 46;\n }, 0);\n const smplData = new IndexedByteArray(smplSize);\n // resample to int16 and write out\n this.samples.forEach((sample, i) => {\n const data = sampleDatas[i];\n let startOffset;\n let endOffset;\n let jump = data.length;\n if(sample.isCompressed)\n {\n // sf3 offset is in bytes\n startOffset = smplData.currentIndex;\n endOffset = startOffset + data.length;\n }\n else\n {\n // sf2 in sample data points\n startOffset = smplData.currentIndex / 2;\n endOffset = startOffset + data.length / 2;\n jump += 46;\n }\n smplStartOffsets.push(startOffset);\n smplData.set(data, smplData.currentIndex);\n smplData.currentIndex += jump;\n smplEndOffsets.push(endOffset);\n });\n\n const smplChunk = writeRIFFChunk(new RiffChunk(\n \"smpl\",\n smplData.length,\n smplData\n ), new IndexedByteArray([115, 100, 116, 97])); // `sdta`\n\n return writeRIFFChunk(new RiffChunk(\n \"LIST\",\n smplChunk.length,\n smplChunk\n ));\n}", "import { IndexedByteArray } from '../../utils/indexed_array.js'\nimport { writeStringAsBytes } from '../../utils/byte_functions/string.js'\nimport { writeDword, writeWord } from '../../utils/byte_functions/little_endian.js'\nimport { RiffChunk, writeRIFFChunk } from '../read/riff_chunk.js'\n\n/**\n * @this {SoundFont2}\n * @param smplStartOffsets {number[]}\n * @param smplEndOffsets {number[]}\n * @returns {IndexedByteArray}\n */\nexport function getSHDR(smplStartOffsets, smplEndOffsets)\n{\n const sampleLength = 46;\n const shdrData = new IndexedByteArray(sampleLength * (this.samples.length + 1 )); // +1 because EOP\n this.samples.forEach((sample, index) => {\n // sample name\n writeStringAsBytes(shdrData, sample.sampleName, 20);\n // start offset\n const dwStart = smplStartOffsets[index];\n writeDword(shdrData, dwStart);\n // end offset\n const dwEnd = smplEndOffsets[index];\n writeDword(shdrData, dwEnd);\n // loop is stored as relative in sample points, change it to absolute sample points here\n let loopStart = sample.sampleLoopStartIndex / 2 + dwStart;\n let loopEnd = sample.sampleLoopEndIndex / 2 + dwStart;\n if(sample.isCompressed)\n {\n // https://github.com/FluidSynth/fluidsynth/wiki/SoundFont3Format\n loopStart -= dwStart;\n loopEnd -= dwStart;\n }\n writeDword(shdrData, loopStart);\n writeDword(shdrData, loopEnd);\n // sample rate\n writeDword(shdrData, sample.sampleRate);\n // pitch and correction\n shdrData[shdrData.currentIndex++] = sample.samplePitch;\n shdrData[shdrData.currentIndex++] = sample.samplePitchCorrection;\n // sample link\n writeWord(shdrData, sample.sampleLink);\n // sample type: write raw because we simply copy compressed samples\n writeWord(shdrData, sample.sampleType);\n });\n\n // write EOS and zero everything else\n writeStringAsBytes(shdrData, \"EOS\", sampleLength);\n return writeRIFFChunk(new RiffChunk(\n \"shdr\",\n shdrData.length,\n shdrData\n ));\n}", "import { IndexedByteArray } from '../../utils/indexed_array.js'\nimport { writeLittleEndian, writeWord } from '../../utils/byte_functions/little_endian.js'\nimport { RiffChunk, writeRIFFChunk } from '../read/riff_chunk.js'\n\n/**\n * @this {SoundFont2}\n * @returns {IndexedByteArray}\n */\nexport function getIMOD()\n{\n // very similar to igen\n // go through all instruments -> zones and write modulators sequentially\n let imodsize = 10;\n for(const inst of this.instruments)\n {\n imodsize += inst.instrumentZones.reduce((sum, z) => z.modulators.length * 10 + sum, 0);\n }\n const imoddata = new IndexedByteArray(imodsize);\n let imodIndex = 0;\n for(const inst of this.instruments)\n {\n for (const ibag of inst.instrumentZones)\n {\n // set the start index here\n ibag.modulatorZoneStartIndex = imodIndex;\n for (const mod of ibag.modulators)\n {\n writeWord(imoddata, mod.modulatorSource);\n writeWord(imoddata, mod.modulatorDestination);\n writeWord(imoddata, mod.transformAmount);\n writeWord(imoddata, mod.modulationSecondarySrc);\n writeWord(imoddata, mod.transformType);\n imodIndex++;\n }\n }\n }\n\n // terminal modulator, is zero\n writeLittleEndian(imoddata, 0, 10);\n\n return writeRIFFChunk(new RiffChunk(\n \"imod\",\n imoddata.length,\n imoddata\n ));\n}", "import { IndexedByteArray } from '../../utils/indexed_array.js'\nimport { writeWord } from '../../utils/byte_functions/little_endian.js'\nimport { RiffChunk, writeRIFFChunk } from '../read/riff_chunk.js'\n\n/**\n * @this {SoundFont2}\n * @returns {IndexedByteArray}\n */\nexport function getIBAG()\n{\n // write all ibags with their start indexes as they were changed in getIGEN() and getIMOD()\n const ibagsize = this.instruments.reduce((sum, i) => i.instrumentZones.length * 4 + sum, 4);\n const ibagdata = new IndexedByteArray(ibagsize);\n let zoneID = 0;\n let generatorIndex = 0;\n let modulatorIndex = 0;\n for(const inst of this.instruments)\n {\n inst.instrumentZoneIndex = zoneID;\n for(const ibag of inst.instrumentZones)\n {\n ibag.zoneID = zoneID;\n writeWord(ibagdata, generatorIndex);\n writeWord(ibagdata, modulatorIndex);\n generatorIndex += ibag.generators.length;\n modulatorIndex += ibag.modulators.length;\n zoneID++;\n }\n }\n // write the terminal IBAG\n writeWord(ibagdata, generatorIndex);\n writeWord(ibagdata, modulatorIndex);\n\n return writeRIFFChunk(new RiffChunk(\n \"ibag\",\n ibagdata.length,\n ibagdata\n ));\n}", "import { IndexedByteArray } from '../../utils/indexed_array.js'\nimport { writeStringAsBytes } from '../../utils/byte_functions/string.js'\nimport { writeWord } from '../../utils/byte_functions/little_endian.js'\nimport { RiffChunk, writeRIFFChunk } from '../read/riff_chunk.js'\n\n/**\n * @this {SoundFont2}\n * @returns {IndexedByteArray}\n */\nexport function getINST()\n{\n const instsize = this.instruments.length * 22 + 22;\n const instdata = new IndexedByteArray(instsize);\n // the instrument start index is adjusted in ibag, simply write it here\n let instrumentStart = 0;\n let instrumentID = 0;\n for(const inst of this.instruments)\n {\n writeStringAsBytes(instdata, inst.instrumentName, 20);\n writeWord(instdata, instrumentStart);\n instrumentStart += inst.instrumentZones.length;\n inst.instrumentID = instrumentID;\n instrumentID++;\n }\n // write EOI\n writeStringAsBytes(instdata, \"EOI\", 20);\n writeWord(instdata, instrumentStart);\n\n return writeRIFFChunk(new RiffChunk(\n \"inst\",\n instdata.length,\n instdata\n ));\n}", "import { writeWord } from '../../utils/byte_functions/little_endian.js'\nimport { IndexedByteArray } from '../../utils/indexed_array.js'\nimport { RiffChunk, writeRIFFChunk } from '../read/riff_chunk.js'\nimport { generatorTypes } from '../read/generators.js'\n\n/**\n * @this {SoundFont2}\n * @returns {IndexedByteArray}\n */\nexport function getPGEN()\n{\n // almost identical to igen, except correct instrument instead of sample gen\n // go through all preset zones and write generators sequentially (add 4 for terminal)\n let pgensize = 4;\n for(const preset of this.presets)\n {\n pgensize += preset.presetZones.reduce((size, z) => {\n // clear instrument and range generators before derermining the size\n z.generators = z.generators.filter(g =>\n g.generatorType !== generatorTypes.instrument &&\n g.generatorType !== generatorTypes.keyRange &&\n g.generatorType !== generatorTypes.velRange\n );\n // unshift vel then key and instrument is last\n if(z.velRange.max !== 127 || z.velRange.min !== 0)\n {\n z.generators.unshift({\n generatorType: generatorTypes.velRange,\n generatorValue: z.velRange.max << 8 | z.velRange.min\n });\n }\n if(z.keyRange.max !== 127 || z.keyRange.min !== 0)\n {\n z.generators.unshift({\n generatorType: generatorTypes.keyRange,\n generatorValue: z.keyRange.max << 8 | z.keyRange.min\n });\n }\n if(!z.isGlobal)\n {\n // write instrument\n z.generators.push({\n generatorType: generatorTypes.instrument,\n generatorValue: this.instruments.indexOf(z.instrument)\n });\n }\n return z.generators.length * 4 + size;\n }, 0);\n }\n const pgendata = new IndexedByteArray(pgensize);\n let pgenIndex = 0;\n for (const preset of this.presets)\n {\n for (const presetZone of preset.presetZones)\n {\n // set the start index here\n presetZone.generatorZoneStartIndex = pgenIndex;\n // write generators\n for (const gen of presetZone.generators)\n {\n // name is deceptive, it works on negatives\n writeWord(pgendata, gen.generatorType);\n writeWord(pgendata, gen.generatorValue);\n }\n pgenIndex += presetZone.generators.length;\n }\n }\n // terminal generator, is zero\n writeWord(pgendata, 0);\n writeWord(pgendata, 0);\n\n return writeRIFFChunk(new RiffChunk(\n \"pgen\",\n pgendata.length,\n pgendata\n ));\n}", "import { IndexedByteArray } from '../../utils/indexed_array.js'\nimport { writeLittleEndian, writeWord } from '../../utils/byte_functions/little_endian.js'\nimport { RiffChunk, writeRIFFChunk } from '../read/riff_chunk.js'\n\n/**\n * @this {SoundFont2}\n * @returns {IndexedByteArray}\n */\nexport function getPMOD()\n{\n // very similar to imod\n // go through all presets -> zones and write modulators sequentially\n let pmodsize = 10;\n for(const preset of this.presets)\n {\n pmodsize += preset.presetZones.reduce((sum, z) => z.modulators.length * 10 + sum, 0);\n }\n const pmoddata = new IndexedByteArray(pmodsize);\n let pmodIndex = 0;\n for(const preset of this.presets)\n {\n for (const pbag of preset.presetZones)\n {\n // set the start index here\n pbag.modulatorZoneStartIndex = pmodIndex;\n for (const mod of pbag.modulators)\n {\n writeWord(pmoddata, mod.modulatorSource);\n writeWord(pmoddata, mod.modulatorDestination);\n writeWord(pmoddata, mod.transformAmount);\n writeWord(pmoddata, mod.modulationSecondarySrc);\n writeWord(pmoddata, mod.transformType);\n pmodIndex++;\n }\n }\n }\n\n // terminal modulator, is zero\n writeLittleEndian(pmoddata, 0, 10);\n\n return writeRIFFChunk(new RiffChunk(\n \"pmod\",\n pmoddata.length,\n pmoddata\n ));\n}", "import { IndexedByteArray } from '../../utils/indexed_array.js'\nimport { writeWord } from '../../utils/byte_functions/little_endian.js'\nimport { RiffChunk, writeRIFFChunk } from '../read/riff_chunk.js'\n\n/**\n * @this {SoundFont2}\n * @returns {IndexedByteArray}\n */\nexport function getPBAG()\n{\n // write all pbags with their start indexes as they were changed in getPGEN() and getPMOD()\n const pbagsize = this.presets.reduce((sum, i) => i.presetZones.length * 4 + sum, 4);\n const pbagdata = new IndexedByteArray(pbagsize);\n let zoneID = 0;\n let generatorIndex = 0;\n let modulatorIndex = 0;\n for(const preset of this.presets)\n {\n preset.presetZoneStartIndex = zoneID;\n for(const pbag of preset.presetZones)\n {\n pbag.zoneID = zoneID;\n writeWord(pbagdata, generatorIndex);\n writeWord(pbagdata, modulatorIndex);\n generatorIndex += pbag.generators.length;\n modulatorIndex += pbag.modulators.length;\n zoneID++;\n }\n }\n // write the terminal PBAG\n writeWord(pbagdata, generatorIndex);\n writeWord(pbagdata, modulatorIndex);\n\n return writeRIFFChunk(new RiffChunk(\n \"pbag\",\n pbagdata.length,\n pbagdata\n ));\n}", "import { IndexedByteArray } from '../../utils/indexed_array.js'\nimport { writeStringAsBytes } from '../../utils/byte_functions/string.js'\nimport { writeDword, writeWord } from '../../utils/byte_functions/little_endian.js'\nimport { RiffChunk, writeRIFFChunk } from '../read/riff_chunk.js'\n\n/**\n * @this {SoundFont2}\n * @returns {IndexedByteArray}\n */\nexport function getPHDR()\n{\n const phdrsize = this.presets.length * 38 + 38;\n const phdrdata = new IndexedByteArray(phdrsize);\n // the preset start is adjusted in pbag, this is only for the terminal preset index\n let presetStart = 0;\n for (const preset of this.presets)\n {\n writeStringAsBytes(phdrdata, preset.presetName, 20);\n writeWord(phdrdata, preset.program);\n writeWord(phdrdata, preset.bank);\n writeWord(phdrdata, presetStart);\n // 3 unused dwords, spec says to keep em so we do\n writeDword(phdrdata, preset.library);\n writeDword(phdrdata, preset.genre);\n writeDword(phdrdata, preset.morphology);\n presetStart += preset.presetZones.length;\n }\n // write EOP\n writeStringAsBytes(phdrdata, \"EOP\", 20);\n writeWord(phdrdata, 0); // program\n writeWord(phdrdata, 0); // bank\n writeWord(phdrdata, presetStart);\n writeDword(phdrdata, 0); // library\n writeDword(phdrdata, 0); // genre\n writeDword(phdrdata, 0); // morphology\n\n return writeRIFFChunk(new RiffChunk(\n \"phdr\",\n phdrdata.length,\n phdrdata\n ));\n}", "import { combineArrays, IndexedByteArray } from '../../utils/indexed_array.js'\nimport { RiffChunk, writeRIFFChunk } from '../read/riff_chunk.js'\nimport { writeStringAsBytes } from '../../utils/byte_functions/string.js'\nimport { consoleColors } from '../../utils/other.js'\nimport { getIGEN } from './igen.js'\nimport { getSDTA } from './sdta.js'\nimport { getSHDR } from './shdr.js'\nimport { getIMOD } from './imod.js'\nimport { getIBAG } from './ibag.js'\nimport { getINST } from './inst.js'\nimport { getPGEN } from './pgen.js'\nimport { getPMOD } from './pmod.js'\nimport { getPBAG } from './pbag.js'\nimport { getPHDR } from './phdr.js'\nimport { writeWord } from '../../utils/byte_functions/little_endian.js'\nimport {\n SpessaSynthGroupCollapsed,\n SpessaSynthGroupEnd,\n SpessaSynthInfo,\n} from '../../utils/loggin.js'\n\n/**\n * @typedef {Object} SoundFont2WriteOptions\n * @property {boolean} compress - if the soundfont should be compressed with the ogg vorbis codec\n * @property {number} compressionQuality - the vorbis compression quality, from -0.1 to 1\n * @property {EncodeVorbisFunction|undefined} compressionFunction - the encode vorbis function. Can be undefined if not compressing.\n */\n\n/**\n * @type {SoundFont2WriteOptions}\n */\nconst DEFAULT_WRITE_OPTIONS = {\n compress: false,\n compressionQuality: 0.5,\n compressionFunction: undefined\n}\n\n/**\n * Write the soundfont as an .sf2 file. This method is DESTRUCTIVE\n * @this {SoundFont2}\n * @param {SoundFont2WriteOptions} options\n * @returns {Uint8Array}\n */\nexport function write(options = DEFAULT_WRITE_OPTIONS)\n{\n if(options.compress)\n {\n if(typeof options.compressionFunction !== \"function\")\n {\n throw new TypeError(\"No compression function supplied but compression enabled.\");\n }\n }\n SpessaSynthGroupCollapsed(\"%cSaving soundfont...\",\n consoleColors.info);\n SpessaSynthInfo(`%cCompression: %c${options?.compress || \"false\"}%c quality: %c${options?.compressionQuality || \"none\"}`,\n consoleColors.info,\n consoleColors.recognized,\n consoleColors.info,\n consoleColors.recognized)\n SpessaSynthInfo(\"%cWriting INFO...\",\n consoleColors.info);\n /**\n * Write INFO\n * @type {IndexedByteArray[]}\n */\n const infoArrays = [];\n this.soundFontInfo[\"ISFT\"] = \"SpessaSynth\"; // ( \u0361\u00B0 \u035C\u0296 \u0361\u00B0)\n if(options?.compress)\n {\n this.soundFontInfo[\"ifil\"] = \"3.0\"; // set version to 3\n }\n for (const [type, data] of Object.entries(this.soundFontInfo))\n {\n if(type === \"ifil\" || type === \"iver\")\n {\n const major= parseInt(data.split(\".\")[0]);\n const minor= parseInt(data.split(\".\")[1]);\n const ckdata = new IndexedByteArray(4);\n writeWord(ckdata, major);\n writeWord(ckdata, minor);\n infoArrays.push(writeRIFFChunk(new RiffChunk(\n type,\n 4,\n ckdata\n )));\n }\n else\n {\n const arr = new IndexedByteArray(data.length);\n writeStringAsBytes(arr, data);\n infoArrays.push(writeRIFFChunk(new RiffChunk(\n type,\n data.length,\n arr\n )));\n }\n }\n const combined = combineArrays([\n new IndexedByteArray([73, 78, 70, 79]), // INFO\n ...infoArrays\n ]);\n const infoChunk = writeRIFFChunk(new RiffChunk(\"LIST\", combined.length, combined));\n\n SpessaSynthInfo(\"%cWriting SDTA...\",\n consoleColors.info);\n // write sdata\n const smplStartOffsets = [];\n const smplEndOffsets = [];\n const sdtaChunk = getSDTA.call(this, smplStartOffsets, smplEndOffsets, options?.compress, options?.compressionQuality || 0.5, options.compressionFunction);\n\n SpessaSynthInfo(\"%cWriting PDTA...\",\n consoleColors.info);\n // write pdata\n // go in reverse so the indexes are correct\n // instruments\n SpessaSynthInfo(\"%cWriting SHDR...\",\n consoleColors.info);\n const shdrChunk = getSHDR.call(this, smplStartOffsets, smplEndOffsets);\n SpessaSynthInfo(\"%cWriting IGEN...\",\n consoleColors.info);\n const igenChunk = getIGEN.call(this);\n SpessaSynthInfo(\"%cWriting IMOD...\",\n consoleColors.info);\n const imodChunk = getIMOD.call(this);\n SpessaSynthInfo(\"%cWriting IBAG...\",\n consoleColors.info);\n const ibagChunk = getIBAG.call(this);\n SpessaSynthInfo(\"%cWriting INST...\",\n consoleColors.info);\n const instChunk = getINST.call(this);\n // presets\n const pgenChunk = getPGEN.call(this);\n SpessaSynthInfo(\"%cWriting PMOD...\",\n consoleColors.info);\n const pmodChunk = getPMOD.call(this);\n SpessaSynthInfo(\"%cWriting PBAG...\",\n consoleColors.info);\n const pbagChunk = getPBAG.call(this);\n SpessaSynthInfo(\"%cWriting PHDR...\",\n consoleColors.info);\n const phdrChunk = getPHDR.call(this);\n // combine in the sfspec order\n const pdtadata = combineArrays([\n new IndexedByteArray([112, 100, 116, 97]), // \"ptda\"\n phdrChunk,\n pbagChunk,\n pmodChunk,\n pgenChunk,\n instChunk,\n ibagChunk,\n imodChunk,\n igenChunk,\n shdrChunk\n ]);\n const pdtaChunk = writeRIFFChunk(new RiffChunk(\n \"LIST\",\n pdtadata.length,\n pdtadata\n ));\n SpessaSynthInfo(\"%cWriting the output file...\",\n consoleColors.info);\n // finally, combine everything\n const riffdata = combineArrays([\n new IndexedByteArray([115, 102, 98, 107]), // \"sfbk\"\n infoChunk,\n sdtaChunk,\n pdtaChunk\n ]);\n\n const main = writeRIFFChunk(new RiffChunk(\n \"RIFF\",\n riffdata.length,\n riffdata\n ));\n SpessaSynthInfo(`%cSaved succesfully! Final file size: %c${main.length}`,\n consoleColors.info,\n consoleColors.recognized)\n SpessaSynthGroupEnd();\n return main;\n}", "import { IndexedByteArray } from '../utils/indexed_array.js'\nimport {readSamples} from \"./read/samples.js\";\nimport { readBytesAsUintLittleEndian } from '../utils/byte_functions/little_endian.js'\nimport { readGenerators, Generator } from './read/generators.js'\nimport {readInstrumentZones, InstrumentZone, readPresetZones} from \"./read/zones.js\";\nimport {Preset, readPresets} from \"./read/presets.js\";\nimport {readInstruments, Instrument} from \"./read/instruments.js\";\nimport {readModulators, Modulator} from \"./read/modulators.js\";\nimport { readRIFFChunk, RiffChunk } from './read/riff_chunk.js'\nimport { consoleColors } from '../utils/other.js'\nimport { SpessaSynthGroup, SpessaSynthGroupEnd, SpessaSynthInfo, SpessaSynthWarn } from '../utils/loggin.js'\nimport { readBytesAsString } from '../utils/byte_functions/string.js'\nimport { write } from './write/write.js'\n\n/**\n * soundfont.js\n * purpose: parses a soundfont2 file\n */\n\nclass SoundFont2\n{\n /**\n * Initializes a new SoundFont2 Parser and parses the given data array\n * @param arrayBuffer {ArrayBuffer|{presets: Preset[], info: Object<string, string>}}\n */\n constructor(arrayBuffer) {\n if(arrayBuffer.presets)\n {\n this.presets = arrayBuffer.presets;\n this.soundFontInfo = arrayBuffer.info;\n return;\n }\n this.dataArray = new IndexedByteArray(arrayBuffer);\n SpessaSynthGroup(\"%cParsing SoundFont...\", consoleColors.info);\n if(!this.dataArray)\n {\n SpessaSynthGroupEnd();\n throw new TypeError(\"No data!\");\n }\n\n // read the main read\n let firstChunk = readRIFFChunk(this.dataArray, false);\n this.verifyHeader(firstChunk, \"riff\");\n\n this.verifyText(readBytesAsString(this.dataArray,4), \"sfbk\");\n\n // INFO\n let infoChunk = readRIFFChunk(this.dataArray);\n this.verifyHeader(infoChunk, \"list\");\n readBytesAsString(infoChunk.chunkData, 4);\n\n /**\n * @type {Object<string, string>}\n */\n this.soundFontInfo = {};\n\n while(infoChunk.chunkData.length > infoChunk.chunkData.currentIndex) {\n let chunk = readRIFFChunk(infoChunk.chunkData);\n let text;\n // special case: ifil\n switch (chunk.header.toLowerCase())\n {\n case \"ifil\":\n case \"iver\":\n text = `${readBytesAsUintLittleEndian(chunk.chunkData, 2)}.${readBytesAsUintLittleEndian(chunk.chunkData, 2)}`;\n break;\n\n case \"icmt\":\n text = readBytesAsString(chunk.chunkData, chunk.chunkData.length, undefined, false);\n break;\n\n default:\n text = readBytesAsString(chunk.chunkData, chunk.chunkData.length);\n }\n\n SpessaSynthInfo(`%c\"${chunk.header}\": %c\"${text}\"`,\n consoleColors.info,\n consoleColors.recognized);\n this.soundFontInfo[chunk.header] = text;\n }\n\n // SDTA\n const sdtaChunk = readRIFFChunk(this.dataArray, false);\n this.verifyHeader(sdtaChunk, \"list\")\n this.verifyText(readBytesAsString(this.dataArray, 4), \"sdta\");\n\n // smpl\n SpessaSynthInfo(\"%cVerifying smpl chunk...\", consoleColors.warn)\n let sampleDataChunk = readRIFFChunk(this.dataArray, false);\n this.verifyHeader(sampleDataChunk, \"smpl\");\n this.sampleDataStartIndex = this.dataArray.currentIndex;\n\n SpessaSynthInfo(`%cSkipping sample chunk, length: %c${sdtaChunk.size - 12}`,\n consoleColors.info,\n consoleColors.value);\n this.dataArray.currentIndex += sdtaChunk.size - 12;\n\n // PDTA\n SpessaSynthInfo(\"%cLoading preset data chunk...\", consoleColors.warn)\n let presetChunk = readRIFFChunk(this.dataArray);\n this.verifyHeader(presetChunk, \"list\");\n readBytesAsString(presetChunk.chunkData, 4);\n\n // read the hydra chunks\n const presetHeadersChunk = readRIFFChunk(presetChunk.chunkData);\n this.verifyHeader(presetHeadersChunk, \"phdr\");\n\n const presetZonesChunk = readRIFFChunk(presetChunk.chunkData);\n this.verifyHeader(presetZonesChunk, \"pbag\");\n\n const presetModulatorsChunk = readRIFFChunk(presetChunk.chunkData);\n this.verifyHeader(presetModulatorsChunk, \"pmod\");\n\n const presetGeneratorsChunk = readRIFFChunk(presetChunk.chunkData);\n this.verifyHeader(presetGeneratorsChunk, \"pgen\");\n\n const presetInstrumentsChunk = readRIFFChunk(presetChunk.chunkData);\n this.verifyHeader(presetInstrumentsChunk, \"inst\");\n\n const presetInstrumentZonesChunk = readRIFFChunk(presetChunk.chunkData);\n this.verifyHeader(presetInstrumentZonesChunk, \"ibag\");\n\n const presetInstrumentModulatorsChunk = readRIFFChunk(presetChunk.chunkData);\n this.verifyHeader(presetInstrumentModulatorsChunk, \"imod\");\n\n const presetInstrumentGeneratorsChunk = readRIFFChunk(presetChunk.chunkData);\n this.verifyHeader(presetInstrumentGeneratorsChunk, \"igen\");\n\n const presetSamplesChunk = readRIFFChunk(presetChunk.chunkData);\n this.verifyHeader(presetSamplesChunk, \"shdr\");\n\n /**\n * read all the samples\n * (the current index points to start of the smpl read)\n */\n this.dataArray.currentIndex = this.sampleDataStartIndex\n this.samples = readSamples(presetSamplesChunk, this.dataArray);\n\n /**\n * read all the instrument generators\n * @type {Generator[]}\n */\n let instrumentGenerators = readGenerators(presetInstrumentGeneratorsChunk);\n\n /**\n * read all the instrument modulators\n * @type {Modulator[]}\n */\n let instrumentModulators = readModulators(presetInstrumentModulatorsChunk);\n\n /**\n * read all the instrument zones\n * @type {InstrumentZone[]}\n */\n let instrumentZones = readInstrumentZones(presetInstrumentZonesChunk,\n instrumentGenerators,\n instrumentModulators,\n this.samples);\n\n /**\n * read all the instruments\n * @type {Instrument[]}\n */\n this.instruments = readInstruments(presetInstrumentsChunk, instrumentZones);\n\n /**\n * read all the preset generators\n * @type {Generator[]}\n */\n let presetGenerators = readGenerators(presetGeneratorsChunk);\n\n /**\n * Read all the preset modulatorrs\n * @type {Modulator[]}\n */\n let presetModulators = readModulators(presetModulatorsChunk);\n\n let presetZones = readPresetZones(presetZonesChunk, presetGenerators, presetModulators, this.instruments);\n /**\n * Finally, read all the presets\n * @type {Preset[]}\n */\n this.presets = readPresets(presetHeadersChunk, presetZones);\n this.presets.sort((a, b) => (a.program - b.program) + (a.bank - b.bank));\n // preload the first preset\n SpessaSynthInfo(`%cParsing finished! %c\"${this.soundFontInfo[\"INAM\"]}\"%c has %c${this.presets.length} %cpresets,\n %c${this.instruments.length}%c instruments and %c${this.samples.length}%c samples.`,\n consoleColors.info,\n consoleColors.recognized,\n consoleColors.info,\n consoleColors.recognized,\n consoleColors.info,\n consoleColors.recognized,\n consoleColors.info,\n consoleColors.recognized,\n consoleColors.info);\n SpessaSynthGroupEnd();\n }\n\n removeUnusedElements()\n {\n this.instruments.forEach(i => {\n if(i.useCount < 1)\n {\n i.instrumentZones.forEach(z => {if(!z.isGlobal) z.sample.useCount--});\n }\n })\n this.instruments = this.instruments.filter(i => i.useCount > 0);\n this.samples = this.samples.filter(s => s.useCount > 0);\n }\n\n /**\n * @param instrument {Instrument}\n */\n deleteInstrument(instrument)\n {\n if(instrument.useCount > 0)\n {\n throw new Error(`Cannot delete an instrument that has ${instrument.useCount} usages.`);\n }\n this.instruments.splice(this.instruments.indexOf(instrument), 1);\n instrument.deleteInstrument();\n this.removeUnusedElements();\n }\n\n /**\n * @param sample {Sample}\n */\n deleteSample(sample)\n {\n if(sample.useCount > 0)\n {\n throw new Error(`Cannot delete sample that has ${sample.useCount} usages.`);\n }\n this.samples.splice(this.samples.indexOf(sample), 1);\n this.removeUnusedElements();\n }\n\n /**\n * @param preset {Preset}\n */\n deletePreset(preset)\n {\n preset.deletePreset();\n this.presets.splice(this.presets.indexOf(preset), 1);\n this.removeUnusedElements();\n }\n\n /**\n * @param chunk {RiffChunk}\n * @param expected {string}\n */\n verifyHeader(chunk, expected)\n {\n if(chunk.header.toLowerCase() !== expected.toLowerCase())\n {\n SpessaSynthGroupEnd();\n throw new SyntaxError(`Invalid chunk header! Expected \"${expected.toLowerCase()}\" got \"${chunk.header.toLowerCase()}\"`);\n }\n }\n\n /**\n * @param text {string}\n * @param expected {string}\n */\n verifyText(text, expected)\n {\n if(text.toLowerCase() !== expected.toLowerCase())\n {\n SpessaSynthGroupEnd();\n throw new SyntaxError(`Invalid soundFont! Expected \"${expected.toLowerCase()}\" got \"${text.toLowerCase()}\"`);\n }\n }\n\n /**\n * Get the appropriate preset\n * @param bankNr {number}\n * @param presetNr {number}\n * @returns {Preset}\n */\n getPreset(bankNr, presetNr)\n {\n let preset = this.presets.find(p => p.bank === bankNr && p.program === presetNr);\n if (!preset)\n {\n preset = this.presets.find(p => p.program === presetNr && p.bank !== 128);\n if(bankNr === 128)\n {\n preset = this.presets.find(p => p.bank === 128 && p.program === presetNr);\n if(!preset)\n {\n preset = this.presets.find(p => p.bank === 128);\n }\n }\n if(preset)\n {\n SpessaSynthWarn(`%cPreset ${bankNr}.${presetNr} not found. Replaced with %c${preset.presetName} (${preset.bank}.${preset.program})`,\n consoleColors.warn,\n consoleColors.recognized);\n }\n }\n if(!preset)\n {\n SpessaSynthWarn(`Preset ${presetNr} not found. Defaulting to`, this.presets[0].presetName);\n preset = this.presets[0];\n }\n return preset;\n }\n\n /**\n * gets preset by name\n * @param presetName {string}\n * @returns {Preset}\n */\n getPresetByName(presetName)\n {\n let preset = this.presets.find(p => p.presetName === presetName);\n if(!preset)\n {\n SpessaSynthWarn(\"Preset not found. Defaulting to:\", this.presets[0].presetName);\n preset = this.presets[0];\n }\n return preset;\n }\n\n\n /**\n * Merges soundfonts with the given order. Keep in mind that the info read is copied from the first one\n * @param soundfonts {...SoundFont2} the soundfonts to merge, the first overwrites the last\n * @returns {SoundFont2}\n */\n static mergeSoundfonts(...soundfonts)\n {\n const mainSf = soundfonts.shift();\n /**\n * @type {Preset[]}\n */\n const presets = mainSf.presets;\n while(soundfonts.length)\n {\n const newPresets = soundfonts.shift().presets;\n newPresets.forEach(newPreset => {\n if(\n presets.find(existingPreset => existingPreset.bank === newPreset.bank && existingPreset.program === newPreset.program) === undefined\n )\n {\n presets.push(newPreset);\n }\n })\n }\n\n return new SoundFont2({presets: presets, info: mainSf.soundFontInfo});\n }\n}\nSoundFont2.prototype.write = write;\n\nexport { SoundFont2 }", "import { ALL_CHANNELS_OR_DIFFERENT_ACTION, masterParameterType, workletMessageType } from './worklet_message.js'\nimport { SpessaSynthLogging, SpessaSynthWarn } from '../../../utils/loggin.js'\n\n/**\n * @this {SpessaSynthProcessor}\n * @param message\n */\nexport function handleMessage(message)\n{\n const data = message.messageData;\n const channel = message.channelNumber;\n /**\n * @type {WorkletProcessorChannel}\n */\n let channelObject = {};\n if(channel >= 0)\n {\n channelObject = this.workletProcessorChannels[channel];\n }\n switch (message.messageType) {\n case workletMessageType.noteOn:\n this.noteOn(channel, data[0], data[1], data[2]);\n break;\n\n case workletMessageType.noteOff:\n this.noteOff(channel, data);\n break;\n\n case workletMessageType.pitchWheel:\n this.pitchWheel(channel, data[0], data[1]);\n break;\n\n case workletMessageType.ccChange:\n this.controllerChange(channel, data[0], data[1], data[2]);\n break;\n\n case workletMessageType.customcCcChange:\n // custom controller change\n channelObject.customControllers[data[0]] = data[1];\n break;\n\n case workletMessageType.killNote:\n this.killNote(channel, data);\n break;\n\n case workletMessageType.programChange:\n this.programChange(channel, data[0], data[1]);\n break;\n\n case workletMessageType.channelPressure:\n this.channelPressure(channel, data);\n break;\n\n case workletMessageType.polyPressure:\n this.polyPressure(channel, data[0], data[1]);\n break;\n\n case workletMessageType.ccReset:\n if(channel === ALL_CHANNELS_OR_DIFFERENT_ACTION)\n {\n this.resetAllControllers();\n }\n else\n {\n this.resetControllers(channel);\n }\n break;\n\n case workletMessageType.systemExclusive:\n this.systemExclusive(data);\n break;\n\n case workletMessageType.setChannelVibrato:\n if(channel === ALL_CHANNELS_OR_DIFFERENT_ACTION)\n {\n for (let i = 0; i < this.workletProcessorChannels.length; i++)\n {\n if(data.rate === -1)\n {\n this.disableAndLockVibrato(i);\n }\n else\n {\n this.setVibrato(i, data.depth, data.rate, data.delay);\n }\n }\n }\n if(data.rate === -1)\n {\n this.disableAndLockVibrato(channel);\n }\n else\n {\n this.setVibrato(channel, data.depth, data.rate, data.delay);\n }\n break;\n\n case workletMessageType.reloadSoundFont:\n this.reloadSoundFont(data);\n break;\n\n case workletMessageType.stopAll:\n if(channel === ALL_CHANNELS_OR_DIFFERENT_ACTION)\n {\n this.stopAllChannels(data === 1);\n }\n else\n {\n this.stopAll(channel, data === 1);\n }\n break;\n\n case workletMessageType.killNotes:\n this.voiceKilling(data);\n break;\n\n case workletMessageType.muteChannel:\n this.muteChannel(channel, data);\n break;\n\n case workletMessageType.addNewChannel:\n this.createWorkletChannel(true);\n break;\n\n case workletMessageType.debugMessage:\n this.debugMessage();\n break;\n\n case workletMessageType.setMasterParameter:\n /**\n * @type {masterParameterType}\n */\n const type = data[0];\n const value = data[1];\n switch (type)\n {\n case masterParameterType.masterPan:\n this.setMasterPan(value);\n break;\n\n case masterParameterType.mainVolume:\n this.setMasterGain(value);\n break;\n\n case masterParameterType.voicesCap:\n this.voiceCap = value;\n break;\n }\n break;\n\n case workletMessageType.setDrums:\n this.setDrums(channel, data);\n break;\n\n case workletMessageType.transpose:\n if(channel === ALL_CHANNELS_OR_DIFFERENT_ACTION)\n {\n this.transposeAllChannels(data[0], data[1]);\n }\n else\n {\n this.transposeChannel(channel, data[0], data[1]);\n }\n break;\n\n case workletMessageType.highPerformanceMode:\n this.highPerformanceMode = data;\n break;\n\n case workletMessageType.lockController:\n if(data[0] === ALL_CHANNELS_OR_DIFFERENT_ACTION)\n {\n channelObject.lockPreset = data[1];\n }\n else\n {\n channelObject.lockedControllers[data[0]] = data[1];\n }\n break;\n\n case workletMessageType.sequencerSpecific:\n this.sequencer.processMessage(data.messageType, data.messageData);\n break;\n\n case workletMessageType.requestSynthesizerSnapshot:\n this.sendSynthesizerSnapshot();\n break;\n\n case workletMessageType.setLogLevel:\n SpessaSynthLogging(data[0], data[1], data[2], data[3]);\n break;\n\n default:\n SpessaSynthWarn(\"Unrecognized event:\", data);\n break;\n }\n}", "import { arrayToHexString, consoleColors } from '../../../utils/other.js'\nimport { SpessaSynthInfo, SpessaSynthWarn } from '../../../utils/loggin.js'\n/**\n * Executes a system exclusive\n * @param messageData {number[]|IndexedByteArray} - the message data without f0\n * @param channelOffset {number}\n * @this {SpessaSynthProcessor}\n */\n\nexport function systemExclusive(messageData, channelOffset = 0)\n{\n const type = messageData[0];\n switch (type)\n {\n default:\n SpessaSynthWarn(`%cUnrecognized SysEx: %c${arrayToHexString(messageData)}`,\n consoleColors.warn,\n consoleColors.unrecognized);\n break;\n\n // non realtime\n case 0x7E:\n // gm system\n if(messageData[2] === 0x09)\n {\n if(messageData[3] === 0x01)\n {\n SpessaSynthInfo(\"%cGM system on\", consoleColors.info);\n this.system = \"gm\";\n }\n else if(messageData[3] === 0x03)\n {\n SpessaSynthInfo(\"%cGM2 system on\", consoleColors.info);\n this.system = \"gm2\";\n }\n else\n {\n SpessaSynthInfo(\"%cGM system off, defaulting to GS\", consoleColors.info);\n this.system = \"gs\";\n }\n }\n break;\n\n // realtime\n // https://midi.org/midi-1-0-universal-system-exclusive-messages\n case 0x7F:\n if(messageData[2] === 0x04)\n {\n let cents\n // device control\n switch(messageData[3])\n {\n case 0x01:\n // main volume\n const vol = messageData[5] << 7 | messageData[4];\n this.setMIDIVolume(vol / 16384);\n SpessaSynthInfo(`%cMaster Volume. Volume: %c${vol}`,\n consoleColors.info,\n consoleColors.value);\n break;\n\n case 0x02:\n // main balance\n // midi spec page 62\n const balance = messageData[5] << 7 | messageData[4];\n const pan = (balance - 8192) / 8192;\n this.setMasterPan(pan);\n SpessaSynthInfo(`%cMaster Pan. Pan: %c${pan}`,\n consoleColors.info,\n consoleColors.value);\n break;\n\n\n case 0x03:\n // fine tuning\n const tuningValue = ((messageData[5] << 7) | messageData[6]) - 8192;\n cents = Math.floor(tuningValue / 81.92); // [-100;+99] cents range\n this.setMasterTuning(cents);\n SpessaSynthInfo(`%cMaster Fine Tuning. Cents: %c${cents}`,\n consoleColors.info,\n consoleColors.value);\n break;\n\n case 0x04:\n // coarse tuning\n // lsb is ignored\n const semitones = messageData[5] - 64;\n cents = semitones * 100;\n this.setMasterTuning(cents);\n SpessaSynthInfo(`%cMaster Coarse Tuning. Cents: %c${cents}`,\n consoleColors.info,\n consoleColors.value)\n break;\n\n default:\n SpessaSynthWarn(\n `%cUnrecognized MIDI Device Control Real-time message: %c${arrayToHexString(messageData)}`,\n consoleColors.warn,\n consoleColors.unrecognized);\n }\n }\n else\n {\n SpessaSynthWarn(\n `%cUnrecognized MIDI Real-time message: %c${arrayToHexString(messageData)}`,\n consoleColors.warn,\n consoleColors.unrecognized);\n }\n break;\n\n // this is a roland sysex\n // http://www.bandtrax.com.au/sysex.htm\n // https://cdn.roland.com/assets/media/pdf/AT-20R_30R_MI.pdf\n case 0x41:\n // messagedata[1] is device id (ignore as we're everything >:) )\n if(messageData[2] === 0x42 && messageData[3] === 0x12)\n {\n // this is a GS sysex\n // messageData[5] and [6] is the system parameter, messageData[7] is the value\n const messageValue = messageData[7];\n if(messageData[6] === 0x7F)\n {\n // GS mode set\n if(messageValue === 0x00)\n {\n // this is a GS reset\n SpessaSynthInfo(\"%cGS system on\", consoleColors.info);\n this.system = \"gs\";\n }\n else if(messageValue === 0x7F)\n {\n // GS mode off\n SpessaSynthInfo(\"%cGS system off, switching to GM2\", consoleColors.info);\n this.system = \"gm2\";\n }\n return;\n }\n else\n if(messageData[4] === 0x40)\n {\n // this is a system parameter\n if((messageData[5] & 0x10) > 0)\n {\n // this is an individual part (channel) parameter\n // determine the channel 0 means channel 10 (default), 1 means 1 etc.\n let channel = [9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15][messageData[5] & 0x0F] + channelOffset;\n // for example 1A means A = 11, which corresponds to channel 12 (counting from 1)\n switch (messageData[6])\n {\n default:\n break;\n\n case 0x15:\n // this is the Use for Drum Part sysex (multiple drums)\n const isDrums = messageValue > 0 && messageData[5] >> 4; // if set to other than 0, is a drum channel\n this.setDrums(channel, isDrums);\n SpessaSynthInfo(\n `%cChannel %c${channel}%c ${isDrums ?\n \"is now a drum channel\"\n :\n \"now isn't a drum channel\"\n }%c via: %c${arrayToHexString(messageData)}`,\n consoleColors.info,\n consoleColors.value,\n consoleColors.recognized,\n consoleColors.info,\n consoleColors.value);\n return;\n\n case 0x16:\n // this is the pitch key shift sysex\n const keyShift = messageValue - 64;\n this.transposeChannel(channel, keyShift);\n SpessaSynthInfo(`%cChannel %c${channel}%c pitch shift. Semitones %c${keyShift}%c, with %c${arrayToHexString(messageData)}`,\n consoleColors.info,\n consoleColors.recognized,\n consoleColors.info,\n consoleColors.value,\n consoleColors.info,\n consoleColors.value);\n return;\n\n case 0x40:\n case 0x41:\n case 0x42:\n case 0x43:\n case 0x44:\n case 0x45:\n case 0x46:\n case 0x47:\n case 0x48:\n case 0x49:\n case 0x4A:\n case 0x4B:\n // scale tuning\n const cents = messageValue - 64;\n SpessaSynthInfo(`%cChannel %c${channel}%c tuning. Cents %c${cents}%c, with %c${arrayToHexString(messageData)}`,\n consoleColors.info,\n consoleColors.recognized,\n consoleColors.info,\n consoleColors.value,\n consoleColors.info,\n consoleColors.value);\n this.setChannelTuning(channel, cents);\n }\n }\n else\n // this is a global system parameter\n if(messageData[5] === 0x00 && messageData[6] === 0x06)\n {\n // roland master pan\n SpessaSynthInfo(`%cRoland GS Master Pan set to: %c${messageValue}%c with: %c${arrayToHexString(messageData)}`,\n consoleColors.info,\n consoleColors.value,\n consoleColors.info,\n consoleColors.value);\n this.setMasterPan((messageValue - 64) / 64);\n return;\n }\n else\n if(messageData[5] === 0x00 && messageData[6] === 0x05)\n {\n // roland master key shift (transpose)\n const transpose = messageValue - 64;\n SpessaSynthInfo(`%cRoland GS Master Key-Shift set to: %c${transpose}%c with: %c${arrayToHexString(messageData)}`,\n consoleColors.info,\n consoleColors.value,\n consoleColors.info,\n consoleColors.value);\n this.setMasterTuning(transpose * 100);\n return;\n }\n else\n if(messageData[5] === 0x00 && messageData[6] === 0x04)\n {\n // roland GS master volume\n SpessaSynthInfo(`%cRoland GS Master Volume set to: %c${messageValue}%c with: %c${arrayToHexString(messageData)}`,\n consoleColors.info,\n consoleColors.value,\n consoleColors.info,\n consoleColors.value);\n this.setMIDIVolume(messageValue / 127);\n return;\n }\n }\n // this is some other GS sysex...\n SpessaSynthWarn(`%cUnrecognized Roland %cGS %cSysEx: %c${arrayToHexString(messageData)}`,\n consoleColors.warn,\n consoleColors.recognized,\n consoleColors.warn,\n consoleColors.unrecognized);\n return;\n }\n else\n if(messageData[2] === 0x16 && messageData[3] === 0x12 && messageData[4] === 0x10)\n {\n // this is a roland master volume message\n this.setMIDIVolume(messageData[7] / 100);\n SpessaSynthInfo(`%cRoland Master Volume control set to: %c${messageData[7]}%c via: %c${arrayToHexString(messageData)}`,\n consoleColors.info,\n consoleColors.value,\n consoleColors.info,\n consoleColors.value);\n return;\n }\n else\n {\n // this is something else...\n SpessaSynthWarn(`%cUnrecognized Roland SysEx: %c${arrayToHexString(messageData)}`,\n consoleColors.warn,\n consoleColors.unrecognized);\n return;\n }\n\n // yamaha\n case 0x43:\n // XG on\n if(messageData[2] === 0x4C && messageData[5] === 0x7E && messageData[6] === 0x00)\n {\n SpessaSynthInfo(\"%cXG system on\", consoleColors.info);\n this.system = \"xg\";\n }\n else\n {\n if(this.system === \"xg\")\n {\n SpessaSynthWarn(`%cUnrecognized Yamaha SysEx: %c${arrayToHexString(messageData)}`,\n consoleColors.warn,\n consoleColors.unrecognized);\n }\n }\n break;\n\n\n }\n}", "/**\n * unit_converter.js\n * purpose: converts soundfont units into more useable values with the use of lookup tables to improve performance\n */\n\n\n// timecent lookup table\nconst MIN_TIMECENT = -15000;\nconst MAX_TIMECENT = 15000;\nconst timecentLookupTable = new Float32Array(MAX_TIMECENT - MIN_TIMECENT + 1);\nfor (let i = 0; i < timecentLookupTable.length; i++) {\n const timecents = MIN_TIMECENT + i;\n timecentLookupTable[i] = Math.pow(2, timecents / 1200);\n}\n\n/**\n * Converts timecents to seconds\n * @param timecents {number} timecents\n * @returns {number} seconds\n */\nexport function timecentsToSeconds(timecents)\n{\n return timecentLookupTable[timecents - MIN_TIMECENT];\n}\n\n// abs cent lookup table\nconst MIN_ABS_CENT = -20000; // freqVibLfo\nconst MAX_ABS_CENT = 16500; // filterFc\nconst absoluteCentLookupTable = new Float32Array(MAX_ABS_CENT - MIN_ABS_CENT + 1);\nfor (let i = 0; i < absoluteCentLookupTable.length; i++) {\n const absoluteCents = MIN_ABS_CENT + i;\n absoluteCentLookupTable[i] = 440 * Math.pow(2, (absoluteCents - 6900) / 1200);\n}\n\n/**\n * Converts absolute cents to hertz\n * @param cents {number} absolute cents\n * @returns {number} hertz\n */\nexport function absCentsToHz(cents)\n{\n if(cents < MIN_ABS_CENT || cents > MAX_ABS_CENT)\n {\n return 440 * Math.pow(2, (cents - 6900) / 1200);\n }\n return absoluteCentLookupTable[~~(cents) - MIN_ABS_CENT];\n}\n\n// decibel lookup table (2 points of precision)\nconst MIN_DECIBELS = -1660;\nconst MAX_DECIBELS = 1600;\nconst decibelLookUpTable = new Float32Array((MAX_DECIBELS - MIN_DECIBELS) * 100 + 1);\nfor (let i = 0; i < decibelLookUpTable.length; i++) {\n const decibels = (MIN_DECIBELS * 100 + i) / 100;\n decibelLookUpTable[i] = Math.pow(10, -decibels / 20);\n}\n\n/**\n * convers decibel attenuation to gain\n * @param decibels {number} the decibel attenuation\n * @returns {number} gain\n */\nexport function decibelAttenuationToGain(decibels)\n{\n return decibelLookUpTable[Math.floor((decibels - MIN_DECIBELS) * 100)];\n}", "import { decibelAttenuationToGain, timecentsToSeconds } from './unit_converter.js'\nimport { generatorTypes } from '../../../soundfont/read/generators.js'\n\n/**\n * volume_envelope.js\n * purpose: applies a volume envelope for a given voice\n */\n\n/**\n * @typedef {Object} WorkletVolumeEnvelope\n * @property {number} currentAttenuationDb - current voice attenuation in dB (current sample)\n * @property {0|1|2|3|4} state - state of the volume envelope. 0 is delay, 1 is attack, 2 is hold, 3 is decay, 4 is sustain\n * @property {number} releaseStartDb - the dB attenuation of the voice when it was released\n * @property {number} currentReleaseGain - the current linear gain of the release phase\n *\n * @property {number} attackDuration - the duration of the attack phase, in seconds\n * @property {number} decayDuration - the duration of the decay phase, in seconds\n *\n * @property {number} attenuation - the absolute attenuation in dB\n * @property {number} releaseDuration - the duration of the release phase in seconds\n * @property {number} sustainDb - the sustain amount in dB\n *\n * @property {number} delayEnd - the time when delay ends, in absolute seconds\n * @property {number} attackEnd - the time when the attack phase ends, in absolute seconds\n * @property {number} holdEnd - the time when the hold phase ends, in absolute seconds\n * @property {number} decayEnd - the time when the decay phase ends, in absolute seconds\n */\n\n/**\n * @type {WorkletVolumeEnvelope}\n */\nexport const DEFAULT_WORKLET_VOLUME_ENVELOPE = {\n attenuation: 100,\n currentAttenuationDb: 100,\n state: 0,\n releaseStartDb: 100,\n attackDuration: 0,\n decayDuration: 0,\n releaseDuration: 0,\n sustainDb: 0,\n delayEnd: 0,\n attackEnd: 0,\n holdEnd: 0,\n decayEnd: 0,\n currentReleaseGain: 1,\n}\n\nexport const VOLUME_ENVELOPE_SMOOTHING_FACTOR = 0.001;\n\nconst DB_SILENCE = 100;\nconst GAIN_SILENCE = 0.005;\n\n/**\n * VOL ENV STATES:\n * 0 - delay\n * 1 - attack\n * 2 - hold/peak\n * 3 - decay\n * 4 - sustain\n * release is indicated by isInRelease property\n */\n\n/**\n * Recalculates the times of the volume envelope\n * @param voice {WorkletVoice} the voice we're working on\n */\nexport function recalculateVolumeEnvelope(voice)\n{\n const env = voice.volumeEnvelope;\n // calculate durations\n env.attackDuration = timecentsToSeconds(voice.modulatedGenerators[generatorTypes.attackVolEnv]);\n env.decayDuration = timecentsToSeconds(voice.modulatedGenerators[generatorTypes.decayVolEnv]\n + ((60 - voice.midiNote) * voice.modulatedGenerators[generatorTypes.keyNumToVolEnvDecay]));\n env.releaseDuration = timecentsToSeconds(voice.modulatedGenerators[generatorTypes.releaseVolEnv]);\n\n // calculate absolute times (they can change so we have to recalculate every time\n env.attenuation = voice.modulatedGenerators[generatorTypes.initialAttenuation] / 10; // divide by ten to get decibelts\n env.sustainDb = voice.volumeEnvelope.attenuation + voice.modulatedGenerators[generatorTypes.sustainVolEnv] / 10;\n\n // calculate absolute end time\n env.delayEnd = timecentsToSeconds(voice.modulatedGenerators[generatorTypes.delayVolEnv]) + voice.startTime;\n env.attackEnd = env.attackDuration + env.delayEnd;\n\n // make sure to take keyNumToVolEnvHold into account!!!\n env.holdEnd = timecentsToSeconds(voice.modulatedGenerators[generatorTypes.holdVolEnv]\n + ((60 - voice.midiNote) * voice.modulatedGenerators[generatorTypes.keyNumToVolEnvHold]))\n + env.attackEnd;\n\n env.decayEnd = env.decayDuration + env.holdEnd;\n // check if voice is in release\n if(voice.isInRelease)\n {\n // calculate the db attenuation at the time of release (not a constant because it can change (ex, volume set to 0, the sound should cut off)\n switch (env.state) {\n case 0:\n env.releaseStartDb = 0;\n break;\n\n case 1:\n // FIXME: this does not work\n // attack phase\n // attack is linear (in gain) so we need to do get db from that\n let elapsed = 1 - ((env.attackEnd - voice.releaseStartTime) / env.attackDuration);\n // calculate the gain that the attack would have\n let attackGain = elapsed * decibelAttenuationToGain(env.attenuation);\n\n // turn that into db\n env.releaseStartDb = 20 * Math.log10(attackGain) * -1;\n break;\n\n case 2:\n env.releaseStartDb = env.attenuation;\n break;\n\n case 3:\n env.releaseStartDb = (1 - (env.decayEnd - voice.releaseStartTime) / env.decayDuration) * (env.sustainDb - env.attenuation) + env.attenuation;\n break;\n\n case 4:\n env.releaseStartDb = env.sustainDb;\n break;\n\n default:\n env.releaseStartDb = env.currentAttenuationDb;\n }\n }\n}\n\n/**\n * Applies volume envelope gain to the given output buffer\n * @param voice {WorkletVoice} the voice we're working on\n * @param audioBuffer {Float32Array} the audio buffer to modify\n * @param currentTime {number} the current audio time\n * @param centibelOffset {number} the centibel offset of volume, for modLFOtoVolume\n * @param sampleTime {number} single sample time in seconds, usually 1 / 44100 of a second\n * @param smoothingFactor {number} the adjusted smoothing factor for the envelope\n */\n\nexport function applyVolumeEnvelope(voice, audioBuffer, currentTime, centibelOffset, sampleTime, smoothingFactor)\n{\n let decibelOffset = centibelOffset / 10;\n const env = voice.volumeEnvelope;\n\n // RELEASE PHASE\n if(voice.isInRelease)\n {\n // release needs a more aggressive smoothing factor as the instant notes don't end instantly when they should\n const releaseSmoothingFactor = smoothingFactor * 10;\n const releaseStartDb = env.releaseStartDb + decibelOffset;\n let elapsedRelease = currentTime - voice.releaseStartTime;\n let dbDifference = DB_SILENCE - releaseStartDb;\n let gain = env.currentReleaseGain;\n for (let i = 0; i < audioBuffer.length; i++)\n {\n let db = (elapsedRelease / env.releaseDuration) * dbDifference + releaseStartDb;\n gain = decibelAttenuationToGain(db + decibelOffset);\n env.currentReleaseGain += (gain - env.currentReleaseGain) * releaseSmoothingFactor;\n audioBuffer[i] *= env.currentReleaseGain;\n elapsedRelease += sampleTime;\n }\n\n if(env.currentReleaseGain <= GAIN_SILENCE)\n {\n voice.finished = true;\n }\n return;\n }\n\n let currentFrameTime = currentTime;\n let filledBuffer = 0;\n switch(env.state)\n {\n case 0:\n // delay phase, no sound is produced\n while(currentFrameTime < env.delayEnd)\n {\n env.currentAttenuationDb = DB_SILENCE;\n audioBuffer[filledBuffer] = 0;\n\n currentFrameTime += sampleTime;\n if(++filledBuffer >= audioBuffer.length)\n {\n return;\n }\n }\n env.state++;\n // fallthrough\n\n case 1:\n // attack phase: ramp from 0 to attenuation\n while(currentFrameTime < env.attackEnd)\n {\n // Special case: linear gain ramp instead of linear db ramp\n let linearAttenuation = 1 - (env.attackEnd - currentFrameTime) / env.attackDuration; // 0 to 1\n const gain = linearAttenuation * decibelAttenuationToGain(env.attenuation + decibelOffset)\n audioBuffer[filledBuffer] *= gain;\n\n // set current attenuation to peak as its invalid during this phase\n env.currentAttenuationDb = env.attenuation;\n\n currentFrameTime += sampleTime;\n if(++filledBuffer >= audioBuffer.length)\n {\n return;\n }\n }\n env.state++;\n // fallthrough\n\n case 2:\n // hold/peak phase: stay at attenuation\n while(currentFrameTime < env.holdEnd)\n {\n const newAttenuation = env.attenuation\n + decibelOffset;\n\n // interpolate attenuation to prevent clicking\n env.currentAttenuationDb += (newAttenuation - env.currentAttenuationDb) * smoothingFactor;\n audioBuffer[filledBuffer] *= decibelAttenuationToGain(env.currentAttenuationDb);\n\n currentFrameTime += sampleTime;\n if(++filledBuffer >= audioBuffer.length)\n {\n return;\n }\n }\n env.state++;\n // fallthrough\n\n case 3:\n // decay phase: linear ramp from attenuation to sustain\n while(currentFrameTime < env.decayEnd)\n {\n const newAttenuation = (1 - (env.decayEnd - currentFrameTime) / env.decayDuration) * (env.sustainDb - env.attenuation) + env.attenuation\n + decibelOffset;\n\n // interpolate attenuation to prevent clicking\n env.currentAttenuationDb += (newAttenuation - env.currentAttenuationDb) * smoothingFactor;\n audioBuffer[filledBuffer] *= decibelAttenuationToGain(env.currentAttenuationDb);\n\n currentFrameTime += sampleTime;\n if(++filledBuffer >= audioBuffer.length)\n {\n return;\n }\n }\n env.state++;\n // fallthrough\n\n case 4:\n // sustain phase: stay at sustain\n while(true)\n {\n // interpolate attenuation to prevent clicking\n const newAttenuation = env.sustainDb\n + decibelOffset;\n env.currentAttenuationDb += (newAttenuation - env.currentAttenuationDb) * smoothingFactor;\n audioBuffer[filledBuffer] *= decibelAttenuationToGain(env.currentAttenuationDb);\n if(++filledBuffer >= audioBuffer.length)\n {\n return;\n }\n }\n\n }\n}", "import { generatorTypes } from '../../../soundfont/read/generators.js'\nimport { absCentsToHz, decibelAttenuationToGain } from './unit_converter.js'\n\n/**\n * lowpass_filter.js\n * purpose: applies a low pass filter to a voice\n * note to self: most of this is code is just javascript version of the C code from fluidsynth,\n * they are the real smart guys.\n * Shoutout to them!\n */\n\n\n/**\n * @typedef {Object} WorkletLowpassFilter\n * @property {number} a0 - filter coefficient 1\n * @property {number} a1 - filter coefficient 2\n * @property {number} a2 - filter coefficient 3\n * @property {number} a3 - filter coefficient 4\n * @property {number} a4 - filter coefficient 5\n * @property {number} x1 - input history 1\n * @property {number} x2 - input history 2\n * @property {number} y1 - output history 1\n * @property {number} y2 - output history 2\n * @property {number} reasonanceCb - reasonance in centibels\n * @property {number} reasonanceGain - resonance gain\n * @property {number} cutoffCents - cutoff frequency in cents\n * @property {number} cutoffHz - cutoff frequency in Hz\n */\n\n/**\n * @type {WorkletLowpassFilter}\n */\nexport const DEFAULT_WORKLET_LOWPASS_FILTER = {\n a0: 0,\n a1: 0,\n a2: 0,\n a3: 0,\n a4: 0,\n\n x1: 0,\n x2: 0,\n y1: 0,\n y2: 0,\n\n reasonanceCb: 0,\n reasonanceGain: 1,\n cutoffCents: 13500,\n cutoffHz: 20000\n}\n\n/**\n * Applies a low-pass filter to the given buffer\n * @param voice {WorkletVoice} the voice we're working on\n * @param outputBuffer {Float32Array} the buffer to apply the filter to\n * @param cutoffCents {number} cutoff frequency in cents\n */\nexport function applyLowpassFilter(voice, outputBuffer, cutoffCents)\n{\n if(cutoffCents > 13499)\n {\n return; // filter is open\n }\n\n // check if the frequency has changed. if so, calculate new coefficients\n if(voice.filter.cutoffCents !== cutoffCents || voice.filter.reasonanceCb !== voice.modulatedGenerators[generatorTypes.initialFilterQ])\n {\n voice.filter.cutoffCents = cutoffCents;\n voice.filter.reasonanceCb = voice.modulatedGenerators[generatorTypes.initialFilterQ];\n calculateCoefficients(voice);\n }\n\n // filter the input\n for (let i = 0; i < outputBuffer.length; i++) {\n let input = outputBuffer[i];\n let filtered = voice.filter.a0 * input\n + voice.filter.a1 * voice.filter.x1\n + voice.filter.a2 * voice.filter.x2\n - voice.filter.a3 * voice.filter.y1\n - voice.filter.a4 * voice.filter.y2;\n\n // set buffer\n voice.filter.x2 = voice.filter.x1;\n voice.filter.x1 = input;\n voice.filter.y2 = voice.filter.y1;\n voice.filter.y1 = filtered;\n\n outputBuffer[i] = filtered;\n }\n}\n\n/**\n * @param voice {WorkletVoice}\n */\nfunction calculateCoefficients(voice)\n{\n voice.filter.cutoffHz = absCentsToHz(voice.filter.cutoffCents);\n\n // fix cutoff on low frequencies (fluid_iir_filter.c line 392)\n if(voice.filter.cutoffHz > 0.45 * sampleRate)\n {\n voice.filter.cutoffHz = 0.45 * sampleRate;\n }\n\n // adjust the filterQ (fluid_iir_filter.c line 204)\n const qDb = (voice.filter.reasonanceCb / 10) - 3.01;\n voice.filter.reasonanceGain = decibelAttenuationToGain(-1 * qDb); // -1 because it's attenuation and we don't want attenuation\n\n // reduce the gain by the Q factor (fluid_iir_filter.c line 250)\n const qGain = 1 / Math.sqrt(voice.filter.reasonanceGain);\n\n\n // code is ported from https://github.com/sinshu/meltysynth/ to work with js. I'm too dumb to understand the math behind this...\n let w = 2 * Math.PI * voice.filter.cutoffHz / sampleRate; // we're in the audioworkletglobalscope so we can use sampleRate\n let cosw = Math.cos(w);\n let alpha = Math.sin(w) / (2 * voice.filter.reasonanceGain);\n\n let b1 = (1 - cosw) * qGain;\n let b0 = b1 / 2;\n let b2 = b0;\n let a0 = 1 + alpha;\n let a1 = -2 * cosw;\n let a2 = 1 - alpha;\n\n // set coefficients\n voice.filter.a0 = b0 / a0;\n voice.filter.a1 = b1 / a0;\n voice.filter.a2 = b2 / a0;\n voice.filter.a3 = a1 / a0;\n voice.filter.a4 = a2 / a0;\n}", "/**\n * worklet_voice.js\n * purpose: prepares workletvoices from sample and generator data and manages sample dumping\n * note: sample dumping means sending it over to the AudioWorkletGlobalScope\n */\n\n/**\n * @typedef {Object} WorkletSample\n * @property {number} sampleID - ID of the sample\n * @property {number} playbackStep - current playback step (rate)\n * @property {number} cursor - current position in the sample\n * @property {number} rootKey - root key of the sample\n * @property {number} loopStart - start position of the loop\n * @property {number} loopEnd - end position of the loop\n * @property {number} end - end position of the sample\n * @property {0|1|2} loopingMode - looping mode of the sample\n */\n\n/**\n * @typedef {Object} WorkletVoice\n * @property {WorkletSample} sample - sample ID for voice.\n * @property {WorkletLowpassFilter} filter - lowpass filter applied to the voice\n * @property {Int16Array} generators - the unmodulated (constant) generators of the voice\n * @property {Modulator[]} modulators - the voice's modulators. Grouped by the destination\n * @property {Int16Array} modulatedGenerators - the generators modulated by the modulators\n *\n * @property {boolean} finished - indicates if the voice has finished\n * @property {boolean} isInRelease - indicates if the voice is in the release phase\n *\n * @property {number} channelNumber - MIDI channel number\n * @property {number} velocity - velocity of the note\n * @property {number} midiNote - MIDI note number\n * @property {number} pressure - the pressure of the note\n * @property {number} targetKey - target key for the note\n *\n * @property {WorkletVolumeEnvelope} volumeEnvelope\n *\n * @property {number} currentModEnvValue - current value of the modulation envelope\n * @property {number} releaseStartModEnv - modenv value at the start of the release phase\n *\n * @property {number} startTime - start time of the voice\n * @property {number} releaseStartTime - start time of the release phase\n *\n * @property {number} currentTuningCents - current tuning adjustment in cents\n * @property {number} currentTuningCalculated - calculated tuning adjustment\n * @property {number} currentPan - from 0 to 1\n */\n\nimport { addAndClampGenerator, generatorTypes } from '../../../soundfont/read/generators.js'\nimport { SpessaSynthTable, SpessaSynthWarn } from '../../../utils/loggin.js'\nimport { DEFAULT_WORKLET_VOLUME_ENVELOPE } from './volume_envelope.js'\nimport { DEFAULT_WORKLET_LOWPASS_FILTER } from './lowpass_filter.js'\n\n\n/**\n * the sampleID is the index\n * @type {boolean[]}\n */\nlet globalDumpedSamplesList = [];\n\nexport function clearSamplesList()\n{\n globalDumpedSamplesList = [];\n}\n\nfunction /**\n * @param channel {number} channel hint for the processor to recalculate cursor positions\n * @param sample {Sample}\n * @param id {number}\n * @param sampleDumpCallback {function({channel: number, sampleID: number, sampleData: Float32Array})}\n */\ndumpSample(channel, sample, id, sampleDumpCallback)\n{\n // flag as defined, so it's currently being dumped\n globalDumpedSamplesList[id] = false;\n\n // load the data\n sampleDumpCallback({\n channel: channel,\n sampleID: id,\n sampleData: sample.getAudioData()\n });\n globalDumpedSamplesList[id] = true;\n}\n\n/**\n * Deep clone function for the WorkletVoice object and its nested structures.\n * This function handles Int16Array, objects, arrays, and primitives.\n * It does not handle circular references.\n * @param {WorkletVoice} obj - The object to clone.\n * @returns {WorkletVoice} - Cloned object.\n */\nfunction deepClone(obj) {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n // Handle Int16Array separately\n if (obj instanceof Int16Array) {\n return new Int16Array(obj);\n }\n\n // Handle objects and arrays\n const clonedObj = Array.isArray(obj) ? [] : {};\n for (let key in obj) {\n if (obj.hasOwnProperty(key)) {\n if (typeof obj[key] === 'object' && obj[key] !== null) {\n clonedObj[key] = deepClone(obj[key]); // Recursively clone nested objects\n } else if (obj[key] instanceof Int16Array) {\n clonedObj[key] = new Int16Array(obj[key]); // Clone Int16Array\n } else {\n clonedObj[key] = obj[key]; // Copy primitives\n }\n }\n }\n return clonedObj;\n}\n\n\n/**\n * @param channel {number} a hint for the processor to recalculate sample cursors when sample dumping\n * @param midiNote {number}\n * @param velocity {number}\n * @param preset {Preset}\n * @param currentTime {number}\n * @param sampleRate {number}\n * @param sampleDumpCallback {function({channel: number, sampleID: number, sampleData: Float32Array})}\n * @param cachedVoices {WorkletVoice[][][]} first is midi note, second is velocity. output is an array of WorkletVoices\n * @param debug {boolean}\n * @returns {WorkletVoice[]}\n */\nexport function getWorkletVoices(channel,\n midiNote,\n velocity,\n preset,\n currentTime,\n sampleRate,\n sampleDumpCallback,\n cachedVoices,\n debug=false)\n{\n /**\n * @type {WorkletVoice[]}\n */\n let workletVoices;\n\n const cached = cachedVoices[midiNote][velocity];\n if(cached !== undefined)\n {\n workletVoices = cached.map(deepClone);\n workletVoices.forEach(v => {\n v.startTime = currentTime;\n });\n }\n else\n {\n /**\n * @returns {WorkletVoice[]}\n */\n workletVoices = preset.getSamplesAndGenerators(midiNote, velocity).reduce((voices, sampleAndGenerators) => {\n // dump the sample if haven't already\n if (globalDumpedSamplesList[sampleAndGenerators.sampleID] !== true)\n {\n dumpSample(channel, sampleAndGenerators.sample, sampleAndGenerators.sampleID, sampleDumpCallback);\n }\n if(sampleAndGenerators.sample.sampleData === undefined)\n {\n SpessaSynthWarn(`Discarding invalid sample: ${sampleAndGenerators.sample.sampleName}`);\n return voices;\n }\n\n // create the generator list\n const generators = new Int16Array(60);\n // apply and sum the gens\n for (let i = 0; i < 60; i++)\n {\n generators[i] = addAndClampGenerator(i, sampleAndGenerators.presetGenerators, sampleAndGenerators.instrumentGenerators);\n }\n\n // !! EMU initial attenuation correction, multiply initial attenuation by 0.4\n generators[generatorTypes.initialAttenuation] = Math.floor(generators[generatorTypes.initialAttenuation] * 0.4);\n\n // key override\n let rootKey = sampleAndGenerators.sample.samplePitch;\n if (generators[generatorTypes.overridingRootKey] > -1) {\n rootKey = generators[generatorTypes.overridingRootKey];\n }\n\n let targetKey = midiNote;\n if (generators[generatorTypes.keyNum] > -1) {\n targetKey = generators[generatorTypes.keyNum];\n }\n\n // determine looping mode now. if the loop is too small, disable\n const loopStart = (sampleAndGenerators.sample.sampleLoopStartIndex / 2) + (generators[generatorTypes.startloopAddrsOffset] + (generators[generatorTypes.startloopAddrsCoarseOffset] * 32768));\n const loopEnd = (sampleAndGenerators.sample.sampleLoopEndIndex / 2) + (generators[generatorTypes.endloopAddrsOffset] + (generators[generatorTypes.endloopAddrsCoarseOffset] * 32768));\n let loopingMode = generators[generatorTypes.sampleModes];\n if (loopEnd - loopStart < 1) {\n loopingMode = 0;\n }\n\n // determine end\n /**\n * create the worklet sample\n * @type {WorkletSample}\n */\n const workletSample = {\n sampleID: sampleAndGenerators.sampleID,\n playbackStep: (sampleAndGenerators.sample.sampleRate / sampleRate) * Math.pow(2, sampleAndGenerators.sample.samplePitchCorrection / 1200),// cent tuning\n cursor: generators[generatorTypes.startAddrsOffset] + (generators[generatorTypes.startAddrsCoarseOffset] * 32768),\n rootKey: rootKey,\n loopStart: loopStart,\n loopEnd: loopEnd,\n end: Math.floor( sampleAndGenerators.sample.sampleData.length) - 1 + (generators[generatorTypes.endAddrOffset] + (generators[generatorTypes.endAddrsCoarseOffset] * 32768)),\n loopingMode: loopingMode\n };\n\n // velocity override\n if (generators[generatorTypes.velocity] > -1) {\n velocity = generators[generatorTypes.velocity];\n }\n\n if(debug)\n {\n SpessaSynthTable([{\n Sample: sampleAndGenerators.sample.sampleName,\n Generators: generators,\n Modulators: sampleAndGenerators.modulators.map(m => m.debugString()),\n Velocity: velocity,\n TargetKey: targetKey,\n MidiNote: midiNote,\n WorkletSample: workletSample\n }]);\n }\n\n\n voices.push({\n filter: deepClone(DEFAULT_WORKLET_LOWPASS_FILTER),\n // generators and modulators\n generators: generators,\n modulators: sampleAndGenerators.modulators,\n modulatedGenerators: new Int16Array(60),\n\n // sample and playback data\n sample: workletSample,\n velocity: velocity,\n midiNote: midiNote,\n pressure: 0,\n channelNumber: channel,\n startTime: currentTime,\n targetKey: targetKey,\n currentTuningCalculated: 1,\n currentTuningCents: 0,\n releaseStartTime: Infinity,\n\n // envelope data\n finished: false,\n isInRelease: false,\n currentModEnvValue: 0,\n releaseStartModEnv: 1,\n currentPan: 0.5,\n\n volumeEnvelope: deepClone(DEFAULT_WORKLET_VOLUME_ENVELOPE)\n });\n return voices;\n }, []);\n // cache the voice\n // clone it so the system won't mess with it!\n cachedVoices[midiNote][velocity] = workletVoices.map(deepClone);\n }\n return workletVoices;\n}", "import { modulatorCurveTypes } from '../../../soundfont/read/modulators.js'\n\n/**\n * modulator_curves.js\n * precomputes modulator concave and conves curves and calculates a curve value for a given polarity, direction and type\n */\n\n// the length of the precomputed curve tables\nexport const MOD_PRECOMPUTED_LENGTH = 16384;\n\n// Precalculate lookup tables for concave and convers\nconst concave = new Float32Array(MOD_PRECOMPUTED_LENGTH);\nconst convex = new Float32Array(MOD_PRECOMPUTED_LENGTH);\n// the equation is taken from FluidSynth as it's the standard for soundFonts\n// more precisely, this:\n// https://github.com/FluidSynth/fluidsynth/blob/cb8da1e1e2c0a5cff2bab6a419755b598b793384/src/gentables/gen_conv.c#L55\nconcave[0] = 0;\nconcave[MOD_PRECOMPUTED_LENGTH - 1] = 1;\n\nconvex[0] = 0;\nconvex[MOD_PRECOMPUTED_LENGTH - 1] = 1;\nfor(let i = 1; i < MOD_PRECOMPUTED_LENGTH - 1; i++)\n{\n let x = (-200 * 2 / 960) * Math.log(i / (MOD_PRECOMPUTED_LENGTH - 1)) / Math.LN10;\n convex[i] = 1 - x;\n concave[MOD_PRECOMPUTED_LENGTH - 1 - i] = x;\n}\n\n/**\n * Transforms a value with a given curve type\n * @param polarity {number} 0 or 1\n * @param direction {number} 0 or 1\n * @param curveType {number} see modulatorCurveTypes in modulators.js\n * @param value {number} the linear value, 0 to 1\n * @returns {number} the transformed value, 0 to 1 or -1 to 1\n */\nexport function getModulatorCurveValue(direction, curveType, value, polarity) {\n // inverse the value if needed\n if(direction)\n {\n value = 1 - value\n }\n switch (curveType) {\n case modulatorCurveTypes.linear:\n if (polarity) {\n // bipolar\n return value * 2 - 1;\n }\n return value;\n\n case modulatorCurveTypes.switch:\n // switch\n value = value > 0.5 ? 1 : 0;\n if (polarity) {\n // multiply\n return value * 2 - 1;\n }\n return value;\n\n case modulatorCurveTypes.concave:\n // look up the value\n if(polarity)\n {\n value = value * 2 - 1;\n if(value < 0)\n {\n return 1 - concave[~~(value * -MOD_PRECOMPUTED_LENGTH)] - 1;\n }\n return concave[~~value * MOD_PRECOMPUTED_LENGTH];\n }\n return concave[~~(value * MOD_PRECOMPUTED_LENGTH)]\n\n case modulatorCurveTypes.convex:\n // look up the value\n if(polarity)\n {\n value = value * 2 - 1;\n if(value < 0)\n {\n return 1 - convex[~~(value * -MOD_PRECOMPUTED_LENGTH)] - 1;\n }\n return convex[~~(value * MOD_PRECOMPUTED_LENGTH)];\n }\n return convex[~~(value * MOD_PRECOMPUTED_LENGTH)];\n }\n}\n", "import { modulatorSources } from '../../../soundfont/read/modulators.js'\nimport { getModulatorCurveValue, MOD_PRECOMPUTED_LENGTH } from './modulator_curves.js'\nimport { NON_CC_INDEX_OFFSET } from './worklet_processor_channel.js'\nimport { recalculateVolumeEnvelope } from './volume_envelope.js'\nimport { generatorTypes } from '../../../soundfont/read/generators.js'\n\n/**\n * worklet_modulator.js\n * purpose: precomputes all curve types and computes modulators\n */\n\n/**\n * Computes a given modulator\n * @param controllerTable {Int16Array} all midi controllers as 14bit values + the non controller indexes, starting at 128\n * @param modulator {Modulator} the modulator to compute\n * @param voice {WorkletVoice} the voice belonging to the modulator\n * @returns {number} the computed value\n */\nexport function computeWorkletModulator(controllerTable, modulator, voice)\n{\n if(modulator.transformAmount === 0)\n {\n return 0;\n }\n // mapped to 0-16384\n let rawSourceValue;\n if(modulator.sourceUsesCC)\n {\n rawSourceValue = controllerTable[modulator.sourceIndex];\n }\n else\n {\n const index = modulator.sourceIndex + NON_CC_INDEX_OFFSET;\n switch (modulator.sourceIndex)\n {\n case modulatorSources.noController:\n rawSourceValue = 16383; // equals to 1\n break;\n\n case modulatorSources.noteOnKeyNum:\n rawSourceValue = voice.midiNote << 7;\n break;\n\n case modulatorSources.noteOnVelocity:\n rawSourceValue = voice.velocity << 7;\n break;\n\n case modulatorSources.polyPressure:\n rawSourceValue = voice.pressure << 7;\n break;\n\n default:\n rawSourceValue = controllerTable[index]; // pitch bend and range are stored in the cc table\n break;\n }\n\n }\n\n const sourceValue = transforms[modulator.sourceCurveType][modulator.sourcePolarity][modulator.sourceDirection][rawSourceValue];\n\n // mapped to 0-127\n let rawSecondSrcValue;\n if(modulator.secSrcUsesCC)\n {\n rawSecondSrcValue = controllerTable[modulator.secSrcIndex];\n }\n else\n {\n const index = modulator.secSrcIndex + NON_CC_INDEX_OFFSET;\n switch (modulator.secSrcIndex)\n {\n case modulatorSources.noController:\n rawSecondSrcValue = 16383; // equals to 1\n break;\n\n case modulatorSources.noteOnKeyNum:\n rawSecondSrcValue = voice.midiNote << 7;\n break;\n\n case modulatorSources.noteOnVelocity:\n rawSecondSrcValue = voice.velocity << 7;\n break;\n\n case modulatorSources.polyPressure:\n rawSecondSrcValue = voice.pressure << 7;\n break;\n\n default:\n rawSecondSrcValue = controllerTable[index]; // pitch bend and range are stored in the cc table\n }\n\n }\n const secondSrcValue = transforms[modulator.secSrcCurveType][modulator.secSrcPolarity][modulator.secSrcDirection][rawSecondSrcValue];\n\n\n // compute the modulator\n const computedValue = sourceValue * secondSrcValue * modulator.transformAmount;\n\n if(modulator.transformType === 2)\n {\n // abs value\n return Math.abs(computedValue);\n }\n return computedValue;\n}\n\n/**\n * Computes modulators of a given voice. Source and index indicate what modulators shall be computed\n * @param voice {WorkletVoice} the voice to compute modulators for\n * @param controllerTable {Int16Array} all midi controllers as 14bit values + the non controller indexes, starting at 128\n * @param sourceUsesCC {number} what modulators should be computed, -1 means all, 0 means modulator source enum 1 means midi controller\n * @param sourceIndex {number} enum for the source\n */\nexport function computeModulators(voice, controllerTable, sourceUsesCC = -1, sourceIndex = 0) {\n const { modulators, generators, modulatedGenerators } = voice;\n\n if (sourceUsesCC === -1)\n {\n // All modulators mode: compute all modulators\n modulatedGenerators.set(generators);\n modulators.forEach(mod => {\n modulatedGenerators[mod.modulatorDestination] += computeWorkletModulator(controllerTable, mod, voice);\n });\n recalculateVolumeEnvelope(voice);\n return;\n }\n\n // Optimized mode: calculate only modulators that use the given source\n const volenvNeedsRecalculation = new Set([\n generatorTypes.initialAttenuation,\n generatorTypes.delayVolEnv,\n generatorTypes.attackVolEnv,\n generatorTypes.holdVolEnv,\n generatorTypes.decayVolEnv,\n generatorTypes.sustainVolEnv,\n generatorTypes.releaseVolEnv,\n generatorTypes.keyNumToVolEnvHold,\n generatorTypes.keyNumToVolEnvDecay\n ]);\n\n const computedDestinations = new Set();\n\n modulators.forEach(mod => {\n if (\n (mod.sourceUsesCC === sourceUsesCC && mod.sourceIndex === sourceIndex) ||\n (mod.secSrcUsesCC === sourceUsesCC && mod.secSrcIndex === sourceIndex)\n ) {\n const destination = mod.modulatorDestination;\n if (!computedDestinations.has(destination))\n {\n // Reset this destination\n modulatedGenerators[destination] = generators[destination];\n // Compute all modulators for this destination\n modulators.forEach(m => {\n if (m.modulatorDestination === destination)\n {\n modulatedGenerators[destination] += computeWorkletModulator(controllerTable, m, voice);\n }\n });\n computedDestinations.add(destination);\n }\n }\n });\n\n // Recalculate volume envelope if necessary\n if ([...computedDestinations].some(dest => volenvNeedsRecalculation.has(dest)))\n {\n recalculateVolumeEnvelope(voice);\n }\n}\n\n\n/**\n * as follows: transforms[curveType][polarity][direction] is an array\n * @type {Float32Array[][][]}\n */\nconst transforms = [];\n\nfor(let curve = 0; curve < 4; curve++)\n{\n transforms[curve] =\n [\n [\n new Float32Array(MOD_PRECOMPUTED_LENGTH),\n new Float32Array(MOD_PRECOMPUTED_LENGTH)\n ],\n [\n new Float32Array(MOD_PRECOMPUTED_LENGTH),\n new Float32Array(MOD_PRECOMPUTED_LENGTH)\n ]\n ];\n for (let i = 0; i < MOD_PRECOMPUTED_LENGTH; i++) {\n\n // polarity 0 dir 0\n transforms[curve][0][0][i] = getModulatorCurveValue(\n 0,\n curve,\n i / MOD_PRECOMPUTED_LENGTH,\n 0);\n if (isNaN(transforms[curve][0][0][i])) {\n transforms[curve][0][0][i] = 1;\n }\n\n // polarity 1 dir 0\n transforms[curve][1][0][i] = getModulatorCurveValue(\n 0,\n curve,\n i / MOD_PRECOMPUTED_LENGTH,\n 1);\n if (isNaN(transforms[curve][1][0][i])) {\n transforms[curve][1][0][i] = 1;\n }\n\n // polarity 0 dir 1\n transforms[curve][0][1][i] = getModulatorCurveValue(\n 1,\n curve,\n i / MOD_PRECOMPUTED_LENGTH,\n 0);\n if (isNaN(transforms[curve][0][1][i])) {\n transforms[curve][0][1][i] = 1;\n }\n\n // polarity 1 dir 1\n transforms[curve][1][1][i] = getModulatorCurveValue(\n 1,\n curve,\n i / MOD_PRECOMPUTED_LENGTH,\n 1);\n if (isNaN(transforms[curve][1][1][i])) {\n transforms[curve][1][1][i] = 1;\n }\n }\n}", "import { getWorkletVoices } from '../worklet_utilities/worklet_voice.js'\nimport { generatorTypes } from '../../../soundfont/read/generators.js'\nimport { computeModulators } from '../worklet_utilities/worklet_modulator.js'\nimport { recalculateVolumeEnvelope } from '../worklet_utilities/volume_envelope.js'\n\n/**\n * Append the voices\n * @param channel {number}\n * @param midiNote {number}\n * @param velocity {number}\n * @param enableDebugging {boolean}\n * @param sendEvent {boolean}\n * @param startTime {number}\n * @this {SpessaSynthProcessor}\n */\nexport function noteOn(channel, midiNote, velocity, enableDebugging = false, sendEvent = true, startTime = currentTime)\n{\n if (velocity === 0)\n {\n this.noteOff(channel, midiNote);\n return;\n }\n\n if (\n (this.highPerformanceMode && this.totalVoicesAmount > 200 && velocity < 40) ||\n (this.highPerformanceMode && velocity < 10) ||\n (this.workletProcessorChannels[channel].isMuted)\n )\n {\n return;\n }\n\n midiNote += this.workletProcessorChannels[channel].channelTransposeKeyShift;\n\n if(midiNote > 127 || midiNote < 0)\n {\n return;\n }\n\n // get voices\n const voices = getWorkletVoices(\n channel,\n midiNote,\n velocity,\n this.workletProcessorChannels[channel].preset,\n startTime,\n sampleRate,\n data => this.sampleDump(data.channel, data.sampleID, data.sampleData),\n this.workletProcessorChannels[channel].cachedVoices,\n enableDebugging\n );\n\n // add voices and exclusive class apply\n const channelVoices = this.workletProcessorChannels[channel].voices;\n voices.forEach(voice => {\n const exclusive = voice.generators[generatorTypes.exclusiveClass];\n if(exclusive !== 0)\n {\n channelVoices.forEach(v => {\n if(v.generators[generatorTypes.exclusiveClass] === exclusive)\n {\n this.releaseVoice(v);\n v.modulatedGenerators[generatorTypes.releaseVolEnv] = -7000; // make the release nearly instant\n v.modulatedGenerators[generatorTypes.releaseModEnv] = -7000;\n recalculateVolumeEnvelope(v);\n }\n })\n }\n // compute all modulators\n computeModulators(voice, this.workletProcessorChannels[channel].midiControllers);\n // set initial pan to avoid split second changing from middle to the correct value\n voice.currentPan = ((Math.max(-500, Math.min(500, voice.modulatedGenerators[generatorTypes.pan] )) + 500) / 1000) // 0 to 1\n });\n\n this.totalVoicesAmount += voices.length;\n // cap the voices\n if(this.totalVoicesAmount > this.voiceCap)\n {\n this.voiceKilling(voices.length);\n }\n channelVoices.push(...voices);\n if(sendEvent)\n {\n this.sendChannelProperties();\n this.callEvent(\"noteon\", {\n midiNote: midiNote - this.workletProcessorChannels[channel].channelTransposeKeyShift,\n channel: channel,\n velocity: velocity,\n });\n }\n}", "import { consoleColors } from '../../../utils/other.js'\nimport { midiControllers } from '../../../midi_parser/midi_message.js'\nimport {\n customControllers,\n dataEntryStates,\n NON_CC_INDEX_OFFSET,\n} from '../worklet_utilities/worklet_processor_channel.js'\nimport { modulatorSources } from '../../../soundfont/read/modulators.js'\nimport { SpessaSynthInfo, SpessaSynthWarn } from '../../../utils/loggin.js'\n\n/**\n * Executes a data entry for an NRP for a sc88pro NRP (because touhou yes) and RPN tuning\n * @param channel {number}\n * @param dataValue {number} dataEntryCoarse MSB\n * @this {SpessaSynthProcessor}\n * @private\n */\nexport function dataEntryCoarse(channel, dataValue)\n{\n /**\n * @type {WorkletProcessorChannel}\n */\n const channelObject = this.workletProcessorChannels[channel];\n let addDefaultVibrato = () =>\n {\n if(channelObject.channelVibrato.delay === 0 && channelObject.channelVibrato.rate === 0 && channelObject.channelVibrato.depth === 0)\n {\n channelObject.channelVibrato.depth = 50;\n channelObject.channelVibrato.rate = 8;\n channelObject.channelVibrato.delay = 0.6;\n }\n }\n switch(channelObject.dataEntryState)\n {\n default:\n case dataEntryStates.Idle:\n break;\n\n // https://cdn.roland.com/assets/media/pdf/SC-88PRO_OM.pdf\n // http://hummer.stanford.edu/sig/doc/classes/MidiOutput/rpn.html\n case dataEntryStates.NRPFine:\n switch(channelObject.NRPCoarse)\n {\n default:\n if(dataValue === 64)\n {\n // default value\n return;\n }\n SpessaSynthWarn(\n `%cUnrecognized NRPN for %c${channel}%c: %c(0x${channelObject.NRPCoarse.toString(16).toUpperCase()} 0x${channelObject.NRPFine.toString(16).toUpperCase()})%c data value: %c${dataValue}`,\n consoleColors.warn,\n consoleColors.recognized,\n consoleColors.warn,\n consoleColors.unrecognized,\n consoleColors.warn,\n consoleColors.value);\n break;\n\n case 0x01:\n switch(channelObject.NRPFine)\n {\n default:\n if(dataValue === 64)\n {\n // default value\n return;\n }\n SpessaSynthWarn(\n `%cUnrecognized NRPN for %c${channel}%c: %c(0x${channelObject.NRPCoarse.toString(16)} 0x${channelObject.NRPFine.toString(16)})%c data value: %c${dataValue}`,\n consoleColors.warn,\n consoleColors.recognized,\n consoleColors.warn,\n consoleColors.unrecognized,\n consoleColors.warn,\n consoleColors.value);\n break;\n\n // vibrato rate\n case 0x08:\n if(channelObject.lockVibrato)\n {\n return;\n }\n if(dataValue === 64)\n {\n return;\n }\n addDefaultVibrato();\n channelObject.channelVibrato.rate = (dataValue / 64) * 8;\n SpessaSynthInfo(`%cVibrato rate for channel %c${channel}%c is now set to %c${channelObject.channelVibrato.rate}%cHz.`,\n consoleColors.info,\n consoleColors.recognized,\n consoleColors.info,\n consoleColors.value,\n consoleColors.info);\n break;\n\n // vibrato depth\n case 0x09:\n if(channelObject.lockVibrato)\n {\n return;\n }\n if(dataValue === 64)\n {\n return;\n }\n addDefaultVibrato();\n channelObject.channelVibrato.depth = dataValue / 2;\n SpessaSynthInfo(`%cVibrato depth for %c${channel}%c is now set to %c${channelObject.channelVibrato.depth}%c cents range of detune.`,\n consoleColors.info,\n consoleColors.recognized,\n consoleColors.info,\n consoleColors.value,\n consoleColors.info);\n break;\n\n // vibrato delay\n case 0x0A:\n if(channelObject.lockVibrato)\n {\n return;\n }\n if(dataValue === 64)\n {\n return;\n }\n addDefaultVibrato();\n channelObject.channelVibrato.delay = (dataValue / 64) / 3;\n SpessaSynthInfo(`%cVibrato delay for %c${channel}%c is now set to %c${channelObject.channelVibrato.delay}%c seconds.`,\n consoleColors.info,\n consoleColors.recognized,\n consoleColors.info,\n consoleColors.value,\n consoleColors.info);\n break;\n\n // filter cutoff\n case 0x20:\n // affect the \"brightness\" controller as we have a default modulator that controls it\n const ccValue = dataValue;\n this.controllerChange(channel, midiControllers.brightness, dataValue)\n SpessaSynthInfo(`%cFilter cutoff for %c${channel}%c is now set to %c${ccValue}`,\n consoleColors.info,\n consoleColors.recognized,\n consoleColors.info,\n consoleColors.value);\n }\n break;\n\n // drum reverb\n case 0x1D:\n if(!channelObject.drumChannel)\n {\n return;\n }\n const reverb = dataValue;\n this.controllerChange(channel, midiControllers.effects1Depth, reverb);\n SpessaSynthInfo(\n `%cGS Drum reverb for %c${channel}%c: %c${reverb}`,\n consoleColors.info,\n consoleColors.recognized,\n consoleColors.info,\n consoleColors.value);\n break;\n }\n break;\n\n case dataEntryStates.RPCoarse:\n case dataEntryStates.RPFine:\n switch(channelObject.RPValue)\n {\n default:\n SpessaSynthWarn(\n `%cUnrecognized RPN for %c${channel}%c: %c(0x${channelObject.RPValue.toString(16)})%c data value: %c${dataValue}`,\n consoleColors.warn,\n consoleColors.recognized,\n consoleColors.warn,\n consoleColors.unrecognized,\n consoleColors.warn,\n consoleColors.value);\n break;\n\n // pitch bend range\n case 0x0000:\n channelObject.midiControllers[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheelRange] = dataValue << 7;\n SpessaSynthInfo(`%cChannel ${channel} bend range. Semitones: %c${dataValue}`,\n consoleColors.info,\n consoleColors.value);\n break;\n\n // coarse tuning\n case 0x0002:\n // semitones\n this.setChannelTuningSemitones(channel, dataValue - 64);\n break;\n\n // fine tuning\n case 0x0001:\n // note: this will not work properly unless the lsb is sent!\n // here we store the raw value to then adjust in fine\n this.setChannelTuning(channel, (dataValue - 64), false);\n break;\n\n // modulation depth\n case 0x0005:\n this.setModulationDepth(channel, dataValue * 100);\n break\n\n case 0x3FFF:\n this.resetParameters(channel);\n break;\n\n }\n\n }\n}\n\n/**\n * Executes a data entry for an RPN tuning\n * @param channel {number}\n * @param dataValue {number} dataEntry LSB\n * @this {SpessaSynthProcessor}\n * @private\n */\nexport function dataEntryFine(channel, dataValue)\n{\n const channelObject = this.workletProcessorChannels[channel];\n switch (channelObject.dataEntryState)\n {\n default:\n break;\n\n case dataEntryStates.RPCoarse:\n case dataEntryStates.RPFine:\n switch(channelObject.RPValue)\n {\n default:\n break;\n\n // pitch bend range fine tune\n case 0x0000:\n if(dataValue === 0)\n {\n break;\n }\n channelObject.midiControllers[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheelRange] |= dataValue; // 14 bit value so upper 7 are coarse and lower 7 are fine!\n const actualTune = (channelObject.midiControllers[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheelRange] >> 7) + dataValue / 127;\n SpessaSynthInfo(`%cChannel ${channel} bend range. Semitones: %c${actualTune}`,\n consoleColors.info,\n consoleColors.value);\n break;\n\n // fine tuning\n case 0x0001:\n // grab the data and shift\n const coarse = channelObject.customControllers[customControllers.channelTuning];\n const finalTuning = (coarse << 7) | dataValue;\n this.setChannelTuning(channel, finalTuning * 0.01220703125); // multiply by 8192 / 100 (cent increment)\n break;\n\n // modulation depth\n case 0x0005:\n const currentModulationDepthCents = channelObject.customControllers[customControllers.modulationMultiplier] * 50;\n let cents = currentModulationDepthCents + (dataValue / 128) * 100;\n this.setModulationDepth(channel, cents);\n break\n\n case 0x3FFF:\n this.resetParameters(channel);\n break;\n\n }\n\n }\n}", "import { generatorTypes } from '../../../soundfont/read/generators.js'\nimport { consoleColors } from '../../../utils/other.js'\nimport { SpessaSynthInfo, SpessaSynthWarn } from '../../../utils/loggin.js'\n\n/**\n * Release a note\n * @param channel {number}\n * @param midiNote {number}\n * @this {SpessaSynthProcessor}\n */\nexport function noteOff(channel, midiNote)\n{\n if(midiNote > 127 || midiNote < 0)\n {\n SpessaSynthWarn(`Received a noteOn for note`, midiNote, \"Ignoring.\");\n return;\n }\n midiNote += this.workletProcessorChannels[channel].channelTransposeKeyShift;\n\n // if high performance mode, kill notes instead of stopping them\n if(this.highPerformanceMode)\n {\n // if the channel is percussion channel, do not kill the notes\n if(!this.workletProcessorChannels[channel].drumChannel)\n {\n this.killNote(channel, midiNote);\n return;\n }\n }\n\n const channelVoices = this.workletProcessorChannels[channel].voices;\n channelVoices.forEach(v => {\n if(v.midiNote !== midiNote || v.isInRelease === true)\n {\n return;\n }\n // if hold pedal, move to sustain\n if(this.workletProcessorChannels[channel].holdPedal) {\n this.workletProcessorChannels[channel].sustainedVoices.push(v);\n }\n else\n {\n this.releaseVoice(v);\n }\n });\n this.callEvent(\"noteoff\", {\n midiNote: midiNote - this.workletProcessorChannels[channel].channelTransposeKeyShift,\n channel: channel\n });\n}\n\n/**\n * Stops a note nearly instantly\n * @param channel {number}\n * @param midiNote {number}\n * @this {SpessaSynthProcessor}\n */\nexport function killNote(channel, midiNote)\n{\n this.workletProcessorChannels[channel].voices.forEach(v => {\n if(v.midiNote !== midiNote)\n {\n return;\n }\n v.modulatedGenerators[generatorTypes.releaseVolEnv] = -12000; // set release to be very short\n this.releaseVoice(v);\n });\n}\n\n/**\n * stops all notes\n * @param channel {number}\n * @param force {boolean}\n * @this {SpessaSynthProcessor}\n */\nexport function stopAll(channel, force = false)\n{\n const channelVoices = this.workletProcessorChannels[channel].voices;\n if(force)\n {\n // force stop all\n channelVoices.length = 0;\n this.workletProcessorChannels[channel].sustainedVoices.length = 0;\n this.sendChannelProperties();\n }\n else\n {\n channelVoices.forEach(v => {\n if(v.isInRelease) return;\n this.releaseVoice(v);\n });\n this.workletProcessorChannels[channel].sustainedVoices.forEach(v => {\n this.releaseVoice(v);\n })\n }\n}\n\n/**\n * @this {SpessaSynthProcessor}\n * @param force {boolean}\n */\nexport function stopAllChannels(force = false)\n{\n SpessaSynthInfo(\"%cStop all received!\", consoleColors.info);\n for (let i = 0; i < this.workletProcessorChannels.length; i++) {\n this.stopAll(i, force);\n }\n this.callEvent(\"stopall\", undefined);\n}", "import { consoleColors } from '../../../utils/other.js'\nimport { midiControllers } from '../../../midi_parser/midi_message.js'\nimport { dataEntryStates } from '../worklet_utilities/worklet_processor_channel.js'\nimport { computeModulators } from '../worklet_utilities/worklet_modulator.js'\nimport { SpessaSynthInfo } from '../../../utils/loggin.js'\nimport { SYNTHESIZER_GAIN } from '../main_processor.js'\n\n/**\n * @param channel {number}\n * @param controllerNumber {midiControllers}\n * @param controllerValue {number}\n * @param force {boolean}\n * @this {SpessaSynthProcessor}\n */\nexport function controllerChange(channel, controllerNumber, controllerValue, force = false)\n{\n /**\n * @type {WorkletProcessorChannel}\n */\n const channelObject = this.workletProcessorChannels[channel];\n // lsb controller values: append them as the lower nibble of the 14 bit value\n // excluding bank select and data entry as it's handled separately\n if(\n controllerNumber >= midiControllers.lsbForControl1ModulationWheel\n && controllerNumber <= midiControllers.lsbForControl13EffectControl2\n && controllerNumber !== midiControllers.lsbForControl6DataEntry\n )\n {\n const actualCCNum = controllerNumber - 32;\n if(channelObject.lockedControllers[actualCCNum])\n {\n return;\n }\n // append the lower nibble to the main controller\n channelObject.midiControllers[actualCCNum] = (channelObject.midiControllers[actualCCNum] & 0x3F80) | (controllerValue & 0x7F);\n channelObject.voices.forEach(v => computeModulators(v, channelObject.midiControllers, 1, actualCCNum));\n }\n switch (controllerNumber) {\n case midiControllers.allNotesOff:\n this.stopAll(channel);\n break;\n\n case midiControllers.allSoundOff:\n this.stopAll(channel, true);\n break;\n\n // special case: bank select\n case midiControllers.bankSelect:\n let bankNr = controllerValue;\n if(!force)\n {\n switch (this.system) {\n case \"gm\":\n // gm ignores bank select\n SpessaSynthInfo(`%cIgnoring the Bank Select (${controllerValue}), as the synth is in GM mode.`, consoleColors.info);\n return;\n\n case \"xg\":\n // for xg, if msb is 120, 126 or 127, then it's drums\n if (bankNr === 120 || bankNr === 126 || bankNr === 127)\n {\n this.setDrums(channel, true);\n }\n else\n {\n this.setDrums(channel, false);\n }\n break;\n\n case \"gm2\":\n if (bankNr === 120)\n {\n channelObject.drumChannel = true;\n this.callEvent(\"drumchange\", {\n channel: channel,\n isDrumChannel: true\n });\n }\n }\n\n if (channelObject.drumChannel)\n {\n // 128 for percussion channel\n bankNr = 128;\n }\n if (bankNr === 128 && !channelObject.drumChannel)\n {\n // if channel is not for percussion, default to bank current\n bankNr = channelObject.midiControllers[midiControllers.bankSelect];\n }\n }\n\n channelObject.midiControllers[midiControllers.bankSelect] = bankNr;\n break;\n\n case midiControllers.lsbForControl0BankSelect:\n if(this.system === 'xg')\n {\n if(!channelObject.drumChannel)\n {\n // some soundfonts use 127 as drums and\n // if it's not marked as drums by bank MSB (line 47), then we DO NOT want the drums!\n if(controllerValue !== 127)\n {\n channelObject.midiControllers[midiControllers.bankSelect] = controllerValue;\n }\n }\n }\n else\n if(this.system === \"gm2\")\n {\n channelObject.midiControllers[midiControllers.bankSelect] = controllerValue;\n }\n break;\n\n // check for RPN and NPRN and data entry\n case midiControllers.RPNLsb:\n channelObject.RPValue = channelObject.RPValue << 7 | controllerValue;\n channelObject.dataEntryState = dataEntryStates.RPFine;\n break;\n\n case midiControllers.RPNMsb:\n channelObject.RPValue = controllerValue;\n channelObject.dataEntryState = dataEntryStates.RPCoarse;\n break;\n\n case midiControllers.NRPNMsb:\n channelObject.NRPCoarse = controllerValue;\n channelObject.dataEntryState = dataEntryStates.NRPCoarse;\n break;\n\n case midiControllers.NRPNLsb:\n channelObject.NRPFine = controllerValue;\n channelObject.dataEntryState = dataEntryStates.NRPFine;\n break;\n\n case midiControllers.dataEntryMsb:\n this.dataEntryCoarse(channel, controllerValue);\n break;\n\n case midiControllers.lsbForControl6DataEntry:\n this.dataEntryFine(channel, controllerValue);\n break;\n\n case midiControllers.resetAllControllers:\n this.resetControllers(channel);\n break;\n\n case midiControllers.sustainPedal:\n if (controllerValue >= 64)\n {\n channelObject.holdPedal = true;\n }\n else\n {\n channelObject.holdPedal = false;\n channelObject.sustainedVoices.forEach(v => {\n this.releaseVoice(v)\n });\n channelObject.sustainedVoices = [];\n }\n break;\n\n // default: apply the controller to the table\n default:\n if(channelObject.lockedControllers[controllerNumber])\n {\n return;\n }\n channelObject.midiControllers[controllerNumber] = controllerValue << 7;\n channelObject.voices.forEach(v => computeModulators(v, channelObject.midiControllers, 1, controllerNumber));\n this.callEvent(\"controllerchange\", {\n channel: channel,\n controllerNumber: controllerNumber,\n controllerValue: controllerValue\n });\n break;\n }\n}\n\n/**\n * @this {SpessaSynthProcessor}\n */\nexport function setMIDIVolume(volume)\n{\n this.midiVolume = volume;\n this.setMasterPan(this.pan);\n}\n\n/**\n * @param volume {number} 0-1\n * @this {SpessaSynthProcessor}\n */\nexport function setMasterGain(volume)\n{\n this.masterGain = volume * SYNTHESIZER_GAIN;\n this.setMasterPan(this.pan);\n}\n\n/**\n * @param pan {number} -1 to 1\n * @this {SpessaSynthProcessor}\n */\nexport function setMasterPan(pan)\n{\n this.pan = pan;\n // clamp to 0-1 (0 is left)\n pan = (pan / 2) + 0.5;\n this.panLeft = (1 - pan) * this.currentGain;\n this.panRight = (pan) * this.currentGain;\n}\n\n/**\n * @param channel {number}\n * @param isMuted {boolean}\n * @this {SpessaSynthProcessor}\n */\nexport function muteChannel(channel, isMuted)\n{\n if(isMuted)\n {\n this.stopAll(channel, true);\n }\n this.workletProcessorChannels[channel].isMuted = isMuted;\n this.sendChannelProperties();\n this.callEvent(\"mutechannel\", {\n channel: channel,\n isMuted: isMuted\n });\n}", "import { returnMessageType } from './worklet_message.js'\nimport { NON_CC_INDEX_OFFSET } from '../worklet_utilities/worklet_processor_channel.js'\nimport { modulatorSources } from '../../../soundfont/read/modulators.js'\n\n/**\n * Calls synth event from the worklet side\n * @param eventName {EventTypes} the event name\n * @param eventData {any}\n * @this {SpessaSynthProcessor}\n */\nexport function callEvent(eventName, eventData)\n{\n if(!this.enableEventSystem)\n {\n return;\n }\n this.post({\n messageType: returnMessageType.eventCall,\n messageData: {\n eventName: eventName,\n eventData: eventData\n }\n })\n}\n\n/**\n * @param data {WorkletReturnMessage}\n * @this {SpessaSynthProcessor}\n */\nexport function post(data)\n{\n if(!this.enableEventSystem)\n {\n return;\n }\n this.port.postMessage(data);\n}\n\n/**\n * @typedef {Object} ChannelProperty\n * @property {number} voicesAmount\n * @property {number} pitchBend - from -8192 do 8192\n * @property {number} pitchBendRangeSemitones - in semitones\n * @property {boolean} isMuted\n * @property {boolean} isDrum\n */\n\n/**\n * @this {SpessaSynthProcessor}\n */\nexport function sendChannelProperties()\n{\n if(!this.enableEventSystem)\n {\n return;\n }\n /**\n * @type {ChannelProperty[]}\n */\n const data = this.workletProcessorChannels.map(c => {\n const range = (c.midiControllers[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheelRange] >> 7) + (c.midiControllers[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheelRange] & 0x7F) / 127;\n return {\n voicesAmount: c.voices.length,\n pitchBend: c.midiControllers[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel],\n pitchBendRangeSemitones: range,\n isMuted: c.isMuted,\n isDrum: c.drumChannel\n }\n });\n this.post({\n messageType: returnMessageType.channelProperties,\n messageData: data\n });\n}", "import { customControllers, NON_CC_INDEX_OFFSET } from '../worklet_utilities/worklet_processor_channel.js'\nimport { consoleColors } from '../../../utils/other.js'\nimport { modulatorSources } from '../../../soundfont/read/modulators.js'\nimport { computeModulators } from '../worklet_utilities/worklet_modulator.js'\nimport { SpessaSynthInfo } from '../../../utils/loggin.js'\n\n/**\n * Transposes all channels by given amount of semitones\n * @this {SpessaSynthProcessor}\n * @param semitones {number} Can be float\n * @param force {boolean} defaults to false, if true transposes the channel even if it's a drum channel\n */\nexport function transposeAllChannels(semitones, force = false)\n{\n this.transposition = 0;\n for (let i = 0; i < this.workletProcessorChannels.length; i++)\n {\n this.transposeChannel(i, semitones, force);\n }\n this.transposition = semitones;\n}\n\n/**\n * Transposes the channel by given amount of semitones\n * @this {SpessaSynthProcessor}\n * @param channel {number}\n * @param semitones {number} Can be float\n * @param force {boolean} defaults to false, if true transposes the channel even if it's a drum channel\n */\nexport function transposeChannel(channel, semitones, force=false)\n{\n const channelObject = this.workletProcessorChannels[channel];\n if(!channelObject.drumChannel)\n {\n semitones += this.transposition;\n }\n const keyShift = Math.trunc(semitones);\n const currentTranspose = channelObject.channelTransposeKeyShift + channelObject.customControllers[customControllers.channelTransposeFine] / 100;\n if(\n (channelObject.drumChannel && !force)\n || semitones === currentTranspose\n )\n {\n return;\n }\n if(keyShift !== channelObject.channelTransposeKeyShift)\n {\n this.stopAll(channel, false);\n }\n // apply transpose\n channelObject.channelTransposeKeyShift = keyShift;\n channelObject.customControllers[customControllers.channelTransposeFine] = (semitones - keyShift) * 100;\n}\n\n/**\n * Sets the channel's tuning\n * @this {SpessaSynthProcessor}\n * @param channel {number}\n * @param cents {number}\n * @param log {boolean}\n */\nexport function setChannelTuning(channel, cents, log = true)\n{\n const channelObject = this.workletProcessorChannels[channel];\n cents = Math.round(cents);\n channelObject.customControllers[customControllers.channelTuning] = cents;\n if(!log)\n {\n return;\n }\n SpessaSynthInfo(`%cChannel ${channel} fine tuning. Cents: %c${cents}`,\n consoleColors.info,\n consoleColors.value);\n}\n\n/**\n * Sets the channel's tuning in semitones\n * @param channel {number}\n * @param semitones {number}\n * @this {SpessaSynthProcessor}\n */\nexport function setChannelTuningSemitones(channel, semitones)\n{\n const channelObject = this.workletProcessorChannels[channel];\n semitones = Math.round(semitones);\n channelObject.customControllers[customControllers.channelTuningSemitones] = semitones;\n SpessaSynthInfo(`%cChannel ${channel} coarse tuning. Semitones: %c${semitones}`,\n consoleColors.info,\n consoleColors.value);\n}\n\n/**\n * Sets the worklet's master tuning\n * @this {SpessaSynthProcessor}\n * @param cents {number}\n */\nexport function setMasterTuning(cents)\n{\n cents = Math.round(cents);\n for (let i = 0; i < this.workletProcessorChannels.length; i++) {\n this.workletProcessorChannels[i].customControllers[customControllers.masterTuning] = cents;\n }\n}\n\n/**\n * @this {SpessaSynthProcessor}\n * @param channel {number}\n * @param cents {number}\n */\nexport function setModulationDepth(channel, cents)\n{\n let channelObject = this.workletProcessorChannels[channel];\n cents = Math.round(cents);\n SpessaSynthInfo(`%cChannel ${channel} modulation depth. Cents: %c${cents}`,\n consoleColors.info,\n consoleColors.value);\n /* ==============\n IMPORTANT\n here we convert cents into a multiplier.\n midi spec assumes the default is 50 cents,\n but it might be different for the soundfont\n so we create a multiplier by divinging cents by 50.\n for example, if we want 100 cents, then multiplier will be 2,\n which for a preset with depth of 50 will create 100.\n ================ */\n channelObject.customControllers[customControllers.modulationMultiplier] = cents / 50;\n}\n\n/**\n * Sets the pitch of the given channel\n * @this {SpessaSynthProcessor}\n * @param channel {number} usually 0-15: the channel to change pitch\n * @param MSB {number} SECOND byte of the MIDI pitchWheel message\n * @param LSB {number} FIRST byte of the MIDI pitchWheel message\n */\nexport function pitchWheel(channel, MSB, LSB)\n{\n if(this.workletProcessorChannels[channel].lockedControllers[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel])\n {\n return;\n }\n const bend = (LSB | (MSB << 7));\n this.callEvent(\"pitchwheel\", {\n channel: channel,\n MSB: MSB,\n LSB: LSB\n });\n this.workletProcessorChannels[channel].midiControllers[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel] = bend;\n this.workletProcessorChannels[channel].voices.forEach(v =>\n // compute pitch modulators\n computeModulators(v, this.workletProcessorChannels[channel].midiControllers, 0, modulatorSources.pitchWheel));\n this.sendChannelProperties();\n}\n\n/**\n * Sets the pressure of the given channel\n * @this {SpessaSynthProcessor}\n * @param channel {number} usually 0-15: the channel to change pitch\n * @param pressure {number} the pressure of the channel\n */\nexport function channelPressure(channel, pressure)\n{\n const channelObject = this.workletProcessorChannels[channel];\n channelObject.midiControllers[NON_CC_INDEX_OFFSET + modulatorSources.channelPressure] = pressure << 7;\n this.workletProcessorChannels[channel].voices.forEach(v =>\n computeModulators(v, channelObject.midiControllers, 0, modulatorSources.channelPressure));\n this.callEvent(\"channelpressure\",{\n channel: channel,\n pressure: pressure\n });\n}\n\n/**\n * Sets the pressure of the given note on a specific channel\n * @this {SpessaSynthProcessor}\n * @param channel {number} usually 0-15: the channel to change pitch\n * @param midiNote {number} 0-127\n * @param pressure {number} the pressure of the note\n */\nexport function polyPressure(channel, midiNote, pressure)\n{\n this.workletProcessorChannels[channel].voices.forEach(v => {\n if(v.midiNote !== midiNote)\n {\n return;\n }\n v.pressure = pressure;\n computeModulators(v, this.workletProcessorChannels[channel].midiControllers, 0, modulatorSources.polyPressure);\n });\n this.callEvent(\"polypressure\", {\n channel: channel,\n midiNote: midiNote,\n pressure: pressure\n });\n}", "import { midiControllers } from '../../../midi_parser/midi_message.js'\nimport { SoundFont2 } from '../../../soundfont/soundfont.js'\nimport { clearSamplesList } from '../worklet_utilities/worklet_voice.js'\nimport { generatorTypes } from '../../../soundfont/read/generators.js'\nimport { returnMessageType } from '../message_protocol/worklet_message.js'\nimport { SpessaSynthInfo } from '../../../utils/loggin.js'\nimport { consoleColors } from '../../../utils/other.js'\n\n/**\n * executes a program change\n * @param channel {number}\n * @param programNumber {number}\n * @param userChange {boolean}\n * @this {SpessaSynthProcessor}\n */\nexport function programChange(channel, programNumber, userChange=false)\n{\n /**\n * @type {WorkletProcessorChannel}\n */\n const channelObject = this.workletProcessorChannels[channel];\n if(channelObject.lockPreset)\n {\n return;\n }\n // always 128 for percussion\n const bank = channelObject.drumChannel ? 128 : channelObject.midiControllers[midiControllers.bankSelect];\n const preset = this.soundfont.getPreset(bank, programNumber);\n this.setPreset(channel, preset);\n this.callEvent(\"programchange\",{\n channel: channel,\n program: preset.program,\n bank: preset.bank,\n userCalled: userChange\n });\n}\n\n/**\n * @param channel {number}\n * @param preset {Preset}\n * @this {SpessaSynthProcessor}\n */\nexport function setPreset(channel, preset)\n{\n if(this.workletProcessorChannels[channel].lockPreset)\n {\n return;\n }\n this.workletProcessorChannels[channel].preset = preset;\n\n // reset cached voices\n this.workletProcessorChannels[channel].cachedVoices = [];\n for (let i = 0; i < 128; i++) {\n this.workletProcessorChannels[channel].cachedVoices.push([]);\n }\n}\n\n/**\n * Toggles drums on a given channel\n * @param channel {number}\n * @param isDrum {boolean}\n * @this {SpessaSynthProcessor}\n */\nexport function setDrums(channel, isDrum)\n{\n const channelObject = this.workletProcessorChannels[channel];\n if(channelObject.lockPreset)\n {\n return;\n }\n if(isDrum)\n {\n // clear transpose\n channelObject.channelTransposeKeyShift = 0;\n channelObject.drumChannel = true;\n this.setPreset(channel, this.soundfont.getPreset(128, channelObject.preset.program));\n }\n else\n {\n channelObject.drumChannel = false;\n this.setPreset(channel, this.soundfont.getPreset(channelObject.midiControllers[midiControllers.bankSelect], channelObject.preset.program));\n }\n this.callEvent(\"drumchange\",{\n channel: channel,\n isDrumChannel: channelObject.drumChannel\n });\n this.sendChannelProperties();\n}\n\n/**\n * @this {SpessaSynthProcessor}\n */\nexport function sendPresetList()\n{\n this.callEvent(\"presetlistchange\", this.soundfont.presets.map(p => {\n return {presetName: p.presetName, bank: p.bank, program: p.program};\n }));\n}\n\n/**\n * @param buffer {ArrayBuffer}\n * @this {SpessaSynthProcessor}\n */\nexport function reloadSoundFont(buffer)\n{\n this.stopAllChannels(true);\n delete this.soundfont;\n\n\n try {\n this.soundfont = new SoundFont2(buffer);\n }\n catch (e)\n {\n this.post({\n messageType: returnMessageType.soundfontError,\n messageData: e\n });\n return;\n }\n clearSamplesList();\n delete this.workletDumpedSamplesList;\n this.workletDumpedSamplesList = [];\n this.defaultPreset = this.soundfont.getPreset(0, 0);\n this.drumPreset = this.soundfont.getPreset(128, 0);\n\n for(let i = 0; i < this.workletProcessorChannels.length; i++)\n {\n const channelObject = this.workletProcessorChannels[i];\n channelObject.cachedVoices = [];\n for (let j = 0; j < 128; j++) {\n channelObject.cachedVoices.push([]);\n }\n channelObject.lockPreset = false;\n this.programChange(i, channelObject.preset.program);\n }\n this.post({messageType: returnMessageType.ready, messageData: undefined});\n this.sendPresetList();\n SpessaSynthInfo(\"%cSpessaSynth is ready!\", consoleColors.recognized);\n}\n\n/**\n * saves a sample\n * @param channel {number}\n * @param sampleID {number}\n * @param sampleData {Float32Array}\n * @this {SpessaSynthProcessor}\n */\nexport function sampleDump(channel, sampleID, sampleData)\n{\n this.workletDumpedSamplesList[sampleID] = sampleData;\n // the sample maybe was loaded after the voice was sent... adjust the end position!\n\n // not for all channels because the system tells us for what channel this voice was dumped! yay!\n this.workletProcessorChannels[channel].voices.forEach(v => {\n if(v.sample.sampleID !== sampleID)\n {\n return;\n }\n v.sample.end = sampleData.length - 1 + v.generators[generatorTypes.endAddrOffset] + (v.generators[generatorTypes.endAddrsCoarseOffset] * 32768);\n // calculate for how long the sample has been playing and move the cursor there\n v.sample.cursor = (v.sample.playbackStep * sampleRate) * (currentTime - v.startTime);\n if(v.sample.loopingMode === 0) // no loop\n {\n if (v.sample.cursor >= v.sample.end)\n {\n v.finished = true;\n return;\n }\n }\n else\n {\n // go through modulo (adjust cursor if the sample has looped\n if(v.sample.cursor > v.sample.loopEnd)\n {\n v.sample.cursor = v.sample.cursor % (v.sample.loopEnd - v.sample.loopStart) + v.sample.loopStart - 1;\n }\n }\n // set start time to current!\n v.startTime = currentTime;\n })\n\n}", "/**\n * @param channel {number}\n * @this {SpessaSynthProcessor}\n */\nexport function disableAndLockVibrato(channel)\n{\n this.workletProcessorChannels[channel].lockVibrato = true;\n this.workletProcessorChannels[channel].channelVibrato.rate = 0;\n this.workletProcessorChannels[channel].channelVibrato.delay = 0;\n this.workletProcessorChannels[channel].channelVibrato.depth = 0;\n}\n\n/**\n * @param channel {number}\n * @param depth {number}\n * @param rate {number}\n * @param delay {number}\n * @this {SpessaSynthProcessor}\n */\nexport function setVibrato(channel, depth, rate, delay)\n{\n if(this.workletProcessorChannels[channel].lockVibrato)\n {\n return;\n }\n this.workletProcessorChannels[channel].channelVibrato.rate = rate;\n this.workletProcessorChannels[channel].channelVibrato.delay = delay;\n this.workletProcessorChannels[channel].channelVibrato.depth = depth;\n}", "/**\n * @enum {number}\n * @property {number} loadNewSongList - 0 -> [...song<MIDI>]\n * @property {number} pause - 1 -> isFinished<boolean>\n * @property {number} stop - 2 -> (no data)\n * @property {number} play - 3 -> resetTime<boolean>\n * @property {number} setTime - 4 -> time<number>\n * @property {number} changeMIDIMessageSending - 5 -> sendMIDIMessages<boolean>\n * @property {number} setPlaybackRate - 6 -> playbackRate<number>\n * @property {number} setLoop - 7 -> loop<boolean>\n * @property {number} changeSong - 8 -> goForwards<boolean> if true, next song, if false, previous\n * @property {number} getMIDI - 9 -> (no data)\n */\nexport const WorkletSequencerMessageType = {\n loadNewSongList: 0,\n pause: 1,\n stop: 2,\n play: 3,\n setTime: 4,\n changeMIDIMessageSending: 5,\n setPlaybackRate: 6,\n setLoop: 7,\n changeSong: 8,\n getMIDI: 9\n}\n\n/**\n *\n * @enum {number}\n */\nexport const WorkletSequencerReturnMessageType = {\n midiEvent: 0, // [...midiEventBytes<number>]\n songChange: 1, // [midiData<MidiData>, songIndex<number>]\n textEvent: 2, // [messageData<number[]>, statusByte<number]\n timeChange: 3, // newAbsoluteTime<number>\n pause: 4, // no data\n getMIDI: 5, // midiData<MIDI>\n midiError: 6, // errorMSG<string>\n}", "/**\n * Reads as Big endian\n * @param dataArray {IndexedByteArray}\n * @param bytesAmount {number}\n * @returns {number}\n */\nexport function readBytesAsUintBigEndian(dataArray, bytesAmount) {\n let out = 0\n for (let i = 8 * (bytesAmount - 1); i >= 0; i -= 8) {\n out |= (dataArray[dataArray.currentIndex++] << i)\n }\n return out >>> 0\n}\n\n/**\n * @param number {number}\n * @param bytesAmount {number}\n * @returns {number[]}\n */\nexport function writeBytesAsUintBigEndian(number, bytesAmount) {\n const bytes = new Array(bytesAmount).fill(0)\n for (let i = bytesAmount - 1; i >= 0; i--) {\n bytes[i] = number & 0xFF\n number >>= 8\n }\n\n return bytes\n}", "import { getEvent, messageTypes, midiControllers } from '../../midi_parser/midi_message.js'\nimport { WorkletSequencerReturnMessageType } from './sequencer_message.js'\nimport { consoleColors } from '../../utils/other.js'\nimport { SpessaSynthWarn } from '../../utils/loggin.js'\nimport { readBytesAsUintBigEndian } from '../../utils/byte_functions/big_endian.js'\nimport { DEFAULT_PERCUSSION } from '../../synthetizer/synthetizer.js'\n\n/**\n * Processes a single event\n * @param event {MidiMessage}\n * @param trackIndex {number}\n * @this {WorkletSequencer}\n * @private\n */\nexport function _processEvent(event, trackIndex)\n{\n if(this.ignoreEvents) return;\n if(this.sendMIDIMessages)\n {\n if(event.messageStatusByte >= 0x80)\n {\n this.sendMIDIMessage([event.messageStatusByte, ...event.messageData]);\n return;\n }\n }\n const statusByteData = getEvent(event.messageStatusByte);\n const offset = this.midiPortChannelOffsets[this.midiPorts[trackIndex]] || 0\n statusByteData.channel += offset;\n // process the event\n switch (statusByteData.status) {\n case messageTypes.noteOn:\n const velocity = event.messageData[1];\n if(velocity > 0)\n {\n this.synth.noteOn(statusByteData.channel, event.messageData[0], velocity);\n this.playingNotes.push({\n midiNote: event.messageData[0],\n channel: statusByteData.channel,\n velocity: velocity,\n startTime: this.currentTime\n });\n }\n else\n {\n this.synth.noteOff(statusByteData.channel, event.messageData[0]);\n const toDelete = this.playingNotes.findIndex(n =>\n n.midiNote === event.messageData[0] && n.channel === statusByteData.channel);\n if(toDelete !== -1)\n {\n this.playingNotes.splice(toDelete, 1);\n }\n }\n break;\n\n case messageTypes.noteOff:\n this.synth.noteOff(statusByteData.channel, event.messageData[0]);\n const toDelete = this.playingNotes.findIndex(n =>\n n.midiNote === event.messageData[0] && n.channel === statusByteData.channel);\n if(toDelete !== -1)\n {\n this.playingNotes.splice(toDelete, 1);\n }\n break;\n\n case messageTypes.pitchBend:\n this.synth.pitchWheel(statusByteData.channel, event.messageData[1], event.messageData[0]);\n break;\n\n case messageTypes.controllerChange:\n // special case if the RMID is embedded: subtract 1 from bank. See wiki About-RMIDI\n let v = event.messageData[1];\n if(this.midiData.embeddedSoundFont && event.messageData[0] === midiControllers.bankSelect)\n {\n v--;\n }\n this.synth.controllerChange(statusByteData.channel, event.messageData[0], v);\n break;\n\n case messageTypes.programChange:\n this.synth.programChange(statusByteData.channel, event.messageData[0]);\n break;\n\n case messageTypes.polyPressure:\n this.synth.polyPressure(statusByteData.channel, event.messageData[0], event.messageData[1]);\n break;\n\n case messageTypes.channelPressure:\n this.synth.channelPressure(statusByteData.channel, event.messageData[0]);\n break;\n\n case messageTypes.systemExclusive:\n this.synth.systemExclusive(event.messageData, offset);\n break;\n\n case messageTypes.setTempo:\n this.oneTickToSeconds = 60 / (getTempo(event) * this.midiData.timeDivision);\n if(this.oneTickToSeconds === 0)\n {\n this.oneTickToSeconds = 60 / (120 * this.midiData.timeDivision);\n SpessaSynthWarn(\"invalid tempo! falling back to 120 BPM\");\n }\n break;\n\n // recongized but ignored\n case messageTypes.timeSignature:\n case messageTypes.endOfTrack:\n case messageTypes.midiChannelPrefix:\n case messageTypes.songPosition:\n case messageTypes.activeSensing:\n case messageTypes.keySignature:\n break;\n\n case messageTypes.text:\n case messageTypes.lyric:\n case messageTypes.copyright:\n case messageTypes.trackName:\n case messageTypes.marker:\n case messageTypes.cuePoint:\n case messageTypes.instrumentName:\n this.post(WorkletSequencerReturnMessageType.textEvent, [event.messageData, statusByteData.status])\n break;\n\n case messageTypes.midiPort:\n this.assignMIDIPort(trackIndex, event.messageData[0]);\n break;\n\n case messageTypes.reset:\n this.synth.stopAllChannels();\n this.synth.resetAllControllers();\n break;\n\n default:\n SpessaSynthWarn(`%cUnrecognized Event: %c${event.messageStatusByte}%c status byte: %c${Object.keys(messageTypes).find(k => messageTypes[k] === statusByteData.status)}`,\n consoleColors.warn,\n consoleColors.unrecognized,\n consoleColors.warn,\n consoleColors.value);\n break;\n }\n}\n\n/**\n * Adds 16 channels to the synth\n * @this {WorkletSequencer}\n * @private\n */\nexport function _addNewMidiPort()\n{\n for (let i = 0; i < 16; i++) {\n this.synth.createWorkletChannel(true);\n if(i === DEFAULT_PERCUSSION)\n {\n this.synth.setDrums(this.synth.workletProcessorChannels.length - 1, true);\n }\n }\n}\n\n/**\n * gets tempo from the midi message\n * @param event {MidiMessage}\n * @return {number} the tempo in bpm\n */\nfunction getTempo(event)\n{\n event.messageData.currentIndex = 0;\n return 60000000 / readBytesAsUintBigEndian(event.messageData, 3);\n}", "/**\n * Processes a single tick\n * @private\n * @this {WorkletSequencer}\n */\nexport function _processTick()\n{\n let current = this.currentTime;\n while(this.playedTime < current)\n {\n // find next event\n let trackIndex = this._findFirstEventIndex();\n let event = this.tracks[trackIndex][this.eventIndex[trackIndex]];\n this._processEvent(event, trackIndex);\n\n this.eventIndex[trackIndex]++;\n\n // find next event\n trackIndex = this._findFirstEventIndex();\n if(this.tracks[trackIndex].length <= this.eventIndex[trackIndex])\n {\n // song has ended\n if(this.loop)\n {\n this.setTimeTicks(this.midiData.loop.start);\n return;\n }\n this.eventIndex[trackIndex]--;\n this.pause(true);\n if(this.songs.length > 1)\n {\n this.nextSong();\n }\n return;\n }\n let eventNext = this.tracks[trackIndex][this.eventIndex[trackIndex]];\n this.playedTime += this.oneTickToSeconds * (eventNext.ticks - event.ticks);\n\n // loop\n if((this.midiData.loop.end <= event.ticks) && this.loop)\n {\n this.setTimeTicks(this.midiData.loop.start);\n return;\n }\n // if song has ended\n else if(current >= this.duration)\n {\n if(this.loop)\n {\n this.setTimeTicks(this.midiData.loop.start);\n return;\n }\n this.eventIndex[trackIndex]--;\n this.pause(true);\n if(this.songs.length > 1)\n {\n this.nextSong();\n }\n return;\n }\n }\n}\n\n\n/**\n * @returns {number} the index of the first to the current played time\n * @this {WorkletSequencer}\n */\nexport function _findFirstEventIndex()\n{\n let index = 0;\n let ticks = Infinity;\n this.tracks.forEach((track, i) => {\n if(this.eventIndex[i] >= track.length)\n {\n return;\n }\n if(track[this.eventIndex[i]].ticks < ticks)\n {\n index = i;\n ticks = track[this.eventIndex[i]].ticks;\n }\n });\n return index;\n}", "import { getEvent, messageTypes, midiControllers } from '../../midi_parser/midi_message.js'\nimport { WorkletSequencerReturnMessageType } from './sequencer_message.js'\nimport { MIDI_CHANNEL_COUNT } from '../../synthetizer/synthetizer.js'\n\n\n// an array with preset default values\nconst defaultControllerArray = new Int16Array(127);\n// default values\ndefaultControllerArray[midiControllers.mainVolume] = 100;\ndefaultControllerArray[midiControllers.expressionController] = 127;\ndefaultControllerArray[midiControllers.pan] = 64;\ndefaultControllerArray[midiControllers.releaseTime] = 64;\ndefaultControllerArray[midiControllers.brightness] = 64;\ndefaultControllerArray[midiControllers.effects1Depth] = 40;\n\n/**\n * plays from start to the target time, excluding note messages (to get the synth to the correct state)\n * @private\n * @param time {number} in seconds\n * @param ticks {number} optional MIDI ticks, when given is used instead of time\n * @returns {boolean} true if the midi file is not finished\n * @this {WorkletSequencer}\n */\nexport function _playTo(time, ticks = undefined)\n{\n this.oneTickToSeconds = 60 / (120 * this.midiData.timeDivision);\n // reset\n this.synth.resetAllControllers();\n if(this.sendMIDIMessages)\n {\n this.sendMIDIMessage([messageTypes.reset]);\n for(let ch = 0; ch < MIDI_CHANNEL_COUNT; ch++)\n {\n this.sendMIDIMessage([messageTypes.controllerChange | ch, midiControllers.resetAllControllers, 0]);\n }\n }\n this._resetTimers()\n\n const channelsToSave = this.synth.workletProcessorChannels.length;\n /**\n * save pitch bends here and send them only after\n * @type {number[]}\n */\n const pitchBends = Array(channelsToSave).fill(8192);\n\n /**\n * Save programs here and send them only after\n * @type {number[]}\n */\n const programs = Array(channelsToSave).fill(-1 );\n\n /**\n * Save controllers here and send them only after\n * @type {number[][]}\n */\n const savedControllers = [];\n for (let i = 0; i < channelsToSave; i++)\n {\n savedControllers.push(Array.from(defaultControllerArray));\n }\n\n while(true)\n {\n // find next event\n let trackIndex = this._findFirstEventIndex();\n let event = this.tracks[trackIndex][this.eventIndex[trackIndex]];\n if(ticks !== undefined)\n {\n if(event.ticks >= ticks)\n {\n break;\n }\n }\n else\n {\n if(this.playedTime >= time)\n {\n break;\n }\n }\n\n // skip note ons\n const info = getEvent(event.messageStatusByte);\n // Keep in mind midi ports to determine channel!!\n const channel = info.channel + (this.midiPortChannelOffsets[this.midiPorts[trackIndex]] || 0);\n switch(info.status)\n {\n // skip note messages\n case messageTypes.noteOn:\n case messageTypes.noteOff:\n case messageTypes.keySignature:\n break;\n\n // skip pitch bend\n case messageTypes.pitchBend:\n pitchBends[channel] = event.messageData[1] << 7 | event.messageData[0];\n break;\n\n case messageTypes.programChange:\n programs[channel] = event.messageData[0];\n break;\n\n case messageTypes.controllerChange:\n // do not skip data entries\n const controllerNumber = event.messageData[0];\n if(\n controllerNumber === midiControllers.dataDecrement ||\n controllerNumber === midiControllers.dataIncrement ||\n controllerNumber === midiControllers.dataEntryMsb ||\n controllerNumber === midiControllers.dataDecrement ||\n controllerNumber === midiControllers.lsbForControl6DataEntry ||\n controllerNumber === midiControllers.RPNLsb ||\n controllerNumber === midiControllers.RPNMsb ||\n controllerNumber === midiControllers.NRPNLsb ||\n controllerNumber === midiControllers.NRPNMsb ||\n controllerNumber === midiControllers.bankSelect ||\n controllerNumber === midiControllers.lsbForControl0BankSelect||\n controllerNumber === midiControllers.resetAllControllers\n )\n {\n if(this.sendMIDIMessages)\n {\n this.sendMIDIMessage([messageTypes.controllerChange | (channel % 16), controllerNumber, event.messageData[1]])\n }\n else\n {\n let ccV = event.messageData[1];\n if(this.midiData.embeddedSoundFont !== undefined && controllerNumber === midiControllers.bankSelect)\n {\n // special case if the RMID is embedded: subtract 1 from bank. See wiki About-RMIDI\n ccV--;\n }\n this.synth.controllerChange(channel, controllerNumber, ccV);\n }\n }\n else\n {\n if(savedControllers[channel] === undefined)\n {\n savedControllers[channel] = Array.from(defaultControllerArray);\n }\n savedControllers[channel][controllerNumber] = event.messageData[1];\n }\n break;\n\n default:\n this._processEvent(event, trackIndex);\n break;\n }\n\n this.eventIndex[trackIndex]++;\n // find next event\n trackIndex = this._findFirstEventIndex();\n let nextEvent = this.tracks[trackIndex][this.eventIndex[trackIndex]];\n if(nextEvent === undefined)\n {\n this.stop();\n return false;\n }\n this.playedTime += this.oneTickToSeconds * (nextEvent.ticks - event.ticks);\n }\n\n // restoring saved controllers\n if(this.sendMIDIMessages)\n {\n // for all 16 channels\n for (let channelNumber = 0; channelNumber < channelsToSave; channelNumber++) {\n // send saved pitch bend\n this.sendMIDIMessage([messageTypes.pitchBend | (channelNumber % 16), pitchBends[channelNumber] & 0x7F, pitchBends[channelNumber] >> 7]);\n\n // every controller that has changed\n savedControllers[channelNumber].forEach((value, index) => {\n if(value !== defaultControllerArray[index])\n {\n this.sendMIDIMessage([messageTypes.controllerChange | (channelNumber % 16), index, value])\n }\n });\n\n // restore programs\n if(programs[channelNumber] !== 0)\n {\n this.sendMIDIMessage([messageTypes.programChange | (channelNumber % 16), programs[channelNumber]]);\n }\n }\n }\n else\n {\n // for all synth channels\n for (let channelNumber = 0; channelNumber < channelsToSave; channelNumber++)\n {\n // restore pitch bends\n if(pitchBends[channelNumber] !== undefined)\n {\n this.synth.pitchWheel(channelNumber, pitchBends[channelNumber] >> 7, pitchBends[channelNumber] & 0x7F);\n }\n if(savedControllers[channelNumber] !== undefined)\n {\n // every controller that has changed\n savedControllers[channelNumber].forEach((value, index) => {\n if(value !== defaultControllerArray[index])\n {\n this.synth.controllerChange(channelNumber, index, value);\n }\n })\n }\n // restore programs\n if(programs[channelNumber] !== -1)\n {\n this.synth.programChange(channelNumber, programs[channelNumber]);\n }\n }\n }\n return true;\n}\n\n/**\n * Starts the playback\n * @param resetTime {boolean} If true, time is set to 0s\n * @this {WorkletSequencer}\n */\nexport function play(resetTime = false)\n{\n if(this.midiData === undefined)\n {\n return;\n }\n\n // reset the time if necesarry\n if(resetTime)\n {\n this.currentTime = 0;\n return;\n }\n\n if(this.currentTime >= this.duration)\n {\n this.currentTime = 0;\n return;\n }\n\n // unpause if paused\n if(this.paused)\n {\n // adjust the start time\n this._recalculateStartTime(this.pausedTime)\n this.pausedTime = undefined;\n }\n if(!this.sendMIDIMessages)\n {\n const time = this.currentTime;\n this.playingNotes.forEach(n => {\n const timeOffset = n.startTime - time;\n this.synth.noteOn(n.channel, n.midiNote, n.velocity, false, true, currentTime + timeOffset);\n });\n }\n this.setProcessHandler();\n}\n\n/**\n * Coverts ticks to time in seconds\n * @param changes {{tempo: number, ticks: number}[]}\n * @param ticks {number}\n * @param division {number}\n * @returns {number}\n */\nexport function ticksToSeconds(changes, ticks, division)\n{\n if (ticks <= 0) {\n return 0;\n }\n\n // find the last tempo change that has occured\n let tempo = changes.find(v => v.ticks < ticks);\n\n let timeSinceLastTempo = ticks - tempo.ticks;\n return ticksToSeconds(changes, ticks - timeSinceLastTempo, division) + (timeSinceLastTempo * 60) / (tempo.tempo * division);\n}\n\n/**\n * @this {WorkletSequencer}\n * @param ticks {number}\n */\nexport function setTimeTicks(ticks)\n{\n this.stop();\n this.playingNotes = [];\n this.pausedTime = undefined;\n this.post(\n WorkletSequencerReturnMessageType.timeChange,\n currentTime - ticksToSeconds(this.midiData.tempoChanges, ticks, this.midiData.timeDivision)\n );\n const isNotFinished = this._playTo(0, ticks);\n this._recalculateStartTime(this.playedTime);\n if(!isNotFinished)\n {\n return;\n }\n this.play();\n}\n\n/**\n * @param time\n * @private\n * @this {WorkletSequencer}\n */\nexport function _recalculateStartTime(time)\n{\n this.absoluteStartTime = currentTime - time / this._playbackRate;\n}", "/**\n * A simplified version of the MIDI, accessible at all times from the Sequencer. use getMIDI() to get the actual sequence\n * This class contains all properties that MIDI does, except for tracks, which is the track data.\n */\nexport class MidiData\n{\n /**\n * @param midi {MIDI}\n */\n constructor(midi)\n {\n /**\n * The time division of the sequence\n * @type {number}\n */\n this.timeDivision = midi.timeDivision;\n /**\n * The duration of the sequence, in seconds\n * @type {number}\n */\n this.duration = midi.duration;\n /**\n * The tempo changes in the sequence, ordered from last to first\n * @type {{ticks: number, tempo: number}[]}\n */\n this.tempoChanges = midi.tempoChanges;\n /**\n * Contains the copyright strings\n * @type {string}\n */\n this.copyright = midi.copyright;\n\n /**\n * The amount of tracks in the sequence\n * @type {number}\n */\n this.tracksAmount = midi.tracksAmount;\n\n /**\n * The lyrics of the sequence as binary chunks\n * @type {Uint8Array[]}\n */\n this.lyrics = midi.lyrics;\n\n this.firstNoteOn = midi.firstNoteOn;\n\n /**\n * The MIDI's key range\n * @type {{min: number, max: number}}\n */\n this.keyRange = midi.keyRange;\n\n /**\n * The last voice (note on, off, cc change etc.) event tick\n * @type {number}\n */\n this.lastVoiceEventTick = midi.lastVoiceEventTick;\n\n /**\n * Midi port numbers for each track\n * @type {number[]}\n */\n this.midiPorts = midi.midiPorts;\n\n /**\n * Channel offsets for each port, using the SpessaSynth method\n * @type {number[]}\n */\n this.midiPortChannelOffsets = midi.midiPortChannelOffsets;\n\n /**\n * All channels that each track uses\n * @type {Set<number>[]}\n */\n this.usedChannelsOnTrack = midi.usedChannelsOnTrack;\n\n /**\n * The loop points (in ticks) of the sequence\n * @type {{start: number, end: number}}\n */\n this.loop = midi.loop;\n\n /**\n * The sequence's name\n * @type {string}\n */\n this.midiName = midi.midiName;\n\n /**\n * The file name of the sequence, if provided in the MIDI class\n * @type {string}\n */\n this.fileName = midi.fileName;\n\n /**\n * The raw, encoded MIDI name.\n * @type {Uint8Array}\n */\n this.rawMidiName = midi.rawMidiName;\n }\n}\n\n/**\n *\n * @type {MidiData}\n */\nexport const DUMMY_MIDI_DATA = {\n duration: 99999,\n firstNoteOn: 0,\n loop: {\n start: 0,\n end: 123456\n },\n\n lastVoiceEventTick: 123456,\n lyrics: [],\n copyright: \"\",\n midiPorts: [],\n midiPortChannelOffsets: [],\n tracksAmount: 0,\n tempoChanges: [{ticks: 0, tempo: 120}],\n fileName: \"NOT_LOADED.mid\",\n midiName: \"Loading...\",\n rawMidiName: new Uint8Array([76, 111, 97, 100, 105, 110, 103, 46, 46, 46]), // \"Loading...\"\n usedChannelsOnTrack: [],\n timeDivision: 0,\n keyRange: {min: 0, max: 127}\n};", "/**\n * Reads VLQ From a MIDI byte array\n * @param MIDIbyteArray {IndexedByteArray}\n * @returns {number}\n */\nexport function readVariableLengthQuantity(MIDIbyteArray) {\n let out = 0\n while (MIDIbyteArray) {\n const byte = MIDIbyteArray[MIDIbyteArray.currentIndex++]\n // extract the first 7 bytes\n out = (out << 7) | (byte & 127)\n\n // if the last byte isn't 1, stop reading\n if ((byte >> 7) !== 1) {\n break\n }\n }\n return out\n}\n\n/**\n * Write a VLQ from a number to a byte array\n * @param number {number}\n * @returns {number[]}\n */\nexport function writeVariableLengthQuantity(number) {\n // Add the first byte\n let bytes = [number & 127]\n number >>= 7\n\n // Continue processing the remaining bytes\n while (number > 0) {\n bytes.unshift((number & 127) | 128)\n number >>= 7\n }\n return bytes\n}", "import { dataBytesAmount, getChannel, messageTypes, MidiMessage } from './midi_message.js'\nimport { IndexedByteArray } from '../utils/indexed_array.js'\nimport { arrayToHexString, consoleColors, formatTitle } from '../utils/other.js'\nimport { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd, SpessaSynthInfo } from '../utils/loggin.js'\nimport { readRIFFChunk } from '../soundfont/read/riff_chunk.js'\nimport { readVariableLengthQuantity } from '../utils/byte_functions/variable_length_quantity.js'\nimport { readBytesAsUintBigEndian } from '../utils/byte_functions/big_endian.js'\nimport { readBytesAsString } from '../utils/byte_functions/string.js'\n\n/**\n * midi_loader.js\n * purpose: parses a midi file for the seqyencer, including things like marker or CC 2/4 loop detection, copyright detection etc.\n */\nclass MIDI{\n /**\n * Parses a given midi file\n * @param arrayBuffer {ArrayBuffer}\n * @param fileName {string} optional, replaces the decoded title if empty\n */\n constructor(arrayBuffer, fileName=\"\") {\n SpessaSynthGroupCollapsed(`%cParsing MIDI File...`, consoleColors.info);\n const binaryData = new IndexedByteArray(arrayBuffer);\n let fileByteArray;\n\n // check for rmid\n /**\n * If the RMI file has an embedded sf2 in it, it will appeear here, otherwise undefined\n * @type {ArrayBuffer}\n */\n this.embeddedSoundFont = undefined;\n\n /**\n * Contains the copyright strings\n * @type {string}\n */\n this.copyright = \"\";\n\n const initialString = readBytesAsString(binaryData, 4);\n binaryData.currentIndex -= 4;\n if(initialString === \"RIFF\")\n {\n // possibly an RMID file (https://web.archive.org/web/20110610135604/http://www.midi.org/about-midi/rp29spec(rmid).pdf)\n // skip size\n binaryData.currentIndex += 8;\n const rmid = readBytesAsString(binaryData, 4, undefined, false);\n if(rmid !== \"RMID\")\n {\n SpessaSynthGroupEnd();\n throw new SyntaxError(`Invalid RMIDI Header! Expected \"RMID\", got \"${rmid}\"`);\n }\n const riff = readRIFFChunk(binaryData);\n if(riff.header !== 'data')\n {\n SpessaSynthGroupEnd();\n throw new SyntaxError(`Invalid RMIDI Chunk header! Expected \"data\", got \"${rmid}\"`);\n }\n // this is an rmid, load the midi into array for parsing\n fileByteArray = riff.chunkData;\n\n // keep loading chunks until we get sfbk\n while(binaryData.currentIndex <= binaryData.length)\n {\n const startIndex = binaryData.currentIndex;\n const currentChunk = readRIFFChunk(binaryData, true);\n if(currentChunk.header === \"RIFF\")\n {\n const type = readBytesAsString(currentChunk.chunkData, 4);\n if(type === \"sfbk\")\n {\n SpessaSynthInfo(\"%cFound embedded soundfont!\", consoleColors.recognized);\n this.embeddedSoundFont = binaryData.slice(startIndex, startIndex + currentChunk.size).buffer;\n }\n }\n }\n }\n else\n {\n fileByteArray = binaryData;\n }\n const headerChunk = this.readMIDIChunk(fileByteArray);\n if(headerChunk.type !== \"MThd\")\n {\n SpessaSynthGroupEnd();\n throw new SyntaxError(`Invalid MIDI Header! Expected \"MThd\", got \"${headerChunk.type}\"`);\n }\n\n if(headerChunk.size !== 6)\n {\n SpessaSynthGroupEnd();\n throw new RangeError(`Invalid MIDI header chunk size! Expected 6, got ${headerChunk.size}`);\n }\n\n // format\n this.format = readBytesAsUintBigEndian(headerChunk.data, 2);\n // tracks count\n this.tracksAmount = readBytesAsUintBigEndian(headerChunk.data, 2);\n // time division\n this.timeDivision = readBytesAsUintBigEndian(headerChunk.data, 2);\n\n /**\n * The MIDI's key range\n * @type {{min: number, max: number}}\n */\n this.keyRange = {min: 127, max: 0};\n\n /**\n * Contains the lyrics as binary chunks\n * @type {Uint8Array[]}\n */\n this.lyrics = [];\n\n /**\n * Contains all the tempo changes in the file. (Ordered from last to first)\n * @type {{\n * ticks: number,\n * tempo: number\n * }[]}\n */\n this.tempoChanges = [{ticks: 0, tempo: 120}];\n\n let loopStart = null;\n let loopEnd = null;\n\n this.lastVoiceEventTick = 0;\n\n /**\n * Midi port numbers for each tracks\n * @type {number[]}\n */\n this.midiPorts = [];\n\n let portOffset = 0\n /**\n * Channel offsets for each port, using the SpessaSynth method\n * @type {number[]}\n */\n this.midiPortChannelOffsets = [];\n\n /**\n * All channels that each track uses. Note: these channels range from 0 to 15, excluding the port offsets!\n * @type {Set<number>[]}\n */\n this.usedChannelsOnTrack = [];\n\n /**\n * Read all the tracks\n * @type {MidiMessage[][]}\n */\n this.tracks = [];\n for(let i = 0; i < this.tracksAmount; i++)\n {\n /**\n * @type {MidiMessage[]}\n */\n const track = [];\n const trackChunk = this.readMIDIChunk(fileByteArray);\n const usedChannels = new Set();\n this.midiPorts.push(-1);\n\n if(trackChunk.type !== \"MTrk\")\n {\n SpessaSynthGroupEnd();\n throw new SyntaxError(`Invalid track header! Expected \"MTrk\" got \"${trackChunk.type}\"`);\n }\n\n /**\n * MIDI running byte\n * @type {number}\n */\n let runningByte = undefined;\n\n let totalTicks = 0;\n // format 2 plays sequentially\n if(this.format === 2 && i > 0)\n {\n totalTicks += this.tracks[i - 1][this.tracks[i - 1].length - 1].ticks;\n }\n // loop until we reach the end of track\n while(trackChunk.data.currentIndex < trackChunk.size)\n {\n totalTicks += readVariableLengthQuantity(trackChunk.data);\n\n // check if the status byte is valid (IE. larger than 127)\n const statusByteCheck = trackChunk.data[trackChunk.data.currentIndex];\n\n let statusByte;\n // if we have a running byte and the status byte isn't valid\n if(runningByte !== undefined && statusByteCheck < 0x80)\n {\n statusByte = runningByte;\n }\n else if(!runningByte && statusByteCheck < 0x80)\n {\n // if we don't have a running byte and the status byte isn't valid, it's an error.\n SpessaSynthGroupEnd();\n throw new SyntaxError(`Unexpected byte with no running byte. (${statusByteCheck})`);\n }\n else\n {\n // if the status byte is valid, just use that\n statusByte = trackChunk.data[trackChunk.data.currentIndex++];\n }\n const statusByteChannel = getChannel(statusByte);\n\n let eventDataLength;\n\n // determine the message's length;\n switch(statusByteChannel)\n {\n case -1:\n // system common/realtime (no length)\n eventDataLength = 0;\n break;\n\n case -2:\n // meta (the next is the actual status byte)\n statusByte = trackChunk.data[trackChunk.data.currentIndex++];\n eventDataLength = readVariableLengthQuantity(trackChunk.data);\n break;\n\n case -3:\n // sysex\n eventDataLength = readVariableLengthQuantity(trackChunk.data);\n break;\n\n default:\n // voice message\n // get the midi message length\n if(totalTicks > this.lastVoiceEventTick)\n {\n this.lastVoiceEventTick = totalTicks;\n }\n eventDataLength = dataBytesAmount[statusByte >> 4];\n if((statusByte & 0xF0) === messageTypes.noteOn)\n {\n usedChannels.add(statusByteChannel);\n const note = trackChunk.data[trackChunk.data.currentIndex]\n this.keyRange.min = Math.min(this.keyRange.min, note);\n this.keyRange.max = Math.max(this.keyRange.max, note);\n }\n\n // save the status byte\n runningByte = statusByte;\n break;\n }\n\n // put the event data into the array\n const eventData = new IndexedByteArray(eventDataLength);\n const messageData = trackChunk.data.slice(trackChunk.data.currentIndex, trackChunk.data.currentIndex + eventDataLength);\n trackChunk.data.currentIndex += eventDataLength;\n eventData.set(messageData, 0);\n\n const message = new MidiMessage(totalTicks, statusByte, eventData);\n track.push(message);\n\n switch(statusByteChannel)\n {\n case -2:\n // since this is a meta message\n switch(statusByte)\n {\n case messageTypes.setTempo:\n // add the tempo change\n this.tempoChanges.push({\n ticks: totalTicks,\n tempo: 60000000 / readBytesAsUintBigEndian(messageData, 3)\n });\n break;\n\n case messageTypes.marker:\n // check for loop markers\n const text = readBytesAsString(eventData, eventData.length).trim().toLowerCase();\n switch (text)\n {\n default:\n break;\n\n case \"start\":\n case \"loopstart\":\n loopStart = totalTicks;\n break;\n\n case \"loopend\":\n loopEnd = totalTicks;\n }\n eventData.currentIndex = 0;\n break;\n\n case messageTypes.midiPort:\n const port = eventData[0];\n this.midiPorts[i] = port;\n if(this.midiPortChannelOffsets[port] === undefined)\n {\n this.midiPortChannelOffsets[port] = portOffset;\n portOffset += 16;\n }\n break;\n\n case messageTypes.copyright:\n this.copyright += readBytesAsString(eventData, eventData.length) + \"\\n\";\n break;\n\n case messageTypes.lyric:\n this.lyrics.push(eventData);\n }\n break;\n\n case -3:\n // since this is a sysex message\n // check for embedded copyright (roland SC display sysex) http://www.bandtrax.com.au/sysex.htm\n // header goes like this: 41 10 45 12 10 00 00\n if(arrayToHexString(eventData.slice(0, 7)).trim() === \"41 10 45 12 10 00 00\")\n {\n /**\n * @type {IndexedByteArray}\n */\n const cutText = eventData.slice(7, messageData.length - 3);\n const decoded = readBytesAsString(cutText, cutText.length) + \"\\n\";\n this.copyright += decoded;\n SpessaSynthInfo(`%cDecoded Roland SC message! %c${decoded}`,\n consoleColors.recognized,\n consoleColors.value)\n }\n break;\n\n\n default:\n // since this is a voice message\n // check for loop (CC 2/4)\n if((statusByte & 0xF0) === messageTypes.controllerChange)\n {\n switch(eventData[0])\n {\n case 2:\n case 116:\n loopStart = totalTicks;\n break;\n\n case 4:\n case 117:\n if(loopEnd === null)\n {\n loopEnd = totalTicks;\n }\n else\n {\n // this controller has occured more than once, this means that it doesnt indicate the loop\n loopEnd = 0;\n }\n break;\n }\n }\n }\n }\n this.tracks.push(track);\n this.usedChannelsOnTrack.push(usedChannels);\n SpessaSynthInfo(`%cParsed %c${this.tracks.length}%c / %c${this.tracksAmount}`,\n consoleColors.info,\n consoleColors.value,\n consoleColors.info,\n consoleColors.value);\n }\n\n const firstNoteOns = [];\n for(const t of this.tracks)\n {\n const firstNoteOn = t.find(e => (e.messageStatusByte & 0xF0) === messageTypes.noteOn);\n if(firstNoteOn)\n {\n firstNoteOns.push(firstNoteOn.ticks);\n }\n }\n this.firstNoteOn = Math.min(...firstNoteOns);\n\n SpessaSynthInfo(`%cMIDI file parsed. Total tick time: %c${this.lastVoiceEventTick}`,\n consoleColors.info,\n consoleColors.recognized);\n SpessaSynthGroupEnd();\n \n if(loopStart !== null && loopEnd === null)\n {\n // not a loop\n loopStart = this.firstNoteOn;\n loopEnd = this.lastVoiceEventTick;\n }\n else {\n if (loopStart === null) {\n loopStart = this.firstNoteOn;\n }\n\n if (loopEnd === null || loopEnd === 0) {\n loopEnd = this.lastVoiceEventTick;\n }\n }\n\n // fix midi ports:\n // midi tracks without ports will have a value of -1\n // if all ports have a value of -1, set it to 0, otherwise take the first midi port and replace all -1 with it\n // why do this? some midis (for some reason) specify all channels to port 1 or else, but leave the conductor track with no port pref.\n // this spessasynth to reserve the first 16 channels for the conductor track (which doesn't play anything) and use additional 16 for the actual ports.\n let defaultPort = 0;\n for(let port of this.midiPorts)\n {\n if(port !== -1)\n {\n defaultPort = port;\n break;\n }\n }\n this.midiPorts = this.midiPorts.map(port => port === -1 ? defaultPort : port);\n // add dummy port if empty\n if(this.midiPortChannelOffsets.length === 0)\n {\n this.midiPortChannelOffsets = [0];\n }\n\n /**\n *\n * @type {{start: number, end: number}}\n */\n this.loop = {start: loopStart, end: loopEnd};\n\n // get track name\n this.midiName = \"\";\n\n this.rawMidiName = new Uint8Array(0);\n\n // midi name\n if(this.tracks.length > 1)\n {\n // if more than 1 track and the first track has no notes, just find the first trackName in the first track\n if(this.tracks[0].find(\n message => message.messageStatusByte >= messageTypes.noteOn\n &&\n message.messageStatusByte < messageTypes.systemExclusive\n ) === undefined)\n {\n let name = this.tracks[0].find(message => message.messageStatusByte === messageTypes.trackName);\n if(name)\n {\n this.rawMidiName = name.messageData;\n this.midiName = readBytesAsString(name.messageData, name.messageData.length, undefined, false);\n }\n }\n }\n else\n {\n // if only 1 track, find the first \"track name\" event\n let name = this.tracks[0].find(message => message.messageStatusByte === messageTypes.trackName);\n if(name)\n {\n this.rawMidiName = name.messageData;\n this.midiName = readBytesAsString(name.messageData, name.messageData.length, undefined, false);\n }\n }\n\n this.fileName = fileName;\n this.midiName = this.midiName.trim();\n // if midiName is \"\", use the file name\n if(this.midiName.length === 0)\n {\n this.midiName = formatTitle(fileName);\n // encode it too\n this.rawMidiName = new Uint8Array(this.midiName.length);\n for(let i = 0; i < this.midiName.length; i++)\n {\n this.rawMidiName[i] = this.midiName.charCodeAt(i);\n }\n }\n\n // reverse the tempo changes\n this.tempoChanges.reverse();\n\n /**\n * The total playback time, in seconds\n * @type {number}\n */\n this.duration = this._ticksToSeconds(this.lastVoiceEventTick);\n }\n\n /**\n * @param fileByteArray {IndexedByteArray}\n * @returns {{type: string, size: number, data: IndexedByteArray}}\n */\n readMIDIChunk(fileByteArray)\n {\n const chunk = {};\n // type\n chunk.type = readBytesAsString(fileByteArray, 4);\n // size\n chunk.size = readBytesAsUintBigEndian(fileByteArray, 4);\n // data\n chunk.data = new IndexedByteArray(chunk.size);\n const dataSlice = fileByteArray.slice(fileByteArray.currentIndex, fileByteArray.currentIndex + chunk.size);\n chunk.data.set(dataSlice, 0);\n fileByteArray.currentIndex += chunk.size;\n return chunk;\n }\n\n\n /**\n * Coverts ticks to time in seconds\n * @param ticks {number}\n * @returns {number}\n * @private\n */\n _ticksToSeconds(ticks)\n {\n if (ticks <= 0) {\n return 0;\n }\n\n // find the last tempo change that has occured\n let tempo = this.tempoChanges.find(v => v.ticks < ticks);\n\n let timeSinceLastTempo = ticks - tempo.ticks;\n return this._ticksToSeconds(ticks - timeSinceLastTempo) + (timeSinceLastTempo * 60) / (tempo.tempo * this.timeDivision);\n }\n}\nexport { MIDI }", "import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd, SpessaSynthInfo } from '../utils/loggin.js'\nimport { consoleColors } from '../utils/other.js'\nimport { DEFAULT_PERCUSSION } from '../synthetizer/synthetizer.js'\nimport { messageTypes, midiControllers } from './midi_message.js'\n\n/**\n * @param mid {MIDI}\n * @param soundfont {SoundFont2}\n */\nexport function getUsedProgramsAndKeys(mid, soundfont)\n{\n SpessaSynthGroupCollapsed(\"%cSearching for all used programs and keys...\",\n consoleColors.info);\n // find every bank:program combo and every key:velocity for each. Make sure to care about ports and drums\n const channelsAmount = 16 + Math.max.apply(undefined, mid.midiPortChannelOffsets);\n /**\n * @type {{program: number, bank: number, drums: boolean, string: string}[]}\n */\n const channelPresets = [];\n for (let i = 0; i < channelsAmount; i++) {\n const bank = i % 16 === DEFAULT_PERCUSSION ? 128 : 0;\n channelPresets.push({\n program: 0,\n bank: bank,\n drums: i % 16 === DEFAULT_PERCUSSION, // drums appear on 9 every 16 channels,\n string: `${bank}:0`,\n });\n }\n\n function updateString(ch)\n {\n // check if this exists in the soundfont\n let exists = soundfont.getPreset(ch.bank, ch.program);\n if(exists.bank !== ch.bank && mid.embeddedSoundFont)\n {\n // maybe it doesn't exists becase RMIDI has a bank shift?\n exists = soundfont.getPreset(ch.bank - 1, ch.program);\n }\n ch.bank = exists.bank;\n ch.program = exists.program;\n ch.string = ch.bank + \":\" + ch.program;\n if(!usedProgramsAndKeys[ch.string])\n {\n SpessaSynthInfo(`%cDetected a new preset: %c${ch.string}`,\n consoleColors.info,\n consoleColors.recognized);\n usedProgramsAndKeys[ch.string] = new Set();\n }\n }\n /**\n * find all programs used and key-velocity combos in them\n * bank:program each has a set of midiNote-velocity\n * @type {Object<string, Set<string>>}\n */\n const usedProgramsAndKeys = {};\n\n /**\n * indexes for tracks\n * @type {number[]}\n */\n const eventIndexes = Array(mid.tracks.length).fill(0);\n let remainingTracks = mid.tracks.length;\n function findFirstEventIndex()\n {\n let index = 0;\n let ticks = Infinity;\n mid.tracks.forEach((track, i) => {\n if(eventIndexes[i] >= track.length)\n {\n return;\n }\n if(track[eventIndexes[i]].ticks < ticks)\n {\n index = i;\n ticks = track[eventIndexes[i]].ticks;\n }\n });\n return index;\n }\n const ports = mid.midiPorts.slice();\n // check for xg\n let system = \"gs\";\n while(remainingTracks > 0)\n {\n let trackNum = findFirstEventIndex();\n const track = mid.tracks[trackNum];\n if(eventIndexes[trackNum] >= track.length)\n {\n remainingTracks--;\n continue;\n }\n const event = track[eventIndexes[trackNum]];\n eventIndexes[trackNum]++;\n\n if(event.messageStatusByte === messageTypes.midiPort)\n {\n ports[trackNum] = event.messageData[0];\n continue;\n }\n const status = event.messageStatusByte & 0xF0;\n if(\n status !== messageTypes.noteOn &&\n status !== messageTypes.controllerChange &&\n status !== messageTypes.programChange &&\n status !== messageTypes.systemExclusive\n )\n {\n continue;\n }\n const channel = (event.messageStatusByte & 0xF) + mid.midiPortChannelOffsets[ports[trackNum]] || 0;\n let ch = channelPresets[channel];\n switch(status)\n {\n case messageTypes.programChange:\n ch.program = event.messageData[0];\n updateString(ch);\n break;\n\n case messageTypes.controllerChange:\n if(event.messageData[0] !== midiControllers.bankSelect)\n {\n // we only care about bank select\n continue;\n }\n if(system === \"gs\" && ch.drums)\n {\n // gs drums get changed via sysex, ignore here\n continue;\n }\n const bank = event.messageData[1];\n if(system === \"xg\")\n {\n // check for xg drums\n const drumsBool = bank === 120 || bank === 126 || bank === 127;\n if(drumsBool !== ch.drums)\n {\n // drum change is a program change\n ch.drums = drumsBool;\n ch.bank = ch.drums ? 128 : bank;\n updateString(ch);\n }\n else\n {\n ch.bank = ch.drums ? 128 : bank;\n }\n continue;\n }\n channelPresets[channel].bank = bank;\n // do not update the data, bank change doesnt change the preset\n break;\n\n case messageTypes.noteOn:\n if(event.messageData[1] === 0)\n {\n // that's a note off\n continue;\n }\n usedProgramsAndKeys[ch.string].add(`${event.messageData[0]}-${event.messageData[1]}`);\n break;\n\n case messageTypes.systemExclusive:\n // check for drum sysex\n if(\n event.messageData[0] !== 0x41 || // roland\n event.messageData[2] !== 0x42 || // GS\n event.messageData[3] !== 0x12 || // GS\n event.messageData[4] !== 0x40 || // system parameter\n (event.messageData[5] & 0x10 ) === 0 || // part parameter\n event.messageData[6] !== 0x15 // drum pars\n\n )\n {\n // check for XG\n if(\n event.messageData[0] === 0x43 && // yamaha\n event.messageData[2] === 0x4C && // sXG ON\n event.messageData[5] === 0x7E &&\n event.messageData[6] === 0x00\n )\n {\n system = \"xg\";\n }\n continue;\n }\n const sysexChannel = [9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15][event.messageData[5] & 0x0F] + mid.midiPortChannelOffsets[ports[trackNum]];\n const isDrum = !!(event.messageData[7] > 0 && event.messageData[5] >> 4);\n ch = channelPresets[sysexChannel];\n ch.drums = isDrum;\n ch.bank = isDrum ? 128 : 0;\n updateString(ch);\n break;\n\n }\n }\n for(const key of Object.keys(usedProgramsAndKeys))\n {\n if(usedProgramsAndKeys[key].size === 0)\n {\n SpessaSynthInfo(`%cDetected change but no keys for %c${key}`,\n consoleColors.info,\n consoleColors.value)\n delete usedProgramsAndKeys[key];\n }\n }\n SpessaSynthGroupEnd();\n return usedProgramsAndKeys;\n}", "import { WorkletSequencerReturnMessageType } from './sequencer_message.js'\nimport { consoleColors, formatTime } from '../../utils/other.js'\nimport { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd, SpessaSynthInfo, SpessaSynthWarn } from '../../utils/loggin.js'\nimport { ticksToSeconds } from './play.js'\nimport { MidiData } from '../../midi_parser/midi_data.js'\nimport { MIDI } from '../../midi_parser/midi_loader.js'\nimport { getUsedProgramsAndKeys } from '../../midi_parser/used_keys_loaded.js'\n\n/**\n * @param trackNum {number}\n * @param port {number}\n * @this {WorkletSequencer}\n */\nexport function assignMIDIPort(trackNum, port)\n{\n // assign new 16 channels if the port is not occupied yet\n if(this.midiPortChannelOffset === 0)\n {\n this.midiPortChannelOffset += 16;\n this.midiPortChannelOffsets[port] = 0;\n }\n\n if(this.midiPortChannelOffsets[port] === undefined)\n {\n if(this.synth.workletProcessorChannels.length < this.midiPortChannelOffset + 15)\n {\n this._addNewMidiPort();\n }\n this.midiPortChannelOffsets[port] = this.midiPortChannelOffset;\n this.midiPortChannelOffset += 16;\n }\n\n this.midiPorts[trackNum] = port;\n}\n\n/**\n * Loads a new sequence\n * @param parsedMidi {MIDI}\n * @this {WorkletSequencer}\n */\nexport function loadNewSequence(parsedMidi)\n{\n this.stop();\n if (!parsedMidi.tracks)\n {\n throw \"No tracks supplied!\";\n }\n\n this.oneTickToSeconds = 60 / (120 * parsedMidi.timeDivision)\n\n /**\n * @type {MIDI}\n */\n this.midiData = parsedMidi;\n\n // check for embedded soundfont\n if(this.midiData.embeddedSoundFont !== undefined)\n {\n this.synth.reloadSoundFont(this.midiData.embeddedSoundFont);\n // preload all samples\n this.synth.soundfont.samples.forEach(s => s.getAudioData());\n }\n else\n {\n SpessaSynthGroupCollapsed(\"%cPreloading samples...\", consoleColors.info);\n // smart preloading: load only samples used in the midi!\n const used = getUsedProgramsAndKeys(this.midiData, this.synth.soundfont);\n for (const [programBank, combos] of Object.entries(used))\n {\n const bank = parseInt(programBank.split(\":\")[0]);\n const program = parseInt(programBank.split(\":\")[1]);\n const preset = this.synth.soundfont.getPreset(bank, program);\n SpessaSynthInfo(`%cPreloading used samples on %c${preset.presetName}%c...`,\n consoleColors.info,\n consoleColors.recognized,\n consoleColors.info)\n for (const combo of combos) {\n const split = combo.split(\"-\");\n preset.preloadSpecific(parseInt(split[0]), parseInt(split[1]));\n }\n }\n SpessaSynthGroupEnd();\n }\n\n /**\n * the midi track data\n * @type {MidiMessage[][]}\n */\n this.tracks = this.midiData.tracks;\n\n // copy over the port data\n this.midiPorts = this.midiData.midiPorts;\n\n // clear last port data\n this.midiPortChannelOffset = 0;\n this.midiPortChannelOffsets = {};\n // assign port offsets\n this.midiData.midiPorts.forEach((port, trackIndex) => {\n this.assignMIDIPort(trackIndex, port);\n });\n\n /**\n * Same as Audio.duration (seconds)\n * @type {number}\n */\n this.duration = this.midiData.duration;\n this.firstNoteTime = ticksToSeconds(this.midiData.tempoChanges, this.midiData.firstNoteOn, this.midiData.timeDivision);\n SpessaSynthInfo(`%cTotal song time: ${formatTime(Math.ceil(this.duration)).time}`, consoleColors.recognized);\n\n this.post(WorkletSequencerReturnMessageType.songChange, [new MidiData(this.midiData), this.songIndex]);\n\n this.synth.resetAllControllers();\n if(this.duration <= 1)\n {\n SpessaSynthWarn(`%cVery short song: (${formatTime(Math.round(this.duration)).time}). Disabling loop!`,\n consoleColors.warn);\n this.loop = false;\n }\n this.play(true);\n}\n\n/**\n * @param midiBuffers {MIDIFile[]}\n * @this {WorkletSequencer}\n */\nexport function loadNewSongList(midiBuffers)\n{\n /**\n * parse the MIDIs (only the array buffers, MIDI is unchanged)\n * @type {MIDI[]}\n */\n this.songs = midiBuffers.reduce((mids, b) => {\n if(b.duration)\n {\n mids.push(b);\n return mids;\n }\n try\n {\n mids.push(new MIDI(b.binary, b.altName || \"\"));\n }\n catch (e)\n {\n this.post(WorkletSequencerReturnMessageType.midiError, e.message);\n return mids;\n }\n return mids;\n }, []);\n if(this.songs.length < 1)\n {\n console.log(\"no valid songs!\")\n return;\n }\n this.songIndex = 0;\n if(this.songs.length > 1)\n {\n this.loop = false;\n }\n this.loadNewSequence(this.songs[this.songIndex]);\n}\n\n/**\n * @this {WorkletSequencer}\n */\nexport function nextSong()\n{\n if(this.songs.length === 1)\n {\n this.currentTime = 0;\n return;\n }\n this.songIndex++;\n this.songIndex %= this.songs.length;\n this.loadNewSequence(this.songs[this.songIndex]);\n}\n\n/**\n * @this {WorkletSequencer}\n */\nexport function previousSong()\n{\n if(this.songs.length === 1)\n {\n this.currentTime = 0;\n return;\n }\n this.songIndex--;\n if(this.songIndex < 0)\n {\n this.songIndex = this.songs.length - 1;\n }\n this.loadNewSequence(this.songs[this.songIndex]);\n}", "import { returnMessageType } from '../../synthetizer/worklet_system/message_protocol/worklet_message.js'\nimport { WorkletSequencerMessageType, WorkletSequencerReturnMessageType } from './sequencer_message.js'\n\n/**\n * @param messageType {WorkletSequencerMessageType}\n * @param messageData {any}\n * @this {WorkletSequencer}\n */\nexport function processMessage(messageType, messageData)\n{\n switch (messageType)\n {\n default:\n break;\n\n case WorkletSequencerMessageType.loadNewSongList:\n this.loadNewSongList(messageData);\n break;\n\n case WorkletSequencerMessageType.pause:\n this.pause();\n break;\n\n case WorkletSequencerMessageType.play:\n this.play(messageData);\n break;\n\n case WorkletSequencerMessageType.stop:\n this.stop();\n break;\n\n case WorkletSequencerMessageType.setTime:\n this.currentTime = messageData;\n break;\n\n case WorkletSequencerMessageType.changeMIDIMessageSending:\n this.sendMIDIMessages = messageData;\n break;\n\n case WorkletSequencerMessageType.setPlaybackRate:\n this.playbackRate = messageData;\n break;\n\n case WorkletSequencerMessageType.setLoop:\n this.loop = messageData;\n break;\n\n case WorkletSequencerMessageType.changeSong:\n if (messageData)\n {\n this.nextSong();\n }\n else\n {\n this.previousSong();\n }\n break;\n\n case WorkletSequencerMessageType.getMIDI:\n this.post(WorkletSequencerReturnMessageType.getMIDI, this.midiData);\n }\n}\n\n/**\n *\n * @param messageType {WorkletSequencerReturnMessageType}\n * @param messageData {any}\n * @this {WorkletSequencer}\n */\nexport function post(messageType, messageData = undefined)\n{\n if(!this.synth.enableEventSystem)\n {\n return;\n }\n this.synth.post({\n messageType: returnMessageType.sequencerSpecific,\n messageData: {\n messageType: messageType,\n messageData: messageData\n }\n })\n}\n\n/**\n * @param message {number[]}\n * @this {WorkletSequencer}\n */\nexport function sendMIDIMessage(message)\n{\n this.post(WorkletSequencerReturnMessageType.midiEvent, message);\n}", "import { WorkletSequencerReturnMessageType } from './sequencer_message.js'\nimport { _addNewMidiPort, _processEvent } from './process_event.js'\nimport { _findFirstEventIndex, _processTick } from './process_tick.js'\nimport { assignMIDIPort, loadNewSequence, loadNewSongList, nextSong, previousSong } from './song_control.js'\nimport { _playTo, _recalculateStartTime, play, setTimeTicks } from './play.js'\nimport { messageTypes, midiControllers } from '../../midi_parser/midi_message.js'\nimport { post, processMessage, sendMIDIMessage } from './events.js'\nimport { SpessaSynthWarn } from '../../utils/loggin.js'\nimport { MIDI_CHANNEL_COUNT } from '../../synthetizer/synthetizer.js'\n\nclass WorkletSequencer\n{\n /**\n * @param spessasynthProcessor {SpessaSynthProcessor}\n */\n constructor(spessasynthProcessor)\n {\n this.synth = spessasynthProcessor;\n this.ignoreEvents = false;\n\n /**\n * If the event should instead be sent back to the main thread instead of synth\n * @type {boolean}\n */\n this.sendMIDIMessages = false;\n\n // event's number in this.events\n /**\n * @type {number[]}\n */\n this.eventIndex = [];\n this.songIndex = 0;\n\n // tracks the time that we have already played\n /**\n * @type {number}\n */\n this.playedTime = 0;\n\n /**\n * The (relative) time when the sequencer was paused. If it's not paused then it's undefined.\n * @type {number}\n */\n this.pausedTime = undefined;\n\n /**\n * Absolute playback startTime, bases on the synth's time\n * @type {number}\n */\n this.absoluteStartTime = currentTime;\n\n /**\n * Controls the playback's rate\n * @type {number}\n */\n this._playbackRate = 1;\n\n /**\n * Currently playing notes (for pausing and resuming)\n * @type {{\n * midiNote: number,\n * channel: number,\n * velocity: number,\n * startTime: number\n * }[]}\n */\n this.playingNotes = [];\n\n // controls if the sequencer loops (defaults to true)\n this.loop = true;\n\n /**\n * the current track data\n * @type {MIDI}\n */\n this.midiData = undefined;\n\n /**\n * midi port number for the corresponding track\n * @type {number[]}\n */\n this.midiPorts = [];\n\n this.midiPortChannelOffset = 0;\n\n /**\n * midi port: channel offset\n * @type {Object<number, number>}\n */\n this.midiPortChannelOffsets = {};\n }\n\n /**\n * @param value {number}\n */\n set playbackRate(value)\n {\n const time = this.currentTime;\n this._playbackRate = value;\n this.currentTime = time;\n }\n\n get currentTime()\n {\n // return the paused time if it's set to something other than undefined\n if(this.pausedTime)\n {\n return this.pausedTime;\n }\n\n return (currentTime - this.absoluteStartTime) * this._playbackRate;\n }\n\n set currentTime(time)\n {\n if(time < this.firstNoteTime || time > this.duration)\n {\n // time is 0\n this.setTimeTicks(this.midiData.firstNoteOn - 1);\n return;\n }\n this.stop();\n this.playingNotes = [];\n this.pausedTime = undefined;\n this.post(WorkletSequencerReturnMessageType.timeChange, currentTime - time);\n const isNotFinished = this._playTo(time);\n this._recalculateStartTime(time);\n if(!isNotFinished)\n {\n return;\n }\n this.play();\n }\n\n /**\n * Pauses the playback\n * @param isFinished {boolean}\n */\n pause(isFinished = false)\n {\n if(this.paused)\n {\n SpessaSynthWarn(\"Already paused\");\n return;\n }\n this.pausedTime = this.currentTime;\n this.stop();\n this.post(WorkletSequencerReturnMessageType.pause, isFinished);\n }\n\n /**\n * Stops the playback\n */\n stop()\n {\n this.clearProcessHandler()\n // disable sustain\n for (let i = 0; i < 16; i++) {\n this.synth.controllerChange(i, midiControllers.sustainPedal, 0);\n }\n this.synth.stopAllChannels();\n if(this.sendMIDIMessages)\n {\n for (let c = 0; c < MIDI_CHANNEL_COUNT; c++)\n {\n this.sendMIDIMessage([messageTypes.controllerChange | c, 120, 0]); // all notes off\n this.sendMIDIMessage([messageTypes.controllerChange | c, 123, 0]); // all sound off\n }\n }\n }\n\n _resetTimers()\n {\n this.playedTime = 0\n this.eventIndex = Array(this.tracks.length).fill(0);\n }\n\n /**\n * true if paused, false if playing or stopped\n * @returns {boolean}\n */\n get paused()\n {\n return this.pausedTime !== undefined;\n }\n\n setProcessHandler()\n {\n this.synth.processTickCallback = this._processTick.bind(this);\n }\n\n clearProcessHandler()\n {\n this.synth.processTickCallback = undefined;\n }\n}\n\nWorkletSequencer.prototype.post = post;\nWorkletSequencer.prototype.sendMIDIMessage = sendMIDIMessage;\nWorkletSequencer.prototype.assignMIDIPort = assignMIDIPort;\nWorkletSequencer.prototype.processMessage = processMessage;\n\nWorkletSequencer.prototype._processEvent = _processEvent;\nWorkletSequencer.prototype._addNewMidiPort = _addNewMidiPort;\nWorkletSequencer.prototype._processTick = _processTick;\nWorkletSequencer.prototype._findFirstEventIndex = _findFirstEventIndex;\n\nWorkletSequencer.prototype.loadNewSequence = loadNewSequence;\nWorkletSequencer.prototype.loadNewSongList = loadNewSongList;\nWorkletSequencer.prototype.nextSong = nextSong;\nWorkletSequencer.prototype.previousSong = previousSong;\n\nWorkletSequencer.prototype.play = play;\nWorkletSequencer.prototype._playTo = _playTo;\nWorkletSequencer.prototype.setTimeTicks = setTimeTicks;\nWorkletSequencer.prototype._recalculateStartTime = _recalculateStartTime;\n\nexport { WorkletSequencer }", "\n/**\n * @typedef {Object} ChannelSnapshot - a snapshot of the channel.\n *\n * @property {number} program - the channel's program\n * @property {number} bank - the channel's bank\n * @property {string} patchName - the channel's patch name\n * @property {boolean} lockPreset - indicates whether the channel's program change is disabled\n *\n * @property {Int16Array} midiControllers - the array of all midi controllers (in 14-bit values) with the modulator sources at the end. See Synthesizer Class on wiki (lockController section)\n * @property {boolean[]} lockedControllers - an array of booleans, indicating if the controller with a current index is locked\n * @property {Float32Array} customControllers - array of custom (not sf2) control values such as RPN pitch tuning, transpose, modulation depth, etc.\n *\n * // note: this is a custom vibrato object, set by NRPN messages\n * @property {boolean} lockVibrato - indicates whether the channel vibrato is locked\n * @property {Object} channelVibrato - the channel's vibrato\n * @property {number} channelVibrato.depth - vibrato depth, in gain\n * @property {number} channelVibrato.delay - vibrato delay from note on in seconds\n * @property {number} channelVibrato.rate - vibrato rate in Hz\n *\n * @property {number} channelTransposeKeyShift - key shift for the channel\n * @property {boolean} isMuted - indicates whether the channel is muted\n * @property {boolean} drumChannel - indicates whether the channel is a drum channel\n */\n/**\n * @typedef {Object} SynthesizerSnapshot\n * @property {ChannelSnapshot[]} channelSnapshots - the individual channel snapshots\n * @property {number} mainVolume - main synth volume (set by MIDI), from 0 to 1\n * @property {number} pan - master stereo panning, from -1 to 1\n * @property {SynthSystem} system - the synths system. Values can be \"gs\", \"gm\", \"gm2\" or \"xg\"\n * @property {number} transposition - the current synth transpositon in semitones. can be a float\n */\n\nimport { returnMessageType } from '../message_protocol/worklet_message.js'\nimport { SpessaSynthInfo } from '../../../utils/loggin.js'\nimport { consoleColors } from '../../../utils/other.js'\nimport { midiControllers } from '../../../midi_parser/midi_message.js'\n\n/**\n * sends a snapshot of the current controller values of the synth (used to copy that data to OfflineAudioContext when rendering)\n * @this {SpessaSynthProcessor}\n */\nexport function sendSynthesizerSnapshot()\n{\n /**\n * @type {ChannelSnapshot[]}\n */\n const channelSnapshots = this.workletProcessorChannels.map(channel => {\n return {\n program: channel.preset.program,\n bank: channel.preset.bank,\n lockPreset: channel.lockPreset,\n patchName: channel.preset.presetName,\n\n midiControllers: channel.midiControllers,\n lockedControllers: channel.lockedControllers,\n customControllers: channel.customControllers,\n\n channelVibrato: channel.channelVibrato,\n lockVibrato: channel.lockVibrato,\n\n channelTransposeKeyShift: channel.channelTransposeKeyShift,\n isMuted: channel.isMuted,\n drumChannel: channel.drumChannel\n }\n });\n\n /**\n * @type {SynthesizerSnapshot}\n */\n const synthesizerSnapshot = {\n channelSnapshots: channelSnapshots,\n mainVolume: this.midiVolume,\n pan: this.pan,\n transposition: this.transposition,\n system: this.system\n };\n\n this.post({\n messageType: returnMessageType.synthesizerSnapshot,\n messageData: synthesizerSnapshot\n });\n}\n\n/**\n * Applies the snapshot to the synth\n * @param snapshot {SynthesizerSnapshot}\n * @this {SpessaSynthProcessor}\n */\nexport function applySynthesizerSnapshot(snapshot)\n{\n // restore system\n this.system = snapshot.system;\n\n // restore pan and volume\n this.setMasterGain(snapshot.mainVolume);\n this.setMasterPan(snapshot.pan);\n this.transposeAllChannels(snapshot.transposition);\n\n // add channels if more needed\n while(this.workletProcessorChannels.length < snapshot.channelSnapshots.length)\n {\n this.createWorkletChannel();\n }\n\n // restore cahnnels\n snapshot.channelSnapshots.forEach((channelSnapshot, index) => {\n const channelObject = this.workletProcessorChannels[index];\n this.muteChannel(index, channelSnapshot.isMuted);\n this.setDrums(index, channelSnapshot.drumChannel);\n\n // restore controllers\n channelObject.midiControllers = channelSnapshot.midiControllers;\n channelObject.lockedControllers = channelSnapshot.lockedControllers;\n channelObject.customControllers = channelSnapshot.customControllers;\n\n // restore vibrato and transpose\n channelObject.channelVibrato = channelSnapshot.channelVibrato;\n channelObject.lockVibrato = channelSnapshot.lockVibrato;\n channelObject.channelTransposeKeyShift = channelSnapshot.channelTransposeKeyShift;\n\n // restore preset and lock\n channelObject.lockPreset = false;\n channelObject.midiControllers[midiControllers.bankSelect] = channelSnapshot.bank;\n this.programChange(index, channelSnapshot.program);\n channelObject.lockPreset = channelSnapshot.lockPreset;\n });\n SpessaSynthInfo(\"%cFinished restoring controllers!\", consoleColors.info);\n}", "/**\n * lfo.js\n * purpose: low frequency triangel oscillator\n */\n\n/**\n * Calculates a triangular wave value for the given time\n * @param startTime {number} seconds\n * @param frequency {number} Hz\n * @param currentTime {number} seconds\n * @return {number} the value from -1 to 1\n */\nexport function getLFOValue(startTime, frequency, currentTime) {\n if (currentTime < startTime) {\n return 0;\n }\n\n const xVal = (currentTime - startTime) / (1 / frequency) - 0.25;\n // offset by -0.25, otherwise we start at -1 and can have unexpected jump in pitch or lowpass (happened with Synth Strings 2)\n\n // triangle, not sine\n return Math.abs(xVal - (~~(xVal + 0.5))) * 4 - 1;\n}\n", "import { timecentsToSeconds } from './unit_converter.js'\nimport { generatorTypes } from '../../../soundfont/read/generators.js'\nimport { getModulatorCurveValue } from './modulator_curves.js'\nimport { modulatorCurveTypes } from '../../../soundfont/read/modulators.js'\n\n/**\n * modulation_envelope.js\n * purpose: calculates the modulation envelope for the given voice\n */\nconst PEAK = 1;\n\n// 1000 should be precise enough\nconst CONVEX_ATTACK = new Float32Array(1000);\nfor (let i = 0; i < CONVEX_ATTACK.length; i++) {\n // this makes the db linear ( i think\n CONVEX_ATTACK[i] = getModulatorCurveValue(0, modulatorCurveTypes.convex, i / 1000, 0);\n}\n\n/**\n * Calculates the current modulation envelope value for the given time and voice\n * @param voice {WorkletVoice} the voice we're working on\n * @param currentTime {number} in seconds\n * @returns {number} modenv value, from 0 to 1\n */\nexport function getModEnvValue(voice, currentTime)\n{\n // calculate env times\n let attack = timecentsToSeconds(voice.modulatedGenerators[generatorTypes.attackModEnv]);\n let decay = timecentsToSeconds(voice.modulatedGenerators[generatorTypes.decayModEnv] + ((60 - voice.midiNote) * voice.modulatedGenerators[generatorTypes.keyNumToModEnvDecay]));\n let hold = timecentsToSeconds(voice.modulatedGenerators[generatorTypes.holdModEnv] + ((60 - voice.midiNote) * voice.modulatedGenerators[generatorTypes.keyNumToModEnvHold]));\n\n // calculate absolute times\n if(voice.isInRelease && voice.releaseStartTime < currentTime)\n {\n let release = timecentsToSeconds(voice.modulatedGenerators[generatorTypes.releaseModEnv]);\n if(voice.modulatedGenerators[generatorTypes.releaseModEnv] < -7199)\n {\n // prevent lowpass bugs if release is instant\n return voice.releaseStartModEnv;\n }\n return (1 - (currentTime - voice.releaseStartTime) / release) * voice.releaseStartModEnv;\n }\n\n let sustain = 1 - (voice.modulatedGenerators[generatorTypes.sustainModEnv] / 1000);\n let delayEnd = timecentsToSeconds(voice.modulatedGenerators[generatorTypes.delayModEnv]) + voice.startTime;\n let attackEnd = attack + delayEnd;\n let holdEnd = hold + attackEnd;\n let decayEnd = decay + holdEnd;\n\n let modEnvVal\n if(currentTime < delayEnd)\n {\n modEnvVal = 0; // delay\n }\n else if(currentTime < attackEnd)\n {\n modEnvVal = CONVEX_ATTACK[~~((1 - (attackEnd - currentTime) / attack) * 1000)]; // convex attack\n }\n else if(currentTime < holdEnd)\n {\n modEnvVal = PEAK; // peak\n }\n else if(currentTime < decayEnd)\n {\n modEnvVal = (1 - (decayEnd - currentTime) / decay) * (sustain - PEAK) + PEAK; // decay\n }\n else\n {\n modEnvVal = sustain; // sustain\n }\n voice.currentModEnvValue = modEnvVal;\n return modEnvVal;\n}", "/**\n * wavetable_oscillator.js\n * purpose: plays back raw audio data at an arbitrary playback rate\n */\n\n\n/**\n * Fills the output buffer with raw sample data\n * @param voice {WorkletVoice} the voice we're working on\n * @param sampleData {Float32Array} the sample data to write with\n * @param outputBuffer {Float32Array} the output buffer to write to\n */\nexport function getOscillatorData(voice, sampleData, outputBuffer)\n{\n let cur = voice.sample.cursor;\n const loop = (voice.sample.loopingMode === 1) || (voice.sample.loopingMode === 3 && !voice.isInRelease);\n const loopLength = voice.sample.loopEnd - voice.sample.loopStart;\n\n if(loop)\n {\n for (let i = 0; i < outputBuffer.length; i++) {\n // check for loop\n while(cur >= voice.sample.loopEnd) {\n cur -= loopLength;\n }\n\n // grab the 2 nearest points\n const floor = ~~cur;\n let ceil = floor + 1;\n\n while(ceil >= voice.sample.loopEnd) {\n ceil -= loopLength;\n }\n\n const fraction = cur - floor;\n\n // grab the samples and interpolate\n const upper = sampleData[ceil];\n const lower = sampleData[floor];\n outputBuffer[i] = (lower + (upper - lower) * fraction);\n\n // commented code because it's probably gonna come handy... (it did like 6 times already :/)\n // if(isNaN(outputBuffer[i]))\n // {\n // console.error(voice, upper, lower, floor, ceil, cur)\n // throw \"NAN ALERT\";\n // }\n\n cur += voice.sample.playbackStep * voice.currentTuningCalculated;\n }\n }\n else\n {\n // check and correct end errors\n if(voice.sample.end >= sampleData.length)\n {\n voice.sample.end = sampleData.length - 1;\n }\n for (let i = 0; i < outputBuffer.length; i++) {\n\n // linear interpolation\n const floor = ~~cur;\n const ceil = floor + 1;\n\n // flag the voice as finished if needed\n if(ceil >= voice.sample.end)\n {\n voice.finished = true;\n return;\n }\n\n const fraction = cur - floor;\n\n // grab the samples and interpolate\n const upper = sampleData[ceil];\n const lower = sampleData[floor];\n outputBuffer[i] = (lower + (upper - lower) * fraction);\n\n cur += voice.sample.playbackStep * voice.currentTuningCalculated;\n }\n }\n voice.sample.cursor = cur;\n}", "export const WORKLET_SYSTEM_REVERB_DIVIDER = 500;\nexport const WORKLET_SYSTEM_CHORUS_DIVIDER = 500;\n/**\n * stereo_panner.js\n * purpose: pans a given voice out to the stereo output and to the effects' outputs\n */\n\n/**\n * Pans the voice to the given output buffers\n * @param gainLeft {number} the left channel gain\n * @param gainRight {number} the right channel gain\n * @param inputBuffer {Float32Array} the input buffer in mono\n * @param outputLeft {Float32Array} left output buffer\n * @param outputRight {Float32Array} right output buffer\n * @param reverb {Float32Array[]} stereo reverb input\n * @param reverbLevel {number} 0 to 1000, the level of reverb to send\n * @param chorus {Float32Array[]} stereo chorus buttfer\n * @param chorusLevel {number} 0 to 1000, the level of chorus to send\n */\nexport function panVoice(gainLeft,\n gainRight,\n inputBuffer,\n outputLeft, outputRight,\n reverb,\n reverbLevel,\n chorus,\n chorusLevel)\n{\n if(isNaN(inputBuffer[0]))\n {\n return;\n }\n\n if(reverbLevel > 0)\n {\n const reverbLeft = reverb[0];\n const reverbRight = reverb[1];\n // cap reverb\n reverbLevel = Math.min(reverbLevel, 1000);\n const reverbGain = reverbLevel / WORKLET_SYSTEM_REVERB_DIVIDER;\n const reverbLeftGain = gainLeft * reverbGain;\n const reverbRightGain = gainRight * reverbGain;\n for (let i = 0; i < inputBuffer.length; i++)\n {\n reverbLeft[i] += reverbLeftGain * inputBuffer[i];\n reverbRight[i] += reverbRightGain * inputBuffer[i];\n }\n }\n\n if(chorusLevel > 0)\n {\n const chorusLeft = chorus[0];\n const chorusRight = chorus[1];\n // cap chorus\n chorusLevel = Math.min(chorusLevel, 1000);\n const chorusGain = chorusLevel / WORKLET_SYSTEM_CHORUS_DIVIDER;\n const chorusLeftGain = gainLeft * chorusGain;\n const chorusRightGain = gainRight * chorusGain;\n for (let i = 0; i < inputBuffer.length; i++)\n {\n chorusLeft[i] += chorusLeftGain * inputBuffer[i];\n chorusRight[i] += chorusRightGain * inputBuffer[i];\n }\n }\n\n // mix out the audio data\n if(gainLeft > 0)\n {\n for (let i = 0; i < inputBuffer.length; i++)\n {\n outputLeft[i] += gainLeft * inputBuffer[i];\n }\n }\n if(gainRight > 0)\n {\n for (let i = 0; i < inputBuffer.length; i++)\n {\n outputRight[i] += gainRight * inputBuffer[i];\n }\n }\n}", "import { generatorTypes } from '../../../soundfont/read/generators.js'\nimport { absCentsToHz, decibelAttenuationToGain, timecentsToSeconds } from '../worklet_utilities/unit_converter.js'\nimport { getLFOValue } from '../worklet_utilities/lfo.js'\nimport { customControllers } from '../worklet_utilities/worklet_processor_channel.js'\nimport { getModEnvValue } from '../worklet_utilities/modulation_envelope.js'\nimport { getOscillatorData } from '../worklet_utilities/wavetable_oscillator.js'\nimport { panVoice } from '../worklet_utilities/stereo_panner.js'\nimport { applyVolumeEnvelope, recalculateVolumeEnvelope } from '../worklet_utilities/volume_envelope.js'\nimport { applyLowpassFilter } from '../worklet_utilities/lowpass_filter.js'\nimport { MIN_NOTE_LENGTH } from '../main_processor.js'\n\n\nconst HALF_PI = Math.PI / 2;\nexport const PAN_SMOOTHING_FACTOR = 0.01;\n/**\n * Renders a voice to the stereo output buffer\n * @param channel {WorkletProcessorChannel} the voice's channel\n * @param voice {WorkletVoice} the voice to render\n * @param outputLeft {Float32Array} the left output buffer\n * @param outputRight {Float32Array} the right output buffer\n * @param reverbOutput {Float32Array[]} output for reverb\n * @param chorusOutput {Float32Array[]} output for chorus\n * @this {SpessaSynthProcessor}\n */\nexport function renderVoice(\n channel,\n voice,\n outputLeft, outputRight,\n reverbOutput,\n chorusOutput\n)\n{\n // check if release\n if(!voice.isInRelease)\n {\n // if not in release, check if the release time is\n if (currentTime >= voice.releaseStartTime)\n {\n voice.releaseStartModEnv = voice.currentModEnvValue;\n voice.isInRelease = true;\n recalculateVolumeEnvelope(voice);\n voice.volumeEnvelope.currentReleaseGain = decibelAttenuationToGain(voice.volumeEnvelope.currentAttenuationDb);\n }\n }\n\n\n // if the initial attenuation is more than 100dB, skip the voice (it's silent anyways)\n if(voice.modulatedGenerators[generatorTypes.initialAttenuation] > 2500)\n {\n if(voice.isInRelease)\n {\n voice.finished = true;\n }\n return;\n }\n\n // TUNING\n\n // calculate tuning\n let cents = voice.modulatedGenerators[generatorTypes.fineTune]\n + channel.customControllers[customControllers.channelTuning]\n + channel.customControllers[customControllers.channelTransposeFine]\n + channel.customControllers[customControllers.masterTuning];\n let semitones = voice.modulatedGenerators[generatorTypes.coarseTune]\n + channel.customControllers[customControllers.channelTuningSemitones];\n\n // calculate tuning by key\n cents += (voice.targetKey - voice.sample.rootKey) * voice.modulatedGenerators[generatorTypes.scaleTuning];\n\n // vibrato LFO\n const vibratoDepth = voice.modulatedGenerators[generatorTypes.vibLfoToPitch];\n if(vibratoDepth !== 0)\n {\n const vibStart = voice.startTime + timecentsToSeconds(voice.modulatedGenerators[generatorTypes.delayVibLFO]);\n const vibFreqHz = absCentsToHz(voice.modulatedGenerators[generatorTypes.freqVibLFO]);\n const lfoVal = getLFOValue(vibStart, vibFreqHz, currentTime);\n if(lfoVal)\n {\n cents += lfoVal * (vibratoDepth * channel.customControllers[customControllers.modulationMultiplier]);\n }\n }\n\n // lowpass frequency\n let lowpassCents = voice.modulatedGenerators[generatorTypes.initialFilterFc];\n\n // mod LFO\n const modPitchDepth = voice.modulatedGenerators[generatorTypes.modLfoToPitch];\n const modVolDepth = voice.modulatedGenerators[generatorTypes.modLfoToVolume];\n const modFilterDepth = voice.modulatedGenerators[generatorTypes.modLfoToFilterFc];\n let modLfoCentibels = 0;\n if(modPitchDepth + modFilterDepth + modVolDepth !== 0)\n {\n const modStart = voice.startTime + timecentsToSeconds(voice.modulatedGenerators[generatorTypes.delayModLFO]);\n const modFreqHz = absCentsToHz(voice.modulatedGenerators[generatorTypes.freqModLFO]);\n const modLfoValue = getLFOValue(modStart, modFreqHz, currentTime);\n cents += modLfoValue * (modPitchDepth * channel.customControllers[customControllers.modulationMultiplier]);\n modLfoCentibels = modLfoValue * modVolDepth;\n lowpassCents += modLfoValue * modFilterDepth;\n }\n\n // channel vibrato (GS NRPN)\n if(channel.channelVibrato.depth > 0)\n {\n const channelVibrato = getLFOValue(voice.startTime + channel.channelVibrato.delay, channel.channelVibrato.rate, currentTime);\n if(channelVibrato)\n {\n cents += channelVibrato * channel.channelVibrato.depth;\n }\n }\n\n // mod env\n const modEnvPitchDepth = voice.modulatedGenerators[generatorTypes.modEnvToPitch];\n const modEnvFilterDepth = voice.modulatedGenerators[generatorTypes.modEnvToFilterFc];\n const modEnv = getModEnvValue(voice, currentTime);\n lowpassCents += modEnv * modEnvFilterDepth;\n cents += modEnv * modEnvPitchDepth;\n\n // finally calculate the playback rate\n const centsTotal = ~~(cents + semitones * 100);\n if(centsTotal !== voice.currentTuningCents)\n {\n voice.currentTuningCents = centsTotal;\n voice.currentTuningCalculated = Math.pow(2, centsTotal / 1200);\n }\n\n // PANNING\n const pan = ((Math.max(-500, Math.min(500, voice.modulatedGenerators[generatorTypes.pan] )) + 500) / 1000) ; // 0 to 1\n\n // SYNTHESIS\n const bufferOut = new Float32Array(outputLeft.length);\n\n // wavetable oscillator\n getOscillatorData(voice, this.workletDumpedSamplesList[voice.sample.sampleID], bufferOut);\n\n // lowpass filter\n applyLowpassFilter(voice, bufferOut, lowpassCents);\n\n // volenv\n applyVolumeEnvelope(voice, bufferOut, currentTime, modLfoCentibels, this.sampleTime, this.volumeEnvelopeSmoothingFactor);\n\n // pan the voice and write out\n voice.currentPan += (pan - voice.currentPan) * this.panSmoothingFactor; // smooth out pan to prevent clicking\n const panLeft = Math.cos(HALF_PI * voice.currentPan) * this.panLeft;\n const panRight = Math.sin(HALF_PI * voice.currentPan) * this.panRight;\n const reverb = this.oneOutputMode ? 0 : voice.modulatedGenerators[generatorTypes.reverbEffectsSend];\n const chorus = this.oneOutputMode ? 0 : voice.modulatedGenerators[generatorTypes.chorusEffectsSend];\n panVoice(\n panLeft,\n panRight,\n bufferOut,\n outputLeft, outputRight,\n reverbOutput, reverb,\n chorusOutput, chorus);\n}\n\n\n/**\n * @param channel {WorkletProcessorChannel}\n * @param voice {WorkletVoice}\n * @return {number}\n */\nfunction getPriority(channel, voice)\n{\n let priority = 0;\n if(channel.drumChannel)\n {\n // important\n priority += 5;\n }\n if(voice.isInRelease)\n {\n // not important\n priority -= 5;\n }\n // less velocity = less important\n priority += voice.velocity / 25; // map to 0-5\n // the newer, more important\n priority -= voice.volumeEnvelope.state;\n if(voice.isInRelease)\n {\n priority -= 5;\n }\n priority -= voice.volumeEnvelope.currentAttenuationDb / 50;\n return priority;\n}\n\n/**\n * @this {SpessaSynthProcessor}\n * @param amount {number}\n */\nexport function voiceKilling(amount)\n{\n let allVoices = [];\n for (const channel of this.workletProcessorChannels)\n {\n for (const voice of channel.voices)\n {\n if (!voice.finished)\n {\n const priority = getPriority(channel, voice);\n allVoices.push({ channel, voice, priority });\n }\n }\n }\n\n // Step 2: Sort voices by priority (ascending order)\n allVoices.sort((a, b) => a.priority - b.priority);\n const voicesToRemove = allVoices.slice(0, amount);\n\n for (const { channel, voice } of voicesToRemove)\n {\n const index = channel.voices.indexOf(voice);\n if (index > -1)\n {\n channel.voices.splice(index, 1);\n }\n }\n}\n\n/**\n * Stops the voice\n * @param voice {WorkletVoice} the voice to stop\n * @this {SpessaSynthProcessor}\n */\nexport function releaseVoice(voice)\n{\n voice.releaseStartTime = currentTime;\n // check if the note is shorter than the min note time, if so, extend it\n if(voice.releaseStartTime - voice.startTime < MIN_NOTE_LENGTH)\n {\n voice.releaseStartTime = voice.startTime + MIN_NOTE_LENGTH;\n }\n}", "import { consoleColors } from '../../../utils/other.js'\nimport { midiControllers } from '../../../midi_parser/midi_message.js'\nimport { DEFAULT_PERCUSSION, DEFAULT_SYNTH_MODE } from '../../synthetizer.js'\nimport {\n customControllers,\n customResetArray, dataEntryStates,\n NON_CC_INDEX_OFFSET,\n resetArray,\n} from '../worklet_utilities/worklet_processor_channel.js'\nimport { modulatorSources } from '../../../soundfont/read/modulators.js'\nimport { SpessaSynthInfo } from '../../../utils/loggin.js'\n\n/**\n * @this {SpessaSynthProcessor}\n */\nexport function resetAllControllers()\n{\n SpessaSynthInfo(\"%cResetting all controllers!\", consoleColors.info);\n this.callEvent(\"allcontrollerreset\", undefined);\n for (let channelNumber = 0; channelNumber < this.workletProcessorChannels.length; channelNumber++)\n {\n this.resetControllers(channelNumber);\n\n /**\n * @type {WorkletProcessorChannel}\n **/\n const ch = this.workletProcessorChannels[channelNumber];\n\n // if preset is unlocked, switch to non drums and call event\n if(!ch.lockPreset)\n {\n ch.midiControllers[midiControllers.bankSelect] = 0;\n if (channelNumber % 16 === DEFAULT_PERCUSSION)\n {\n this.setPreset(channelNumber, this.drumPreset);\n ch.drumChannel = true;\n this.callEvent(\"drumchange\", {\n channel: channelNumber,\n isDrumChannel: true\n });\n }\n else\n {\n ch.drumChannel = false;\n this.setPreset(channelNumber, this.defaultPreset);\n this.callEvent(\"drumchange\", {\n channel: channelNumber,\n isDrumChannel: false\n });\n }\n }\n else\n {\n this.callEvent(\"drumchange\", {\n channel: channelNumber,\n isDrumChannel: ch.drumChannel\n })\n }\n\n // call program change\n this.callEvent(\"programchange\", {\n channel: channelNumber,\n program: ch.preset.program,\n bank: ch.preset.bank,\n userCalled: false\n });\n\n let restoreControllerValueEvent = ccNum =>\n {\n if(this.workletProcessorChannels[channelNumber].lockedControllers[ccNum])\n {\n // was not reset so restore the value\n this.callEvent(\"controllerchange\", {\n channel: channelNumber,\n controllerNumber: ccNum,\n controllerValue: this.workletProcessorChannels[channelNumber].midiControllers[ccNum] >> 7\n });\n }\n\n }\n\n restoreControllerValueEvent(midiControllers.mainVolume);\n restoreControllerValueEvent(midiControllers.pan);\n restoreControllerValueEvent(midiControllers.expressionController);\n restoreControllerValueEvent(midiControllers.modulationWheel);\n restoreControllerValueEvent(midiControllers.effects3Depth);\n restoreControllerValueEvent(midiControllers.effects1Depth);\n\n // restore pitch wheel\n if(this.workletProcessorChannels[channelNumber].lockedControllers[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel])\n {\n const val = this.workletProcessorChannels[channelNumber].midiControllers[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel];\n const msb = val >> 7;\n const lsb = val & 0x7F;\n this.callEvent(\"pitchwheel\", {\n channel: channelNumber,\n MSB: msb,\n LSB: lsb\n })\n }\n }\n this.setMIDIVolume(1);\n this.system = DEFAULT_SYNTH_MODE;\n}\n\n/**\n * Resets all controllers for channel\n * @param channel {number}\n * @this {SpessaSynthProcessor}\n */\nexport function resetControllers(channel)\n{\n const channelObject = this.workletProcessorChannels[channel];\n /**\n * get excluded (locked) cc numbers as locked ccs are unaffected by reset\n * @type {number[]}\n */\n const excludedCCs = channelObject.lockedControllers.reduce((lockedCCs, cc, ccNum) => {\n if(cc)\n {\n lockedCCs.push(ccNum);\n }\n return lockedCCs;\n }, []);\n // save excluded controllers as reset doesn't affect them\n let excludedCCvalues = excludedCCs.map(ccNum => {\n return {\n ccNum: ccNum,\n ccVal: channelObject.midiControllers[ccNum]\n }\n });\n\n // reset the array\n channelObject.midiControllers.set(resetArray);\n channelObject.channelVibrato = {rate: 0, depth: 0, delay: 0};\n channelObject.holdPedal = false;\n\n excludedCCvalues.forEach((cc) => {\n channelObject.midiControllers[cc.ccNum] = cc.ccVal;\n });\n\n // reset custom controllers\n // special case: transpose does not get affected\n const transpose = channelObject.customControllers[customControllers.channelTransposeFine];\n channelObject.customControllers.set(customResetArray);\n channelObject.customControllers[customControllers.channelTransposeFine] = transpose;\n\n this.resetParameters(channel);\n\n}\n\n/**\n * @param channel {number}\n * @this {SpessaSynthProcessor}\n */\nexport function resetParameters(channel)\n{\n const channelObject = this.workletProcessorChannels[channel];\n\n // reset parameters\n /**\n * @type {number}\n */\n channelObject.NRPCoarse = 0;\n /**\n * @type {number}\n */\n channelObject.NRPFine = 0;\n /**\n * @type {number}\n */\n channelObject.RPValue = 0;\n /**\n * @type {string}\n */\n channelObject.dataEntryState = dataEntryStates.Idle;\n}", "import { DEFAULT_PERCUSSION, DEFAULT_SYNTH_MODE, VOICE_CAP } from '../synthetizer.js'\nimport {\n createWorkletChannel,\n} from './worklet_utilities/worklet_processor_channel.js'\n\nimport { SoundFont2 } from '../../soundfont/soundfont.js'\nimport { handleMessage } from './message_protocol/handle_message.js'\nimport { systemExclusive } from './worklet_methods/system_exclusive.js'\nimport { noteOn } from './worklet_methods/note_on.js'\nimport { dataEntryCoarse, dataEntryFine } from './worklet_methods/data_entry.js'\nimport { killNote, noteOff, stopAll, stopAllChannels } from './worklet_methods/note_off.js'\nimport {\n controllerChange, muteChannel, setMasterGain, setMasterPan, setMIDIVolume,\n} from './worklet_methods/controller_control.js'\nimport { callEvent, post, sendChannelProperties } from './message_protocol/message_sending.js'\nimport {\n channelPressure,\n pitchWheel, polyPressure,\n setChannelTuning, setChannelTuningSemitones,\n setMasterTuning, setModulationDepth,\n transposeAllChannels,\n transposeChannel,\n} from './worklet_methods/tuning_control.js'\nimport {\n programChange,\n reloadSoundFont,\n sampleDump,\n sendPresetList,\n setDrums,\n setPreset,\n} from './worklet_methods/program_control.js'\nimport { disableAndLockVibrato, setVibrato } from './worklet_methods/vibrato_control.js'\nimport { WorkletSequencer } from '../../sequencer/worklet_sequencer/worklet_sequencer.js'\nimport { SpessaSynthInfo } from '../../utils/loggin.js'\nimport { applySynthesizerSnapshot, sendSynthesizerSnapshot } from './worklet_methods/snapshot.js'\nimport { consoleColors } from '../../utils/other.js'\nimport { PAN_SMOOTHING_FACTOR, releaseVoice, renderVoice, voiceKilling } from './worklet_methods/voice_control.js'\nimport { returnMessageType } from './message_protocol/worklet_message.js'\nimport { stbvorbis } from '../../externals/stbvorbis_sync/stbvorbis_sync.min.js'\nimport { VOLUME_ENVELOPE_SMOOTHING_FACTOR } from './worklet_utilities/volume_envelope.js'\nimport { resetAllControllers, resetControllers, resetParameters } from './worklet_methods/reset_controllers.js'\n\n\n/**\n * worklet_processor.js\n * purpose: manages the synthesizer (and worklet sequencer) from the AudioWorkletGlobalScope and renders the audio data\n */\n\nexport const MIN_NOTE_LENGTH = 0.07; // if the note is released faster than that, it forced to last that long\n\nexport const SYNTHESIZER_GAIN = 1.0;\n\nclass SpessaSynthProcessor extends AudioWorkletProcessor {\n /**\n * Creates a new worklet synthesis system. contains all channels\n * @param options {{\n * processorOptions: {\n * midiChannels: number,\n * soundfont: ArrayBuffer,\n * enableEventSystem: boolean,\n * startRenderingData: {\n * parsedMIDI: MIDI,\n * snapshot: SynthesizerSnapshot,\n * oneOutput: boolean\n * }\n * }}}\n */\n constructor(options) {\n super();\n this.oneOutputMode = options.processorOptions?.startRenderingData?.oneOutput === true;\n this._outputsAmount = this.oneOutputMode ? 1 : options.processorOptions.midiChannels;\n\n this.enableEventSystem = options.processorOptions.enableEventSystem;\n\n /**\n * @type {function}\n */\n this.processTickCallback = undefined;\n\n this.sequencer = new WorkletSequencer(this);\n\n this.transposition = 0;\n\n /**\n * The volume gain, set by user\n * @type {number}\n */\n this.masterGain = SYNTHESIZER_GAIN;\n\n this.midiVolume = 1;\n\n /**\n * Maximum number of voices allowed at once\n * @type {number}\n */\n this.voiceCap = VOICE_CAP;\n\n /**\n * -1 to 1\n * @type {number}\n */\n this.pan = 0.0;\n /**\n * the pan of the left channel\n * @type {number}\n */\n this.panLeft = 0.5 * this.currentGain;\n\n this.highPerformanceMode = false;\n\n /**\n * the pan of the right channel\n * @type {number}\n */\n this.panRight = 0.5 * this.currentGain;\n try\n {\n /**\n * @type {SoundFont2}\n */\n this.soundfont = new SoundFont2(options.processorOptions.soundfont);\n }\n catch (e)\n {\n this.post({\n messageType: returnMessageType.soundfontError,\n messageData: e\n });\n throw e;\n }\n this.sendPresetList();\n\n this.defaultPreset = this.soundfont.getPreset(0, 0);\n this.drumPreset = this.soundfont.getPreset(128, 0);\n\n /**\n * @type {Float32Array[]}\n */\n this.workletDumpedSamplesList = [];\n /**\n * contains all the channels with their voices on the processor size\n * @type {WorkletProcessorChannel[]}\n */\n this.workletProcessorChannels = [];\n for (let i = 0; i < options.processorOptions.midiChannels; i++)\n {\n this.createWorkletChannel(false);\n }\n\n this.workletProcessorChannels[DEFAULT_PERCUSSION].preset = this.drumPreset;\n this.workletProcessorChannels[DEFAULT_PERCUSSION].drumChannel = true;\n\n // in seconds, time between two samples (very, very short)\n this.sampleTime = 1 / sampleRate;\n\n // these smoothing factors were tested on 44100Hz, adjust them here\n this.volumeEnvelopeSmoothingFactor = VOLUME_ENVELOPE_SMOOTHING_FACTOR * (sampleRate / 44100);\n this.panSmoothingFactor = PAN_SMOOTHING_FACTOR * (sampleRate / 44100);\n\n /**\n * Controls the system\n * @typedef {\"gm\"|\"gm2\"|\"gs\"|\"xg\"} SynthSystem\n */\n /*\n * @type {SynthSystem}\n */\n this.system = DEFAULT_SYNTH_MODE;\n\n this.totalVoicesAmount = 0;\n\n this.port.onmessage = e => this.handleMessage(e.data);\n\n // if sent, start rendering\n if(options.processorOptions.startRenderingData)\n {\n if (options.processorOptions.startRenderingData.snapshot)\n {\n this.applySynthesizerSnapshot(options.processorOptions.startRenderingData.snapshot);\n this.resetAllControllers();\n }\n\n SpessaSynthInfo(\"%cRendering enabled! Starting render.\", consoleColors.info)\n if (options.processorOptions.startRenderingData.parsedMIDI)\n {\n this.sequencer.loadNewSongList([options.processorOptions.startRenderingData.parsedMIDI]);\n this.sequencer.loop = false;\n }\n }\n\n stbvorbis.isInitialized.then(() => {\n this.post({\n messageType: returnMessageType.ready,\n messageData: undefined\n });\n SpessaSynthInfo(\"%cSpessaSynth is ready!\", consoleColors.recognized);\n });\n }\n\n /**\n * @returns {number}\n */\n get currentGain()\n {\n return this.masterGain * this.midiVolume;\n }\n\n debugMessage()\n {\n SpessaSynthInfo({\n channels: this.workletProcessorChannels,\n voicesAmount: this.totalVoicesAmount,\n outputAmount: this._outputsAmount,\n dumpedSamples: this.workletDumpedSamplesList\n });\n }\n\n /**\n * Syntesizes the voice to buffers\n * @param inputs {Float32Array[][]} required by WebAudioAPI\n * @param outputs {Float32Array[][]} the outputs to write to, only the first 2 channels are populated\n * @returns {boolean} true\n */\n process(inputs, outputs) {\n if(this.processTickCallback)\n {\n this.processTickCallback();\n }\n\n // for every channel\n let totalCurrentVoices = 0;\n this.workletProcessorChannels.forEach((channel, index) => {\n if(channel.voices.length < 1 || channel.isMuted)\n {\n // skip the channels\n return;\n }\n let outputIndex;\n let outputLeft;\n let outputRight;\n let reverbChannels;\n let chorusChannels;\n if(this.oneOutputMode)\n {\n // first output only\n const output = outputs[0];\n // reverb and chorus are disabled. 32 output channels: two for each midi channels\n outputIndex = (index % 16) * 2;\n outputLeft = output[outputIndex];\n outputRight = output[outputIndex + 1];\n }\n else\n {\n // 2 first outputs are reverb and chorus, other are for channels\n outputIndex = (index % this._outputsAmount) + 2;\n outputLeft = outputs[outputIndex][0];\n outputRight = outputs[outputIndex][1];\n reverbChannels = outputs[0];\n chorusChannels = outputs[1];\n }\n\n const tempV = channel.voices;\n\n // reset voices\n channel.voices = [];\n\n // for every voice\n tempV.forEach(v => {\n // render voice\n this.renderVoice(\n channel,\n v,\n outputLeft, outputRight,\n reverbChannels,\n chorusChannels\n );\n if(!v.finished)\n {\n // if not finished, add it back\n channel.voices.push(v);\n }\n });\n\n totalCurrentVoices += tempV.length;\n });\n\n // if voice count changed, update voice amount\n if(totalCurrentVoices !== this.totalVoicesAmount)\n {\n this.totalVoicesAmount = totalCurrentVoices;\n this.sendChannelProperties();\n }\n return true;\n }\n}\n\n// include other methods\n// voice related\nSpessaSynthProcessor.prototype.renderVoice = renderVoice;\nSpessaSynthProcessor.prototype.releaseVoice = releaseVoice;\nSpessaSynthProcessor.prototype.voiceKilling = voiceKilling;\n\n// message port related\nSpessaSynthProcessor.prototype.handleMessage = handleMessage;\nSpessaSynthProcessor.prototype.post = post;\nSpessaSynthProcessor.prototype.sendChannelProperties = sendChannelProperties;\nSpessaSynthProcessor.prototype.callEvent = callEvent;\n\n// system exlcusive related\nSpessaSynthProcessor.prototype.systemExclusive = systemExclusive;\n\n// note messages related\nSpessaSynthProcessor.prototype.noteOn = noteOn;\nSpessaSynthProcessor.prototype.noteOff = noteOff;\nSpessaSynthProcessor.prototype.polyPressure = polyPressure;\nSpessaSynthProcessor.prototype.killNote = killNote;\nSpessaSynthProcessor.prototype.stopAll = stopAll;\nSpessaSynthProcessor.prototype.stopAllChannels = stopAllChannels;\nSpessaSynthProcessor.prototype.muteChannel = muteChannel;\n\n// custom vibrato related\nSpessaSynthProcessor.prototype.setVibrato = setVibrato;\nSpessaSynthProcessor.prototype.disableAndLockVibrato = disableAndLockVibrato;\n\n// data entry related\nSpessaSynthProcessor.prototype.dataEntryCoarse = dataEntryCoarse;\nSpessaSynthProcessor.prototype.dataEntryFine = dataEntryFine;\n\n// channel related\nSpessaSynthProcessor.prototype.createWorkletChannel = createWorkletChannel;\nSpessaSynthProcessor.prototype.controllerChange = controllerChange;\nSpessaSynthProcessor.prototype.channelPressure = channelPressure;\nSpessaSynthProcessor.prototype.resetAllControllers = resetAllControllers;\nSpessaSynthProcessor.prototype.resetControllers = resetControllers;\nSpessaSynthProcessor.prototype.resetParameters = resetParameters;\n\n// master parameter related\nSpessaSynthProcessor.prototype.setMasterGain = setMasterGain;\nSpessaSynthProcessor.prototype.setMasterPan = setMasterPan;\nSpessaSynthProcessor.prototype.setMIDIVolume = setMIDIVolume;\n\n// tuning related\nSpessaSynthProcessor.prototype.transposeAllChannels = transposeAllChannels;\nSpessaSynthProcessor.prototype.transposeChannel = transposeChannel;\nSpessaSynthProcessor.prototype.setChannelTuning = setChannelTuning;\nSpessaSynthProcessor.prototype.setChannelTuningSemitones = setChannelTuningSemitones;\nSpessaSynthProcessor.prototype.setMasterTuning = setMasterTuning;\nSpessaSynthProcessor.prototype.setModulationDepth = setModulationDepth;\nSpessaSynthProcessor.prototype.pitchWheel = pitchWheel;\n\n// program related\nSpessaSynthProcessor.prototype.programChange = programChange;\nSpessaSynthProcessor.prototype.setPreset = setPreset;\nSpessaSynthProcessor.prototype.setDrums = setDrums;\nSpessaSynthProcessor.prototype.reloadSoundFont = reloadSoundFont;\nSpessaSynthProcessor.prototype.sampleDump = sampleDump;\nSpessaSynthProcessor.prototype.sendPresetList = sendPresetList;\n\n// snapshot related\nSpessaSynthProcessor.prototype.sendSynthesizerSnapshot = sendSynthesizerSnapshot;\nSpessaSynthProcessor.prototype.applySynthesizerSnapshot = applySynthesizerSnapshot;\n\n\nexport { SpessaSynthProcessor }", "import { WORKLET_PROCESSOR_NAME } from '../synthetizer.js'\nimport { consoleColors } from '../../utils/other.js'\nimport { SpessaSynthProcessor } from './main_processor.js'\nimport { SpessaSynthInfo } from '../../utils/loggin.js'\n\n\n// noinspection JSUnresolvedReference\nregisterProcessor(WORKLET_PROCESSOR_NAME, SpessaSynthProcessor);\nSpessaSynthInfo(\"%cProcessor succesfully registered!\", consoleColors.recognized);"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["IndexedByteArray", "args", "combineArrays", "arrs", "length", "sum", "current", "newArr", "offset", "arr", "formatTime", "totalSeconds", "minutes", "seconds", "formatTitle", "fileName", "arrayToHexString", "arr", "hexString", "i", "hex", "consoleColors", "MidiMessage", "ticks", "byte", "data", "getChannel", "statusByte", "eventType", "channel", "resultChannel", "messageTypes", "getEvent", "status", "eventChannel", "eventStatus", "midiControllers", "dataBytesAmount", "workletMessageType", "masterParameterType", "ALL_CHANNELS_OR_DIFFERENT_ACTION", "returnMessageType", "ENABLE_INFO", "ENABLE_WARN", "ENABLE_GROUP", "ENABLE_TABLE", "SpessaSynthLogging", "enableInfo", "enableWarn", "enableGroup", "enableTable", "SpessaSynthInfo", "message", "SpessaSynthWarn", "SpessaSynthTable", "args", "SpessaSynthGroup", "SpessaSynthGroupCollapsed", "SpessaSynthGroupEnd", "WORKLET_PROCESSOR_NAME", "VOICE_CAP", "DEFAULT_PERCUSSION", "MIDI_CHANNEL_COUNT", "DEFAULT_SYNTH_MODE", "readBytesAsUintLittleEndian", "dataArray", "bytesAmount", "out", "i", "writeLittleEndian", "number", "byteTarget", "writeWord", "word", "writeDword", "dword", "signedInt16", "byte1", "byte2", "val", "signedInt8", "byte", "readBytesAsString", "dataArray", "bytes", "encoding", "trimEnd", "byteBuffer", "finished", "string", "byte", "writeStringAsBytes", "outArray", "string", "padLength", "i", "RiffChunk", "header", "size", "data", "readRIFFChunk", "dataArray", "readData", "forceShift", "readBytesAsString", "readBytesAsUintLittleEndian", "chunkData", "IndexedByteArray", "writeRIFFChunk", "chunk", "prepend", "array", "writeStringAsBytes", "writeDword", "generatorTypes", "generatorLimits", "addAndClampGenerator", "generatorType", "presetGens", "instrumentGens", "limits", "presetGen", "g", "presetValue", "instruGen", "instruValue", "Generator", "dataArray", "i", "signedInt16", "readGenerators", "generatorChunk", "gens", "modulatorSources", "modulatorCurveTypes", "precomputedTransforms", "i", "Modulator", "_Modulator", "dataArray", "readBytesAsUintLittleEndian", "signedInt16", "modulator", "getKeyByValue", "object", "value", "key", "sourceString", "midiControllers", "secSrcString", "generatorTypes", "getModSourceEnum", "curveType", "polarity", "direction", "isCC", "index", "DEFAULT_ATTENUATION_MOD_AMOUNT", "DEFAULT_ATTENUATION_MOD_CURVE_TYPE", "defaultModulators", "readModulators", "modulatorChunk", "gens", "createWorkletChannel", "sendEvent", "channel", "CONTROLLER_TABLE_SIZE", "CUSTOM_CONTROLLER_TABLE_SIZE", "dataEntryStates", "i", "NON_CC_INDEX_OFFSET", "resetArray", "midiControllers", "modulatorSources", "customControllers", "customResetArray", "stbvorbis", "isReady", "readySolver", "A", "atob", "I", "g", "B", "E", "Q", "C", "i", "o", "G", "D", "a", "S", "F", "R", "s", "w", "y", "c", "n", "U", "$", "e", "t", "k", "N", "r", "__require", "Y", "J", "_", "II", "f", "H", "L", "M", "AN", "Ae", "d", "q", "K", "l", "u", "b", "X", "m", "Z", "V", "x", "p", "W", "IE", "T", "v", "IA", "A9", "A5", "Ai", "O", "j", "h", "Ag", "P", "Ax", "Ap", "A6", "AV", "z", "AA", "A8", "AI", "A0", "AQ", "AB", "AE", "AC", "Ah", "Ao", "AG", "AD", "Aa", "AS", "AF", "AR", "As", "Aw", "Ay", "Ac", "An", "AU", "A$", "Az", "Ak", "Ar", "AY", "AJ", "Af", "AH", "AL", "AM", "Ad", "Aq", "AK", "Al", "Au", "Ab", "AX", "Am", "AZ", "A7", "A1", "AW", "A_", "AT", "A2", "Av", "AO", "Aj", "AP", "A4", "A3", "Ig", "IB", "BasicSample", "sampleName", "sampleRate", "samplePitch", "samplePitchCorrection", "sampleLink", "sampleType", "loopStart", "loopEnd", "e", "quality", "encodeVorbis", "SpessaSynthWarn", "Sample", "sampleStartIndex", "sampleEndIndex", "sampleLoopStartIndex", "sampleLoopEndIndex", "smplArr", "sampleIndex", "smplStart", "dataStartIndex", "buff", "vorbis", "stbvorbis", "audioData", "convertedSigned16", "i", "readSamples", "sampleHeadersChunk", "smplChunkData", "samples", "index", "sample", "readSample", "sampleHeaderData", "smplArrayData", "readBytesAsString", "readBytesAsUintLittleEndian", "signedInt8", "Instrument", "instrumentChunk", "readBytesAsString", "readBytesAsUintLittleEndian", "z", "i", "index", "amount", "zones", "readInstruments", "instrumentZones", "instruments", "instrument", "instrumentsAmount", "InstrumentZone", "dataArray", "index", "readBytesAsUintLittleEndian", "modulatorZoneSize", "generatorZoneSize", "generators", "i", "modulators", "samples", "sampleID", "g", "generatorTypes", "range", "readInstrumentZones", "zonesChunk", "instrumentGenerators", "instrumentModulators", "instrumentSamples", "zones", "zone", "PresetZone", "instruments", "instrumentID", "readPresetZones", "presetGenerators", "presetModulators", "Preset", "presetChunk", "readBytesAsString", "readBytesAsUintLittleEndian", "i", "amount", "zones", "z", "index", "keyMin", "keyMax", "key", "velocity", "samandgen", "midiNote", "memorized", "isInRange", "min", "max", "number", "identicalMod", "mod1", "mod2", "addUnique", "main", "adder", "g", "mg", "addUniqueMods", "m", "mm", "parsedGeneratorsAndSamples", "globalPresetGenerators", "globalPresetModulators", "currentZone", "zone", "presetGenerators", "presetModulators", "globalInstrumentGenerators", "globalInstrumentModulators", "instrumentZone", "instrumentGenerators", "instrumentModulators", "defaultModulators", "finalModulatorList", "mod", "identicalInstrumentModulator", "generatorTypes", "readPresets", "presetZones", "presets", "preset", "presetZonesAmount", "getIGEN", "igensize", "inst", "sum", "z", "g", "generatorTypes", "igendata", "IndexedByteArray", "igenIndex", "instrument", "instrumentZone", "gen", "writeWord", "writeDword", "writeRIFFChunk", "RiffChunk", "getSDTA", "smplStartOffsets", "smplEndOffsets", "compress", "quality", "vorbisFunc", "sampleDatas", "s", "i", "r", "SpessaSynthInfo", "consoleColors", "smplSize", "total", "smplData", "IndexedByteArray", "sample", "data", "startOffset", "endOffset", "jump", "smplChunk", "writeRIFFChunk", "RiffChunk", "getSHDR", "smplStartOffsets", "smplEndOffsets", "shdrData", "IndexedByteArray", "sample", "index", "writeStringAsBytes", "dwStart", "writeDword", "dwEnd", "loopStart", "loopEnd", "writeWord", "writeRIFFChunk", "RiffChunk", "getIMOD", "imodsize", "inst", "sum", "z", "imoddata", "IndexedByteArray", "imodIndex", "ibag", "mod", "writeWord", "writeLittleEndian", "writeRIFFChunk", "RiffChunk", "getIBAG", "ibagsize", "sum", "ibagdata", "IndexedByteArray", "zoneID", "generatorIndex", "modulatorIndex", "inst", "ibag", "writeWord", "writeRIFFChunk", "RiffChunk", "getINST", "instsize", "instdata", "IndexedByteArray", "instrumentStart", "instrumentID", "inst", "writeStringAsBytes", "writeWord", "writeRIFFChunk", "RiffChunk", "getPGEN", "pgensize", "preset", "size", "z", "g", "generatorTypes", "pgendata", "IndexedByteArray", "pgenIndex", "presetZone", "gen", "writeWord", "writeRIFFChunk", "RiffChunk", "getPMOD", "pmodsize", "preset", "sum", "z", "pmoddata", "IndexedByteArray", "pmodIndex", "pbag", "mod", "writeWord", "writeLittleEndian", "writeRIFFChunk", "RiffChunk", "getPBAG", "pbagsize", "sum", "pbagdata", "IndexedByteArray", "zoneID", "generatorIndex", "modulatorIndex", "preset", "pbag", "writeWord", "writeRIFFChunk", "RiffChunk", "getPHDR", "phdrsize", "phdrdata", "IndexedByteArray", "presetStart", "preset", "writeStringAsBytes", "writeWord", "writeDword", "writeRIFFChunk", "RiffChunk", "DEFAULT_WRITE_OPTIONS", "write", "options", "SpessaSynthGroupCollapsed", "consoleColors", "SpessaSynthInfo", "infoArrays", "type", "data", "major", "minor", "ckdata", "IndexedByteArray", "writeWord", "writeRIFFChunk", "RiffChunk", "arr", "writeStringAsBytes", "combined", "combineArrays", "infoChunk", "smplStartOffsets", "smplEndOffsets", "sdtaChunk", "getSDTA", "shdrChunk", "getSHDR", "igenChunk", "getIGEN", "imodChunk", "getIMOD", "ibagChunk", "getIBAG", "instChunk", "getINST", "pgenChunk", "getPGEN", "pmodChunk", "getPMOD", "pbagChunk", "getPBAG", "phdrChunk", "getPHDR", "pdtadata", "pdtaChunk", "riffdata", "main", "SpessaSynthGroupEnd", "SoundFont2", "_SoundFont2", "arrayBuffer", "IndexedByteArray", "SpessaSynthGroup", "consoleColors", "SpessaSynthGroupEnd", "firstChunk", "readRIFFChunk", "readBytesAsString", "infoChunk", "chunk", "text", "readBytesAsUintLittleEndian", "SpessaSynthInfo", "sdtaChunk", "sampleDataChunk", "presetChunk", "presetHeadersChunk", "presetZonesChunk", "presetModulatorsChunk", "presetGeneratorsChunk", "presetInstrumentsChunk", "presetInstrumentZonesChunk", "presetInstrumentModulatorsChunk", "presetInstrumentGeneratorsChunk", "presetSamplesChunk", "readSamples", "instrumentGenerators", "readGenerators", "instrumentModulators", "readModulators", "instrumentZones", "readInstrumentZones", "readInstruments", "presetGenerators", "presetModulators", "presetZones", "readPresetZones", "readPresets", "a", "b", "i", "z", "s", "instrument", "sample", "preset", "expected", "bankNr", "presetNr", "p", "SpessaSynthWarn", "presetName", "soundfonts", "mainSf", "presets", "newPreset", "existingPreset", "write", "handleMessage", "message", "data", "channel", "channelObject", "workletMessageType", "ALL_CHANNELS_OR_DIFFERENT_ACTION", "type", "value", "masterParameterType", "SpessaSynthLogging", "SpessaSynthWarn", "systemExclusive", "messageData", "channelOffset", "SpessaSynthWarn", "arrayToHexString", "consoleColors", "SpessaSynthInfo", "cents", "vol", "pan", "tuningValue", "messageValue", "channel", "isDrums", "keyShift", "transpose", "timecentLookupTable", "i", "timecents", "timecentsToSeconds", "MIN_ABS_CENT", "MAX_ABS_CENT", "absoluteCentLookupTable", "absoluteCents", "absCentsToHz", "cents", "MIN_DECIBELS", "MAX_DECIBELS", "decibelLookUpTable", "decibels", "decibelAttenuationToGain", "DEFAULT_WORKLET_VOLUME_ENVELOPE", "VOLUME_ENVELOPE_SMOOTHING_FACTOR", "DB_SILENCE", "GAIN_SILENCE", "recalculateVolumeEnvelope", "voice", "env", "timecentsToSeconds", "generatorTypes", "attackGain", "decibelAttenuationToGain", "applyVolumeEnvelope", "audioBuffer", "currentTime", "centibelOffset", "sampleTime", "smoothingFactor", "decibelOffset", "releaseSmoothingFactor", "releaseStartDb", "elapsedRelease", "dbDifference", "gain", "i", "db", "currentFrameTime", "filledBuffer", "newAttenuation", "DEFAULT_WORKLET_LOWPASS_FILTER", "applyLowpassFilter", "voice", "outputBuffer", "cutoffCents", "generatorTypes", "calculateCoefficients", "i", "input", "filtered", "absCentsToHz", "qDb", "decibelAttenuationToGain", "qGain", "w", "cosw", "alpha", "b1", "b0", "b2", "a0", "a1", "a2", "globalDumpedSamplesList", "clearSamplesList", "dumpSample", "channel", "sample", "id", "sampleDumpCallback", "deepClone", "obj", "clonedObj", "key", "getWorkletVoices", "midiNote", "velocity", "preset", "currentTime", "sampleRate", "cachedVoices", "debug", "workletVoices", "cached", "v", "voices", "sampleAndGenerators", "SpessaSynthWarn", "generators", "i", "addAndClampGenerator", "generatorTypes", "rootKey", "targetKey", "loopStart", "loopEnd", "loopingMode", "workletSample", "SpessaSynthTable", "m", "DEFAULT_WORKLET_LOWPASS_FILTER", "DEFAULT_WORKLET_VOLUME_ENVELOPE", "MOD_PRECOMPUTED_LENGTH", "concave", "convex", "i", "x", "getModulatorCurveValue", "direction", "curveType", "value", "polarity", "modulatorCurveTypes", "computeWorkletModulator", "controllerTable", "modulator", "voice", "rawSourceValue", "index", "NON_CC_INDEX_OFFSET", "modulatorSources", "sourceValue", "transforms", "rawSecondSrcValue", "secondSrcValue", "computedValue", "computeModulators", "sourceUsesCC", "sourceIndex", "modulators", "generators", "modulatedGenerators", "mod", "recalculateVolumeEnvelope", "volenvNeedsRecalculation", "generatorTypes", "computedDestinations", "destination", "m", "dest", "curve", "MOD_PRECOMPUTED_LENGTH", "i", "getModulatorCurveValue", "noteOn", "channel", "midiNote", "velocity", "enableDebugging", "sendEvent", "startTime", "voices", "getWorkletVoices", "data", "channelVoices", "voice", "exclusive", "generatorTypes", "v", "recalculateVolumeEnvelope", "computeModulators", "dataEntryCoarse", "channel", "dataValue", "channelObject", "addDefaultVibrato", "dataEntryStates", "SpessaSynthWarn", "consoleColors", "SpessaSynthInfo", "ccValue", "midiControllers", "reverb", "NON_CC_INDEX_OFFSET", "modulatorSources", "dataEntryFine", "actualTune", "finalTuning", "customControllers", "cents", "noteOff", "channel", "midiNote", "SpessaSynthWarn", "v", "killNote", "generatorTypes", "stopAll", "force", "channelVoices", "stopAllChannels", "SpessaSynthInfo", "consoleColors", "i", "controllerChange", "channel", "controllerNumber", "controllerValue", "force", "channelObject", "midiControllers", "actualCCNum", "v", "computeModulators", "bankNr", "SpessaSynthInfo", "consoleColors", "dataEntryStates", "setMIDIVolume", "volume", "setMasterGain", "SYNTHESIZER_GAIN", "setMasterPan", "pan", "muteChannel", "isMuted", "callEvent", "eventName", "eventData", "returnMessageType", "post", "data", "sendChannelProperties", "c", "range", "NON_CC_INDEX_OFFSET", "modulatorSources", "transposeAllChannels", "semitones", "force", "i", "transposeChannel", "channel", "channelObject", "keyShift", "currentTranspose", "customControllers", "setChannelTuning", "cents", "log", "SpessaSynthInfo", "consoleColors", "setChannelTuningSemitones", "setMasterTuning", "setModulationDepth", "pitchWheel", "MSB", "LSB", "NON_CC_INDEX_OFFSET", "modulatorSources", "bend", "v", "computeModulators", "channelPressure", "pressure", "polyPressure", "midiNote", "programChange", "channel", "programNumber", "userChange", "channelObject", "bank", "midiControllers", "preset", "setPreset", "i", "setDrums", "isDrum", "sendPresetList", "p", "reloadSoundFont", "buffer", "SoundFont2", "e", "returnMessageType", "clearSamplesList", "j", "SpessaSynthInfo", "consoleColors", "sampleDump", "sampleID", "sampleData", "v", "generatorTypes", "disableAndLockVibrato", "channel", "setVibrato", "depth", "rate", "delay", "WorkletSequencerMessageType", "WorkletSequencerReturnMessageType", "readBytesAsUintBigEndian", "dataArray", "bytesAmount", "out", "i", "_processEvent", "event", "trackIndex", "statusByteData", "getEvent", "offset", "messageTypes", "velocity", "toDelete", "n", "v", "midiControllers", "getTempo", "SpessaSynthWarn", "WorkletSequencerReturnMessageType", "k", "consoleColors", "_addNewMidiPort", "i", "DEFAULT_PERCUSSION", "readBytesAsUintBigEndian", "_processTick", "current", "trackIndex", "event", "eventNext", "_findFirstEventIndex", "index", "ticks", "track", "i", "defaultControllerArray", "midiControllers", "_playTo", "time", "ticks", "messageTypes", "ch", "MIDI_CHANNEL_COUNT", "channelsToSave", "pitchBends", "programs", "savedControllers", "trackIndex", "event", "info", "getEvent", "channel", "controllerNumber", "ccV", "nextEvent", "channelNumber", "value", "index", "play", "resetTime", "n", "timeOffset", "ticksToSeconds", "changes", "division", "tempo", "v", "timeSinceLastTempo", "setTimeTicks", "WorkletSequencerReturnMessageType", "isNotFinished", "_recalculateStartTime", "MidiData", "midi", "DUMMY_MIDI_DATA", "readVariableLengthQuantity", "MIDIbyteArray", "out", "byte", "MIDI", "arrayBuffer", "fileName", "SpessaSynthGroupCollapsed", "consoleColors", "binaryData", "IndexedByteArray", "fileByteArray", "initialString", "readBytesAsString", "rmid", "SpessaSynthGroupEnd", "riff", "readRIFFChunk", "startIndex", "currentChunk", "SpessaSynthInfo", "headerChunk", "readBytesAsUintBigEndian", "loopStart", "loopEnd", "portOffset", "i", "track", "trackChunk", "usedChannels", "runningByte", "totalTicks", "readVariableLengthQuantity", "statusByteCheck", "statusByte", "statusByteChannel", "getChannel", "eventDataLength", "dataBytesAmount", "messageTypes", "note", "eventData", "messageData", "message", "MidiMessage", "port", "arrayToHexString", "cutText", "decoded", "firstNoteOns", "t", "firstNoteOn", "e", "defaultPort", "name", "formatTitle", "chunk", "dataSlice", "ticks", "tempo", "v", "timeSinceLastTempo", "getUsedProgramsAndKeys", "mid", "soundfont", "SpessaSynthGroupCollapsed", "consoleColors", "channelsAmount", "channelPresets", "i", "bank", "DEFAULT_PERCUSSION", "updateString", "ch", "exists", "usedProgramsAndKeys", "SpessaSynthInfo", "eventIndexes", "remainingTracks", "findFirstEventIndex", "index", "ticks", "track", "ports", "system", "trackNum", "event", "messageTypes", "status", "channel", "midiControllers", "drumsBool", "sysexChannel", "isDrum", "key", "SpessaSynthGroupEnd", "assignMIDIPort", "trackNum", "port", "loadNewSequence", "parsedMidi", "s", "SpessaSynthGroupCollapsed", "consoleColors", "used", "getUsedProgramsAndKeys", "programBank", "combos", "bank", "program", "preset", "SpessaSynthInfo", "combo", "split", "SpessaSynthGroupEnd", "trackIndex", "ticksToSeconds", "formatTime", "WorkletSequencerReturnMessageType", "MidiData", "SpessaSynthWarn", "loadNewSongList", "midiBuffers", "mids", "b", "MIDI", "e", "nextSong", "previousSong", "processMessage", "messageType", "messageData", "WorkletSequencerMessageType", "WorkletSequencerReturnMessageType", "post", "returnMessageType", "sendMIDIMessage", "message", "WorkletSequencer", "spessasynthProcessor", "value", "time", "WorkletSequencerReturnMessageType", "isNotFinished", "isFinished", "SpessaSynthWarn", "i", "midiControllers", "c", "MIDI_CHANNEL_COUNT", "messageTypes", "post", "sendMIDIMessage", "assignMIDIPort", "processMessage", "_processEvent", "_addNewMidiPort", "_processTick", "_findFirstEventIndex", "loadNewSequence", "loadNewSongList", "nextSong", "previousSong", "play", "_playTo", "setTimeTicks", "_recalculateStartTime", "sendSynthesizerSnapshot", "synthesizerSnapshot", "channel", "returnMessageType", "applySynthesizerSnapshot", "snapshot", "channelSnapshot", "index", "channelObject", "midiControllers", "SpessaSynthInfo", "consoleColors", "getLFOValue", "startTime", "frequency", "currentTime", "xVal", "PEAK", "CONVEX_ATTACK", "i", "getModulatorCurveValue", "modulatorCurveTypes", "getModEnvValue", "voice", "currentTime", "attack", "timecentsToSeconds", "generatorTypes", "decay", "hold", "release", "sustain", "delayEnd", "attackEnd", "holdEnd", "decayEnd", "modEnvVal", "getOscillatorData", "voice", "sampleData", "outputBuffer", "cur", "loop", "loopLength", "floor", "ceil", "fraction", "upper", "lower", "panVoice", "gainLeft", "gainRight", "inputBuffer", "outputLeft", "outputRight", "reverb", "reverbLevel", "chorus", "chorusLevel", "reverbLeft", "reverbRight", "reverbGain", "reverbLeftGain", "reverbRightGain", "i", "chorusLeft", "chorusRight", "chorusGain", "chorusLeftGain", "chorusRightGain", "HALF_PI", "PAN_SMOOTHING_FACTOR", "renderVoice", "channel", "voice", "outputLeft", "outputRight", "reverbOutput", "chorusOutput", "recalculateVolumeEnvelope", "decibelAttenuationToGain", "generatorTypes", "cents", "customControllers", "semitones", "vibratoDepth", "vibStart", "timecentsToSeconds", "vibFreqHz", "absCentsToHz", "lfoVal", "getLFOValue", "lowpassCents", "modPitchDepth", "modVolDepth", "modFilterDepth", "modLfoCentibels", "modStart", "modFreqHz", "modLfoValue", "channelVibrato", "modEnvPitchDepth", "modEnvFilterDepth", "modEnv", "getModEnvValue", "centsTotal", "pan", "bufferOut", "getOscillatorData", "applyLowpassFilter", "applyVolumeEnvelope", "panLeft", "panRight", "reverb", "chorus", "panVoice", "getPriority", "priority", "voiceKilling", "amount", "allVoices", "a", "b", "voicesToRemove", "index", "releaseVoice", "MIN_NOTE_LENGTH", "resetAllControllers", "SpessaSynthInfo", "consoleColors", "channelNumber", "ch", "midiControllers", "DEFAULT_PERCUSSION", "restoreControllerValueEvent", "ccNum", "NON_CC_INDEX_OFFSET", "modulatorSources", "val", "msb", "lsb", "DEFAULT_SYNTH_MODE", "resetControllers", "channel", "channelObject", "excludedCCvalues", "lockedCCs", "cc", "resetArray", "transpose", "customControllers", "customResetArray", "resetParameters", "dataEntryStates", "MIN_NOTE_LENGTH", "SYNTHESIZER_GAIN", "SpessaSynthProcessor", "options", "WorkletSequencer", "VOICE_CAP", "SoundFont2", "e", "returnMessageType", "i", "DEFAULT_PERCUSSION", "VOLUME_ENVELOPE_SMOOTHING_FACTOR", "PAN_SMOOTHING_FACTOR", "DEFAULT_SYNTH_MODE", "SpessaSynthInfo", "consoleColors", "stbvorbis", "inputs", "outputs", "totalCurrentVoices", "channel", "index", "outputIndex", "outputLeft", "outputRight", "reverbChannels", "chorusChannels", "output", "tempV", "v", "renderVoice", "releaseVoice", "voiceKilling", "handleMessage", "post", "sendChannelProperties", "callEvent", "systemExclusive", "noteOn", "noteOff", "polyPressure", "killNote", "stopAll", "stopAllChannels", "muteChannel", "setVibrato", "disableAndLockVibrato", "dataEntryCoarse", "dataEntryFine", "createWorkletChannel", "controllerChange", "channelPressure", "resetAllControllers", "resetControllers", "resetParameters", "setMasterGain", "setMasterPan", "setMIDIVolume", "transposeAllChannels", "transposeChannel", "setChannelTuning", "setChannelTuningSemitones", "setMasterTuning", "setModulationDepth", "pitchWheel", "programChange", "setPreset", "setDrums", "reloadSoundFont", "sampleDump", "sendPresetList", "sendSynthesizerSnapshot", "applySynthesizerSnapshot", "WORKLET_PROCESSOR_NAME", "SpessaSynthProcessor", "SpessaSynthInfo", "consoleColors"]
|
|
7
|
-
}
|