midiwire 0.13.0 → 0.13.1
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/dist/midiwire.es.js +1 -1
- package/dist/midiwire.umd.js +1 -1
- package/package.json +1 -1
- package/src/utils/dx7/DX7Voice.js +1 -1
package/dist/midiwire.es.js
CHANGED
|
@@ -3017,7 +3017,7 @@ const t = class t {
|
|
|
3017
3017
|
99
|
|
3018
3018
|
);
|
|
3019
3019
|
const T = A.osc?.freq?.mode?.toUpperCase() === "FIXED" ? 1 : 0, f = Number(A.osc?.freq?.coarse) || 0, I = Number(A.osc?.freq?.fine) || 0;
|
|
3020
|
-
n[h + t.UNPACKED_OP_MODE] = T, s(h + t.UNPACKED_OP_FREQ_COARSE, f, `operators[${a}].osc.freq.coarse`, 0, 31), s(h + t.UNPACKED_OP_FREQ_FINE, I, `operators[${a}].osc.freq.fine`, 0,
|
|
3020
|
+
n[h + t.UNPACKED_OP_MODE] = T, s(h + t.UNPACKED_OP_FREQ_COARSE, f, `operators[${a}].osc.freq.coarse`, 0, 31), s(h + t.UNPACKED_OP_FREQ_FINE, I, `operators[${a}].osc.freq.fine`, 0, 99), s(
|
|
3021
3021
|
h + t.UNPACKED_OP_KEY_VEL_SENS,
|
|
3022
3022
|
A.key?.velocity || 0,
|
|
3023
3023
|
`operators[${a}].key.velocity`,
|
package/dist/midiwire.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(l,I){typeof exports=="object"&&typeof module<"u"?I(exports):typeof define=="function"&&define.amd?define(["exports"],I):(l=typeof globalThis<"u"?globalThis:l||self,I(l.MIDIControls={}))})(this,(function(l){"use strict";var dt=Object.defineProperty;var Tt=(l,I,K)=>I in l?dt(l,I,{enumerable:!0,configurable:!0,writable:!0,value:K}):l[I]=K;var _=(l,I,K)=>Tt(l,typeof I!="symbol"?I+"":I,K);class I{constructor(e,i="[data-midi-cc]"){this.controller=e,this.selector=i,this.observer=null}bindAll(){document.querySelectorAll(this.selector==="[data-midi-cc]"?"[data-midi-cc], [data-midi-msb][data-midi-lsb]":this.selector).forEach(i=>{if(i.hasAttribute("data-midi-bound"))return;const n=this._parseAttributes(i);n&&(this.controller.bind(i,n),i.setAttribute("data-midi-bound","true"))})}enableAutoBinding(){if(this.observer)return;const e=this.selector==="[data-midi-cc]"?"[data-midi-cc], [data-midi-msb][data-midi-lsb]":this.selector;this.observer=new MutationObserver(i=>{i.forEach(n=>{n.addedNodes.forEach(s=>{if(s.nodeType===Node.ELEMENT_NODE){if(s.matches?.(e)){const r=this._parseAttributes(s);r&&!s.hasAttribute("data-midi-bound")&&(this.controller.bind(s,r),s.setAttribute("data-midi-bound","true"))}s.querySelectorAll&&s.querySelectorAll(e).forEach(E=>{if(!E.hasAttribute("data-midi-bound")){const o=this._parseAttributes(E);o&&(this.controller.bind(E,o),E.setAttribute("data-midi-bound","true"))}})}}),n.removedNodes.forEach(s=>{s.nodeType===Node.ELEMENT_NODE&&(s.hasAttribute?.("data-midi-bound")&&this.controller.unbind(s),s.querySelectorAll&&s.querySelectorAll("[data-midi-bound]").forEach(E=>{this.controller.unbind(E)}))})})}),this.observer.observe(document.body,{childList:!0,subtree:!0})}disableAutoBinding(){this.observer&&(this.observer.disconnect(),this.observer=null)}_parseAttributes(e){const i=parseInt(e.dataset.midiMsb,10),n=parseInt(e.dataset.midiLsb,10);if(!Number.isNaN(i)&&!Number.isNaN(n)&&i>=0&&i<=127&&n>=0&&n<=127){const r=parseInt(e.dataset.midiCc,10);return!Number.isNaN(r)&&r>=0&&r<=127&&console.warn(`Element has both 7-bit (data-midi-cc="${r}") and 14-bit (data-midi-msb="${i}" data-midi-lsb="${n}") CC attributes. 14-bit takes precedence.`,e),{msb:i,lsb:n,is14Bit:!0,channel:parseInt(e.dataset.midiChannel,10)||void 0,min:parseFloat(e.getAttribute("min"))||0,max:parseFloat(e.getAttribute("max"))||127,invert:e.dataset.midiInvert==="true",label:e.dataset.midiLabel}}const s=parseInt(e.dataset.midiCc,10);return!Number.isNaN(s)&&s>=0&&s<=127?{cc:s,channel:parseInt(e.dataset.midiChannel,10)||void 0,min:parseFloat(e.getAttribute("min"))||0,max:parseFloat(e.getAttribute("max"))||127,invert:e.dataset.midiInvert==="true",label:e.dataset.midiLabel}:((e.dataset.midiCc!==void 0||e.dataset.midiMsb!==void 0&&e.dataset.midiLsb!==void 0)&&console.warn("Invalid MIDI configuration on element:",e),null)}destroy(){this.disableAutoBinding()}}class K extends Error{constructor(e,i){super(e),this.name="MIDIError",this.code=i,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class F extends K{constructor(e,i){super(e,"MIDI_ACCESS_ERROR"),this.name="MIDIAccessError",this.reason=i}}class y extends K{constructor(e){super(e,"MIDI_CONNECTION_ERROR"),this.name="MIDIConnectionError"}}class R extends K{constructor(e,i,n){super(e,"MIDI_DEVICE_ERROR"),this.name="MIDIDeviceError",this.deviceType=i,this.deviceId=n}}class M extends K{constructor(e,i){super(e,"MIDI_VALIDATION_ERROR"),this.name="MIDIValidationError",this.validationType=i}}class H extends Error{constructor(e,i){super(e),this.name="DX7Error",this.code=i,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class g extends H{constructor(e,i,n){super(e,"DX7_PARSE_ERROR"),this.name="DX7ParseError",this.parseType=i,this.offset=n}}class d extends H{constructor(e,i,n){super(e,"DX7_VALIDATION_ERROR"),this.name="DX7ValidationError",this.validationType=i,this.value=n}}function O(c,e,i){return Math.max(e,Math.min(i,c))}function w(c,e,i,n=!1){const s=(c-e)/(i-e),E=(n?1-s:s)*127;return O(Math.round(E),0,127)}function J(c,e,i,n=!1){let s=O(c,0,127)/127;return n&&(s=1-s),e+s*(i-e)}function k(c){const e={C:0,"C#":1,DB:1,D:2,"D#":3,EB:3,E:4,F:5,"F#":6,GB:6,G:7,"G#":8,AB:8,A:9,"A#":10,BB:10,B:11},i=c.match(/^([A-G][#b]?)(-?\d+)$/i);if(!i)throw new M(`Invalid note name: ${c}`,"note",c);const[,n,s]=i,r=e[n.toUpperCase()];if(r===void 0)throw new M(`Invalid note: ${n}`,"note",n);const E=(parseInt(s,10)+1)*12+r;return O(E,0,127)}function j(c,e=!1){const s=e?["C","Db","D","Eb","E","F","Gb","G","Ab","A","Bb","B"]:["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],r=Math.floor(c/12)-1;return`${s[c%12]}${r}`}function X(c){const e=69+12*Math.log2(c/440);return O(Math.round(e),0,127)}function tt(c){return 440*2**((c-69)/12)}function et(c){return{0:"Bank Select",1:"Modulation",2:"Breath Controller",4:"Foot Controller",5:"Portamento Time",7:"Volume",8:"Balance",10:"Pan",11:"Expression",64:"Sustain Pedal",65:"Portamento",66:"Sostenuto",67:"Soft Pedal",68:"Legato",71:"Resonance",72:"Release Time",73:"Attack Time",74:"Cutoff",75:"Decay Time",76:"Vibrato Rate",77:"Vibrato Depth",78:"Vibrato Delay",84:"Portamento Control",91:"Reverb",92:"Tremolo",93:"Chorus",94:"Detune",95:"Phaser",120:"All Sound Off",121:"Reset All Controllers",123:"All Notes Off"}[c]||`CC ${c}`}function B(c){const e=O(Math.round(c),0,16383);return{msb:e>>7&127,lsb:e&127}}function Y(c,e){return O(c,0,127)<<7|O(e,0,127)}function x(c,e,i,n=!1){const s=(c-e)/(i-e),E=(n?1-s:s)*16383;return B(E)}function it(c,e,i,n,s=!1){let E=Y(c,e)/16383;return s&&(E=1-E),i+E*(n-i)}class v{constructor(){this.events=new Map}on(e,i){return this.events.has(e)||this.events.set(e,[]),this.events.get(e).push(i),()=>this.off(e,i)}once(e,i){const n=(...s)=>{i(...s),this.off(e,n)};this.on(e,n)}off(e,i){if(!this.events.has(e))return;const n=this.events.get(e),s=n.indexOf(i);s>-1&&n.splice(s,1),n.length===0&&this.events.delete(e)}emit(e,i){if(!this.events.has(e))return;[...this.events.get(e)].forEach(s=>{try{s(i)}catch(r){console.error(`Error in event handler for "${e}":`,r)}})}removeAllListeners(e){e?this.events.delete(e):this.events.clear()}}const p={DEVICE_CHANGE:"device-change",IN_DEV_CONNECTED:"in-dev-connected",IN_DEV_DISCONNECTED:"in-dev-disconnected",OUT_DEV_CONNECTED:"out-dev-connected",OUT_DEV_DISCONNECTED:"out-dev-disconnected"};class $ extends v{constructor(e={}){super(),this.options={sysex:!1,...e},this.midiAccess=null,this.output=null,this.input=null}async requestAccess(){if(!navigator.requestMIDIAccess)throw new F("Web MIDI API is not supported in this browser","unsupported");try{this.midiAccess=await navigator.requestMIDIAccess({sysex:this.options.sysex}),this.midiAccess.onstatechange=e=>{const i=e.port,n=e.port.state;this.emit(p.DEVICE_CHANGE,{port:i,state:n,type:i.type,device:{id:i.id,name:i.name,manufacturer:i.manufacturer||"Unknown"}}),n==="disconnected"?i.type==="input"?(this.emit(p.IN_DEV_DISCONNECTED,{device:i}),this.input&&this.input.id===i.id&&(this.input=null)):i.type==="output"&&(this.emit(p.OUT_DEV_DISCONNECTED,{device:i}),this.output&&this.output.id===i.id&&(this.output=null)):n==="connected"&&(i.type==="input"?this.emit(p.IN_DEV_CONNECTED,{device:i}):i.type==="output"&&this.emit(p.OUT_DEV_CONNECTED,{device:i}))}}catch(e){throw e.name==="SecurityError"?new F("MIDI access denied. SysEx requires user permission.","denied"):new F(`Failed to get MIDI access: ${e.message}`,"failed")}}async connect(e){if(!this.midiAccess)throw new y("MIDI access not initialized. Call requestAccess() first.");const i=Array.from(this.midiAccess.outputs.values());if(i.length===0)throw new R("No MIDI output devices available","output");if(e===void 0){this.output=i[0];return}if(typeof e=="number"){if(e<0||e>=i.length)throw new R(`Output index ${e} out of range (0-${i.length-1})`,"output",e);this.output=i[e];return}if(this.output=i.find(n=>n.name===e||n.id===e),!this.output){const n=i.map(s=>s.name).join(", ");throw new R(`MIDI output "${e}" not found. Available: ${n}`,"output",e)}}async connectInput(e,i){if(!this.midiAccess)throw new y("MIDI access not initialized. Call requestAccess() first.");if(typeof i!="function")throw new M("onMessage callback must be a function","callback");const n=Array.from(this.midiAccess.inputs.values());if(n.length===0)throw new R("No MIDI input devices available","input");if(this.input&&(this.input.onmidimessage=null),e===void 0)this.input=n[0];else if(typeof e=="number"){if(e<0||e>=n.length)throw new R(`Input index ${e} out of range (0-${n.length-1})`,"input",e);this.input=n[e]}else if(this.input=n.find(s=>s.name===e||s.id===e),!this.input){const s=n.map(r=>r.name).join(", ");throw new R(`MIDI input "${e}" not found. Available: ${s}`,"input",e)}this.input.onmidimessage=s=>{i(s)}}disconnectOutput(){this.output=null}disconnectInput(){this.input&&(this.input.onmidimessage=null,this.input=null)}disconnect(){this.disconnectOutput(),this.disconnectInput()}isConnected(){return this.output!==null}getCurrentOutput(){return this.output?{id:this.output.id,name:this.output.name,manufacturer:this.output.manufacturer||"Unknown"}:null}getCurrentInput(){return this.input?{id:this.input.id,name:this.input.name,manufacturer:this.input.manufacturer||"Unknown"}:null}getOutputs(){if(!this.midiAccess)return[];const e=[];return this.midiAccess.outputs.forEach(i=>{i.state==="connected"&&e.push({id:i.id,name:i.name,manufacturer:i.manufacturer||"Unknown"})}),e}getInputs(){if(!this.midiAccess)return[];const e=[];return this.midiAccess.inputs.forEach(i=>{i.state==="connected"&&e.push({id:i.id,name:i.name,manufacturer:i.manufacturer||"Unknown"})}),e}send(e,i=null){if(!this.output){console.warn("No MIDI output connected. Call connect() first.");return}try{const n=new Uint8Array(e);i===null?this.output.send(n):this.output.send(n,i)}catch(n){console.error("Failed to send MIDI message:",n)}}sendSysEx(e,i=!1){if(!this.options.sysex){console.warn("SysEx not enabled. Initialize with sysex: true");return}let n;i?n=[240,...e,247]:n=e,this.send(n)}}const A={READY:"ready",ERROR:"error",DESTROYED:"destroyed",DEV_OUT_CONNECTED:"dev-out-connected",DEV_OUT_DISCONNECTED:"dev-out-disconnected",DEV_IN_CONNECTED:"dev-in-connected",DEV_IN_DISCONNECTED:"dev-in-disconnected",CH_CC_SEND:"ch-cc-send",CH_CC_RECV:"ch-cc-recv",CH_NOTE_ON_SEND:"ch-note-on-send",CH_NOTE_ON_RECV:"ch-note-on-recv",CH_NOTE_OFF_SEND:"ch-note-off-send",CH_NOTE_OFF_RECV:"ch-note-off-recv",CH_PC_SEND:"ch-pc-send",CH_PC_RECV:"ch-pc-recv",CH_PITCH_BEND_SEND:"ch-pitch-bend-send",CH_PITCH_BEND_RECV:"ch-pitch-bend-recv",CH_MONO_PRESS_SEND:"ch-mono-press-send",CH_MONO_PRESS_RECV:"ch-mono-press-recv",CH_POLY_PRESS_SEND:"ch-poly-press-send",CH_POLY_PRESS_RECV:"ch-poly-press-recv",CH_ALL_SOUNDS_OFF_SEND:"ch-all-sounds-off-send",CH_RESET_CONTROLLERS_SEND:"ch-reset-controllers-send",CH_LOCAL_CONTROL_SEND:"ch-local-control-send",CH_ALL_NOTES_OFF_SEND:"ch-all-notes-off-send",CH_OMNI_OFF_SEND:"ch-omni-off-send",CH_OMNI_ON_SEND:"ch-omni-on-send",CH_MONO_ON_SEND:"ch-mono-on-send",CH_POLY_ON_SEND:"ch-poly-on-send",SYS_EX_SEND:"sys-ex-send",SYS_EX_RECV:"sys-ex-recv",SYS_CLOCK_RECV:"sys-clock-recv",SYS_START_RECV:"sys-start-recv",SYS_CONTINUE_RECV:"sys-continue-recv",SYS_STOP_RECV:"sys-stop-recv",SYS_MTC_RECV:"sys-mtc-recv",SYS_SONG_POS_RECV:"sys-song-pos-recv",SYS_SONG_SEL_RECV:"sys-song-sel-recv",SYS_TUNE_REQ_RECV:"sys-tune-req-recv",SYS_ACT_SENSE_RECV:"sys-act-sense-recv",SYS_RESET_RECV:"sys-reset-recv",MIDI_RAW:"midi-raw",PATCH_SAVED:"patch-saved",PATCH_LOADED:"patch-loaded",PATCH_DELETED:"patch-deleted"};class Z extends v{constructor(e={}){super(),this.options={inputChannel:1,outputChannel:1,autoConnect:!0,sysex:!1,...e},this.connection=null,this.bindings=new Map,this.state={controlChange:new Map,programChange:new Map,pitchBend:new Map,monoPressure:new Map,polyPressure:new Map},this.initialized=!1,this._initNamespaces()}async init(){if(this.initialized){console.warn("MIDI Controller already initialized");return}try{this.connection=new $({sysex:this.options.sysex}),await this.connection.requestAccess(),this.connection.on(p.DEVICE_CHANGE,async({state:e,type:i,device:n})=>{try{if(e==="connected")i==="output"?this.emit(A.DEV_OUT_CONNECTED,n):i==="input"&&this.emit(A.DEV_IN_CONNECTED,n);else if(e==="disconnected"){if(i==="output"&&n){const s=this.connection.getCurrentOutput();s&&s.id===n.id?await this._disconnectOutput():this.emit(A.DEV_OUT_DISCONNECTED,n)}if(i==="input"&&n){const s=this.connection.getCurrentInput();s&&s.id===n.id?await this._disconnectInput():this.emit(A.DEV_IN_DISCONNECTED,n)}}}catch(s){console.error("Error in device change handler:",s),this.emit(A.ERROR,s)}}),this.options.autoConnect&&await this.connection.connect(this.options.output),this.options.input!==void 0&&await this._connectInput(this.options.input),this.initialized=!0,this.emit(A.READY,this),this.options.onReady?.(this)}catch(e){throw this.emit(A.ERROR,e),this.options.onError?.(e),e}}_initNamespaces(){this.device={connect:this._connect.bind(this),disconnect:this._disconnect.bind(this),connectInput:this._connectInput.bind(this),disconnectInput:this._disconnectInput.bind(this),connectOutput:this._connectOutput.bind(this),disconnectOutput:this._disconnectOutput.bind(this),getCurrentOutput:this._getCurrentOutput.bind(this),getCurrentInput:this._getCurrentInput.bind(this),getOutputs:this._getOutputs.bind(this),getInputs:this._getInputs.bind(this)},this.channel={sendNoteOn:this._sendNoteOn.bind(this),sendNoteOff:this._sendNoteOff.bind(this),sendCC:this._sendCC.bind(this),getCC:this._getCC.bind(this),sendPC:this._sendPC.bind(this),getPC:this._getPC.bind(this),sendPitchBend:this._sendPitchBend.bind(this),getPitchBend:this._getPitchBend.bind(this),sendMonoPressure:this._sendMonoPressure.bind(this),getMonoPressure:this._getMonoPressure.bind(this),sendPolyPressure:this._sendPolyPressure.bind(this),getPolyPressure:this._getPolyPressure.bind(this),allSoundsOff:this._allSoundsOff.bind(this),resetControllers:this._resetControllers.bind(this),localControl:this._localControl.bind(this),allNotesOff:this._allNotesOff.bind(this),omniOff:this._omniOff.bind(this),omniOn:this._omniOn.bind(this),monoOn:this._monoOn.bind(this),polyOn:this._polyOn.bind(this)},this.system={sendEx:function(e,i=!1){return this._sendSysEx(e,i)}.bind(this),sendClock:this._sendClock.bind(this),start:this._sendStart.bind(this),continue:this._sendContinue.bind(this),stop:this._sendStop.bind(this),sendMTC:this._sendMTC.bind(this),sendSongPosition:this._sendSongPosition.bind(this),sendSongSelect:this._sendSongSelect.bind(this),sendTuneRequest:this._sendTuneRequest.bind(this),sendActiveSensing:this._sendActiveSensing.bind(this),sendSystemReset:this._sendSystemReset.bind(this)},this.patch={get:this._getPatch.bind(this),set:this._setPatch.bind(this),save:this._savePatch.bind(this),load:this._loadPatch.bind(this),delete:this._deletePatch.bind(this),list:this._listPatches.bind(this)}}bind(e,i,n={}){if(!e)return console.warn("Cannot bind: element is null or undefined"),()=>{};const s=this._createBinding(e,i,n);return this.bindings.set(e,s),this.initialized&&this.connection?.isConnected()&&s.handler({target:e}),()=>this.unbind(e)}_createBinding(e,i,n={}){const{min:s=parseFloat(e.getAttribute("min"))||0,max:r=parseFloat(e.getAttribute("max"))||127,channel:E,invert:o=!1,onInput:h=void 0}=i,{debounce:N=0}=n,u={...i,min:s,max:r,invert:o,onInput:h};if(E!==void 0&&(u.channel=E),i.is14Bit){const{msb:T,lsb:f}=i,U=V=>{const W=parseFloat(V.target.value);if(Number.isNaN(W))return;const{msb:Dt,lsb:Ot}=x(W,s,r,o),Q=E||this.options.outputChannel;this._sendCC(T,Dt,Q),this._sendCC(f,Ot,Q)};let L=null;const b=N>0?V=>{L&&clearTimeout(L),L=setTimeout(()=>{U(V),L=null},N)}:U;return e.addEventListener("input",b),e.addEventListener("change",b),{element:e,config:u,handler:U,destroy:()=>{L&&clearTimeout(L),e.removeEventListener("input",b),e.removeEventListener("change",b)}}}const{cc:a}=i,C=T=>{const f=parseFloat(T.target.value);if(Number.isNaN(f))return;const U=w(f,s,r,o),L=E===void 0?this.options.outputChannel:E;this._sendCC(a,U,L)};let S=null;const D=N>0?T=>{S&&clearTimeout(S),S=setTimeout(()=>{C(T),S=null},N)}:C;return e.addEventListener("input",D),e.addEventListener("change",D),{element:e,config:u,handler:C,destroy:()=>{S&&clearTimeout(S),e.removeEventListener("input",D),e.removeEventListener("change",D)}}}unbind(e){const i=this.bindings.get(e);i&&(i.destroy(),this.bindings.delete(e))}async destroy(){for(const e of this.bindings.values())e.destroy();this.bindings.clear(),this.state.controlChange.clear(),this.state.programChange.clear(),this.state.pitchBend.clear(),this.state.monoPressure.clear(),this.state.polyPressure.clear(),await this._disconnect(),this.initialized=!1,this.emit(A.DESTROYED),this.removeAllListeners()}async _connect(e){e?await this.connection.connect(e):this.options.output!==void 0?await this.connection.connect(this.options.output):this.options.autoConnect&&await this.connection.connect()}async _disconnect(){this.connection.disconnect()}async _connectInput(e){await this.connection.connectInput(e,i=>{this._handleMIDIMessage(i)}),this.emit(A.DEV_IN_CONNECTED,this.connection.getCurrentInput())}async _disconnectInput(){const e=this.connection.getCurrentInput();this.connection.disconnectInput(),this.emit(A.DEV_IN_DISCONNECTED,e)}async _connectOutput(e){await this.connection.connect(e),this.emit(A.DEV_OUT_CONNECTED,this.connection.getCurrentOutput())}async _disconnectOutput(){const e=this.connection.getCurrentOutput();this.connection.disconnectOutput(),this.emit(A.DEV_OUT_DISCONNECTED,e)}_getCurrentOutput(){return this.connection?.getCurrentOutput()||null}_getCurrentInput(){return this.connection?.getCurrentInput()||null}_getOutputs(){return this.connection?.getOutputs()||[]}_getInputs(){return this.connection?.getInputs()||[]}send(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send(e)}_sendNoteOn(e,i=64,n=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),0,127),n=O(Math.round(n),1,16);const s=144+(n-1);this.connection.send([s,e,i]),this.emit(A.CH_NOTE_ON_SEND,{note:e,velocity:i,channel:n})}_sendNoteOff(e,i=this.options.outputChannel,n=0){if(!this.initialized)return;e=O(Math.round(e),0,127),n=O(Math.round(n),0,127),i=O(Math.round(i),1,16);const s=144+(i-1);this.connection.send([s,e,n]),this.emit(A.CH_NOTE_OFF_SEND,{note:e,channel:i,velocity:n})}_sendCC(e,i,n=this.options.outputChannel){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,127),i=O(Math.round(i),0,127),n=O(Math.round(n),1,16);const s=176+(n-1);this.connection.send([s,e,i]);const r=`${n}:${e}`;this.state.controlChange.set(r,i),this.emit(A.CH_CC_SEND,{cc:e,value:i,channel:n})}_sendPC(e,i=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),1,16);const n=192+(i-1);this.connection.send([n,e]),this.state.programChange.set(i.toString(),e),this.emit(A.CH_PC_SEND,{program:e,channel:i})}_getPC(e=this.options.inputChannel){return this.state.programChange.get(e.toString())}_getCC(e,i=this.options.inputChannel){const n=`${i}:${e}`;return this.state.controlChange.get(n)}_sendPitchBend(e,i=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,16383),i=O(Math.round(i),1,16);const n=224+(i-1),s=e&127,r=e>>7&127;this.connection.send([n,s,r]),this.state.pitchBend.set(i.toString(),e),this.emit(A.CH_PITCH_BEND_SEND,{value:e,channel:i})}_getPitchBend(e=this.options.inputChannel){return this.state.pitchBend.get(e.toString())}_sendMonoPressure(e,i=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),1,16);const n=208+(i-1);this.connection.send([n,e]),this.state.monoPressure.set(i.toString(),e),this.emit(A.CH_MONO_PRESS_SEND,{pressure:e,channel:i})}_getMonoPressure(e=this.options.inputChannel){return this.state.monoPressure.get(e.toString())}_sendPolyPressure(e,i,n=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),0,127),n=O(Math.round(n),1,16);const s=160+(n-1);this.connection.send([s,e,i]);const r=`${n}:${e}`;this.state.polyPressure.set(r,i),this.emit(A.CH_POLY_PRESS_SEND,{note:e,pressure:i,channel:n})}_getPolyPressure(e,i=this.options.inputChannel){const n=`${i}:${e}`;return this.state.polyPressure.get(n)}_allSoundsOff(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,120,0]),this.emit(A.CH_ALL_SOUNDS_OFF_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,120,0])}this.emit(A.CH_ALL_SOUNDS_OFF_SEND,{channel:null})}}_resetControllers(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,121,0]),this.emit(A.CH_RESET_CONTROLLERS_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,121,0])}this.emit(A.CH_RESET_CONTROLLERS_SEND,{channel:null})}}_localControl(e,i){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}const n=e?127:0;if(i!==void 0){i=O(Math.round(i),1,16);const s=176+(i-1);this.connection.send([s,122,n]),this.emit(A.CH_LOCAL_CONTROL_SEND,{enabled:e,channel:i})}else{for(let s=1;s<=16;s++){const r=176+(s-1);this.connection.send([r,122,n])}this.emit(A.CH_LOCAL_CONTROL_SEND,{enabled:e,channel:null})}}_allNotesOff(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,123,0]),this.emit(A.CH_ALL_NOTES_OFF_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,123,0])}this.emit(A.CH_ALL_NOTES_OFF_SEND,{channel:null})}}_omniOff(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,124,0]),this.emit(A.CH_OMNI_OFF_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,124,0])}this.emit(A.CH_OMNI_OFF_SEND,{channel:null})}}_omniOn(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,125,0]),this.emit(A.CH_OMNI_ON_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,125,0])}this.emit(A.CH_OMNI_ON_SEND,{channel:null})}}_monoOn(e=1,i){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e=Math.max(0,Math.min(16,Math.round(e))),i!==void 0){i=O(Math.round(i),1,16);const n=176+(i-1);this.connection.send([n,126,e]),this.emit(A.CH_MONO_ON_SEND,{channels:e,channel:i})}else{for(let n=1;n<=16;n++){const s=176+(n-1);this.connection.send([s,126,e])}this.emit(A.CH_MONO_ON_SEND,{channels:e,channel:null})}}_polyOn(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,127,0]),this.emit(A.CH_POLY_ON_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,127,0])}this.emit(A.CH_POLY_ON_SEND,{channel:null})}}_sendSysEx(e,i=!1){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(!this.options.sysex){console.warn("SysEx not enabled. Initialize with sysex: true");return}this.connection.sendSysEx(e,i),this.emit(A.SYS_EX_SEND,{data:e,includeWrapper:i})}_sendClock(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([248])}_sendStart(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([250])}_sendContinue(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([251])}_sendStop(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([252])}_sendMTC(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,127),this.connection.send([241,e])}_sendSongPosition(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,16383);const i=e&127,n=e>>7&127;this.connection.send([242,i,n])}_sendSongSelect(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,127),this.connection.send([243,e])}_sendTuneRequest(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([246])}_sendActiveSensing(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([254])}_sendSystemReset(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([255])}_handleMIDIMessage(e){const[i,n,s]=e.data,r=i&240,E=(i&15)+1;if(i===248){this.emit(A.SYS_CLOCK_RECV,{timestamp:e.midiwire});return}if(i===250){this.emit(A.SYS_START_RECV,{timestamp:e.midiwire});return}if(i===251){this.emit(A.SYS_CONTINUE_RECV,{timestamp:e.midiwire});return}if(i===252){this.emit(A.SYS_STOP_RECV,{timestamp:e.midiwire});return}if(i===254){this.emit(A.SYS_ACT_SENSE_RECV,{timestamp:e.midiwire});return}if(i===255){this.emit(A.SYS_RESET_RECV,{timestamp:e.midiwire});return}if(i===240){this.emit(A.SYS_EX_RECV,{data:Array.from(e.data),timestamp:e.midiwire});return}if(i===241){this.emit(A.SYS_MTC_RECV,{data:n,timestamp:e.midiwire});return}if(i===242){const o=n+(s<<7);this.emit(A.SYS_SONG_POS_RECV,{position:o,timestamp:e.midiwire});return}if(i===243){this.emit(A.SYS_SONG_SEL_RECV,{song:n,timestamp:e.midiwire});return}if(i===246){this.emit(A.SYS_TUNE_REQ_RECV,{timestamp:e.midiwire});return}if(i===247){this.emit(A.MIDI_RAW,{status:i,data:[n,s],channel:E,timestamp:e.midiwire});return}if(r===176){const o=`${E}:${n}`;this.state.controlChange.set(o,s),this.emit(A.CH_CC_RECV,{cc:n,value:s,channel:E});return}if(r===192){this.state.programChange.set(E.toString(),n),this.emit(A.CH_PC_RECV,{program:n,channel:E});return}if(r===224){const o=n+(s<<7);this.state.pitchBend.set(E.toString(),o),this.emit(A.CH_PITCH_BEND_RECV,{value:o,channel:E});return}if(r===208){this.state.monoPressure.set(E.toString(),n),this.emit(A.CH_MONO_PRESS_RECV,{pressure:n,channel:E});return}if(r===160){const o=`${E}:${n}`;this.state.polyPressure.set(o,s),this.emit(A.CH_POLY_PRESS_RECV,{note:n,pressure:s,channel:E});return}if(r===144&&s>0){this.emit(A.CH_NOTE_ON_RECV,{note:n,velocity:s,channel:E});return}if(r===128||r===144&&s===0){this.emit(A.CH_NOTE_OFF_RECV,{note:n,channel:E});return}this.emit(A.MIDI_RAW,{status:i,data:[n,s],channel:E,timestamp:e.midiwire})}_getPatch(e="Unnamed Patch"){const i={name:e,device:this._getCurrentOutput()?.name||null,timestamp:new Date().toISOString(),version:"1.0",channels:{},settings:{}};for(const[n,s]of this.state.controlChange.entries()){const[r,E]=n.split(":").map(Number);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].ccs[E]=s}for(const[n,s]of this.state.programChange.entries()){const r=parseInt(n,10);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].program=s}for(const[n,s]of this.state.pitchBend.entries()){const r=parseInt(n,10);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].pitchBend=s}for(const[n,s]of this.state.monoPressure.entries()){const r=parseInt(n,10);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].monoPressure=s}for(const[n,s]of this.state.polyPressure.entries()){const[r,E]=n.split(":").map(Number),o=parseInt(r,10);i.channels[o]||(i.channels[o]={ccs:{},notes:{}}),i.channels[o].polyPressure||(i.channels[o].polyPressure={}),i.channels[o].polyPressure[E]=s}for(const[n,s]of this.bindings.entries()){const{config:r}=s;if(r.cc){const E=`cc${r.cc}`;i.settings[E]={min:r.min,max:r.max,invert:r.invert||!1,is14Bit:r.is14Bit||!1,label:n.getAttribute?.("data-midi-label")||null,elementId:n.id||null}}}return i}async _setPatch(e){if(!e||!e.channels)throw new M("Invalid patch format","patch");const i=e.version||"1.0";i==="1.0"?await this._applyPatchV1(e):(console.warn(`Unknown patch version: ${i}. Attempting to apply as v1.0`),await this._applyPatchV1(e)),this.emit(A.PATCH_LOADED,{patch:e})}async _applyPatchV1(e){for(const[i,n]of Object.entries(e.channels)){const s=parseInt(i,10);if(n.ccs)for(const[r,E]of Object.entries(n.ccs)){const o=parseInt(r,10);this._sendCC(o,E,s)}if(n.program!==void 0&&this._sendPC(n.program,s),n.pitchBend!==void 0&&this._sendPitchBend(n.pitchBend,s),n.monoPressure!==void 0&&this._sendMonoPressure(n.monoPressure,s),n.polyPressure)for(const[r,E]of Object.entries(n.polyPressure)){const o=parseInt(r,10);this._sendPolyPressure(o,E,s)}if(n.notes)for(const[r,E]of Object.entries(n.notes)){const o=parseInt(r,10);E>0?this._sendNoteOn(o,E,s):this._sendNoteOff(o,s)}}if(e.settings)for(const[i,n]of Object.entries(e.settings))for(const[s,r]of this.bindings.entries())r.config.cc?.toString()===i.replace("cc","")&&(s.min!==void 0&&n.min!==void 0&&(s.min=String(n.min)),s.max!==void 0&&n.max!==void 0&&(s.max=String(n.max)));for(const[i,n]of this.bindings.entries()){const{config:s}=n;if(s.cc!==void 0){const r=s.channel||this.options.inputChannel,E=e.channels[r];if(E?.ccs){const o=E.ccs[s.cc];if(o!==void 0){const h=s.min!==void 0?s.min:parseFloat(i.getAttribute?.("min"))||0,N=s.max!==void 0?s.max:parseFloat(i.getAttribute?.("max"))||127,u=s.invert||!1;let a;u?a=N-o/127*(N-h):a=h+o/127*(N-h),s.onInput&&typeof s.onInput=="function"?s.onInput(a):(i.value=a,i.dispatchEvent(new Event("input",{bubbles:!0})))}}}}}_savePatch(e,i=null){const n=i||this._getPatch(e),s=`midiwire_patch_${e}`;try{return localStorage.setItem(s,JSON.stringify(n)),this.emit(A.PATCH_SAVED,{name:e,patch:n}),s}catch(r){throw console.error("Failed to save patch:",r),r}}_loadPatch(e){const i=`midiwire_patch_${e}`;try{const n=localStorage.getItem(i);if(!n)return null;const s=JSON.parse(n);return this.emit(A.PATCH_LOADED,{name:e,patch:s}),s}catch(n){return console.error("Failed to load patch:",n),null}}_deletePatch(e){const i=`midiwire_patch_${e}`;try{return localStorage.removeItem(i),this.emit(A.PATCH_DELETED,{name:e}),!0}catch(n){return console.error("Failed to delete patch:",n),!1}}_listPatches(){const e=[];try{for(let i=0;i<localStorage.length;i++){const n=localStorage.key(i);if(n?.startsWith("midiwire_patch_")){const s=n.replace("midiwire_patch_",""),r=this._loadPatch(s);r&&e.push({name:s,patch:r})}}}catch(i){console.error("Failed to list patches:",i)}return e.sort((i,n)=>i.name.localeCompare(n.name))}}class z{constructor(e={}){this.midi=e.midiController||null,this.onStatusUpdate=e.onStatusUpdate||(()=>{}),this.onConnectionUpdate=e.onConnectionUpdate||(()=>{}),this.channel=e.channel||1,this.currentOutput=null,this.currentInput=null,this.isConnecting=!1}async setupSelectors(e={},i={}){if(!this.midi)throw new Error("MIDI controller not initialized. Pass midiController in constructor options.");const{output:n,input:s,channel:r}=e,E=this._resolveSelector(n),o=this._resolveSelector(s),h=this._resolveSelector(r);if(this._setupDeviceChangeListeners({output:E,input:o},i.onDeviceListChange),E){await this._populateOutputDeviceList(E);const N=i.onConnect?async(a,C)=>i.onConnect({midi:a,device:C,type:"output"}):void 0,u=i.onDisconnect?async a=>i.onDisconnect({midi:a,type:"output"}):void 0;this._connectOutputDeviceSelection(E,N,u)}if(o){await this._populateInputDeviceList(o);const N=i.onConnect?async(a,C)=>i.onConnect({midi:a,device:C,type:"input"}):void 0,u=i.onDisconnect?async a=>i.onDisconnect({midi:a,type:"input"}):void 0;this._connectInputDeviceSelection(o,N,u)}return h&&this._connectChannelSelection(h,"output"),this.midi}updateStatus(e,i=""){this.onStatusUpdate(e,i)}updateConnectionStatus(){this.onConnectionUpdate(this.currentOutput,this.currentInput,this.midi)}_setupDeviceChangeListeners(e={},i){!this.midi||this._listenersInitialized||(this._listenersInitialized=!0,this.midi.on(A.DEV_OUT_CONNECTED,async n=>{this.updateStatus(`Output device connected: ${n?.name||"Unknown"}`,"connected"),e.output&&await this._populateOutputDeviceList(e.output),i&&i()}),this.midi.on(A.DEV_OUT_DISCONNECTED,async n=>{this.updateStatus(`Output device disconnected: ${n?.name||"Unknown"}`,"error"),this.currentOutput&&n?.name===this.currentOutput.name&&(this.currentOutput=null,this.updateConnectionStatus(),e.output&&(e.output.value="")),e.output&&await this._populateOutputDeviceList(e.output),i&&i()}),this.midi.on(A.DEV_IN_CONNECTED,async n=>{this.updateStatus(`Input device connected: ${n?.name||"Unknown"}`,"connected"),e.input&&await this._populateInputDeviceList(e.input),i&&i()}),this.midi.on(A.DEV_IN_DISCONNECTED,async n=>{this.updateStatus(`Input device disconnected: ${n?.name||"Unknown"}`,"error"),e.input&&(e.input.value="",await this._populateInputDeviceList(e.input)),i&&i()}))}_resolveSelector(e){if(typeof e=="string"){const i=document.querySelector(e);return i||console.warn(`MIDIDeviceManager: Selector "${e}" not found`),i}return e||null}_getOutputDevices(){return this.midi?this.midi.device.getOutputs():[]}_getInputDevices(){return this.midi?this.midi.device.getInputs():[]}_connectOutputDeviceSelection(e,i,n){!e||!this.midi||e.addEventListener("change",async s=>{if(this.isConnecting)return;this.isConnecting=!0;const r=s.target.value;if(!r){this.currentOutput&&this.midi&&(await this.midi.device.disconnectOutput(),this.currentOutput=null,this.updateStatus("Output device disconnected",""),this.updateConnectionStatus()),this.isConnecting=!1,n&&await n(this.midi);return}try{if(await this.midi.device.connectOutput(parseInt(r,10)),this.currentOutput=this.midi.device.getCurrentOutput(),this.currentOutput){const o=this.midi.device.getOutputs().findIndex(h=>h.id===this.currentOutput.id);o!==-1&&(e.value=o.toString())}this.updateConnectionStatus(),i&&await i(this.midi,this.currentOutput)}catch(E){this.updateStatus(`Output connection failed: ${E.message}`,"error")}finally{this.isConnecting=!1}})}_connectInputDeviceSelection(e,i,n){!e||!this.midi||e.addEventListener("change",async s=>{const r=s.target.value;if(!r){this.midi&&(await this.midi.device.disconnectInput(),this.updateStatus("Input device disconnected",""),this.updateConnectionStatus()),n&&await n(this.midi);return}if(!this.isConnecting){this.isConnecting=!0;try{await this.midi.device.connectInput(parseInt(r,10));const E=this.midi.device.getCurrentInput();this.updateConnectionStatus(),i&&await i(this.midi,E)}catch(E){this.updateStatus(`Input connection failed: ${E.message}`,"error")}finally{this.isConnecting=!1}}})}_populateDeviceList(e,i,n,s,r){if(i.length>0){if(e.innerHTML='<option value="">Select a device</option>'+i.map((E,o)=>`<option value="${o}">${E.name}</option>`).join(""),n){const E=i.findIndex(o=>o.name===n.name);E!==-1?e.value=E.toString():(e.value="",r&&(this.currentOutput=null,this.updateConnectionStatus()))}else e.value="";e.disabled=!1,r&&!this.currentOutput&&this.updateStatus("Select a device")}else e.innerHTML='<option value="">No devices connected</option>',e.disabled=!0,r&&this.updateStatus("No devices connected","error");s&&s()}async _populateOutputDeviceList(e,i){if(!e||!this.midi)return;const n=this._getOutputDevices();this._populateDeviceList(e,n,this.currentOutput,i,!0)}async _populateInputDeviceList(e,i){if(!e||!this.midi)return;const n=this._getInputDevices(),s=this.midi.device.getCurrentInput();this._populateDeviceList(e,n,s,i,!1)}_connectChannelSelection(e,i){if(!e||!this.midi)return;const n=i==="input"?"inputChannel":"outputChannel";e.addEventListener("change",s=>{this.midi&&(this.midi.options[n]=parseInt(s.target.value,10),this.updateConnectionStatus())})}}const t=class t{constructor(e,i=0){if(e.length!==t.PACKED_SIZE)throw new d(`Invalid voice data length: expected ${t.PACKED_SIZE} bytes, got ${e.length}`,"length",e.length);this.index=i,this.data=new Uint8Array(e),this.name=this._extractName(),this._unpackedCache=null}_extractName(){const e=this.data.subarray(t.PACKED_NAME_START,t.PACKED_NAME_START+t.NAME_LENGTH);return Array.from(e).map(n=>{let s=n&t.MASK_7BIT;return s===t.CHAR_YEN&&(s=t.CHAR_REPLACEMENT_Y),s===t.CHAR_ARROW_RIGHT&&(s=t.CHAR_REPLACEMENT_GT),s===t.CHAR_ARROW_LEFT&&(s=t.CHAR_REPLACEMENT_LT),(s<t.CHAR_MIN_PRINTABLE||s>t.CHAR_MAX_PRINTABLE)&&(s=t.CHAR_SPACE),String.fromCharCode(s)}).join("").trim()}getParameter(e){if(e<0||e>=t.PACKED_SIZE)throw new d(`Parameter offset out of range: ${e} (must be 0-${t.PACKED_SIZE-1})`,"offset",e);return this.data[e]&t.MASK_7BIT}getUnpackedParameter(e){if(e<0||e>=t.UNPACKED_SIZE)throw new d(`Unpacked parameter offset out of range: ${e} (must be 0-${t.UNPACKED_SIZE-1})`,"offset",e);return this._unpackedCache||(this._unpackedCache=this.unpack()),this._unpackedCache[e]&t.MASK_7BIT}setParameter(e,i){if(e<0||e>=t.PACKED_SIZE)throw new d(`Parameter offset out of range: ${e} (must be 0-${t.PACKED_SIZE-1})`,"offset",e);this.data[e]=i&t.MASK_7BIT,this._unpackedCache=null,e>=t.PACKED_NAME_START&&e<t.PACKED_NAME_START+t.NAME_LENGTH&&(this.name=this._extractName())}unpack(){const e=this.data,i=new Uint8Array(t.UNPACKED_SIZE);return this._unpackOperators(e,i),this._unpackPitchEG(e,i),this._unpackGlobalParams(e,i),this._unpackName(e,i),i}_unpackOperators(e,i){for(let n=0;n<t.NUM_OPERATORS;n++){const s=(t.NUM_OPERATORS-1-n)*t.PACKED_OP_SIZE,r=n*t.UNPACKED_OP_SIZE;this._unpackOperator(e,i,s,r)}}_unpackOperator(e,i,n,s){this._unpackOperatorEG(e,i,n,s),this._unpackOperatorScaling(e,i,n,s),this._unpackOperatorPackedParams(e,i,n,s),this._unpackOperatorFrequency(e,i,n,s)}_unpackOperatorEG(e,i,n,s){i[s+t.UNPACKED_OP_EG_RATE_1]=e[n+t.PACKED_OP_EG_RATE_1]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_RATE_2]=e[n+t.PACKED_OP_EG_RATE_2]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_RATE_3]=e[n+t.PACKED_OP_EG_RATE_3]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_RATE_4]=e[n+t.PACKED_OP_EG_RATE_4]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_1]=e[n+t.PACKED_OP_EG_LEVEL_1]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_2]=e[n+t.PACKED_OP_EG_LEVEL_2]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_3]=e[n+t.PACKED_OP_EG_LEVEL_3]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_4]=e[n+t.PACKED_OP_EG_LEVEL_4]&t.MASK_7BIT}_unpackOperatorScaling(e,i,n,s){i[s+t.UNPACKED_OP_BREAK_POINT]=e[n+t.PACKED_OP_BREAK_POINT]&t.MASK_7BIT,i[s+t.UNPACKED_OP_L_SCALE_DEPTH]=e[n+t.PACKED_OP_L_SCALE_DEPTH]&t.MASK_7BIT,i[s+t.UNPACKED_OP_R_SCALE_DEPTH]=e[n+t.PACKED_OP_R_SCALE_DEPTH]&t.MASK_7BIT}_unpackOperatorPackedParams(e,i,n,s){const r=e[n+t.PACKED_OP_CURVES]&t.MASK_7BIT;i[s+t.UNPACKED_OP_L_CURVE]=r&t.MASK_2BIT,i[s+t.UNPACKED_OP_R_CURVE]=r>>2&t.MASK_2BIT;const E=e[n+t.PACKED_OP_RATE_SCALING]&t.MASK_7BIT;i[s+t.UNPACKED_OP_RATE_SCALING]=E&t.MASK_3BIT,i[s+t.UNPACKED_OP_DETUNE]=E>>3&t.MASK_4BIT;const o=e[n+t.PACKED_OP_MOD_SENS]&t.MASK_7BIT;i[s+t.UNPACKED_OP_AMP_MOD_SENS]=o&t.MASK_2BIT,i[s+t.UNPACKED_OP_KEY_VEL_SENS]=o>>2&t.MASK_3BIT,i[s+t.UNPACKED_OP_OUTPUT_LEVEL]=e[n+t.PACKED_OP_OUTPUT_LEVEL]&t.MASK_7BIT}_unpackOperatorFrequency(e,i,n,s){const r=e[n+t.PACKED_OP_MODE_FREQ]&t.MASK_7BIT;i[s+t.UNPACKED_OP_MODE]=r&t.MASK_1BIT,i[s+t.UNPACKED_OP_FREQ_COARSE]=r>>1&t.MASK_5BIT;const E=e[n+t.PACKED_OP_DETUNE_FINE]&t.MASK_7BIT;i[s+t.UNPACKED_OP_OSC_DETUNE]=E&t.MASK_3BIT,i[s+t.UNPACKED_OP_FREQ_FINE]=E>>3&t.MASK_4BIT}_unpackPitchEG(e,i){i[t.UNPACKED_PITCH_EG_RATE_1]=e[t.PACKED_PITCH_EG_RATE_1]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_RATE_2]=e[t.PACKED_PITCH_EG_RATE_2]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_RATE_3]=e[t.PACKED_PITCH_EG_RATE_3]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_RATE_4]=e[t.PACKED_PITCH_EG_RATE_4]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_1]=e[t.PACKED_PITCH_EG_LEVEL_1]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_2]=e[t.PACKED_PITCH_EG_LEVEL_2]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_3]=e[t.PACKED_PITCH_EG_LEVEL_3]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_4]=e[t.PACKED_PITCH_EG_LEVEL_4]&t.MASK_7BIT}_unpackGlobalParams(e,i){i[t.UNPACKED_ALGORITHM]=e[t.OFFSET_ALGORITHM]&t.MASK_5BIT;const n=e[t.OFFSET_FEEDBACK]&t.MASK_7BIT;i[t.UNPACKED_FEEDBACK]=n&t.MASK_3BIT,i[t.UNPACKED_OSC_SYNC]=n>>3&t.MASK_1BIT,i[t.UNPACKED_LFO_SPEED]=e[t.OFFSET_LFO_SPEED]&t.MASK_7BIT,i[t.UNPACKED_LFO_DELAY]=e[t.OFFSET_LFO_DELAY]&t.MASK_7BIT,i[t.UNPACKED_LFO_PM_DEPTH]=e[t.OFFSET_LFO_PM_DEPTH]&t.MASK_7BIT,i[t.UNPACKED_LFO_AM_DEPTH]=e[t.OFFSET_LFO_AM_DEPTH]&t.MASK_7BIT;const s=e[t.OFFSET_LFO_SYNC_WAVE]&t.MASK_7BIT;i[t.UNPACKED_LFO_KEY_SYNC]=s&t.MASK_1BIT,i[t.UNPACKED_LFO_WAVE]=s>>1&t.MASK_3BIT,i[t.UNPACKED_LFO_PM_SENS]=s>>4&t.MASK_3BIT,i[t.UNPACKED_AMP_MOD_SENS]=e[t.OFFSET_AMP_MOD_SENS]&t.MASK_7BIT,i[t.UNPACKED_TRANSPOSE]=e[t.OFFSET_TRANSPOSE]&t.MASK_7BIT,i[t.UNPACKED_EG_BIAS_SENS]=e[t.OFFSET_EG_BIAS_SENS]&t.MASK_7BIT}_unpackName(e,i){for(let n=0;n<t.NAME_LENGTH;n++)i[t.UNPACKED_NAME_START+n]=e[t.PACKED_NAME_START+n]&t.MASK_7BIT}static pack(e){if(e.length!==t.UNPACKED_SIZE)throw new d(`Invalid unpacked data length: expected ${t.UNPACKED_SIZE} bytes, got ${e.length}`,"length",e.length);const i=new Uint8Array(t.PACKED_SIZE);return t._packOperators(e,i),t._packPitchEG(e,i),t._packGlobalParams(e,i),t._packName(e,i),i}static _packOperators(e,i){for(let n=0;n<t.NUM_OPERATORS;n++){const s=n*t.UNPACKED_OP_SIZE,r=(t.NUM_OPERATORS-1-n)*t.PACKED_OP_SIZE;t._packOperator(e,i,s,r)}}static _packOperator(e,i,n,s){t._packOperatorEG(e,i,n,s),t._packOperatorScaling(e,i,n,s),t._packOperatorPackedParams(e,i,n,s),t._packOperatorFrequency(e,i,n,s)}static _packOperatorEG(e,i,n,s){i[s+t.PACKED_OP_EG_RATE_1]=e[n+t.UNPACKED_OP_EG_RATE_1],i[s+t.PACKED_OP_EG_RATE_2]=e[n+t.UNPACKED_OP_EG_RATE_2],i[s+t.PACKED_OP_EG_RATE_3]=e[n+t.UNPACKED_OP_EG_RATE_3],i[s+t.PACKED_OP_EG_RATE_4]=e[n+t.UNPACKED_OP_EG_RATE_4],i[s+t.PACKED_OP_EG_LEVEL_1]=e[n+t.UNPACKED_OP_EG_LEVEL_1],i[s+t.PACKED_OP_EG_LEVEL_2]=e[n+t.UNPACKED_OP_EG_LEVEL_2],i[s+t.PACKED_OP_EG_LEVEL_3]=e[n+t.UNPACKED_OP_EG_LEVEL_3],i[s+t.PACKED_OP_EG_LEVEL_4]=e[n+t.UNPACKED_OP_EG_LEVEL_4]}static _packOperatorScaling(e,i,n,s){i[s+t.PACKED_OP_BREAK_POINT]=e[n+t.UNPACKED_OP_BREAK_POINT],i[s+t.PACKED_OP_L_SCALE_DEPTH]=e[n+t.UNPACKED_OP_L_SCALE_DEPTH],i[s+t.PACKED_OP_R_SCALE_DEPTH]=e[n+t.UNPACKED_OP_R_SCALE_DEPTH]}static _packOperatorPackedParams(e,i,n,s){const r=e[n+t.UNPACKED_OP_L_CURVE]&t.MASK_2BIT,E=e[n+t.UNPACKED_OP_R_CURVE]&t.MASK_2BIT;i[s+t.PACKED_OP_CURVES]=r|E<<2;const o=e[n+t.UNPACKED_OP_RATE_SCALING]&t.MASK_3BIT,h=e[n+t.UNPACKED_OP_DETUNE]&t.MASK_4BIT;i[s+t.PACKED_OP_RATE_SCALING]=o|h<<3;const N=e[n+t.UNPACKED_OP_AMP_MOD_SENS]&t.MASK_2BIT,u=e[n+t.UNPACKED_OP_KEY_VEL_SENS]&t.MASK_3BIT;i[s+t.PACKED_OP_MOD_SENS]=N|u<<2,i[s+t.PACKED_OP_OUTPUT_LEVEL]=e[n+t.UNPACKED_OP_OUTPUT_LEVEL]}static _packOperatorFrequency(e,i,n,s){const r=e[n+t.UNPACKED_OP_MODE]&t.MASK_1BIT,E=e[n+t.UNPACKED_OP_FREQ_COARSE]&t.MASK_5BIT;i[s+t.PACKED_OP_MODE_FREQ]=r|E<<1;const o=e[n+t.UNPACKED_OP_OSC_DETUNE]&t.MASK_3BIT,h=e[n+t.UNPACKED_OP_FREQ_FINE]&t.MASK_4BIT;i[s+t.PACKED_OP_DETUNE_FINE]=o|h<<3}static _packPitchEG(e,i){i[t.PACKED_PITCH_EG_RATE_1]=e[t.UNPACKED_PITCH_EG_RATE_1],i[t.PACKED_PITCH_EG_RATE_2]=e[t.UNPACKED_PITCH_EG_RATE_2],i[t.PACKED_PITCH_EG_RATE_3]=e[t.UNPACKED_PITCH_EG_RATE_3],i[t.PACKED_PITCH_EG_RATE_4]=e[t.UNPACKED_PITCH_EG_RATE_4],i[t.PACKED_PITCH_EG_LEVEL_1]=e[t.UNPACKED_PITCH_EG_LEVEL_1],i[t.PACKED_PITCH_EG_LEVEL_2]=e[t.UNPACKED_PITCH_EG_LEVEL_2],i[t.PACKED_PITCH_EG_LEVEL_3]=e[t.UNPACKED_PITCH_EG_LEVEL_3],i[t.PACKED_PITCH_EG_LEVEL_4]=e[t.UNPACKED_PITCH_EG_LEVEL_4]}static _packGlobalParams(e,i){i[t.OFFSET_ALGORITHM]=e[t.UNPACKED_ALGORITHM];const n=e[t.UNPACKED_FEEDBACK]&t.MASK_3BIT,s=e[t.UNPACKED_OSC_SYNC]&t.MASK_1BIT;i[t.OFFSET_FEEDBACK]=n|s<<3,i[t.OFFSET_LFO_SPEED]=e[t.UNPACKED_LFO_SPEED],i[t.OFFSET_LFO_DELAY]=e[t.UNPACKED_LFO_DELAY],i[t.OFFSET_LFO_PM_DEPTH]=e[t.UNPACKED_LFO_PM_DEPTH],i[t.OFFSET_LFO_AM_DEPTH]=e[t.UNPACKED_LFO_AM_DEPTH];const r=e[t.UNPACKED_LFO_KEY_SYNC]&t.MASK_1BIT,E=e[t.UNPACKED_LFO_WAVE]&t.MASK_3BIT,o=e[t.UNPACKED_LFO_PM_SENS]&t.MASK_3BIT;i[t.OFFSET_LFO_SYNC_WAVE]=r|E<<1|o<<4,i[t.OFFSET_AMP_MOD_SENS]=e[t.UNPACKED_AMP_MOD_SENS],i[t.OFFSET_TRANSPOSE]=e[t.UNPACKED_TRANSPOSE],i[t.OFFSET_EG_BIAS_SENS]=e[t.UNPACKED_EG_BIAS_SENS]}static _packName(e,i){for(let n=0;n<t.NAME_LENGTH;n++)i[t.PACKED_NAME_START+n]=e[t.UNPACKED_NAME_START+n]}static createDefault(e=0){const i=new Uint8Array(t.UNPACKED_SIZE);for(let r=0;r<t.NUM_OPERATORS;r++){const E=r*t.UNPACKED_OP_SIZE;i[E+t.UNPACKED_OP_EG_RATE_1]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_RATE_2]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_RATE_3]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_RATE_4]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_LEVEL_1]=t.DEFAULT_EG_LEVEL_MAX,i[E+t.UNPACKED_OP_EG_LEVEL_2]=t.DEFAULT_EG_LEVEL_MAX,i[E+t.UNPACKED_OP_EG_LEVEL_3]=t.DEFAULT_EG_LEVEL_MAX,i[E+t.UNPACKED_OP_EG_LEVEL_4]=t.DEFAULT_EG_LEVEL_MIN,i[E+t.UNPACKED_OP_BREAK_POINT]=t.DEFAULT_BREAK_POINT,i[E+t.UNPACKED_OP_L_SCALE_DEPTH]=0,i[E+t.UNPACKED_OP_R_SCALE_DEPTH]=0,i[E+t.UNPACKED_OP_L_CURVE]=0,i[E+t.UNPACKED_OP_R_CURVE]=0,i[E+t.UNPACKED_OP_RATE_SCALING]=0,i[E+t.UNPACKED_OP_DETUNE]=t.DEFAULT_DETUNE,i[E+t.UNPACKED_OP_AMP_MOD_SENS]=0,i[E+t.UNPACKED_OP_KEY_VEL_SENS]=0,i[E+t.UNPACKED_OP_OUTPUT_LEVEL]=t.DEFAULT_OUTPUT_LEVEL,i[E+t.UNPACKED_OP_MODE]=0,i[E+t.UNPACKED_OP_FREQ_COARSE]=t.DEFAULT_FREQ_COARSE,i[E+t.UNPACKED_OP_OSC_DETUNE]=0,i[E+t.UNPACKED_OP_FREQ_FINE]=0}i[t.UNPACKED_PITCH_EG_RATE_1]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_RATE_2]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_RATE_3]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_RATE_4]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_LEVEL_1]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_PITCH_EG_LEVEL_2]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_PITCH_EG_LEVEL_3]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_PITCH_EG_LEVEL_4]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_ALGORITHM]=t.DEFAULT_ALGORITHM,i[t.UNPACKED_FEEDBACK]=t.DEFAULT_FEEDBACK,i[t.UNPACKED_OSC_SYNC]=t.DEFAULT_OSC_SYNC,i[t.UNPACKED_LFO_SPEED]=t.DEFAULT_LFO_SPEED,i[t.UNPACKED_LFO_DELAY]=0,i[t.UNPACKED_LFO_PM_DEPTH]=0,i[t.UNPACKED_LFO_AM_DEPTH]=0,i[t.UNPACKED_LFO_KEY_SYNC]=t.DEFAULT_LFO_KEY_SYNC,i[t.UNPACKED_LFO_WAVE]=0,i[t.UNPACKED_LFO_PM_SENS]=t.DEFAULT_LFO_PM_SENS,i[t.UNPACKED_AMP_MOD_SENS]=0,i[t.UNPACKED_TRANSPOSE]=t.TRANSPOSE_CENTER,i[t.UNPACKED_EG_BIAS_SENS]=0;const n="Init Voice";for(let r=0;r<t.NAME_LENGTH;r++)i[t.UNPACKED_NAME_START+r]=r<n.length?n.charCodeAt(r):t.CHAR_SPACE;const s=t.pack(i);return new t(s,e)}static fromUnpacked(e,i=0){const n=t.pack(e);return new t(n,i)}static async fromFile(e){return new Promise((i,n)=>{const s=new FileReader;s.onload=r=>{try{const E=new Uint8Array(r.target.result);if(E[0]!==t.VCED_SYSEX_START||E[1]!==t.VCED_YAMAHA_ID||E[2]!==t.VCED_SUB_STATUS||E[3]!==t.VCED_FORMAT_SINGLE||E[4]!==t.VCED_BYTE_COUNT_MSB||E[5]!==t.VCED_BYTE_COUNT_LSB)throw new g("Invalid VCED header","header",0);const o=E.subarray(t.VCED_HEADER_SIZE,t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE),h=E[t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE],N=G._calculateChecksum(o,t.VCED_DATA_SIZE);h!==N&&console.warn(`DX7 VCED checksum mismatch (expected ${N.toString(16)}, got ${h.toString(16)}). This is common with vintage SysEx files.`);const u=new Uint8Array(t.UNPACKED_SIZE);let a=0;for(let S=0;S<t.NUM_OPERATORS;S++){const D=(t.NUM_OPERATORS-1-S)*t.UNPACKED_OP_SIZE;u[D+t.UNPACKED_OP_EG_RATE_1]=o[a++],u[D+t.UNPACKED_OP_EG_RATE_2]=o[a++],u[D+t.UNPACKED_OP_EG_RATE_3]=o[a++],u[D+t.UNPACKED_OP_EG_RATE_4]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_1]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_2]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_3]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_4]=o[a++],u[D+t.UNPACKED_OP_BREAK_POINT]=o[a++],u[D+t.UNPACKED_OP_L_SCALE_DEPTH]=o[a++],u[D+t.UNPACKED_OP_R_SCALE_DEPTH]=o[a++],u[D+t.UNPACKED_OP_L_CURVE]=o[a++],u[D+t.UNPACKED_OP_R_CURVE]=o[a++],u[D+t.UNPACKED_OP_RATE_SCALING]=o[a++],u[D+t.UNPACKED_OP_DETUNE]=o[a++];const T=o[a++];u[D+t.UNPACKED_OP_AMP_MOD_SENS]=T&t.MASK_2BIT,u[D+t.UNPACKED_OP_KEY_VEL_SENS]=T>>2&t.MASK_3BIT,u[D+t.UNPACKED_OP_OUTPUT_LEVEL]=o[a++],u[D+t.UNPACKED_OP_MODE]=o[a++],u[D+t.UNPACKED_OP_FREQ_COARSE]=o[a++],u[D+t.UNPACKED_OP_FREQ_FINE]=o[a++],u[D+t.UNPACKED_OP_OSC_DETUNE]=o[a++]}u[t.UNPACKED_PITCH_EG_RATE_1]=o[a++],u[t.UNPACKED_PITCH_EG_RATE_2]=o[a++],u[t.UNPACKED_PITCH_EG_RATE_3]=o[a++],u[t.UNPACKED_PITCH_EG_RATE_4]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_1]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_2]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_3]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_4]=o[a++],u[t.UNPACKED_ALGORITHM]=o[a++],u[t.UNPACKED_FEEDBACK]=o[a++],u[t.UNPACKED_OSC_SYNC]=o[a++],u[t.UNPACKED_LFO_SPEED]=o[a++],u[t.UNPACKED_LFO_DELAY]=o[a++],u[t.UNPACKED_LFO_PM_DEPTH]=o[a++],u[t.UNPACKED_LFO_AM_DEPTH]=o[a++],u[t.UNPACKED_LFO_KEY_SYNC]=o[a++],u[t.UNPACKED_LFO_WAVE]=o[a++],u[t.UNPACKED_LFO_PM_SENS]=o[a++],u[t.UNPACKED_TRANSPOSE]=o[a++];for(let S=0;S<t.NAME_LENGTH;S++)u[t.UNPACKED_NAME_START+S]=o[a++];const C=t.pack(u);i(new t(C,0))}catch(E){n(E)}},s.onerror=()=>n(new Error("Failed to read file")),s.readAsArrayBuffer(e)})}static fromSysEx(e,i=0){const n=e instanceof Uint8Array?e:new Uint8Array(e);let s;if(n[0]===t.VCED_SYSEX_START){if(n[0]!==t.VCED_SYSEX_START||n[1]!==t.VCED_YAMAHA_ID||n[2]!==t.VCED_SUB_STATUS||n[3]!==t.VCED_FORMAT_SINGLE||n[4]!==t.VCED_BYTE_COUNT_MSB||n[5]!==t.VCED_BYTE_COUNT_LSB)throw new g("Invalid VCED header","header",0);s=n.subarray(t.VCED_HEADER_SIZE,t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE)}else if(n.length===t.PACKED_SIZE)s=n;else throw new d(`Invalid data length: expected ${t.PACKED_SIZE} or ${t.VCED_SIZE} bytes, got ${n.length}`,"length",n.length);if(s.length!==t.VCED_DATA_SIZE&&s.length!==t.PACKED_SIZE)throw new d(`Invalid voice data length: expected ${t.VCED_DATA_SIZE} or ${t.PACKED_SIZE} bytes, got ${s.length}`,"length",s.length);if(s.length===t.VCED_DATA_SIZE){const r=new Uint8Array(t.UNPACKED_SIZE);let E=0;for(let h=0;h<t.NUM_OPERATORS;h++){const N=(t.NUM_OPERATORS-1-h)*t.UNPACKED_OP_SIZE;r[N+t.UNPACKED_OP_EG_RATE_1]=s[E++],r[N+t.UNPACKED_OP_EG_RATE_2]=s[E++],r[N+t.UNPACKED_OP_EG_RATE_3]=s[E++],r[N+t.UNPACKED_OP_EG_RATE_4]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_1]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_2]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_3]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_4]=s[E++],r[N+t.UNPACKED_OP_BREAK_POINT]=s[E++],r[N+t.UNPACKED_OP_L_SCALE_DEPTH]=s[E++],r[N+t.UNPACKED_OP_R_SCALE_DEPTH]=s[E++],r[N+t.UNPACKED_OP_L_CURVE]=s[E++],r[N+t.UNPACKED_OP_R_CURVE]=s[E++],r[N+t.UNPACKED_OP_RATE_SCALING]=s[E++],r[N+t.UNPACKED_OP_DETUNE]=s[E++];const u=s[E++];r[N+t.UNPACKED_OP_AMP_MOD_SENS]=u&t.MASK_2BIT,r[N+t.UNPACKED_OP_KEY_VEL_SENS]=u>>2&t.MASK_3BIT,r[N+t.UNPACKED_OP_OUTPUT_LEVEL]=s[E++],r[N+t.UNPACKED_OP_MODE]=s[E++],r[N+t.UNPACKED_OP_FREQ_COARSE]=s[E++],r[N+t.UNPACKED_OP_FREQ_FINE]=s[E++],r[N+t.UNPACKED_OP_OSC_DETUNE]=s[E++]}r[t.UNPACKED_PITCH_EG_RATE_1]=s[E++],r[t.UNPACKED_PITCH_EG_RATE_2]=s[E++],r[t.UNPACKED_PITCH_EG_RATE_3]=s[E++],r[t.UNPACKED_PITCH_EG_RATE_4]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_1]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_2]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_3]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_4]=s[E++],r[t.UNPACKED_ALGORITHM]=s[E++],r[t.UNPACKED_FEEDBACK]=s[E++],r[t.UNPACKED_OSC_SYNC]=s[E++],r[t.UNPACKED_LFO_SPEED]=s[E++],r[t.UNPACKED_LFO_DELAY]=s[E++],r[t.UNPACKED_LFO_PM_DEPTH]=s[E++],r[t.UNPACKED_LFO_AM_DEPTH]=s[E++],r[t.UNPACKED_LFO_KEY_SYNC]=s[E++],r[t.UNPACKED_LFO_WAVE]=s[E++],r[t.UNPACKED_LFO_PM_SENS]=s[E++],r[t.UNPACKED_TRANSPOSE]=s[E++];for(let h=0;h<t.NAME_LENGTH;h++)r[t.UNPACKED_NAME_START+h]=s[E++];const o=t.pack(r);return new t(o,i)}return new t(s,i)}static fromJSON(e,i=0){if(!e||typeof e!="object")throw new d("Invalid JSON: expected object","json",e);const n=new Uint8Array(t.UNPACKED_SIZE),s=(a,C,S,D=0,T=127)=>{if(C==null)throw new d(`Missing required parameter: ${S}`,S,C);const f=Number(C);if(Number.isNaN(f))throw new d(`Invalid parameter value for ${S}: ${C}`,S,C);if(f<D||f>T)throw new d(`Parameter ${S} out of range: ${f} (must be ${D}-${T})`,S,f);n[a]=Math.floor(f)},r=a=>{const C={"-LN":0,"-EX":1,"+EX":2,"+LN":3};return C[a]!==void 0?C[a]:0},E=a=>{const C={TRIANGLE:0,"SAW DOWN":1,"SAW UP":2,SQUARE:3,SINE:4,"SAMPLE & HOLD":5};return C[a]!==void 0?C[a]:0},o=a=>{if(!a||typeof a!="string")return 60;const C=a.trim().match(/^([A-G]#?)(-?\d+)$/);if(!C)return 60;const[,S,D]=C,T=parseInt(D,10),U={C:0,"C#":1,D:2,"D#":3,E:4,F:5,"F#":6,G:7,"G#":8,A:9,"A#":10,B:11}[S.toUpperCase()];return U===void 0?60:(T-t.MIDI_OCTAVE_OFFSET)*12+U};if(!Array.isArray(e.operators))throw new d("Invalid operators array: expected array","operators",e.operators);for(let a=0;a<e.operators.length;a++){const C=e.operators[a];if(!C||typeof C!="object")throw new d(`Invalid operator data at index ${a}`,`operators[${a}]`,C);if(!C.eg||!Array.isArray(C.eg.rates)||C.eg.rates.length!==4)throw new d(`Invalid EG rates for operator ${a}`,`operators[${a}].eg.rates`,C.eg?.rates);if(!C.eg||!Array.isArray(C.eg.levels)||C.eg.levels.length!==4)throw new d(`Invalid EG levels for operator ${a}`,`operators[${a}].eg.levels`,C.eg?.levels)}if(e.operators.length!==t.NUM_OPERATORS)throw new d(`Invalid operators array: expected ${t.NUM_OPERATORS} operators`,"operators",e.operators);for(let a=0;a<t.NUM_OPERATORS;a++){const C=e.operators[a],S=a*t.UNPACKED_OP_SIZE;if(!C.eg||!Array.isArray(C.eg.rates)||C.eg.rates.length!==4)throw new d(`Invalid EG rates for operator ${a}`,`operators[${a}].eg.rates`,C.eg?.rates);if(s(S+t.UNPACKED_OP_EG_RATE_1,C.eg.rates[0],`operators[${a}].eg.rates[0]`,0,99),s(S+t.UNPACKED_OP_EG_RATE_2,C.eg.rates[1],`operators[${a}].eg.rates[1]`,0,99),s(S+t.UNPACKED_OP_EG_RATE_3,C.eg.rates[2],`operators[${a}].eg.rates[2]`,0,99),s(S+t.UNPACKED_OP_EG_RATE_4,C.eg.rates[3],`operators[${a}].eg.rates[3]`,0,99),!C.eg||!Array.isArray(C.eg.levels)||C.eg.levels.length!==4)throw new d(`Invalid EG levels for operator ${a}`,`operators[${a}].eg.levels`,C.eg?.levels);s(S+t.UNPACKED_OP_EG_LEVEL_1,C.eg.levels[0],`operators[${a}].eg.levels[0]`,0,99),s(S+t.UNPACKED_OP_EG_LEVEL_2,C.eg.levels[1],`operators[${a}].eg.levels[1]`,0,99),s(S+t.UNPACKED_OP_EG_LEVEL_3,C.eg.levels[2],`operators[${a}].eg.levels[2]`,0,99),s(S+t.UNPACKED_OP_EG_LEVEL_4,C.eg.levels[3],`operators[${a}].eg.levels[3]`,0,99);const D=o(C.key?.breakPoint)-t.MIDI_BREAK_POINT_OFFSET;s(S+t.UNPACKED_OP_BREAK_POINT,D,`operators[${a}].key.breakPoint`,0,127),s(S+t.UNPACKED_OP_L_SCALE_DEPTH,C.scale?.left?.depth||0,`operators[${a}].scale.left.depth`,0,99),s(S+t.UNPACKED_OP_R_SCALE_DEPTH,C.scale?.right?.depth||0,`operators[${a}].scale.right.depth`,0,99),n[S+t.UNPACKED_OP_L_CURVE]=r(C.scale?.left?.curve||"-LN"),n[S+t.UNPACKED_OP_R_CURVE]=r(C.scale?.right?.curve||"-LN"),s(S+t.UNPACKED_OP_RATE_SCALING,C.key?.scaling||0,`operators[${a}].key.scaling`,0,7);const T=Number(C.osc?.detune)||0;s(S+t.UNPACKED_OP_DETUNE,T+7,`operators[${a}].osc.detune`,0,14),s(S+t.UNPACKED_OP_AMP_MOD_SENS,C.output?.ampModSens||0,`operators[${a}].output.ampModSens`,0,3),s(S+t.UNPACKED_OP_OUTPUT_LEVEL,C.output?.level||0,`operators[${a}].output.level`,0,99);const f=C.osc?.freq?.mode?.toUpperCase()==="FIXED"?1:0,U=Number(C.osc?.freq?.coarse)||0,L=Number(C.osc?.freq?.fine)||0;n[S+t.UNPACKED_OP_MODE]=f,s(S+t.UNPACKED_OP_FREQ_COARSE,U,`operators[${a}].osc.freq.coarse`,0,31),s(S+t.UNPACKED_OP_FREQ_FINE,L,`operators[${a}].osc.freq.fine`,0,15),s(S+t.UNPACKED_OP_KEY_VEL_SENS,C.key?.velocity||0,`operators[${a}].key.velocity`,0,7)}if(!e.pitchEG||!Array.isArray(e.pitchEG.rates)||e.pitchEG.rates.length!==4)throw new d("Invalid pitch EG rates","pitchEG.rates",e.pitchEG?.rates);if(!e.pitchEG||!Array.isArray(e.pitchEG.levels)||e.pitchEG.levels.length!==4)throw new d("Invalid pitch EG levels","pitchEG.levels",e.pitchEG?.levels);if(s(t.UNPACKED_PITCH_EG_RATE_1,e.pitchEG.rates[0],"pitchEG.rates[0]",0,99),s(t.UNPACKED_PITCH_EG_RATE_2,e.pitchEG.rates[1],"pitchEG.rates[1]",0,99),s(t.UNPACKED_PITCH_EG_RATE_3,e.pitchEG.rates[2],"pitchEG.rates[2]",0,99),s(t.UNPACKED_PITCH_EG_RATE_4,e.pitchEG.rates[3],"pitchEG.rates[3]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_1,e.pitchEG.levels[0],"pitchEG.levels[0]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_2,e.pitchEG.levels[1],"pitchEG.levels[1]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_3,e.pitchEG.levels[2],"pitchEG.levels[2]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_4,e.pitchEG.levels[3],"pitchEG.levels[3]",0,99),!e.lfo||typeof e.lfo!="object")throw new d("Invalid LFO data","lfo",e.lfo);if(s(t.UNPACKED_LFO_SPEED,e.lfo.speed,"lfo.speed",0,99),s(t.UNPACKED_LFO_DELAY,e.lfo.delay,"lfo.delay",0,99),s(t.UNPACKED_LFO_PM_DEPTH,e.lfo.pmDepth,"lfo.pmDepth",0,99),s(t.UNPACKED_LFO_AM_DEPTH,e.lfo.amDepth,"lfo.amDepth",0,99),n[t.UNPACKED_LFO_KEY_SYNC]=e.lfo.keySync?1:0,n[t.UNPACKED_LFO_WAVE]=E(e.lfo.wave),!e.global||typeof e.global!="object")throw new d("Invalid global data","global",e.global);const h=Number(e.global.algorithm)||1;s(t.UNPACKED_ALGORITHM,h-1,"global.algorithm",0,31),s(t.UNPACKED_FEEDBACK,e.global.feedback,"global.feedback",0,7),n[t.UNPACKED_OSC_SYNC]=e.global.oscKeySync?1:0,s(t.UNPACKED_LFO_PM_SENS,e.global.pitchModSens,"global.pitchModSens",0,7);const N=Number(e.global.transpose)||0;s(t.UNPACKED_TRANSPOSE,N+t.TRANSPOSE_CENTER,"global.transpose",0,127),s(t.UNPACKED_AMP_MOD_SENS,e.global.ampModSens||0,"global.ampModSens",0,3),s(t.UNPACKED_EG_BIAS_SENS,e.global.egBiasSens||0,"global.egBiasSens",0,7);const u=e.name||"";for(let a=0;a<t.NAME_LENGTH;a++)n[t.UNPACKED_NAME_START+a]=a<u.length?u.charCodeAt(a):t.CHAR_SPACE;return t.fromUnpacked(n,i)}toSysEx(){const e=this.unpack(),i=new Uint8Array(t.VCED_SIZE);let n=0;i[n++]=t.VCED_SYSEX_START,i[n++]=t.VCED_YAMAHA_ID,i[n++]=t.VCED_SUB_STATUS,i[n++]=t.VCED_FORMAT_SINGLE,i[n++]=t.VCED_BYTE_COUNT_MSB,i[n++]=t.VCED_BYTE_COUNT_LSB;for(let r=t.NUM_OPERATORS-1;r>=0;r--){const E=r*t.UNPACKED_OP_SIZE;i[n++]=e[E+t.UNPACKED_OP_EG_RATE_1],i[n++]=e[E+t.UNPACKED_OP_EG_RATE_2],i[n++]=e[E+t.UNPACKED_OP_EG_RATE_3],i[n++]=e[E+t.UNPACKED_OP_EG_RATE_4],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_1],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_2],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_3],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_4],i[n++]=e[E+t.UNPACKED_OP_BREAK_POINT],i[n++]=e[E+t.UNPACKED_OP_L_SCALE_DEPTH],i[n++]=e[E+t.UNPACKED_OP_R_SCALE_DEPTH],i[n++]=e[E+t.UNPACKED_OP_L_CURVE],i[n++]=e[E+t.UNPACKED_OP_R_CURVE],i[n++]=e[E+t.UNPACKED_OP_RATE_SCALING],i[n++]=e[E+t.UNPACKED_OP_DETUNE];const o=e[E+t.UNPACKED_OP_AMP_MOD_SENS]&t.MASK_2BIT,h=e[E+t.UNPACKED_OP_KEY_VEL_SENS]&t.MASK_3BIT;i[n++]=o|h<<2,i[n++]=e[E+t.UNPACKED_OP_OUTPUT_LEVEL],i[n++]=e[E+t.UNPACKED_OP_MODE],i[n++]=e[E+t.UNPACKED_OP_FREQ_COARSE],i[n++]=e[E+t.UNPACKED_OP_OSC_DETUNE],i[n++]=e[E+t.UNPACKED_OP_FREQ_FINE]}i[n++]=e[t.UNPACKED_PITCH_EG_RATE_1],i[n++]=e[t.UNPACKED_PITCH_EG_RATE_2],i[n++]=e[t.UNPACKED_PITCH_EG_RATE_3],i[n++]=e[t.UNPACKED_PITCH_EG_RATE_4],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_1],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_2],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_3],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_4],i[n++]=e[t.UNPACKED_ALGORITHM],i[n++]=e[t.UNPACKED_FEEDBACK],i[n++]=e[t.UNPACKED_OSC_SYNC],i[n++]=e[t.UNPACKED_LFO_SPEED],i[n++]=e[t.UNPACKED_LFO_DELAY],i[n++]=e[t.UNPACKED_LFO_PM_DEPTH],i[n++]=e[t.UNPACKED_LFO_AM_DEPTH],i[n++]=e[t.UNPACKED_LFO_KEY_SYNC],i[n++]=e[t.UNPACKED_LFO_WAVE],i[n++]=e[t.UNPACKED_LFO_PM_SENS],i[n++]=e[t.UNPACKED_TRANSPOSE];for(let r=0;r<t.NAME_LENGTH;r++)i[n++]=e[t.UNPACKED_NAME_START+r];const s=i.subarray(t.VCED_HEADER_SIZE,t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE);return i[n++]=G._calculateChecksum(s,t.VCED_DATA_SIZE),i[n++]=t.VCED_SYSEX_END,i}toJSON(){const e=this.unpack(),i=[],n=E=>["-LN","-EX","+EX","+LN"][E]||"UNKNOWN",s=E=>["TRIANGLE","SAW DOWN","SAW UP","SQUARE","SINE","SAMPLE & HOLD"][E]||"UNKNOWN",r=E=>{const o=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],h=Math.floor(E/12)+t.MIDI_OCTAVE_OFFSET;return`${o[E%12]}${h}`};for(let E=0;E<t.NUM_OPERATORS;E++){const o=E*t.UNPACKED_OP_SIZE,h=e[o+t.UNPACKED_OP_MODE]===0?"RATIO":"FIXED";i.push({id:E+1,osc:{detune:e[o+t.UNPACKED_OP_OSC_DETUNE],freq:{coarse:e[o+t.UNPACKED_OP_FREQ_COARSE],fine:e[o+t.UNPACKED_OP_FREQ_FINE],mode:h}},eg:{rates:[e[o+t.UNPACKED_OP_EG_RATE_1],e[o+t.UNPACKED_OP_EG_RATE_2],e[o+t.UNPACKED_OP_EG_RATE_3],e[o+t.UNPACKED_OP_EG_RATE_4]],levels:[e[o+t.UNPACKED_OP_EG_LEVEL_1],e[o+t.UNPACKED_OP_EG_LEVEL_2],e[o+t.UNPACKED_OP_EG_LEVEL_3],e[o+t.UNPACKED_OP_EG_LEVEL_4]]},key:{velocity:e[o+t.UNPACKED_OP_KEY_VEL_SENS],scaling:e[o+t.UNPACKED_OP_RATE_SCALING],breakPoint:r(e[o+t.UNPACKED_OP_BREAK_POINT]+t.MIDI_BREAK_POINT_OFFSET)},output:{level:e[o+t.UNPACKED_OP_OUTPUT_LEVEL],ampModSens:e[o+t.UNPACKED_OP_AMP_MOD_SENS]},scale:{left:{depth:e[o+t.UNPACKED_OP_L_SCALE_DEPTH],curve:n(e[o+t.UNPACKED_OP_L_CURVE])},right:{depth:e[o+t.UNPACKED_OP_R_SCALE_DEPTH],curve:n(e[o+t.UNPACKED_OP_R_CURVE])}}})}return{name:this.name||"(Empty)",operators:i,pitchEG:{rates:[e[t.UNPACKED_PITCH_EG_RATE_1],e[t.UNPACKED_PITCH_EG_RATE_2],e[t.UNPACKED_PITCH_EG_RATE_3],e[t.UNPACKED_PITCH_EG_RATE_4]],levels:[e[t.UNPACKED_PITCH_EG_LEVEL_1],e[t.UNPACKED_PITCH_EG_LEVEL_2],e[t.UNPACKED_PITCH_EG_LEVEL_3],e[t.UNPACKED_PITCH_EG_LEVEL_4]]},lfo:{speed:e[t.UNPACKED_LFO_SPEED],delay:e[t.UNPACKED_LFO_DELAY],pmDepth:e[t.UNPACKED_LFO_PM_DEPTH],amDepth:e[t.UNPACKED_LFO_AM_DEPTH],keySync:e[t.UNPACKED_LFO_KEY_SYNC]===1,wave:s(e[t.UNPACKED_LFO_WAVE])},global:{algorithm:e[t.UNPACKED_ALGORITHM]+1,feedback:e[t.UNPACKED_FEEDBACK],oscKeySync:e[t.UNPACKED_OSC_SYNC]===1,pitchModSens:e[t.UNPACKED_LFO_PM_SENS],transpose:e[t.UNPACKED_TRANSPOSE]-t.TRANSPOSE_CENTER}}}};_(t,"PACKED_SIZE",128),_(t,"PACKED_OP_SIZE",17),_(t,"NUM_OPERATORS",6),_(t,"PACKED_OP_EG_RATE_1",0),_(t,"PACKED_OP_EG_RATE_2",1),_(t,"PACKED_OP_EG_RATE_3",2),_(t,"PACKED_OP_EG_RATE_4",3),_(t,"PACKED_OP_EG_LEVEL_1",4),_(t,"PACKED_OP_EG_LEVEL_2",5),_(t,"PACKED_OP_EG_LEVEL_3",6),_(t,"PACKED_OP_EG_LEVEL_4",7),_(t,"PACKED_OP_BREAK_POINT",8),_(t,"PACKED_OP_L_SCALE_DEPTH",9),_(t,"PACKED_OP_R_SCALE_DEPTH",10),_(t,"PACKED_OP_CURVES",11),_(t,"PACKED_OP_RATE_SCALING",12),_(t,"PACKED_OP_MOD_SENS",13),_(t,"PACKED_OP_OUTPUT_LEVEL",14),_(t,"PACKED_OP_MODE_FREQ",15),_(t,"PACKED_OP_DETUNE_FINE",16),_(t,"PACKED_PITCH_EG_RATE_1",102),_(t,"PACKED_PITCH_EG_RATE_2",103),_(t,"PACKED_PITCH_EG_RATE_3",104),_(t,"PACKED_PITCH_EG_RATE_4",105),_(t,"PACKED_PITCH_EG_LEVEL_1",106),_(t,"PACKED_PITCH_EG_LEVEL_2",107),_(t,"PACKED_PITCH_EG_LEVEL_3",108),_(t,"PACKED_PITCH_EG_LEVEL_4",109),_(t,"OFFSET_ALGORITHM",110),_(t,"OFFSET_FEEDBACK",111),_(t,"OFFSET_LFO_SPEED",112),_(t,"OFFSET_LFO_DELAY",113),_(t,"OFFSET_LFO_PM_DEPTH",114),_(t,"OFFSET_LFO_AM_DEPTH",115),_(t,"OFFSET_LFO_SYNC_WAVE",116),_(t,"OFFSET_TRANSPOSE",117),_(t,"OFFSET_AMP_MOD_SENS",118),_(t,"OFFSET_EG_BIAS_SENS",119),_(t,"PACKED_NAME_START",118),_(t,"NAME_LENGTH",10),_(t,"UNPACKED_SIZE",169),_(t,"UNPACKED_OP_SIZE",23),_(t,"UNPACKED_OP_EG_RATE_1",0),_(t,"UNPACKED_OP_EG_RATE_2",1),_(t,"UNPACKED_OP_EG_RATE_3",2),_(t,"UNPACKED_OP_EG_RATE_4",3),_(t,"UNPACKED_OP_EG_LEVEL_1",4),_(t,"UNPACKED_OP_EG_LEVEL_2",5),_(t,"UNPACKED_OP_EG_LEVEL_3",6),_(t,"UNPACKED_OP_EG_LEVEL_4",7),_(t,"UNPACKED_OP_BREAK_POINT",8),_(t,"UNPACKED_OP_L_SCALE_DEPTH",9),_(t,"UNPACKED_OP_R_SCALE_DEPTH",10),_(t,"UNPACKED_OP_L_CURVE",11),_(t,"UNPACKED_OP_R_CURVE",12),_(t,"UNPACKED_OP_RATE_SCALING",13),_(t,"UNPACKED_OP_DETUNE",14),_(t,"UNPACKED_OP_AMP_MOD_SENS",15),_(t,"UNPACKED_OP_OUTPUT_LEVEL",16),_(t,"UNPACKED_OP_MODE",17),_(t,"UNPACKED_OP_KEY_VEL_SENS",18),_(t,"UNPACKED_OP_FREQ_COARSE",19),_(t,"UNPACKED_OP_OSC_DETUNE",20),_(t,"UNPACKED_OP_FREQ_FINE",21),_(t,"UNPACKED_PITCH_EG_RATE_1",138),_(t,"UNPACKED_PITCH_EG_RATE_2",139),_(t,"UNPACKED_PITCH_EG_RATE_3",140),_(t,"UNPACKED_PITCH_EG_RATE_4",141),_(t,"UNPACKED_PITCH_EG_LEVEL_1",142),_(t,"UNPACKED_PITCH_EG_LEVEL_2",143),_(t,"UNPACKED_PITCH_EG_LEVEL_3",144),_(t,"UNPACKED_PITCH_EG_LEVEL_4",145),_(t,"UNPACKED_ALGORITHM",146),_(t,"UNPACKED_FEEDBACK",147),_(t,"UNPACKED_OSC_SYNC",148),_(t,"UNPACKED_LFO_SPEED",149),_(t,"UNPACKED_LFO_DELAY",150),_(t,"UNPACKED_LFO_PM_DEPTH",151),_(t,"UNPACKED_LFO_AM_DEPTH",152),_(t,"UNPACKED_LFO_KEY_SYNC",153),_(t,"UNPACKED_LFO_WAVE",154),_(t,"UNPACKED_LFO_PM_SENS",155),_(t,"UNPACKED_AMP_MOD_SENS",156),_(t,"UNPACKED_TRANSPOSE",157),_(t,"UNPACKED_EG_BIAS_SENS",158),_(t,"UNPACKED_NAME_START",159),_(t,"VCED_SIZE",163),_(t,"VCED_HEADER_SIZE",6),_(t,"VCED_DATA_SIZE",155),_(t,"VCED_SYSEX_START",240),_(t,"VCED_YAMAHA_ID",67),_(t,"VCED_SUB_STATUS",0),_(t,"VCED_FORMAT_SINGLE",0),_(t,"VCED_BYTE_COUNT_MSB",1),_(t,"VCED_BYTE_COUNT_LSB",27),_(t,"VCED_SYSEX_END",247),_(t,"MASK_7BIT",127),_(t,"MASK_2BIT",3),_(t,"MASK_3BIT",7),_(t,"MASK_4BIT",15),_(t,"MASK_5BIT",31),_(t,"MASK_1BIT",1),_(t,"TRANSPOSE_CENTER",24),_(t,"CHAR_YEN",92),_(t,"CHAR_ARROW_RIGHT",126),_(t,"CHAR_ARROW_LEFT",127),_(t,"CHAR_REPLACEMENT_Y",89),_(t,"CHAR_REPLACEMENT_GT",62),_(t,"CHAR_REPLACEMENT_LT",60),_(t,"CHAR_SPACE",32),_(t,"CHAR_MIN_PRINTABLE",32),_(t,"CHAR_MAX_PRINTABLE",126),_(t,"DEFAULT_EG_RATE",99),_(t,"DEFAULT_EG_LEVEL_MAX",99),_(t,"DEFAULT_EG_LEVEL_MIN",0),_(t,"DEFAULT_BREAK_POINT",0),_(t,"DEFAULT_OUTPUT_LEVEL",99),_(t,"DEFAULT_PITCH_EG_LEVEL",50),_(t,"DEFAULT_LFO_SPEED",35),_(t,"DEFAULT_LFO_PM_SENS",3),_(t,"DEFAULT_DETUNE",7),_(t,"DEFAULT_FREQ_COARSE",1),_(t,"DEFAULT_ALGORITHM",0),_(t,"DEFAULT_FEEDBACK",0),_(t,"DEFAULT_OSC_SYNC",1),_(t,"DEFAULT_LFO_KEY_SYNC",1),_(t,"MIDI_OCTAVE_OFFSET",-2),_(t,"MIDI_BREAK_POINT_OFFSET",21);let m=t;const P=class P{constructor(e,i=""){if(this.voices=new Array(P.NUM_VOICES),this.name=i,e)this._load(e);else for(let n=0;n<P.NUM_VOICES;n++)this.voices[n]=m.createDefault(n)}static _calculateChecksum(e,i){let n=0;for(let s=0;s<i;s++)n+=e[s];return P.CHECKSUM_MODULO-n%P.CHECKSUM_MODULO&P.MASK_7BIT}_load(e){const i=e instanceof Uint8Array?e:new Uint8Array(e);let n,s=0;if(i[0]===P.SYSEX_START){const E=i.subarray(0,P.SYSEX_HEADER_SIZE),o=P.SYSEX_HEADER;for(let h=0;h<P.SYSEX_HEADER_SIZE;h++)if(E[h]!==o[h])throw new g(`Invalid SysEx header at position ${h}: expected ${o[h].toString(16)}, got ${E[h].toString(16)}`,"header",h);n=i.subarray(P.SYSEX_HEADER_SIZE,P.SYSEX_HEADER_SIZE+P.VOICE_DATA_SIZE),s=P.SYSEX_HEADER_SIZE}else if(i.length===P.VOICE_DATA_SIZE)n=i;else throw new d(`Invalid data length: expected ${P.VOICE_DATA_SIZE} or ${P.SYSEX_SIZE} bytes, got ${i.length}`,"length",i.length);if(n.length!==P.VOICE_DATA_SIZE)throw new d(`Invalid voice data length: expected ${P.VOICE_DATA_SIZE} bytes, got ${n.length}`,"length",n.length);const r=P.SYSEX_HEADER_SIZE+P.VOICE_DATA_SIZE;if(s>0&&i.length>=r+1){const E=i[r],o=P._calculateChecksum(n,P.VOICE_DATA_SIZE);E!==o&&console.warn(`DX7 checksum mismatch (expected ${o.toString(16)}, got ${E.toString(16)}). This is common with vintage SysEx files and the data is likely still valid.`)}this.voices=new Array(P.NUM_VOICES);for(let E=0;E<P.NUM_VOICES;E++){const o=E*P.VOICE_SIZE,h=n.subarray(o,o+P.VOICE_SIZE);this.voices[E]=new m(h,E)}}replaceVoice(e,i){if(e<0||e>=P.NUM_VOICES)throw new d(`Invalid voice index: ${e}`,"index",e);const n=new Uint8Array(i.data);this.voices[e]=new m(n,e)}addVoice(e){for(let i=0;i<this.voices.length;i++){const n=this.voices[i];if(n.name===""||n.name==="Init Voice")return this.replaceVoice(i,e),i}return-1}getVoices(){return this.voices}getVoice(e){return e<0||e>=this.voices.length?null:this.voices[e]}getVoiceNames(){return this.voices.map(e=>e.name)}findVoiceByName(e){const i=e.toLowerCase();return this.voices.find(n=>n.name.toLowerCase().includes(i))||null}static async fromFile(e){return new Promise((i,n)=>{const s=new FileReader;s.onload=async r=>{try{const E=e.name||"",o=new Uint8Array(r.target.result);if(o[0]===P.SYSEX_START&&o[3]===m.VCED_FORMAT_SINGLE)n(new g("This is a single voice file. Use DX7Voice.fromFile() instead.","format",3));else{const h=E.replace(/\.[^/.]+$/,""),N=new P(r.target.result,h);i(N)}}catch(E){n(E)}},s.onerror=()=>n(new Error("Failed to read file")),s.readAsArrayBuffer(e)})}static fromSysEx(e,i=""){return new P(e,i)}static fromJSON(e){if(!e||typeof e!="object")throw new d("Invalid JSON: expected object","json",e);const i=new P;if(i.name=e.name||"",!Array.isArray(e.voices))throw new d("Invalid voices array","voices",e.voices);e.voices.length!==P.NUM_VOICES&&console.warn(`Bank JSON has ${e.voices.length} voices, expected ${P.NUM_VOICES}. Missing voices will be filled with defaults.`);const n=Math.min(e.voices.length,P.NUM_VOICES);for(let s=0;s<n;s++){const r=e.voices[s];if(!r||typeof r!="object"){console.warn(`Invalid voice data at index ${s}, using default voice`);continue}try{const{index:E,...o}=r,h=m.fromJSON(o,s);i.replaceVoice(s,h)}catch(E){console.warn(`Failed to load voice at index ${s}: ${E.message}, using default voice`)}}return i}toSysEx(){const e=new Uint8Array(P.SYSEX_SIZE);let i=0;P.SYSEX_HEADER.forEach(s=>{e[i++]=s});for(const s of this.voices)for(let r=0;r<P.VOICE_SIZE;r++)e[i++]=s.data[r];const n=e.subarray(P.SYSEX_HEADER_SIZE,P.SYSEX_HEADER_SIZE+P.VOICE_DATA_SIZE);return e[i++]=P._calculateChecksum(n,P.VOICE_DATA_SIZE),e[i++]=P.SYSEX_END,e}toJSON(){const e=this.voices.map((i,n)=>{const s=i.toJSON();return{index:n+1,...s}});return{version:"1.0",name:this.name||"",voices:e}}};_(P,"SYSEX_START",240),_(P,"SYSEX_END",247),_(P,"SYSEX_YAMAHA_ID",67),_(P,"SYSEX_SUB_STATUS",0),_(P,"SYSEX_FORMAT_32_VOICES",9),_(P,"SYSEX_BYTE_COUNT_MSB",32),_(P,"SYSEX_BYTE_COUNT_LSB",0),_(P,"SYSEX_HEADER",[P.SYSEX_START,P.SYSEX_YAMAHA_ID,P.SYSEX_SUB_STATUS,P.SYSEX_FORMAT_32_VOICES,P.SYSEX_BYTE_COUNT_MSB,P.SYSEX_BYTE_COUNT_LSB]),_(P,"SYSEX_HEADER_SIZE",6),_(P,"VOICE_DATA_SIZE",4096),_(P,"SYSEX_SIZE",4104),_(P,"VOICE_SIZE",128),_(P,"NUM_VOICES",32),_(P,"CHECKSUM_MODULO",128),_(P,"MASK_7BIT",127);let G=P;function nt(c){return c[0]!==240||c[c.length-1]!==247?null:{manufacturerId:c[1],payload:c.slice(2,-1),raw:c}}function st(c,e){return[240,c,...e,247]}function Et(c){return c.length>=2&&c[0]===240&&c[c.length-1]===247}function rt(c){const e=[];for(let i=0;i<c.length;i+=7){const n=c.slice(i,i+7);let s=0;const r=[];for(let E=0;E<n.length;E++){const o=n[E];o&128&&(s|=1<<E),r.push(o&127)}e.push(s,...r)}return e}function ot(c){const e=[];for(let i=0;i<c.length;i+=8){const n=c[i],s=Math.min(7,c.length-i-1);for(let r=0;r<s;r++){let E=c[i+1+r];n&1<<r&&(E|=128),e.push(E)}}return e}function _t(c){return Number.isInteger(c)&&c>=1&&c<=16}function at(c){return Number.isInteger(c)&&c>=0&&c<=127}function ct(c){return Number.isInteger(c)&&c>=0&&c<=31}function Ct(c){return Number.isInteger(c)&&c>=0&&c<=127}function At(c){return Number.isInteger(c)&&c>=0&&c<=127}function Pt(c){return Number.isInteger(c)&&c>=0&&c<=127}function ut(c){return Number.isInteger(c)&&c>=0&&c<=127}function lt(c){return Number.isInteger(c)&&c>=0&&c<=16383}function ht(c,e){return Number.isInteger(c)&&c>=0&&c<=127&&Number.isInteger(e)&&e>=0&&e<=127}async function St(c={}){const{onStatusUpdate:e,onConnectionUpdate:i,inputChannel:n=1,outputChannel:s=1,output:r,sysex:E,onReady:o,onError:h,selector:N,watchDOM:u,...a}=c,S=await q({autoConnect:!1,sysex:E,inputChannel:n,outputChannel:s,selector:N||"[data-midi-cc]",watchDOM:u,onError:h,...a}),D=new z({midiController:S,onStatusUpdate:e||(()=>{}),onConnectionUpdate:i||(()=>{}),channel:s});if(r)try{await S.device.connectOutput(r),D.currentOutput=S.device.getCurrentOutput(),D.updateConnectionStatus()}catch(T){h?h(T):console.error("Failed to connect to MIDI device:",T.message)}return o&&o(S,D),D}async function q(c={}){const e=new Z(c);await e.init();const i=c.selector||"[data-midi-cc]";{const n=new I(e,i);n.bindAll(),c.watchDOM&&n.enableAutoBinding(),e._binder=n}return e}function Nt(){return typeof navigator<"u"&&typeof navigator.requestMIDIAccess=="function"}l.CONN=p,l.CONNECTION_EVENTS=p,l.CONTROLLER_EVENTS=A,l.CTRL=A,l.DX7Bank=G,l.DX7Error=H,l.DX7ParseError=g,l.DX7ValidationError=d,l.DX7Voice=m,l.DataAttributeBinder=I,l.EventEmitter=v,l.MIDIAccessError=F,l.MIDIConnection=$,l.MIDIConnectionError=y,l.MIDIController=Z,l.MIDIDeviceError=R,l.MIDIDeviceManager=z,l.MIDIError=K,l.MIDIValidationError=M,l.clamp=O,l.createMIDIController=q,l.createMIDIDeviceManager=St,l.createSysEx=st,l.decode14BitValue=Y,l.decode7Bit=ot,l.denormalize14BitValue=it,l.denormalizeValue=J,l.encode14BitValue=B,l.encode7Bit=rt,l.frequencyToNote=X,l.getCCName=et,l.isMIDISupported=Nt,l.isSysEx=Et,l.isValid14BitCC=ct,l.isValidCC=at,l.isValidChannel=_t,l.isValidMIDIValue=Ct,l.isValidNote=At,l.isValidPitchBend=lt,l.isValidPitchBendBytes=ht,l.isValidProgramChange=ut,l.isValidVelocity=Pt,l.normalize14BitValue=x,l.normalizeValue=w,l.noteNameToNumber=k,l.noteNumberToName=j,l.noteToFrequency=tt,l.parseSysEx=nt,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})}));
|
|
1
|
+
(function(l,I){typeof exports=="object"&&typeof module<"u"?I(exports):typeof define=="function"&&define.amd?define(["exports"],I):(l=typeof globalThis<"u"?globalThis:l||self,I(l.MIDIControls={}))})(this,(function(l){"use strict";var dt=Object.defineProperty;var Tt=(l,I,K)=>I in l?dt(l,I,{enumerable:!0,configurable:!0,writable:!0,value:K}):l[I]=K;var _=(l,I,K)=>Tt(l,typeof I!="symbol"?I+"":I,K);class I{constructor(e,i="[data-midi-cc]"){this.controller=e,this.selector=i,this.observer=null}bindAll(){document.querySelectorAll(this.selector==="[data-midi-cc]"?"[data-midi-cc], [data-midi-msb][data-midi-lsb]":this.selector).forEach(i=>{if(i.hasAttribute("data-midi-bound"))return;const n=this._parseAttributes(i);n&&(this.controller.bind(i,n),i.setAttribute("data-midi-bound","true"))})}enableAutoBinding(){if(this.observer)return;const e=this.selector==="[data-midi-cc]"?"[data-midi-cc], [data-midi-msb][data-midi-lsb]":this.selector;this.observer=new MutationObserver(i=>{i.forEach(n=>{n.addedNodes.forEach(s=>{if(s.nodeType===Node.ELEMENT_NODE){if(s.matches?.(e)){const r=this._parseAttributes(s);r&&!s.hasAttribute("data-midi-bound")&&(this.controller.bind(s,r),s.setAttribute("data-midi-bound","true"))}s.querySelectorAll&&s.querySelectorAll(e).forEach(E=>{if(!E.hasAttribute("data-midi-bound")){const o=this._parseAttributes(E);o&&(this.controller.bind(E,o),E.setAttribute("data-midi-bound","true"))}})}}),n.removedNodes.forEach(s=>{s.nodeType===Node.ELEMENT_NODE&&(s.hasAttribute?.("data-midi-bound")&&this.controller.unbind(s),s.querySelectorAll&&s.querySelectorAll("[data-midi-bound]").forEach(E=>{this.controller.unbind(E)}))})})}),this.observer.observe(document.body,{childList:!0,subtree:!0})}disableAutoBinding(){this.observer&&(this.observer.disconnect(),this.observer=null)}_parseAttributes(e){const i=parseInt(e.dataset.midiMsb,10),n=parseInt(e.dataset.midiLsb,10);if(!Number.isNaN(i)&&!Number.isNaN(n)&&i>=0&&i<=127&&n>=0&&n<=127){const r=parseInt(e.dataset.midiCc,10);return!Number.isNaN(r)&&r>=0&&r<=127&&console.warn(`Element has both 7-bit (data-midi-cc="${r}") and 14-bit (data-midi-msb="${i}" data-midi-lsb="${n}") CC attributes. 14-bit takes precedence.`,e),{msb:i,lsb:n,is14Bit:!0,channel:parseInt(e.dataset.midiChannel,10)||void 0,min:parseFloat(e.getAttribute("min"))||0,max:parseFloat(e.getAttribute("max"))||127,invert:e.dataset.midiInvert==="true",label:e.dataset.midiLabel}}const s=parseInt(e.dataset.midiCc,10);return!Number.isNaN(s)&&s>=0&&s<=127?{cc:s,channel:parseInt(e.dataset.midiChannel,10)||void 0,min:parseFloat(e.getAttribute("min"))||0,max:parseFloat(e.getAttribute("max"))||127,invert:e.dataset.midiInvert==="true",label:e.dataset.midiLabel}:((e.dataset.midiCc!==void 0||e.dataset.midiMsb!==void 0&&e.dataset.midiLsb!==void 0)&&console.warn("Invalid MIDI configuration on element:",e),null)}destroy(){this.disableAutoBinding()}}class K extends Error{constructor(e,i){super(e),this.name="MIDIError",this.code=i,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class F extends K{constructor(e,i){super(e,"MIDI_ACCESS_ERROR"),this.name="MIDIAccessError",this.reason=i}}class y extends K{constructor(e){super(e,"MIDI_CONNECTION_ERROR"),this.name="MIDIConnectionError"}}class R extends K{constructor(e,i,n){super(e,"MIDI_DEVICE_ERROR"),this.name="MIDIDeviceError",this.deviceType=i,this.deviceId=n}}class M extends K{constructor(e,i){super(e,"MIDI_VALIDATION_ERROR"),this.name="MIDIValidationError",this.validationType=i}}class H extends Error{constructor(e,i){super(e),this.name="DX7Error",this.code=i,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class g extends H{constructor(e,i,n){super(e,"DX7_PARSE_ERROR"),this.name="DX7ParseError",this.parseType=i,this.offset=n}}class d extends H{constructor(e,i,n){super(e,"DX7_VALIDATION_ERROR"),this.name="DX7ValidationError",this.validationType=i,this.value=n}}function O(c,e,i){return Math.max(e,Math.min(i,c))}function w(c,e,i,n=!1){const s=(c-e)/(i-e),E=(n?1-s:s)*127;return O(Math.round(E),0,127)}function J(c,e,i,n=!1){let s=O(c,0,127)/127;return n&&(s=1-s),e+s*(i-e)}function k(c){const e={C:0,"C#":1,DB:1,D:2,"D#":3,EB:3,E:4,F:5,"F#":6,GB:6,G:7,"G#":8,AB:8,A:9,"A#":10,BB:10,B:11},i=c.match(/^([A-G][#b]?)(-?\d+)$/i);if(!i)throw new M(`Invalid note name: ${c}`,"note",c);const[,n,s]=i,r=e[n.toUpperCase()];if(r===void 0)throw new M(`Invalid note: ${n}`,"note",n);const E=(parseInt(s,10)+1)*12+r;return O(E,0,127)}function j(c,e=!1){const s=e?["C","Db","D","Eb","E","F","Gb","G","Ab","A","Bb","B"]:["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],r=Math.floor(c/12)-1;return`${s[c%12]}${r}`}function X(c){const e=69+12*Math.log2(c/440);return O(Math.round(e),0,127)}function tt(c){return 440*2**((c-69)/12)}function et(c){return{0:"Bank Select",1:"Modulation",2:"Breath Controller",4:"Foot Controller",5:"Portamento Time",7:"Volume",8:"Balance",10:"Pan",11:"Expression",64:"Sustain Pedal",65:"Portamento",66:"Sostenuto",67:"Soft Pedal",68:"Legato",71:"Resonance",72:"Release Time",73:"Attack Time",74:"Cutoff",75:"Decay Time",76:"Vibrato Rate",77:"Vibrato Depth",78:"Vibrato Delay",84:"Portamento Control",91:"Reverb",92:"Tremolo",93:"Chorus",94:"Detune",95:"Phaser",120:"All Sound Off",121:"Reset All Controllers",123:"All Notes Off"}[c]||`CC ${c}`}function B(c){const e=O(Math.round(c),0,16383);return{msb:e>>7&127,lsb:e&127}}function Y(c,e){return O(c,0,127)<<7|O(e,0,127)}function x(c,e,i,n=!1){const s=(c-e)/(i-e),E=(n?1-s:s)*16383;return B(E)}function it(c,e,i,n,s=!1){let E=Y(c,e)/16383;return s&&(E=1-E),i+E*(n-i)}class v{constructor(){this.events=new Map}on(e,i){return this.events.has(e)||this.events.set(e,[]),this.events.get(e).push(i),()=>this.off(e,i)}once(e,i){const n=(...s)=>{i(...s),this.off(e,n)};this.on(e,n)}off(e,i){if(!this.events.has(e))return;const n=this.events.get(e),s=n.indexOf(i);s>-1&&n.splice(s,1),n.length===0&&this.events.delete(e)}emit(e,i){if(!this.events.has(e))return;[...this.events.get(e)].forEach(s=>{try{s(i)}catch(r){console.error(`Error in event handler for "${e}":`,r)}})}removeAllListeners(e){e?this.events.delete(e):this.events.clear()}}const p={DEVICE_CHANGE:"device-change",IN_DEV_CONNECTED:"in-dev-connected",IN_DEV_DISCONNECTED:"in-dev-disconnected",OUT_DEV_CONNECTED:"out-dev-connected",OUT_DEV_DISCONNECTED:"out-dev-disconnected"};class $ extends v{constructor(e={}){super(),this.options={sysex:!1,...e},this.midiAccess=null,this.output=null,this.input=null}async requestAccess(){if(!navigator.requestMIDIAccess)throw new F("Web MIDI API is not supported in this browser","unsupported");try{this.midiAccess=await navigator.requestMIDIAccess({sysex:this.options.sysex}),this.midiAccess.onstatechange=e=>{const i=e.port,n=e.port.state;this.emit(p.DEVICE_CHANGE,{port:i,state:n,type:i.type,device:{id:i.id,name:i.name,manufacturer:i.manufacturer||"Unknown"}}),n==="disconnected"?i.type==="input"?(this.emit(p.IN_DEV_DISCONNECTED,{device:i}),this.input&&this.input.id===i.id&&(this.input=null)):i.type==="output"&&(this.emit(p.OUT_DEV_DISCONNECTED,{device:i}),this.output&&this.output.id===i.id&&(this.output=null)):n==="connected"&&(i.type==="input"?this.emit(p.IN_DEV_CONNECTED,{device:i}):i.type==="output"&&this.emit(p.OUT_DEV_CONNECTED,{device:i}))}}catch(e){throw e.name==="SecurityError"?new F("MIDI access denied. SysEx requires user permission.","denied"):new F(`Failed to get MIDI access: ${e.message}`,"failed")}}async connect(e){if(!this.midiAccess)throw new y("MIDI access not initialized. Call requestAccess() first.");const i=Array.from(this.midiAccess.outputs.values());if(i.length===0)throw new R("No MIDI output devices available","output");if(e===void 0){this.output=i[0];return}if(typeof e=="number"){if(e<0||e>=i.length)throw new R(`Output index ${e} out of range (0-${i.length-1})`,"output",e);this.output=i[e];return}if(this.output=i.find(n=>n.name===e||n.id===e),!this.output){const n=i.map(s=>s.name).join(", ");throw new R(`MIDI output "${e}" not found. Available: ${n}`,"output",e)}}async connectInput(e,i){if(!this.midiAccess)throw new y("MIDI access not initialized. Call requestAccess() first.");if(typeof i!="function")throw new M("onMessage callback must be a function","callback");const n=Array.from(this.midiAccess.inputs.values());if(n.length===0)throw new R("No MIDI input devices available","input");if(this.input&&(this.input.onmidimessage=null),e===void 0)this.input=n[0];else if(typeof e=="number"){if(e<0||e>=n.length)throw new R(`Input index ${e} out of range (0-${n.length-1})`,"input",e);this.input=n[e]}else if(this.input=n.find(s=>s.name===e||s.id===e),!this.input){const s=n.map(r=>r.name).join(", ");throw new R(`MIDI input "${e}" not found. Available: ${s}`,"input",e)}this.input.onmidimessage=s=>{i(s)}}disconnectOutput(){this.output=null}disconnectInput(){this.input&&(this.input.onmidimessage=null,this.input=null)}disconnect(){this.disconnectOutput(),this.disconnectInput()}isConnected(){return this.output!==null}getCurrentOutput(){return this.output?{id:this.output.id,name:this.output.name,manufacturer:this.output.manufacturer||"Unknown"}:null}getCurrentInput(){return this.input?{id:this.input.id,name:this.input.name,manufacturer:this.input.manufacturer||"Unknown"}:null}getOutputs(){if(!this.midiAccess)return[];const e=[];return this.midiAccess.outputs.forEach(i=>{i.state==="connected"&&e.push({id:i.id,name:i.name,manufacturer:i.manufacturer||"Unknown"})}),e}getInputs(){if(!this.midiAccess)return[];const e=[];return this.midiAccess.inputs.forEach(i=>{i.state==="connected"&&e.push({id:i.id,name:i.name,manufacturer:i.manufacturer||"Unknown"})}),e}send(e,i=null){if(!this.output){console.warn("No MIDI output connected. Call connect() first.");return}try{const n=new Uint8Array(e);i===null?this.output.send(n):this.output.send(n,i)}catch(n){console.error("Failed to send MIDI message:",n)}}sendSysEx(e,i=!1){if(!this.options.sysex){console.warn("SysEx not enabled. Initialize with sysex: true");return}let n;i?n=[240,...e,247]:n=e,this.send(n)}}const A={READY:"ready",ERROR:"error",DESTROYED:"destroyed",DEV_OUT_CONNECTED:"dev-out-connected",DEV_OUT_DISCONNECTED:"dev-out-disconnected",DEV_IN_CONNECTED:"dev-in-connected",DEV_IN_DISCONNECTED:"dev-in-disconnected",CH_CC_SEND:"ch-cc-send",CH_CC_RECV:"ch-cc-recv",CH_NOTE_ON_SEND:"ch-note-on-send",CH_NOTE_ON_RECV:"ch-note-on-recv",CH_NOTE_OFF_SEND:"ch-note-off-send",CH_NOTE_OFF_RECV:"ch-note-off-recv",CH_PC_SEND:"ch-pc-send",CH_PC_RECV:"ch-pc-recv",CH_PITCH_BEND_SEND:"ch-pitch-bend-send",CH_PITCH_BEND_RECV:"ch-pitch-bend-recv",CH_MONO_PRESS_SEND:"ch-mono-press-send",CH_MONO_PRESS_RECV:"ch-mono-press-recv",CH_POLY_PRESS_SEND:"ch-poly-press-send",CH_POLY_PRESS_RECV:"ch-poly-press-recv",CH_ALL_SOUNDS_OFF_SEND:"ch-all-sounds-off-send",CH_RESET_CONTROLLERS_SEND:"ch-reset-controllers-send",CH_LOCAL_CONTROL_SEND:"ch-local-control-send",CH_ALL_NOTES_OFF_SEND:"ch-all-notes-off-send",CH_OMNI_OFF_SEND:"ch-omni-off-send",CH_OMNI_ON_SEND:"ch-omni-on-send",CH_MONO_ON_SEND:"ch-mono-on-send",CH_POLY_ON_SEND:"ch-poly-on-send",SYS_EX_SEND:"sys-ex-send",SYS_EX_RECV:"sys-ex-recv",SYS_CLOCK_RECV:"sys-clock-recv",SYS_START_RECV:"sys-start-recv",SYS_CONTINUE_RECV:"sys-continue-recv",SYS_STOP_RECV:"sys-stop-recv",SYS_MTC_RECV:"sys-mtc-recv",SYS_SONG_POS_RECV:"sys-song-pos-recv",SYS_SONG_SEL_RECV:"sys-song-sel-recv",SYS_TUNE_REQ_RECV:"sys-tune-req-recv",SYS_ACT_SENSE_RECV:"sys-act-sense-recv",SYS_RESET_RECV:"sys-reset-recv",MIDI_RAW:"midi-raw",PATCH_SAVED:"patch-saved",PATCH_LOADED:"patch-loaded",PATCH_DELETED:"patch-deleted"};class Z extends v{constructor(e={}){super(),this.options={inputChannel:1,outputChannel:1,autoConnect:!0,sysex:!1,...e},this.connection=null,this.bindings=new Map,this.state={controlChange:new Map,programChange:new Map,pitchBend:new Map,monoPressure:new Map,polyPressure:new Map},this.initialized=!1,this._initNamespaces()}async init(){if(this.initialized){console.warn("MIDI Controller already initialized");return}try{this.connection=new $({sysex:this.options.sysex}),await this.connection.requestAccess(),this.connection.on(p.DEVICE_CHANGE,async({state:e,type:i,device:n})=>{try{if(e==="connected")i==="output"?this.emit(A.DEV_OUT_CONNECTED,n):i==="input"&&this.emit(A.DEV_IN_CONNECTED,n);else if(e==="disconnected"){if(i==="output"&&n){const s=this.connection.getCurrentOutput();s&&s.id===n.id?await this._disconnectOutput():this.emit(A.DEV_OUT_DISCONNECTED,n)}if(i==="input"&&n){const s=this.connection.getCurrentInput();s&&s.id===n.id?await this._disconnectInput():this.emit(A.DEV_IN_DISCONNECTED,n)}}}catch(s){console.error("Error in device change handler:",s),this.emit(A.ERROR,s)}}),this.options.autoConnect&&await this.connection.connect(this.options.output),this.options.input!==void 0&&await this._connectInput(this.options.input),this.initialized=!0,this.emit(A.READY,this),this.options.onReady?.(this)}catch(e){throw this.emit(A.ERROR,e),this.options.onError?.(e),e}}_initNamespaces(){this.device={connect:this._connect.bind(this),disconnect:this._disconnect.bind(this),connectInput:this._connectInput.bind(this),disconnectInput:this._disconnectInput.bind(this),connectOutput:this._connectOutput.bind(this),disconnectOutput:this._disconnectOutput.bind(this),getCurrentOutput:this._getCurrentOutput.bind(this),getCurrentInput:this._getCurrentInput.bind(this),getOutputs:this._getOutputs.bind(this),getInputs:this._getInputs.bind(this)},this.channel={sendNoteOn:this._sendNoteOn.bind(this),sendNoteOff:this._sendNoteOff.bind(this),sendCC:this._sendCC.bind(this),getCC:this._getCC.bind(this),sendPC:this._sendPC.bind(this),getPC:this._getPC.bind(this),sendPitchBend:this._sendPitchBend.bind(this),getPitchBend:this._getPitchBend.bind(this),sendMonoPressure:this._sendMonoPressure.bind(this),getMonoPressure:this._getMonoPressure.bind(this),sendPolyPressure:this._sendPolyPressure.bind(this),getPolyPressure:this._getPolyPressure.bind(this),allSoundsOff:this._allSoundsOff.bind(this),resetControllers:this._resetControllers.bind(this),localControl:this._localControl.bind(this),allNotesOff:this._allNotesOff.bind(this),omniOff:this._omniOff.bind(this),omniOn:this._omniOn.bind(this),monoOn:this._monoOn.bind(this),polyOn:this._polyOn.bind(this)},this.system={sendEx:function(e,i=!1){return this._sendSysEx(e,i)}.bind(this),sendClock:this._sendClock.bind(this),start:this._sendStart.bind(this),continue:this._sendContinue.bind(this),stop:this._sendStop.bind(this),sendMTC:this._sendMTC.bind(this),sendSongPosition:this._sendSongPosition.bind(this),sendSongSelect:this._sendSongSelect.bind(this),sendTuneRequest:this._sendTuneRequest.bind(this),sendActiveSensing:this._sendActiveSensing.bind(this),sendSystemReset:this._sendSystemReset.bind(this)},this.patch={get:this._getPatch.bind(this),set:this._setPatch.bind(this),save:this._savePatch.bind(this),load:this._loadPatch.bind(this),delete:this._deletePatch.bind(this),list:this._listPatches.bind(this)}}bind(e,i,n={}){if(!e)return console.warn("Cannot bind: element is null or undefined"),()=>{};const s=this._createBinding(e,i,n);return this.bindings.set(e,s),this.initialized&&this.connection?.isConnected()&&s.handler({target:e}),()=>this.unbind(e)}_createBinding(e,i,n={}){const{min:s=parseFloat(e.getAttribute("min"))||0,max:r=parseFloat(e.getAttribute("max"))||127,channel:E,invert:o=!1,onInput:h=void 0}=i,{debounce:N=0}=n,u={...i,min:s,max:r,invert:o,onInput:h};if(E!==void 0&&(u.channel=E),i.is14Bit){const{msb:T,lsb:f}=i,U=V=>{const W=parseFloat(V.target.value);if(Number.isNaN(W))return;const{msb:Dt,lsb:Ot}=x(W,s,r,o),Q=E||this.options.outputChannel;this._sendCC(T,Dt,Q),this._sendCC(f,Ot,Q)};let L=null;const b=N>0?V=>{L&&clearTimeout(L),L=setTimeout(()=>{U(V),L=null},N)}:U;return e.addEventListener("input",b),e.addEventListener("change",b),{element:e,config:u,handler:U,destroy:()=>{L&&clearTimeout(L),e.removeEventListener("input",b),e.removeEventListener("change",b)}}}const{cc:a}=i,C=T=>{const f=parseFloat(T.target.value);if(Number.isNaN(f))return;const U=w(f,s,r,o),L=E===void 0?this.options.outputChannel:E;this._sendCC(a,U,L)};let S=null;const D=N>0?T=>{S&&clearTimeout(S),S=setTimeout(()=>{C(T),S=null},N)}:C;return e.addEventListener("input",D),e.addEventListener("change",D),{element:e,config:u,handler:C,destroy:()=>{S&&clearTimeout(S),e.removeEventListener("input",D),e.removeEventListener("change",D)}}}unbind(e){const i=this.bindings.get(e);i&&(i.destroy(),this.bindings.delete(e))}async destroy(){for(const e of this.bindings.values())e.destroy();this.bindings.clear(),this.state.controlChange.clear(),this.state.programChange.clear(),this.state.pitchBend.clear(),this.state.monoPressure.clear(),this.state.polyPressure.clear(),await this._disconnect(),this.initialized=!1,this.emit(A.DESTROYED),this.removeAllListeners()}async _connect(e){e?await this.connection.connect(e):this.options.output!==void 0?await this.connection.connect(this.options.output):this.options.autoConnect&&await this.connection.connect()}async _disconnect(){this.connection.disconnect()}async _connectInput(e){await this.connection.connectInput(e,i=>{this._handleMIDIMessage(i)}),this.emit(A.DEV_IN_CONNECTED,this.connection.getCurrentInput())}async _disconnectInput(){const e=this.connection.getCurrentInput();this.connection.disconnectInput(),this.emit(A.DEV_IN_DISCONNECTED,e)}async _connectOutput(e){await this.connection.connect(e),this.emit(A.DEV_OUT_CONNECTED,this.connection.getCurrentOutput())}async _disconnectOutput(){const e=this.connection.getCurrentOutput();this.connection.disconnectOutput(),this.emit(A.DEV_OUT_DISCONNECTED,e)}_getCurrentOutput(){return this.connection?.getCurrentOutput()||null}_getCurrentInput(){return this.connection?.getCurrentInput()||null}_getOutputs(){return this.connection?.getOutputs()||[]}_getInputs(){return this.connection?.getInputs()||[]}send(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send(e)}_sendNoteOn(e,i=64,n=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),0,127),n=O(Math.round(n),1,16);const s=144+(n-1);this.connection.send([s,e,i]),this.emit(A.CH_NOTE_ON_SEND,{note:e,velocity:i,channel:n})}_sendNoteOff(e,i=this.options.outputChannel,n=0){if(!this.initialized)return;e=O(Math.round(e),0,127),n=O(Math.round(n),0,127),i=O(Math.round(i),1,16);const s=144+(i-1);this.connection.send([s,e,n]),this.emit(A.CH_NOTE_OFF_SEND,{note:e,channel:i,velocity:n})}_sendCC(e,i,n=this.options.outputChannel){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,127),i=O(Math.round(i),0,127),n=O(Math.round(n),1,16);const s=176+(n-1);this.connection.send([s,e,i]);const r=`${n}:${e}`;this.state.controlChange.set(r,i),this.emit(A.CH_CC_SEND,{cc:e,value:i,channel:n})}_sendPC(e,i=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),1,16);const n=192+(i-1);this.connection.send([n,e]),this.state.programChange.set(i.toString(),e),this.emit(A.CH_PC_SEND,{program:e,channel:i})}_getPC(e=this.options.inputChannel){return this.state.programChange.get(e.toString())}_getCC(e,i=this.options.inputChannel){const n=`${i}:${e}`;return this.state.controlChange.get(n)}_sendPitchBend(e,i=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,16383),i=O(Math.round(i),1,16);const n=224+(i-1),s=e&127,r=e>>7&127;this.connection.send([n,s,r]),this.state.pitchBend.set(i.toString(),e),this.emit(A.CH_PITCH_BEND_SEND,{value:e,channel:i})}_getPitchBend(e=this.options.inputChannel){return this.state.pitchBend.get(e.toString())}_sendMonoPressure(e,i=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),1,16);const n=208+(i-1);this.connection.send([n,e]),this.state.monoPressure.set(i.toString(),e),this.emit(A.CH_MONO_PRESS_SEND,{pressure:e,channel:i})}_getMonoPressure(e=this.options.inputChannel){return this.state.monoPressure.get(e.toString())}_sendPolyPressure(e,i,n=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),0,127),n=O(Math.round(n),1,16);const s=160+(n-1);this.connection.send([s,e,i]);const r=`${n}:${e}`;this.state.polyPressure.set(r,i),this.emit(A.CH_POLY_PRESS_SEND,{note:e,pressure:i,channel:n})}_getPolyPressure(e,i=this.options.inputChannel){const n=`${i}:${e}`;return this.state.polyPressure.get(n)}_allSoundsOff(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,120,0]),this.emit(A.CH_ALL_SOUNDS_OFF_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,120,0])}this.emit(A.CH_ALL_SOUNDS_OFF_SEND,{channel:null})}}_resetControllers(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,121,0]),this.emit(A.CH_RESET_CONTROLLERS_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,121,0])}this.emit(A.CH_RESET_CONTROLLERS_SEND,{channel:null})}}_localControl(e,i){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}const n=e?127:0;if(i!==void 0){i=O(Math.round(i),1,16);const s=176+(i-1);this.connection.send([s,122,n]),this.emit(A.CH_LOCAL_CONTROL_SEND,{enabled:e,channel:i})}else{for(let s=1;s<=16;s++){const r=176+(s-1);this.connection.send([r,122,n])}this.emit(A.CH_LOCAL_CONTROL_SEND,{enabled:e,channel:null})}}_allNotesOff(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,123,0]),this.emit(A.CH_ALL_NOTES_OFF_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,123,0])}this.emit(A.CH_ALL_NOTES_OFF_SEND,{channel:null})}}_omniOff(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,124,0]),this.emit(A.CH_OMNI_OFF_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,124,0])}this.emit(A.CH_OMNI_OFF_SEND,{channel:null})}}_omniOn(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,125,0]),this.emit(A.CH_OMNI_ON_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,125,0])}this.emit(A.CH_OMNI_ON_SEND,{channel:null})}}_monoOn(e=1,i){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e=Math.max(0,Math.min(16,Math.round(e))),i!==void 0){i=O(Math.round(i),1,16);const n=176+(i-1);this.connection.send([n,126,e]),this.emit(A.CH_MONO_ON_SEND,{channels:e,channel:i})}else{for(let n=1;n<=16;n++){const s=176+(n-1);this.connection.send([s,126,e])}this.emit(A.CH_MONO_ON_SEND,{channels:e,channel:null})}}_polyOn(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,127,0]),this.emit(A.CH_POLY_ON_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,127,0])}this.emit(A.CH_POLY_ON_SEND,{channel:null})}}_sendSysEx(e,i=!1){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(!this.options.sysex){console.warn("SysEx not enabled. Initialize with sysex: true");return}this.connection.sendSysEx(e,i),this.emit(A.SYS_EX_SEND,{data:e,includeWrapper:i})}_sendClock(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([248])}_sendStart(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([250])}_sendContinue(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([251])}_sendStop(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([252])}_sendMTC(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,127),this.connection.send([241,e])}_sendSongPosition(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,16383);const i=e&127,n=e>>7&127;this.connection.send([242,i,n])}_sendSongSelect(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,127),this.connection.send([243,e])}_sendTuneRequest(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([246])}_sendActiveSensing(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([254])}_sendSystemReset(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([255])}_handleMIDIMessage(e){const[i,n,s]=e.data,r=i&240,E=(i&15)+1;if(i===248){this.emit(A.SYS_CLOCK_RECV,{timestamp:e.midiwire});return}if(i===250){this.emit(A.SYS_START_RECV,{timestamp:e.midiwire});return}if(i===251){this.emit(A.SYS_CONTINUE_RECV,{timestamp:e.midiwire});return}if(i===252){this.emit(A.SYS_STOP_RECV,{timestamp:e.midiwire});return}if(i===254){this.emit(A.SYS_ACT_SENSE_RECV,{timestamp:e.midiwire});return}if(i===255){this.emit(A.SYS_RESET_RECV,{timestamp:e.midiwire});return}if(i===240){this.emit(A.SYS_EX_RECV,{data:Array.from(e.data),timestamp:e.midiwire});return}if(i===241){this.emit(A.SYS_MTC_RECV,{data:n,timestamp:e.midiwire});return}if(i===242){const o=n+(s<<7);this.emit(A.SYS_SONG_POS_RECV,{position:o,timestamp:e.midiwire});return}if(i===243){this.emit(A.SYS_SONG_SEL_RECV,{song:n,timestamp:e.midiwire});return}if(i===246){this.emit(A.SYS_TUNE_REQ_RECV,{timestamp:e.midiwire});return}if(i===247){this.emit(A.MIDI_RAW,{status:i,data:[n,s],channel:E,timestamp:e.midiwire});return}if(r===176){const o=`${E}:${n}`;this.state.controlChange.set(o,s),this.emit(A.CH_CC_RECV,{cc:n,value:s,channel:E});return}if(r===192){this.state.programChange.set(E.toString(),n),this.emit(A.CH_PC_RECV,{program:n,channel:E});return}if(r===224){const o=n+(s<<7);this.state.pitchBend.set(E.toString(),o),this.emit(A.CH_PITCH_BEND_RECV,{value:o,channel:E});return}if(r===208){this.state.monoPressure.set(E.toString(),n),this.emit(A.CH_MONO_PRESS_RECV,{pressure:n,channel:E});return}if(r===160){const o=`${E}:${n}`;this.state.polyPressure.set(o,s),this.emit(A.CH_POLY_PRESS_RECV,{note:n,pressure:s,channel:E});return}if(r===144&&s>0){this.emit(A.CH_NOTE_ON_RECV,{note:n,velocity:s,channel:E});return}if(r===128||r===144&&s===0){this.emit(A.CH_NOTE_OFF_RECV,{note:n,channel:E});return}this.emit(A.MIDI_RAW,{status:i,data:[n,s],channel:E,timestamp:e.midiwire})}_getPatch(e="Unnamed Patch"){const i={name:e,device:this._getCurrentOutput()?.name||null,timestamp:new Date().toISOString(),version:"1.0",channels:{},settings:{}};for(const[n,s]of this.state.controlChange.entries()){const[r,E]=n.split(":").map(Number);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].ccs[E]=s}for(const[n,s]of this.state.programChange.entries()){const r=parseInt(n,10);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].program=s}for(const[n,s]of this.state.pitchBend.entries()){const r=parseInt(n,10);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].pitchBend=s}for(const[n,s]of this.state.monoPressure.entries()){const r=parseInt(n,10);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].monoPressure=s}for(const[n,s]of this.state.polyPressure.entries()){const[r,E]=n.split(":").map(Number),o=parseInt(r,10);i.channels[o]||(i.channels[o]={ccs:{},notes:{}}),i.channels[o].polyPressure||(i.channels[o].polyPressure={}),i.channels[o].polyPressure[E]=s}for(const[n,s]of this.bindings.entries()){const{config:r}=s;if(r.cc){const E=`cc${r.cc}`;i.settings[E]={min:r.min,max:r.max,invert:r.invert||!1,is14Bit:r.is14Bit||!1,label:n.getAttribute?.("data-midi-label")||null,elementId:n.id||null}}}return i}async _setPatch(e){if(!e||!e.channels)throw new M("Invalid patch format","patch");const i=e.version||"1.0";i==="1.0"?await this._applyPatchV1(e):(console.warn(`Unknown patch version: ${i}. Attempting to apply as v1.0`),await this._applyPatchV1(e)),this.emit(A.PATCH_LOADED,{patch:e})}async _applyPatchV1(e){for(const[i,n]of Object.entries(e.channels)){const s=parseInt(i,10);if(n.ccs)for(const[r,E]of Object.entries(n.ccs)){const o=parseInt(r,10);this._sendCC(o,E,s)}if(n.program!==void 0&&this._sendPC(n.program,s),n.pitchBend!==void 0&&this._sendPitchBend(n.pitchBend,s),n.monoPressure!==void 0&&this._sendMonoPressure(n.monoPressure,s),n.polyPressure)for(const[r,E]of Object.entries(n.polyPressure)){const o=parseInt(r,10);this._sendPolyPressure(o,E,s)}if(n.notes)for(const[r,E]of Object.entries(n.notes)){const o=parseInt(r,10);E>0?this._sendNoteOn(o,E,s):this._sendNoteOff(o,s)}}if(e.settings)for(const[i,n]of Object.entries(e.settings))for(const[s,r]of this.bindings.entries())r.config.cc?.toString()===i.replace("cc","")&&(s.min!==void 0&&n.min!==void 0&&(s.min=String(n.min)),s.max!==void 0&&n.max!==void 0&&(s.max=String(n.max)));for(const[i,n]of this.bindings.entries()){const{config:s}=n;if(s.cc!==void 0){const r=s.channel||this.options.inputChannel,E=e.channels[r];if(E?.ccs){const o=E.ccs[s.cc];if(o!==void 0){const h=s.min!==void 0?s.min:parseFloat(i.getAttribute?.("min"))||0,N=s.max!==void 0?s.max:parseFloat(i.getAttribute?.("max"))||127,u=s.invert||!1;let a;u?a=N-o/127*(N-h):a=h+o/127*(N-h),s.onInput&&typeof s.onInput=="function"?s.onInput(a):(i.value=a,i.dispatchEvent(new Event("input",{bubbles:!0})))}}}}}_savePatch(e,i=null){const n=i||this._getPatch(e),s=`midiwire_patch_${e}`;try{return localStorage.setItem(s,JSON.stringify(n)),this.emit(A.PATCH_SAVED,{name:e,patch:n}),s}catch(r){throw console.error("Failed to save patch:",r),r}}_loadPatch(e){const i=`midiwire_patch_${e}`;try{const n=localStorage.getItem(i);if(!n)return null;const s=JSON.parse(n);return this.emit(A.PATCH_LOADED,{name:e,patch:s}),s}catch(n){return console.error("Failed to load patch:",n),null}}_deletePatch(e){const i=`midiwire_patch_${e}`;try{return localStorage.removeItem(i),this.emit(A.PATCH_DELETED,{name:e}),!0}catch(n){return console.error("Failed to delete patch:",n),!1}}_listPatches(){const e=[];try{for(let i=0;i<localStorage.length;i++){const n=localStorage.key(i);if(n?.startsWith("midiwire_patch_")){const s=n.replace("midiwire_patch_",""),r=this._loadPatch(s);r&&e.push({name:s,patch:r})}}}catch(i){console.error("Failed to list patches:",i)}return e.sort((i,n)=>i.name.localeCompare(n.name))}}class z{constructor(e={}){this.midi=e.midiController||null,this.onStatusUpdate=e.onStatusUpdate||(()=>{}),this.onConnectionUpdate=e.onConnectionUpdate||(()=>{}),this.channel=e.channel||1,this.currentOutput=null,this.currentInput=null,this.isConnecting=!1}async setupSelectors(e={},i={}){if(!this.midi)throw new Error("MIDI controller not initialized. Pass midiController in constructor options.");const{output:n,input:s,channel:r}=e,E=this._resolveSelector(n),o=this._resolveSelector(s),h=this._resolveSelector(r);if(this._setupDeviceChangeListeners({output:E,input:o},i.onDeviceListChange),E){await this._populateOutputDeviceList(E);const N=i.onConnect?async(a,C)=>i.onConnect({midi:a,device:C,type:"output"}):void 0,u=i.onDisconnect?async a=>i.onDisconnect({midi:a,type:"output"}):void 0;this._connectOutputDeviceSelection(E,N,u)}if(o){await this._populateInputDeviceList(o);const N=i.onConnect?async(a,C)=>i.onConnect({midi:a,device:C,type:"input"}):void 0,u=i.onDisconnect?async a=>i.onDisconnect({midi:a,type:"input"}):void 0;this._connectInputDeviceSelection(o,N,u)}return h&&this._connectChannelSelection(h,"output"),this.midi}updateStatus(e,i=""){this.onStatusUpdate(e,i)}updateConnectionStatus(){this.onConnectionUpdate(this.currentOutput,this.currentInput,this.midi)}_setupDeviceChangeListeners(e={},i){!this.midi||this._listenersInitialized||(this._listenersInitialized=!0,this.midi.on(A.DEV_OUT_CONNECTED,async n=>{this.updateStatus(`Output device connected: ${n?.name||"Unknown"}`,"connected"),e.output&&await this._populateOutputDeviceList(e.output),i&&i()}),this.midi.on(A.DEV_OUT_DISCONNECTED,async n=>{this.updateStatus(`Output device disconnected: ${n?.name||"Unknown"}`,"error"),this.currentOutput&&n?.name===this.currentOutput.name&&(this.currentOutput=null,this.updateConnectionStatus(),e.output&&(e.output.value="")),e.output&&await this._populateOutputDeviceList(e.output),i&&i()}),this.midi.on(A.DEV_IN_CONNECTED,async n=>{this.updateStatus(`Input device connected: ${n?.name||"Unknown"}`,"connected"),e.input&&await this._populateInputDeviceList(e.input),i&&i()}),this.midi.on(A.DEV_IN_DISCONNECTED,async n=>{this.updateStatus(`Input device disconnected: ${n?.name||"Unknown"}`,"error"),e.input&&(e.input.value="",await this._populateInputDeviceList(e.input)),i&&i()}))}_resolveSelector(e){if(typeof e=="string"){const i=document.querySelector(e);return i||console.warn(`MIDIDeviceManager: Selector "${e}" not found`),i}return e||null}_getOutputDevices(){return this.midi?this.midi.device.getOutputs():[]}_getInputDevices(){return this.midi?this.midi.device.getInputs():[]}_connectOutputDeviceSelection(e,i,n){!e||!this.midi||e.addEventListener("change",async s=>{if(this.isConnecting)return;this.isConnecting=!0;const r=s.target.value;if(!r){this.currentOutput&&this.midi&&(await this.midi.device.disconnectOutput(),this.currentOutput=null,this.updateStatus("Output device disconnected",""),this.updateConnectionStatus()),this.isConnecting=!1,n&&await n(this.midi);return}try{if(await this.midi.device.connectOutput(parseInt(r,10)),this.currentOutput=this.midi.device.getCurrentOutput(),this.currentOutput){const o=this.midi.device.getOutputs().findIndex(h=>h.id===this.currentOutput.id);o!==-1&&(e.value=o.toString())}this.updateConnectionStatus(),i&&await i(this.midi,this.currentOutput)}catch(E){this.updateStatus(`Output connection failed: ${E.message}`,"error")}finally{this.isConnecting=!1}})}_connectInputDeviceSelection(e,i,n){!e||!this.midi||e.addEventListener("change",async s=>{const r=s.target.value;if(!r){this.midi&&(await this.midi.device.disconnectInput(),this.updateStatus("Input device disconnected",""),this.updateConnectionStatus()),n&&await n(this.midi);return}if(!this.isConnecting){this.isConnecting=!0;try{await this.midi.device.connectInput(parseInt(r,10));const E=this.midi.device.getCurrentInput();this.updateConnectionStatus(),i&&await i(this.midi,E)}catch(E){this.updateStatus(`Input connection failed: ${E.message}`,"error")}finally{this.isConnecting=!1}}})}_populateDeviceList(e,i,n,s,r){if(i.length>0){if(e.innerHTML='<option value="">Select a device</option>'+i.map((E,o)=>`<option value="${o}">${E.name}</option>`).join(""),n){const E=i.findIndex(o=>o.name===n.name);E!==-1?e.value=E.toString():(e.value="",r&&(this.currentOutput=null,this.updateConnectionStatus()))}else e.value="";e.disabled=!1,r&&!this.currentOutput&&this.updateStatus("Select a device")}else e.innerHTML='<option value="">No devices connected</option>',e.disabled=!0,r&&this.updateStatus("No devices connected","error");s&&s()}async _populateOutputDeviceList(e,i){if(!e||!this.midi)return;const n=this._getOutputDevices();this._populateDeviceList(e,n,this.currentOutput,i,!0)}async _populateInputDeviceList(e,i){if(!e||!this.midi)return;const n=this._getInputDevices(),s=this.midi.device.getCurrentInput();this._populateDeviceList(e,n,s,i,!1)}_connectChannelSelection(e,i){if(!e||!this.midi)return;const n=i==="input"?"inputChannel":"outputChannel";e.addEventListener("change",s=>{this.midi&&(this.midi.options[n]=parseInt(s.target.value,10),this.updateConnectionStatus())})}}const t=class t{constructor(e,i=0){if(e.length!==t.PACKED_SIZE)throw new d(`Invalid voice data length: expected ${t.PACKED_SIZE} bytes, got ${e.length}`,"length",e.length);this.index=i,this.data=new Uint8Array(e),this.name=this._extractName(),this._unpackedCache=null}_extractName(){const e=this.data.subarray(t.PACKED_NAME_START,t.PACKED_NAME_START+t.NAME_LENGTH);return Array.from(e).map(n=>{let s=n&t.MASK_7BIT;return s===t.CHAR_YEN&&(s=t.CHAR_REPLACEMENT_Y),s===t.CHAR_ARROW_RIGHT&&(s=t.CHAR_REPLACEMENT_GT),s===t.CHAR_ARROW_LEFT&&(s=t.CHAR_REPLACEMENT_LT),(s<t.CHAR_MIN_PRINTABLE||s>t.CHAR_MAX_PRINTABLE)&&(s=t.CHAR_SPACE),String.fromCharCode(s)}).join("").trim()}getParameter(e){if(e<0||e>=t.PACKED_SIZE)throw new d(`Parameter offset out of range: ${e} (must be 0-${t.PACKED_SIZE-1})`,"offset",e);return this.data[e]&t.MASK_7BIT}getUnpackedParameter(e){if(e<0||e>=t.UNPACKED_SIZE)throw new d(`Unpacked parameter offset out of range: ${e} (must be 0-${t.UNPACKED_SIZE-1})`,"offset",e);return this._unpackedCache||(this._unpackedCache=this.unpack()),this._unpackedCache[e]&t.MASK_7BIT}setParameter(e,i){if(e<0||e>=t.PACKED_SIZE)throw new d(`Parameter offset out of range: ${e} (must be 0-${t.PACKED_SIZE-1})`,"offset",e);this.data[e]=i&t.MASK_7BIT,this._unpackedCache=null,e>=t.PACKED_NAME_START&&e<t.PACKED_NAME_START+t.NAME_LENGTH&&(this.name=this._extractName())}unpack(){const e=this.data,i=new Uint8Array(t.UNPACKED_SIZE);return this._unpackOperators(e,i),this._unpackPitchEG(e,i),this._unpackGlobalParams(e,i),this._unpackName(e,i),i}_unpackOperators(e,i){for(let n=0;n<t.NUM_OPERATORS;n++){const s=(t.NUM_OPERATORS-1-n)*t.PACKED_OP_SIZE,r=n*t.UNPACKED_OP_SIZE;this._unpackOperator(e,i,s,r)}}_unpackOperator(e,i,n,s){this._unpackOperatorEG(e,i,n,s),this._unpackOperatorScaling(e,i,n,s),this._unpackOperatorPackedParams(e,i,n,s),this._unpackOperatorFrequency(e,i,n,s)}_unpackOperatorEG(e,i,n,s){i[s+t.UNPACKED_OP_EG_RATE_1]=e[n+t.PACKED_OP_EG_RATE_1]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_RATE_2]=e[n+t.PACKED_OP_EG_RATE_2]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_RATE_3]=e[n+t.PACKED_OP_EG_RATE_3]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_RATE_4]=e[n+t.PACKED_OP_EG_RATE_4]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_1]=e[n+t.PACKED_OP_EG_LEVEL_1]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_2]=e[n+t.PACKED_OP_EG_LEVEL_2]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_3]=e[n+t.PACKED_OP_EG_LEVEL_3]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_4]=e[n+t.PACKED_OP_EG_LEVEL_4]&t.MASK_7BIT}_unpackOperatorScaling(e,i,n,s){i[s+t.UNPACKED_OP_BREAK_POINT]=e[n+t.PACKED_OP_BREAK_POINT]&t.MASK_7BIT,i[s+t.UNPACKED_OP_L_SCALE_DEPTH]=e[n+t.PACKED_OP_L_SCALE_DEPTH]&t.MASK_7BIT,i[s+t.UNPACKED_OP_R_SCALE_DEPTH]=e[n+t.PACKED_OP_R_SCALE_DEPTH]&t.MASK_7BIT}_unpackOperatorPackedParams(e,i,n,s){const r=e[n+t.PACKED_OP_CURVES]&t.MASK_7BIT;i[s+t.UNPACKED_OP_L_CURVE]=r&t.MASK_2BIT,i[s+t.UNPACKED_OP_R_CURVE]=r>>2&t.MASK_2BIT;const E=e[n+t.PACKED_OP_RATE_SCALING]&t.MASK_7BIT;i[s+t.UNPACKED_OP_RATE_SCALING]=E&t.MASK_3BIT,i[s+t.UNPACKED_OP_DETUNE]=E>>3&t.MASK_4BIT;const o=e[n+t.PACKED_OP_MOD_SENS]&t.MASK_7BIT;i[s+t.UNPACKED_OP_AMP_MOD_SENS]=o&t.MASK_2BIT,i[s+t.UNPACKED_OP_KEY_VEL_SENS]=o>>2&t.MASK_3BIT,i[s+t.UNPACKED_OP_OUTPUT_LEVEL]=e[n+t.PACKED_OP_OUTPUT_LEVEL]&t.MASK_7BIT}_unpackOperatorFrequency(e,i,n,s){const r=e[n+t.PACKED_OP_MODE_FREQ]&t.MASK_7BIT;i[s+t.UNPACKED_OP_MODE]=r&t.MASK_1BIT,i[s+t.UNPACKED_OP_FREQ_COARSE]=r>>1&t.MASK_5BIT;const E=e[n+t.PACKED_OP_DETUNE_FINE]&t.MASK_7BIT;i[s+t.UNPACKED_OP_OSC_DETUNE]=E&t.MASK_3BIT,i[s+t.UNPACKED_OP_FREQ_FINE]=E>>3&t.MASK_4BIT}_unpackPitchEG(e,i){i[t.UNPACKED_PITCH_EG_RATE_1]=e[t.PACKED_PITCH_EG_RATE_1]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_RATE_2]=e[t.PACKED_PITCH_EG_RATE_2]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_RATE_3]=e[t.PACKED_PITCH_EG_RATE_3]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_RATE_4]=e[t.PACKED_PITCH_EG_RATE_4]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_1]=e[t.PACKED_PITCH_EG_LEVEL_1]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_2]=e[t.PACKED_PITCH_EG_LEVEL_2]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_3]=e[t.PACKED_PITCH_EG_LEVEL_3]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_4]=e[t.PACKED_PITCH_EG_LEVEL_4]&t.MASK_7BIT}_unpackGlobalParams(e,i){i[t.UNPACKED_ALGORITHM]=e[t.OFFSET_ALGORITHM]&t.MASK_5BIT;const n=e[t.OFFSET_FEEDBACK]&t.MASK_7BIT;i[t.UNPACKED_FEEDBACK]=n&t.MASK_3BIT,i[t.UNPACKED_OSC_SYNC]=n>>3&t.MASK_1BIT,i[t.UNPACKED_LFO_SPEED]=e[t.OFFSET_LFO_SPEED]&t.MASK_7BIT,i[t.UNPACKED_LFO_DELAY]=e[t.OFFSET_LFO_DELAY]&t.MASK_7BIT,i[t.UNPACKED_LFO_PM_DEPTH]=e[t.OFFSET_LFO_PM_DEPTH]&t.MASK_7BIT,i[t.UNPACKED_LFO_AM_DEPTH]=e[t.OFFSET_LFO_AM_DEPTH]&t.MASK_7BIT;const s=e[t.OFFSET_LFO_SYNC_WAVE]&t.MASK_7BIT;i[t.UNPACKED_LFO_KEY_SYNC]=s&t.MASK_1BIT,i[t.UNPACKED_LFO_WAVE]=s>>1&t.MASK_3BIT,i[t.UNPACKED_LFO_PM_SENS]=s>>4&t.MASK_3BIT,i[t.UNPACKED_AMP_MOD_SENS]=e[t.OFFSET_AMP_MOD_SENS]&t.MASK_7BIT,i[t.UNPACKED_TRANSPOSE]=e[t.OFFSET_TRANSPOSE]&t.MASK_7BIT,i[t.UNPACKED_EG_BIAS_SENS]=e[t.OFFSET_EG_BIAS_SENS]&t.MASK_7BIT}_unpackName(e,i){for(let n=0;n<t.NAME_LENGTH;n++)i[t.UNPACKED_NAME_START+n]=e[t.PACKED_NAME_START+n]&t.MASK_7BIT}static pack(e){if(e.length!==t.UNPACKED_SIZE)throw new d(`Invalid unpacked data length: expected ${t.UNPACKED_SIZE} bytes, got ${e.length}`,"length",e.length);const i=new Uint8Array(t.PACKED_SIZE);return t._packOperators(e,i),t._packPitchEG(e,i),t._packGlobalParams(e,i),t._packName(e,i),i}static _packOperators(e,i){for(let n=0;n<t.NUM_OPERATORS;n++){const s=n*t.UNPACKED_OP_SIZE,r=(t.NUM_OPERATORS-1-n)*t.PACKED_OP_SIZE;t._packOperator(e,i,s,r)}}static _packOperator(e,i,n,s){t._packOperatorEG(e,i,n,s),t._packOperatorScaling(e,i,n,s),t._packOperatorPackedParams(e,i,n,s),t._packOperatorFrequency(e,i,n,s)}static _packOperatorEG(e,i,n,s){i[s+t.PACKED_OP_EG_RATE_1]=e[n+t.UNPACKED_OP_EG_RATE_1],i[s+t.PACKED_OP_EG_RATE_2]=e[n+t.UNPACKED_OP_EG_RATE_2],i[s+t.PACKED_OP_EG_RATE_3]=e[n+t.UNPACKED_OP_EG_RATE_3],i[s+t.PACKED_OP_EG_RATE_4]=e[n+t.UNPACKED_OP_EG_RATE_4],i[s+t.PACKED_OP_EG_LEVEL_1]=e[n+t.UNPACKED_OP_EG_LEVEL_1],i[s+t.PACKED_OP_EG_LEVEL_2]=e[n+t.UNPACKED_OP_EG_LEVEL_2],i[s+t.PACKED_OP_EG_LEVEL_3]=e[n+t.UNPACKED_OP_EG_LEVEL_3],i[s+t.PACKED_OP_EG_LEVEL_4]=e[n+t.UNPACKED_OP_EG_LEVEL_4]}static _packOperatorScaling(e,i,n,s){i[s+t.PACKED_OP_BREAK_POINT]=e[n+t.UNPACKED_OP_BREAK_POINT],i[s+t.PACKED_OP_L_SCALE_DEPTH]=e[n+t.UNPACKED_OP_L_SCALE_DEPTH],i[s+t.PACKED_OP_R_SCALE_DEPTH]=e[n+t.UNPACKED_OP_R_SCALE_DEPTH]}static _packOperatorPackedParams(e,i,n,s){const r=e[n+t.UNPACKED_OP_L_CURVE]&t.MASK_2BIT,E=e[n+t.UNPACKED_OP_R_CURVE]&t.MASK_2BIT;i[s+t.PACKED_OP_CURVES]=r|E<<2;const o=e[n+t.UNPACKED_OP_RATE_SCALING]&t.MASK_3BIT,h=e[n+t.UNPACKED_OP_DETUNE]&t.MASK_4BIT;i[s+t.PACKED_OP_RATE_SCALING]=o|h<<3;const N=e[n+t.UNPACKED_OP_AMP_MOD_SENS]&t.MASK_2BIT,u=e[n+t.UNPACKED_OP_KEY_VEL_SENS]&t.MASK_3BIT;i[s+t.PACKED_OP_MOD_SENS]=N|u<<2,i[s+t.PACKED_OP_OUTPUT_LEVEL]=e[n+t.UNPACKED_OP_OUTPUT_LEVEL]}static _packOperatorFrequency(e,i,n,s){const r=e[n+t.UNPACKED_OP_MODE]&t.MASK_1BIT,E=e[n+t.UNPACKED_OP_FREQ_COARSE]&t.MASK_5BIT;i[s+t.PACKED_OP_MODE_FREQ]=r|E<<1;const o=e[n+t.UNPACKED_OP_OSC_DETUNE]&t.MASK_3BIT,h=e[n+t.UNPACKED_OP_FREQ_FINE]&t.MASK_4BIT;i[s+t.PACKED_OP_DETUNE_FINE]=o|h<<3}static _packPitchEG(e,i){i[t.PACKED_PITCH_EG_RATE_1]=e[t.UNPACKED_PITCH_EG_RATE_1],i[t.PACKED_PITCH_EG_RATE_2]=e[t.UNPACKED_PITCH_EG_RATE_2],i[t.PACKED_PITCH_EG_RATE_3]=e[t.UNPACKED_PITCH_EG_RATE_3],i[t.PACKED_PITCH_EG_RATE_4]=e[t.UNPACKED_PITCH_EG_RATE_4],i[t.PACKED_PITCH_EG_LEVEL_1]=e[t.UNPACKED_PITCH_EG_LEVEL_1],i[t.PACKED_PITCH_EG_LEVEL_2]=e[t.UNPACKED_PITCH_EG_LEVEL_2],i[t.PACKED_PITCH_EG_LEVEL_3]=e[t.UNPACKED_PITCH_EG_LEVEL_3],i[t.PACKED_PITCH_EG_LEVEL_4]=e[t.UNPACKED_PITCH_EG_LEVEL_4]}static _packGlobalParams(e,i){i[t.OFFSET_ALGORITHM]=e[t.UNPACKED_ALGORITHM];const n=e[t.UNPACKED_FEEDBACK]&t.MASK_3BIT,s=e[t.UNPACKED_OSC_SYNC]&t.MASK_1BIT;i[t.OFFSET_FEEDBACK]=n|s<<3,i[t.OFFSET_LFO_SPEED]=e[t.UNPACKED_LFO_SPEED],i[t.OFFSET_LFO_DELAY]=e[t.UNPACKED_LFO_DELAY],i[t.OFFSET_LFO_PM_DEPTH]=e[t.UNPACKED_LFO_PM_DEPTH],i[t.OFFSET_LFO_AM_DEPTH]=e[t.UNPACKED_LFO_AM_DEPTH];const r=e[t.UNPACKED_LFO_KEY_SYNC]&t.MASK_1BIT,E=e[t.UNPACKED_LFO_WAVE]&t.MASK_3BIT,o=e[t.UNPACKED_LFO_PM_SENS]&t.MASK_3BIT;i[t.OFFSET_LFO_SYNC_WAVE]=r|E<<1|o<<4,i[t.OFFSET_AMP_MOD_SENS]=e[t.UNPACKED_AMP_MOD_SENS],i[t.OFFSET_TRANSPOSE]=e[t.UNPACKED_TRANSPOSE],i[t.OFFSET_EG_BIAS_SENS]=e[t.UNPACKED_EG_BIAS_SENS]}static _packName(e,i){for(let n=0;n<t.NAME_LENGTH;n++)i[t.PACKED_NAME_START+n]=e[t.UNPACKED_NAME_START+n]}static createDefault(e=0){const i=new Uint8Array(t.UNPACKED_SIZE);for(let r=0;r<t.NUM_OPERATORS;r++){const E=r*t.UNPACKED_OP_SIZE;i[E+t.UNPACKED_OP_EG_RATE_1]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_RATE_2]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_RATE_3]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_RATE_4]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_LEVEL_1]=t.DEFAULT_EG_LEVEL_MAX,i[E+t.UNPACKED_OP_EG_LEVEL_2]=t.DEFAULT_EG_LEVEL_MAX,i[E+t.UNPACKED_OP_EG_LEVEL_3]=t.DEFAULT_EG_LEVEL_MAX,i[E+t.UNPACKED_OP_EG_LEVEL_4]=t.DEFAULT_EG_LEVEL_MIN,i[E+t.UNPACKED_OP_BREAK_POINT]=t.DEFAULT_BREAK_POINT,i[E+t.UNPACKED_OP_L_SCALE_DEPTH]=0,i[E+t.UNPACKED_OP_R_SCALE_DEPTH]=0,i[E+t.UNPACKED_OP_L_CURVE]=0,i[E+t.UNPACKED_OP_R_CURVE]=0,i[E+t.UNPACKED_OP_RATE_SCALING]=0,i[E+t.UNPACKED_OP_DETUNE]=t.DEFAULT_DETUNE,i[E+t.UNPACKED_OP_AMP_MOD_SENS]=0,i[E+t.UNPACKED_OP_KEY_VEL_SENS]=0,i[E+t.UNPACKED_OP_OUTPUT_LEVEL]=t.DEFAULT_OUTPUT_LEVEL,i[E+t.UNPACKED_OP_MODE]=0,i[E+t.UNPACKED_OP_FREQ_COARSE]=t.DEFAULT_FREQ_COARSE,i[E+t.UNPACKED_OP_OSC_DETUNE]=0,i[E+t.UNPACKED_OP_FREQ_FINE]=0}i[t.UNPACKED_PITCH_EG_RATE_1]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_RATE_2]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_RATE_3]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_RATE_4]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_LEVEL_1]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_PITCH_EG_LEVEL_2]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_PITCH_EG_LEVEL_3]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_PITCH_EG_LEVEL_4]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_ALGORITHM]=t.DEFAULT_ALGORITHM,i[t.UNPACKED_FEEDBACK]=t.DEFAULT_FEEDBACK,i[t.UNPACKED_OSC_SYNC]=t.DEFAULT_OSC_SYNC,i[t.UNPACKED_LFO_SPEED]=t.DEFAULT_LFO_SPEED,i[t.UNPACKED_LFO_DELAY]=0,i[t.UNPACKED_LFO_PM_DEPTH]=0,i[t.UNPACKED_LFO_AM_DEPTH]=0,i[t.UNPACKED_LFO_KEY_SYNC]=t.DEFAULT_LFO_KEY_SYNC,i[t.UNPACKED_LFO_WAVE]=0,i[t.UNPACKED_LFO_PM_SENS]=t.DEFAULT_LFO_PM_SENS,i[t.UNPACKED_AMP_MOD_SENS]=0,i[t.UNPACKED_TRANSPOSE]=t.TRANSPOSE_CENTER,i[t.UNPACKED_EG_BIAS_SENS]=0;const n="Init Voice";for(let r=0;r<t.NAME_LENGTH;r++)i[t.UNPACKED_NAME_START+r]=r<n.length?n.charCodeAt(r):t.CHAR_SPACE;const s=t.pack(i);return new t(s,e)}static fromUnpacked(e,i=0){const n=t.pack(e);return new t(n,i)}static async fromFile(e){return new Promise((i,n)=>{const s=new FileReader;s.onload=r=>{try{const E=new Uint8Array(r.target.result);if(E[0]!==t.VCED_SYSEX_START||E[1]!==t.VCED_YAMAHA_ID||E[2]!==t.VCED_SUB_STATUS||E[3]!==t.VCED_FORMAT_SINGLE||E[4]!==t.VCED_BYTE_COUNT_MSB||E[5]!==t.VCED_BYTE_COUNT_LSB)throw new g("Invalid VCED header","header",0);const o=E.subarray(t.VCED_HEADER_SIZE,t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE),h=E[t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE],N=G._calculateChecksum(o,t.VCED_DATA_SIZE);h!==N&&console.warn(`DX7 VCED checksum mismatch (expected ${N.toString(16)}, got ${h.toString(16)}). This is common with vintage SysEx files.`);const u=new Uint8Array(t.UNPACKED_SIZE);let a=0;for(let S=0;S<t.NUM_OPERATORS;S++){const D=(t.NUM_OPERATORS-1-S)*t.UNPACKED_OP_SIZE;u[D+t.UNPACKED_OP_EG_RATE_1]=o[a++],u[D+t.UNPACKED_OP_EG_RATE_2]=o[a++],u[D+t.UNPACKED_OP_EG_RATE_3]=o[a++],u[D+t.UNPACKED_OP_EG_RATE_4]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_1]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_2]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_3]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_4]=o[a++],u[D+t.UNPACKED_OP_BREAK_POINT]=o[a++],u[D+t.UNPACKED_OP_L_SCALE_DEPTH]=o[a++],u[D+t.UNPACKED_OP_R_SCALE_DEPTH]=o[a++],u[D+t.UNPACKED_OP_L_CURVE]=o[a++],u[D+t.UNPACKED_OP_R_CURVE]=o[a++],u[D+t.UNPACKED_OP_RATE_SCALING]=o[a++],u[D+t.UNPACKED_OP_DETUNE]=o[a++];const T=o[a++];u[D+t.UNPACKED_OP_AMP_MOD_SENS]=T&t.MASK_2BIT,u[D+t.UNPACKED_OP_KEY_VEL_SENS]=T>>2&t.MASK_3BIT,u[D+t.UNPACKED_OP_OUTPUT_LEVEL]=o[a++],u[D+t.UNPACKED_OP_MODE]=o[a++],u[D+t.UNPACKED_OP_FREQ_COARSE]=o[a++],u[D+t.UNPACKED_OP_FREQ_FINE]=o[a++],u[D+t.UNPACKED_OP_OSC_DETUNE]=o[a++]}u[t.UNPACKED_PITCH_EG_RATE_1]=o[a++],u[t.UNPACKED_PITCH_EG_RATE_2]=o[a++],u[t.UNPACKED_PITCH_EG_RATE_3]=o[a++],u[t.UNPACKED_PITCH_EG_RATE_4]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_1]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_2]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_3]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_4]=o[a++],u[t.UNPACKED_ALGORITHM]=o[a++],u[t.UNPACKED_FEEDBACK]=o[a++],u[t.UNPACKED_OSC_SYNC]=o[a++],u[t.UNPACKED_LFO_SPEED]=o[a++],u[t.UNPACKED_LFO_DELAY]=o[a++],u[t.UNPACKED_LFO_PM_DEPTH]=o[a++],u[t.UNPACKED_LFO_AM_DEPTH]=o[a++],u[t.UNPACKED_LFO_KEY_SYNC]=o[a++],u[t.UNPACKED_LFO_WAVE]=o[a++],u[t.UNPACKED_LFO_PM_SENS]=o[a++],u[t.UNPACKED_TRANSPOSE]=o[a++];for(let S=0;S<t.NAME_LENGTH;S++)u[t.UNPACKED_NAME_START+S]=o[a++];const C=t.pack(u);i(new t(C,0))}catch(E){n(E)}},s.onerror=()=>n(new Error("Failed to read file")),s.readAsArrayBuffer(e)})}static fromSysEx(e,i=0){const n=e instanceof Uint8Array?e:new Uint8Array(e);let s;if(n[0]===t.VCED_SYSEX_START){if(n[0]!==t.VCED_SYSEX_START||n[1]!==t.VCED_YAMAHA_ID||n[2]!==t.VCED_SUB_STATUS||n[3]!==t.VCED_FORMAT_SINGLE||n[4]!==t.VCED_BYTE_COUNT_MSB||n[5]!==t.VCED_BYTE_COUNT_LSB)throw new g("Invalid VCED header","header",0);s=n.subarray(t.VCED_HEADER_SIZE,t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE)}else if(n.length===t.PACKED_SIZE)s=n;else throw new d(`Invalid data length: expected ${t.PACKED_SIZE} or ${t.VCED_SIZE} bytes, got ${n.length}`,"length",n.length);if(s.length!==t.VCED_DATA_SIZE&&s.length!==t.PACKED_SIZE)throw new d(`Invalid voice data length: expected ${t.VCED_DATA_SIZE} or ${t.PACKED_SIZE} bytes, got ${s.length}`,"length",s.length);if(s.length===t.VCED_DATA_SIZE){const r=new Uint8Array(t.UNPACKED_SIZE);let E=0;for(let h=0;h<t.NUM_OPERATORS;h++){const N=(t.NUM_OPERATORS-1-h)*t.UNPACKED_OP_SIZE;r[N+t.UNPACKED_OP_EG_RATE_1]=s[E++],r[N+t.UNPACKED_OP_EG_RATE_2]=s[E++],r[N+t.UNPACKED_OP_EG_RATE_3]=s[E++],r[N+t.UNPACKED_OP_EG_RATE_4]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_1]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_2]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_3]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_4]=s[E++],r[N+t.UNPACKED_OP_BREAK_POINT]=s[E++],r[N+t.UNPACKED_OP_L_SCALE_DEPTH]=s[E++],r[N+t.UNPACKED_OP_R_SCALE_DEPTH]=s[E++],r[N+t.UNPACKED_OP_L_CURVE]=s[E++],r[N+t.UNPACKED_OP_R_CURVE]=s[E++],r[N+t.UNPACKED_OP_RATE_SCALING]=s[E++],r[N+t.UNPACKED_OP_DETUNE]=s[E++];const u=s[E++];r[N+t.UNPACKED_OP_AMP_MOD_SENS]=u&t.MASK_2BIT,r[N+t.UNPACKED_OP_KEY_VEL_SENS]=u>>2&t.MASK_3BIT,r[N+t.UNPACKED_OP_OUTPUT_LEVEL]=s[E++],r[N+t.UNPACKED_OP_MODE]=s[E++],r[N+t.UNPACKED_OP_FREQ_COARSE]=s[E++],r[N+t.UNPACKED_OP_FREQ_FINE]=s[E++],r[N+t.UNPACKED_OP_OSC_DETUNE]=s[E++]}r[t.UNPACKED_PITCH_EG_RATE_1]=s[E++],r[t.UNPACKED_PITCH_EG_RATE_2]=s[E++],r[t.UNPACKED_PITCH_EG_RATE_3]=s[E++],r[t.UNPACKED_PITCH_EG_RATE_4]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_1]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_2]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_3]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_4]=s[E++],r[t.UNPACKED_ALGORITHM]=s[E++],r[t.UNPACKED_FEEDBACK]=s[E++],r[t.UNPACKED_OSC_SYNC]=s[E++],r[t.UNPACKED_LFO_SPEED]=s[E++],r[t.UNPACKED_LFO_DELAY]=s[E++],r[t.UNPACKED_LFO_PM_DEPTH]=s[E++],r[t.UNPACKED_LFO_AM_DEPTH]=s[E++],r[t.UNPACKED_LFO_KEY_SYNC]=s[E++],r[t.UNPACKED_LFO_WAVE]=s[E++],r[t.UNPACKED_LFO_PM_SENS]=s[E++],r[t.UNPACKED_TRANSPOSE]=s[E++];for(let h=0;h<t.NAME_LENGTH;h++)r[t.UNPACKED_NAME_START+h]=s[E++];const o=t.pack(r);return new t(o,i)}return new t(s,i)}static fromJSON(e,i=0){if(!e||typeof e!="object")throw new d("Invalid JSON: expected object","json",e);const n=new Uint8Array(t.UNPACKED_SIZE),s=(a,C,S,D=0,T=127)=>{if(C==null)throw new d(`Missing required parameter: ${S}`,S,C);const f=Number(C);if(Number.isNaN(f))throw new d(`Invalid parameter value for ${S}: ${C}`,S,C);if(f<D||f>T)throw new d(`Parameter ${S} out of range: ${f} (must be ${D}-${T})`,S,f);n[a]=Math.floor(f)},r=a=>{const C={"-LN":0,"-EX":1,"+EX":2,"+LN":3};return C[a]!==void 0?C[a]:0},E=a=>{const C={TRIANGLE:0,"SAW DOWN":1,"SAW UP":2,SQUARE:3,SINE:4,"SAMPLE & HOLD":5};return C[a]!==void 0?C[a]:0},o=a=>{if(!a||typeof a!="string")return 60;const C=a.trim().match(/^([A-G]#?)(-?\d+)$/);if(!C)return 60;const[,S,D]=C,T=parseInt(D,10),U={C:0,"C#":1,D:2,"D#":3,E:4,F:5,"F#":6,G:7,"G#":8,A:9,"A#":10,B:11}[S.toUpperCase()];return U===void 0?60:(T-t.MIDI_OCTAVE_OFFSET)*12+U};if(!Array.isArray(e.operators))throw new d("Invalid operators array: expected array","operators",e.operators);for(let a=0;a<e.operators.length;a++){const C=e.operators[a];if(!C||typeof C!="object")throw new d(`Invalid operator data at index ${a}`,`operators[${a}]`,C);if(!C.eg||!Array.isArray(C.eg.rates)||C.eg.rates.length!==4)throw new d(`Invalid EG rates for operator ${a}`,`operators[${a}].eg.rates`,C.eg?.rates);if(!C.eg||!Array.isArray(C.eg.levels)||C.eg.levels.length!==4)throw new d(`Invalid EG levels for operator ${a}`,`operators[${a}].eg.levels`,C.eg?.levels)}if(e.operators.length!==t.NUM_OPERATORS)throw new d(`Invalid operators array: expected ${t.NUM_OPERATORS} operators`,"operators",e.operators);for(let a=0;a<t.NUM_OPERATORS;a++){const C=e.operators[a],S=a*t.UNPACKED_OP_SIZE;if(!C.eg||!Array.isArray(C.eg.rates)||C.eg.rates.length!==4)throw new d(`Invalid EG rates for operator ${a}`,`operators[${a}].eg.rates`,C.eg?.rates);if(s(S+t.UNPACKED_OP_EG_RATE_1,C.eg.rates[0],`operators[${a}].eg.rates[0]`,0,99),s(S+t.UNPACKED_OP_EG_RATE_2,C.eg.rates[1],`operators[${a}].eg.rates[1]`,0,99),s(S+t.UNPACKED_OP_EG_RATE_3,C.eg.rates[2],`operators[${a}].eg.rates[2]`,0,99),s(S+t.UNPACKED_OP_EG_RATE_4,C.eg.rates[3],`operators[${a}].eg.rates[3]`,0,99),!C.eg||!Array.isArray(C.eg.levels)||C.eg.levels.length!==4)throw new d(`Invalid EG levels for operator ${a}`,`operators[${a}].eg.levels`,C.eg?.levels);s(S+t.UNPACKED_OP_EG_LEVEL_1,C.eg.levels[0],`operators[${a}].eg.levels[0]`,0,99),s(S+t.UNPACKED_OP_EG_LEVEL_2,C.eg.levels[1],`operators[${a}].eg.levels[1]`,0,99),s(S+t.UNPACKED_OP_EG_LEVEL_3,C.eg.levels[2],`operators[${a}].eg.levels[2]`,0,99),s(S+t.UNPACKED_OP_EG_LEVEL_4,C.eg.levels[3],`operators[${a}].eg.levels[3]`,0,99);const D=o(C.key?.breakPoint)-t.MIDI_BREAK_POINT_OFFSET;s(S+t.UNPACKED_OP_BREAK_POINT,D,`operators[${a}].key.breakPoint`,0,127),s(S+t.UNPACKED_OP_L_SCALE_DEPTH,C.scale?.left?.depth||0,`operators[${a}].scale.left.depth`,0,99),s(S+t.UNPACKED_OP_R_SCALE_DEPTH,C.scale?.right?.depth||0,`operators[${a}].scale.right.depth`,0,99),n[S+t.UNPACKED_OP_L_CURVE]=r(C.scale?.left?.curve||"-LN"),n[S+t.UNPACKED_OP_R_CURVE]=r(C.scale?.right?.curve||"-LN"),s(S+t.UNPACKED_OP_RATE_SCALING,C.key?.scaling||0,`operators[${a}].key.scaling`,0,7);const T=Number(C.osc?.detune)||0;s(S+t.UNPACKED_OP_DETUNE,T+7,`operators[${a}].osc.detune`,0,14),s(S+t.UNPACKED_OP_AMP_MOD_SENS,C.output?.ampModSens||0,`operators[${a}].output.ampModSens`,0,3),s(S+t.UNPACKED_OP_OUTPUT_LEVEL,C.output?.level||0,`operators[${a}].output.level`,0,99);const f=C.osc?.freq?.mode?.toUpperCase()==="FIXED"?1:0,U=Number(C.osc?.freq?.coarse)||0,L=Number(C.osc?.freq?.fine)||0;n[S+t.UNPACKED_OP_MODE]=f,s(S+t.UNPACKED_OP_FREQ_COARSE,U,`operators[${a}].osc.freq.coarse`,0,31),s(S+t.UNPACKED_OP_FREQ_FINE,L,`operators[${a}].osc.freq.fine`,0,99),s(S+t.UNPACKED_OP_KEY_VEL_SENS,C.key?.velocity||0,`operators[${a}].key.velocity`,0,7)}if(!e.pitchEG||!Array.isArray(e.pitchEG.rates)||e.pitchEG.rates.length!==4)throw new d("Invalid pitch EG rates","pitchEG.rates",e.pitchEG?.rates);if(!e.pitchEG||!Array.isArray(e.pitchEG.levels)||e.pitchEG.levels.length!==4)throw new d("Invalid pitch EG levels","pitchEG.levels",e.pitchEG?.levels);if(s(t.UNPACKED_PITCH_EG_RATE_1,e.pitchEG.rates[0],"pitchEG.rates[0]",0,99),s(t.UNPACKED_PITCH_EG_RATE_2,e.pitchEG.rates[1],"pitchEG.rates[1]",0,99),s(t.UNPACKED_PITCH_EG_RATE_3,e.pitchEG.rates[2],"pitchEG.rates[2]",0,99),s(t.UNPACKED_PITCH_EG_RATE_4,e.pitchEG.rates[3],"pitchEG.rates[3]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_1,e.pitchEG.levels[0],"pitchEG.levels[0]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_2,e.pitchEG.levels[1],"pitchEG.levels[1]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_3,e.pitchEG.levels[2],"pitchEG.levels[2]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_4,e.pitchEG.levels[3],"pitchEG.levels[3]",0,99),!e.lfo||typeof e.lfo!="object")throw new d("Invalid LFO data","lfo",e.lfo);if(s(t.UNPACKED_LFO_SPEED,e.lfo.speed,"lfo.speed",0,99),s(t.UNPACKED_LFO_DELAY,e.lfo.delay,"lfo.delay",0,99),s(t.UNPACKED_LFO_PM_DEPTH,e.lfo.pmDepth,"lfo.pmDepth",0,99),s(t.UNPACKED_LFO_AM_DEPTH,e.lfo.amDepth,"lfo.amDepth",0,99),n[t.UNPACKED_LFO_KEY_SYNC]=e.lfo.keySync?1:0,n[t.UNPACKED_LFO_WAVE]=E(e.lfo.wave),!e.global||typeof e.global!="object")throw new d("Invalid global data","global",e.global);const h=Number(e.global.algorithm)||1;s(t.UNPACKED_ALGORITHM,h-1,"global.algorithm",0,31),s(t.UNPACKED_FEEDBACK,e.global.feedback,"global.feedback",0,7),n[t.UNPACKED_OSC_SYNC]=e.global.oscKeySync?1:0,s(t.UNPACKED_LFO_PM_SENS,e.global.pitchModSens,"global.pitchModSens",0,7);const N=Number(e.global.transpose)||0;s(t.UNPACKED_TRANSPOSE,N+t.TRANSPOSE_CENTER,"global.transpose",0,127),s(t.UNPACKED_AMP_MOD_SENS,e.global.ampModSens||0,"global.ampModSens",0,3),s(t.UNPACKED_EG_BIAS_SENS,e.global.egBiasSens||0,"global.egBiasSens",0,7);const u=e.name||"";for(let a=0;a<t.NAME_LENGTH;a++)n[t.UNPACKED_NAME_START+a]=a<u.length?u.charCodeAt(a):t.CHAR_SPACE;return t.fromUnpacked(n,i)}toSysEx(){const e=this.unpack(),i=new Uint8Array(t.VCED_SIZE);let n=0;i[n++]=t.VCED_SYSEX_START,i[n++]=t.VCED_YAMAHA_ID,i[n++]=t.VCED_SUB_STATUS,i[n++]=t.VCED_FORMAT_SINGLE,i[n++]=t.VCED_BYTE_COUNT_MSB,i[n++]=t.VCED_BYTE_COUNT_LSB;for(let r=t.NUM_OPERATORS-1;r>=0;r--){const E=r*t.UNPACKED_OP_SIZE;i[n++]=e[E+t.UNPACKED_OP_EG_RATE_1],i[n++]=e[E+t.UNPACKED_OP_EG_RATE_2],i[n++]=e[E+t.UNPACKED_OP_EG_RATE_3],i[n++]=e[E+t.UNPACKED_OP_EG_RATE_4],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_1],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_2],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_3],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_4],i[n++]=e[E+t.UNPACKED_OP_BREAK_POINT],i[n++]=e[E+t.UNPACKED_OP_L_SCALE_DEPTH],i[n++]=e[E+t.UNPACKED_OP_R_SCALE_DEPTH],i[n++]=e[E+t.UNPACKED_OP_L_CURVE],i[n++]=e[E+t.UNPACKED_OP_R_CURVE],i[n++]=e[E+t.UNPACKED_OP_RATE_SCALING],i[n++]=e[E+t.UNPACKED_OP_DETUNE];const o=e[E+t.UNPACKED_OP_AMP_MOD_SENS]&t.MASK_2BIT,h=e[E+t.UNPACKED_OP_KEY_VEL_SENS]&t.MASK_3BIT;i[n++]=o|h<<2,i[n++]=e[E+t.UNPACKED_OP_OUTPUT_LEVEL],i[n++]=e[E+t.UNPACKED_OP_MODE],i[n++]=e[E+t.UNPACKED_OP_FREQ_COARSE],i[n++]=e[E+t.UNPACKED_OP_OSC_DETUNE],i[n++]=e[E+t.UNPACKED_OP_FREQ_FINE]}i[n++]=e[t.UNPACKED_PITCH_EG_RATE_1],i[n++]=e[t.UNPACKED_PITCH_EG_RATE_2],i[n++]=e[t.UNPACKED_PITCH_EG_RATE_3],i[n++]=e[t.UNPACKED_PITCH_EG_RATE_4],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_1],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_2],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_3],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_4],i[n++]=e[t.UNPACKED_ALGORITHM],i[n++]=e[t.UNPACKED_FEEDBACK],i[n++]=e[t.UNPACKED_OSC_SYNC],i[n++]=e[t.UNPACKED_LFO_SPEED],i[n++]=e[t.UNPACKED_LFO_DELAY],i[n++]=e[t.UNPACKED_LFO_PM_DEPTH],i[n++]=e[t.UNPACKED_LFO_AM_DEPTH],i[n++]=e[t.UNPACKED_LFO_KEY_SYNC],i[n++]=e[t.UNPACKED_LFO_WAVE],i[n++]=e[t.UNPACKED_LFO_PM_SENS],i[n++]=e[t.UNPACKED_TRANSPOSE];for(let r=0;r<t.NAME_LENGTH;r++)i[n++]=e[t.UNPACKED_NAME_START+r];const s=i.subarray(t.VCED_HEADER_SIZE,t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE);return i[n++]=G._calculateChecksum(s,t.VCED_DATA_SIZE),i[n++]=t.VCED_SYSEX_END,i}toJSON(){const e=this.unpack(),i=[],n=E=>["-LN","-EX","+EX","+LN"][E]||"UNKNOWN",s=E=>["TRIANGLE","SAW DOWN","SAW UP","SQUARE","SINE","SAMPLE & HOLD"][E]||"UNKNOWN",r=E=>{const o=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],h=Math.floor(E/12)+t.MIDI_OCTAVE_OFFSET;return`${o[E%12]}${h}`};for(let E=0;E<t.NUM_OPERATORS;E++){const o=E*t.UNPACKED_OP_SIZE,h=e[o+t.UNPACKED_OP_MODE]===0?"RATIO":"FIXED";i.push({id:E+1,osc:{detune:e[o+t.UNPACKED_OP_OSC_DETUNE],freq:{coarse:e[o+t.UNPACKED_OP_FREQ_COARSE],fine:e[o+t.UNPACKED_OP_FREQ_FINE],mode:h}},eg:{rates:[e[o+t.UNPACKED_OP_EG_RATE_1],e[o+t.UNPACKED_OP_EG_RATE_2],e[o+t.UNPACKED_OP_EG_RATE_3],e[o+t.UNPACKED_OP_EG_RATE_4]],levels:[e[o+t.UNPACKED_OP_EG_LEVEL_1],e[o+t.UNPACKED_OP_EG_LEVEL_2],e[o+t.UNPACKED_OP_EG_LEVEL_3],e[o+t.UNPACKED_OP_EG_LEVEL_4]]},key:{velocity:e[o+t.UNPACKED_OP_KEY_VEL_SENS],scaling:e[o+t.UNPACKED_OP_RATE_SCALING],breakPoint:r(e[o+t.UNPACKED_OP_BREAK_POINT]+t.MIDI_BREAK_POINT_OFFSET)},output:{level:e[o+t.UNPACKED_OP_OUTPUT_LEVEL],ampModSens:e[o+t.UNPACKED_OP_AMP_MOD_SENS]},scale:{left:{depth:e[o+t.UNPACKED_OP_L_SCALE_DEPTH],curve:n(e[o+t.UNPACKED_OP_L_CURVE])},right:{depth:e[o+t.UNPACKED_OP_R_SCALE_DEPTH],curve:n(e[o+t.UNPACKED_OP_R_CURVE])}}})}return{name:this.name||"(Empty)",operators:i,pitchEG:{rates:[e[t.UNPACKED_PITCH_EG_RATE_1],e[t.UNPACKED_PITCH_EG_RATE_2],e[t.UNPACKED_PITCH_EG_RATE_3],e[t.UNPACKED_PITCH_EG_RATE_4]],levels:[e[t.UNPACKED_PITCH_EG_LEVEL_1],e[t.UNPACKED_PITCH_EG_LEVEL_2],e[t.UNPACKED_PITCH_EG_LEVEL_3],e[t.UNPACKED_PITCH_EG_LEVEL_4]]},lfo:{speed:e[t.UNPACKED_LFO_SPEED],delay:e[t.UNPACKED_LFO_DELAY],pmDepth:e[t.UNPACKED_LFO_PM_DEPTH],amDepth:e[t.UNPACKED_LFO_AM_DEPTH],keySync:e[t.UNPACKED_LFO_KEY_SYNC]===1,wave:s(e[t.UNPACKED_LFO_WAVE])},global:{algorithm:e[t.UNPACKED_ALGORITHM]+1,feedback:e[t.UNPACKED_FEEDBACK],oscKeySync:e[t.UNPACKED_OSC_SYNC]===1,pitchModSens:e[t.UNPACKED_LFO_PM_SENS],transpose:e[t.UNPACKED_TRANSPOSE]-t.TRANSPOSE_CENTER}}}};_(t,"PACKED_SIZE",128),_(t,"PACKED_OP_SIZE",17),_(t,"NUM_OPERATORS",6),_(t,"PACKED_OP_EG_RATE_1",0),_(t,"PACKED_OP_EG_RATE_2",1),_(t,"PACKED_OP_EG_RATE_3",2),_(t,"PACKED_OP_EG_RATE_4",3),_(t,"PACKED_OP_EG_LEVEL_1",4),_(t,"PACKED_OP_EG_LEVEL_2",5),_(t,"PACKED_OP_EG_LEVEL_3",6),_(t,"PACKED_OP_EG_LEVEL_4",7),_(t,"PACKED_OP_BREAK_POINT",8),_(t,"PACKED_OP_L_SCALE_DEPTH",9),_(t,"PACKED_OP_R_SCALE_DEPTH",10),_(t,"PACKED_OP_CURVES",11),_(t,"PACKED_OP_RATE_SCALING",12),_(t,"PACKED_OP_MOD_SENS",13),_(t,"PACKED_OP_OUTPUT_LEVEL",14),_(t,"PACKED_OP_MODE_FREQ",15),_(t,"PACKED_OP_DETUNE_FINE",16),_(t,"PACKED_PITCH_EG_RATE_1",102),_(t,"PACKED_PITCH_EG_RATE_2",103),_(t,"PACKED_PITCH_EG_RATE_3",104),_(t,"PACKED_PITCH_EG_RATE_4",105),_(t,"PACKED_PITCH_EG_LEVEL_1",106),_(t,"PACKED_PITCH_EG_LEVEL_2",107),_(t,"PACKED_PITCH_EG_LEVEL_3",108),_(t,"PACKED_PITCH_EG_LEVEL_4",109),_(t,"OFFSET_ALGORITHM",110),_(t,"OFFSET_FEEDBACK",111),_(t,"OFFSET_LFO_SPEED",112),_(t,"OFFSET_LFO_DELAY",113),_(t,"OFFSET_LFO_PM_DEPTH",114),_(t,"OFFSET_LFO_AM_DEPTH",115),_(t,"OFFSET_LFO_SYNC_WAVE",116),_(t,"OFFSET_TRANSPOSE",117),_(t,"OFFSET_AMP_MOD_SENS",118),_(t,"OFFSET_EG_BIAS_SENS",119),_(t,"PACKED_NAME_START",118),_(t,"NAME_LENGTH",10),_(t,"UNPACKED_SIZE",169),_(t,"UNPACKED_OP_SIZE",23),_(t,"UNPACKED_OP_EG_RATE_1",0),_(t,"UNPACKED_OP_EG_RATE_2",1),_(t,"UNPACKED_OP_EG_RATE_3",2),_(t,"UNPACKED_OP_EG_RATE_4",3),_(t,"UNPACKED_OP_EG_LEVEL_1",4),_(t,"UNPACKED_OP_EG_LEVEL_2",5),_(t,"UNPACKED_OP_EG_LEVEL_3",6),_(t,"UNPACKED_OP_EG_LEVEL_4",7),_(t,"UNPACKED_OP_BREAK_POINT",8),_(t,"UNPACKED_OP_L_SCALE_DEPTH",9),_(t,"UNPACKED_OP_R_SCALE_DEPTH",10),_(t,"UNPACKED_OP_L_CURVE",11),_(t,"UNPACKED_OP_R_CURVE",12),_(t,"UNPACKED_OP_RATE_SCALING",13),_(t,"UNPACKED_OP_DETUNE",14),_(t,"UNPACKED_OP_AMP_MOD_SENS",15),_(t,"UNPACKED_OP_OUTPUT_LEVEL",16),_(t,"UNPACKED_OP_MODE",17),_(t,"UNPACKED_OP_KEY_VEL_SENS",18),_(t,"UNPACKED_OP_FREQ_COARSE",19),_(t,"UNPACKED_OP_OSC_DETUNE",20),_(t,"UNPACKED_OP_FREQ_FINE",21),_(t,"UNPACKED_PITCH_EG_RATE_1",138),_(t,"UNPACKED_PITCH_EG_RATE_2",139),_(t,"UNPACKED_PITCH_EG_RATE_3",140),_(t,"UNPACKED_PITCH_EG_RATE_4",141),_(t,"UNPACKED_PITCH_EG_LEVEL_1",142),_(t,"UNPACKED_PITCH_EG_LEVEL_2",143),_(t,"UNPACKED_PITCH_EG_LEVEL_3",144),_(t,"UNPACKED_PITCH_EG_LEVEL_4",145),_(t,"UNPACKED_ALGORITHM",146),_(t,"UNPACKED_FEEDBACK",147),_(t,"UNPACKED_OSC_SYNC",148),_(t,"UNPACKED_LFO_SPEED",149),_(t,"UNPACKED_LFO_DELAY",150),_(t,"UNPACKED_LFO_PM_DEPTH",151),_(t,"UNPACKED_LFO_AM_DEPTH",152),_(t,"UNPACKED_LFO_KEY_SYNC",153),_(t,"UNPACKED_LFO_WAVE",154),_(t,"UNPACKED_LFO_PM_SENS",155),_(t,"UNPACKED_AMP_MOD_SENS",156),_(t,"UNPACKED_TRANSPOSE",157),_(t,"UNPACKED_EG_BIAS_SENS",158),_(t,"UNPACKED_NAME_START",159),_(t,"VCED_SIZE",163),_(t,"VCED_HEADER_SIZE",6),_(t,"VCED_DATA_SIZE",155),_(t,"VCED_SYSEX_START",240),_(t,"VCED_YAMAHA_ID",67),_(t,"VCED_SUB_STATUS",0),_(t,"VCED_FORMAT_SINGLE",0),_(t,"VCED_BYTE_COUNT_MSB",1),_(t,"VCED_BYTE_COUNT_LSB",27),_(t,"VCED_SYSEX_END",247),_(t,"MASK_7BIT",127),_(t,"MASK_2BIT",3),_(t,"MASK_3BIT",7),_(t,"MASK_4BIT",15),_(t,"MASK_5BIT",31),_(t,"MASK_1BIT",1),_(t,"TRANSPOSE_CENTER",24),_(t,"CHAR_YEN",92),_(t,"CHAR_ARROW_RIGHT",126),_(t,"CHAR_ARROW_LEFT",127),_(t,"CHAR_REPLACEMENT_Y",89),_(t,"CHAR_REPLACEMENT_GT",62),_(t,"CHAR_REPLACEMENT_LT",60),_(t,"CHAR_SPACE",32),_(t,"CHAR_MIN_PRINTABLE",32),_(t,"CHAR_MAX_PRINTABLE",126),_(t,"DEFAULT_EG_RATE",99),_(t,"DEFAULT_EG_LEVEL_MAX",99),_(t,"DEFAULT_EG_LEVEL_MIN",0),_(t,"DEFAULT_BREAK_POINT",0),_(t,"DEFAULT_OUTPUT_LEVEL",99),_(t,"DEFAULT_PITCH_EG_LEVEL",50),_(t,"DEFAULT_LFO_SPEED",35),_(t,"DEFAULT_LFO_PM_SENS",3),_(t,"DEFAULT_DETUNE",7),_(t,"DEFAULT_FREQ_COARSE",1),_(t,"DEFAULT_ALGORITHM",0),_(t,"DEFAULT_FEEDBACK",0),_(t,"DEFAULT_OSC_SYNC",1),_(t,"DEFAULT_LFO_KEY_SYNC",1),_(t,"MIDI_OCTAVE_OFFSET",-2),_(t,"MIDI_BREAK_POINT_OFFSET",21);let m=t;const P=class P{constructor(e,i=""){if(this.voices=new Array(P.NUM_VOICES),this.name=i,e)this._load(e);else for(let n=0;n<P.NUM_VOICES;n++)this.voices[n]=m.createDefault(n)}static _calculateChecksum(e,i){let n=0;for(let s=0;s<i;s++)n+=e[s];return P.CHECKSUM_MODULO-n%P.CHECKSUM_MODULO&P.MASK_7BIT}_load(e){const i=e instanceof Uint8Array?e:new Uint8Array(e);let n,s=0;if(i[0]===P.SYSEX_START){const E=i.subarray(0,P.SYSEX_HEADER_SIZE),o=P.SYSEX_HEADER;for(let h=0;h<P.SYSEX_HEADER_SIZE;h++)if(E[h]!==o[h])throw new g(`Invalid SysEx header at position ${h}: expected ${o[h].toString(16)}, got ${E[h].toString(16)}`,"header",h);n=i.subarray(P.SYSEX_HEADER_SIZE,P.SYSEX_HEADER_SIZE+P.VOICE_DATA_SIZE),s=P.SYSEX_HEADER_SIZE}else if(i.length===P.VOICE_DATA_SIZE)n=i;else throw new d(`Invalid data length: expected ${P.VOICE_DATA_SIZE} or ${P.SYSEX_SIZE} bytes, got ${i.length}`,"length",i.length);if(n.length!==P.VOICE_DATA_SIZE)throw new d(`Invalid voice data length: expected ${P.VOICE_DATA_SIZE} bytes, got ${n.length}`,"length",n.length);const r=P.SYSEX_HEADER_SIZE+P.VOICE_DATA_SIZE;if(s>0&&i.length>=r+1){const E=i[r],o=P._calculateChecksum(n,P.VOICE_DATA_SIZE);E!==o&&console.warn(`DX7 checksum mismatch (expected ${o.toString(16)}, got ${E.toString(16)}). This is common with vintage SysEx files and the data is likely still valid.`)}this.voices=new Array(P.NUM_VOICES);for(let E=0;E<P.NUM_VOICES;E++){const o=E*P.VOICE_SIZE,h=n.subarray(o,o+P.VOICE_SIZE);this.voices[E]=new m(h,E)}}replaceVoice(e,i){if(e<0||e>=P.NUM_VOICES)throw new d(`Invalid voice index: ${e}`,"index",e);const n=new Uint8Array(i.data);this.voices[e]=new m(n,e)}addVoice(e){for(let i=0;i<this.voices.length;i++){const n=this.voices[i];if(n.name===""||n.name==="Init Voice")return this.replaceVoice(i,e),i}return-1}getVoices(){return this.voices}getVoice(e){return e<0||e>=this.voices.length?null:this.voices[e]}getVoiceNames(){return this.voices.map(e=>e.name)}findVoiceByName(e){const i=e.toLowerCase();return this.voices.find(n=>n.name.toLowerCase().includes(i))||null}static async fromFile(e){return new Promise((i,n)=>{const s=new FileReader;s.onload=async r=>{try{const E=e.name||"",o=new Uint8Array(r.target.result);if(o[0]===P.SYSEX_START&&o[3]===m.VCED_FORMAT_SINGLE)n(new g("This is a single voice file. Use DX7Voice.fromFile() instead.","format",3));else{const h=E.replace(/\.[^/.]+$/,""),N=new P(r.target.result,h);i(N)}}catch(E){n(E)}},s.onerror=()=>n(new Error("Failed to read file")),s.readAsArrayBuffer(e)})}static fromSysEx(e,i=""){return new P(e,i)}static fromJSON(e){if(!e||typeof e!="object")throw new d("Invalid JSON: expected object","json",e);const i=new P;if(i.name=e.name||"",!Array.isArray(e.voices))throw new d("Invalid voices array","voices",e.voices);e.voices.length!==P.NUM_VOICES&&console.warn(`Bank JSON has ${e.voices.length} voices, expected ${P.NUM_VOICES}. Missing voices will be filled with defaults.`);const n=Math.min(e.voices.length,P.NUM_VOICES);for(let s=0;s<n;s++){const r=e.voices[s];if(!r||typeof r!="object"){console.warn(`Invalid voice data at index ${s}, using default voice`);continue}try{const{index:E,...o}=r,h=m.fromJSON(o,s);i.replaceVoice(s,h)}catch(E){console.warn(`Failed to load voice at index ${s}: ${E.message}, using default voice`)}}return i}toSysEx(){const e=new Uint8Array(P.SYSEX_SIZE);let i=0;P.SYSEX_HEADER.forEach(s=>{e[i++]=s});for(const s of this.voices)for(let r=0;r<P.VOICE_SIZE;r++)e[i++]=s.data[r];const n=e.subarray(P.SYSEX_HEADER_SIZE,P.SYSEX_HEADER_SIZE+P.VOICE_DATA_SIZE);return e[i++]=P._calculateChecksum(n,P.VOICE_DATA_SIZE),e[i++]=P.SYSEX_END,e}toJSON(){const e=this.voices.map((i,n)=>{const s=i.toJSON();return{index:n+1,...s}});return{version:"1.0",name:this.name||"",voices:e}}};_(P,"SYSEX_START",240),_(P,"SYSEX_END",247),_(P,"SYSEX_YAMAHA_ID",67),_(P,"SYSEX_SUB_STATUS",0),_(P,"SYSEX_FORMAT_32_VOICES",9),_(P,"SYSEX_BYTE_COUNT_MSB",32),_(P,"SYSEX_BYTE_COUNT_LSB",0),_(P,"SYSEX_HEADER",[P.SYSEX_START,P.SYSEX_YAMAHA_ID,P.SYSEX_SUB_STATUS,P.SYSEX_FORMAT_32_VOICES,P.SYSEX_BYTE_COUNT_MSB,P.SYSEX_BYTE_COUNT_LSB]),_(P,"SYSEX_HEADER_SIZE",6),_(P,"VOICE_DATA_SIZE",4096),_(P,"SYSEX_SIZE",4104),_(P,"VOICE_SIZE",128),_(P,"NUM_VOICES",32),_(P,"CHECKSUM_MODULO",128),_(P,"MASK_7BIT",127);let G=P;function nt(c){return c[0]!==240||c[c.length-1]!==247?null:{manufacturerId:c[1],payload:c.slice(2,-1),raw:c}}function st(c,e){return[240,c,...e,247]}function Et(c){return c.length>=2&&c[0]===240&&c[c.length-1]===247}function rt(c){const e=[];for(let i=0;i<c.length;i+=7){const n=c.slice(i,i+7);let s=0;const r=[];for(let E=0;E<n.length;E++){const o=n[E];o&128&&(s|=1<<E),r.push(o&127)}e.push(s,...r)}return e}function ot(c){const e=[];for(let i=0;i<c.length;i+=8){const n=c[i],s=Math.min(7,c.length-i-1);for(let r=0;r<s;r++){let E=c[i+1+r];n&1<<r&&(E|=128),e.push(E)}}return e}function _t(c){return Number.isInteger(c)&&c>=1&&c<=16}function at(c){return Number.isInteger(c)&&c>=0&&c<=127}function ct(c){return Number.isInteger(c)&&c>=0&&c<=31}function Ct(c){return Number.isInteger(c)&&c>=0&&c<=127}function At(c){return Number.isInteger(c)&&c>=0&&c<=127}function Pt(c){return Number.isInteger(c)&&c>=0&&c<=127}function ut(c){return Number.isInteger(c)&&c>=0&&c<=127}function lt(c){return Number.isInteger(c)&&c>=0&&c<=16383}function ht(c,e){return Number.isInteger(c)&&c>=0&&c<=127&&Number.isInteger(e)&&e>=0&&e<=127}async function St(c={}){const{onStatusUpdate:e,onConnectionUpdate:i,inputChannel:n=1,outputChannel:s=1,output:r,sysex:E,onReady:o,onError:h,selector:N,watchDOM:u,...a}=c,S=await q({autoConnect:!1,sysex:E,inputChannel:n,outputChannel:s,selector:N||"[data-midi-cc]",watchDOM:u,onError:h,...a}),D=new z({midiController:S,onStatusUpdate:e||(()=>{}),onConnectionUpdate:i||(()=>{}),channel:s});if(r)try{await S.device.connectOutput(r),D.currentOutput=S.device.getCurrentOutput(),D.updateConnectionStatus()}catch(T){h?h(T):console.error("Failed to connect to MIDI device:",T.message)}return o&&o(S,D),D}async function q(c={}){const e=new Z(c);await e.init();const i=c.selector||"[data-midi-cc]";{const n=new I(e,i);n.bindAll(),c.watchDOM&&n.enableAutoBinding(),e._binder=n}return e}function Nt(){return typeof navigator<"u"&&typeof navigator.requestMIDIAccess=="function"}l.CONN=p,l.CONNECTION_EVENTS=p,l.CONTROLLER_EVENTS=A,l.CTRL=A,l.DX7Bank=G,l.DX7Error=H,l.DX7ParseError=g,l.DX7ValidationError=d,l.DX7Voice=m,l.DataAttributeBinder=I,l.EventEmitter=v,l.MIDIAccessError=F,l.MIDIConnection=$,l.MIDIConnectionError=y,l.MIDIController=Z,l.MIDIDeviceError=R,l.MIDIDeviceManager=z,l.MIDIError=K,l.MIDIValidationError=M,l.clamp=O,l.createMIDIController=q,l.createMIDIDeviceManager=St,l.createSysEx=st,l.decode14BitValue=Y,l.decode7Bit=ot,l.denormalize14BitValue=it,l.denormalizeValue=J,l.encode14BitValue=B,l.encode7Bit=rt,l.frequencyToNote=X,l.getCCName=et,l.isMIDISupported=Nt,l.isSysEx=Et,l.isValid14BitCC=ct,l.isValidCC=at,l.isValidChannel=_t,l.isValidMIDIValue=Ct,l.isValidNote=At,l.isValidPitchBend=lt,l.isValidPitchBendBytes=ht,l.isValidProgramChange=ut,l.isValidVelocity=Pt,l.normalize14BitValue=x,l.normalizeValue=w,l.noteNameToNumber=k,l.noteNumberToName=j,l.noteToFrequency=tt,l.parseSysEx=nt,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})}));
|
package/package.json
CHANGED
|
@@ -1247,7 +1247,7 @@ export class DX7Voice {
|
|
|
1247
1247
|
const freqFine = Number(opData.osc?.freq?.fine) || 0
|
|
1248
1248
|
unpacked[opOffset + DX7Voice.UNPACKED_OP_MODE] = mode
|
|
1249
1249
|
setParam(opOffset + DX7Voice.UNPACKED_OP_FREQ_COARSE, freqCoarse, `operators[${op}].osc.freq.coarse`, 0, 31)
|
|
1250
|
-
setParam(opOffset + DX7Voice.UNPACKED_OP_FREQ_FINE, freqFine, `operators[${op}].osc.freq.fine`, 0,
|
|
1250
|
+
setParam(opOffset + DX7Voice.UNPACKED_OP_FREQ_FINE, freqFine, `operators[${op}].osc.freq.fine`, 0, 99)
|
|
1251
1251
|
|
|
1252
1252
|
// Key velocity sensitivity (0-7)
|
|
1253
1253
|
setParam(
|