spessasynth_lib 3.22.2 → 3.22.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/@types/synthetizer/worklet_system/worklet_methods/worklet_key_modifier.d.ts +8 -0
- package/package.json +1 -1
- package/synthetizer/worklet_processor.min.js +2 -2
- package/synthetizer/worklet_system/worklet_methods/snapshot.js +4 -1
- package/synthetizer/worklet_system/worklet_methods/worklet_key_modifier.js +16 -0
|
@@ -45,6 +45,14 @@ export class WorkletKeyModifierManager {
|
|
|
45
45
|
addMapping(channel: number, midiNote: number, mapping: KeyModifier): void;
|
|
46
46
|
deleteMapping(channel: any, midiNote: any): void;
|
|
47
47
|
clearMappings(): void;
|
|
48
|
+
/**
|
|
49
|
+
* @param mappings {KeyModifier[][]}
|
|
50
|
+
*/
|
|
51
|
+
setMappings(mappings: KeyModifier[][]): void;
|
|
52
|
+
/**
|
|
53
|
+
* @returns {KeyModifier[][]}
|
|
54
|
+
*/
|
|
55
|
+
getMappings(): KeyModifier[][];
|
|
48
56
|
/**
|
|
49
57
|
* @param channel {number}
|
|
50
58
|
* @param midiNote {number}
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ var cs=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(A,e)=>(
|
|
|
6
6
|
Transform type: ${this.transformType}
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
`}},kt=960,wt=QA.concave;function HA(t,A,e,s,n){return t<<10|A<<9|e<<8|s<<7|n}var Oe=[new j({srcEnum:HA(wt,0,1,0,O.noteOnVelocity),dest:a.initialAttenuation,amt:kt,secSrcEnum:0,transform:0}),new j({srcEnum:129,dest:a.vibLfoToPitch,amt:50,secSrcEnum:0,transform:0}),new j({srcEnum:HA(wt,0,1,1,y.mainVolume),dest:a.initialAttenuation,amt:kt,secSrcEnum:0,transform:0}),new j({srcEnum:13,dest:a.vibLfoToPitch,amt:50,secSrcEnum:0,transform:0}),new j({srcEnum:526,dest:a.fineTune,amt:12700,secSrcEnum:16,transform:0}),new j({srcEnum:650,dest:a.pan,amt:500,secSrcEnum:0,transform:0}),new j({srcEnum:HA(wt,0,1,1,y.expressionController),dest:a.initialAttenuation,amt:kt,secSrcEnum:0,transform:0}),new j({srcEnum:219,dest:a.reverbEffectsSend,amt:200,secSrcEnum:0,transform:0}),new j({srcEnum:221,dest:a.chorusEffectsSend,amt:200,secSrcEnum:0,transform:0}),new j({srcEnum:HA(QA.linear,0,0,0,O.polyPressure),dest:a.vibLfoToPitch,amt:50,secSrcEnum:0,transform:0}),new j({srcEnum:HA(QA.linear,0,0,1,y.tremoloDepth),dest:a.modLfoToVolume,amt:24,secSrcEnum:0,transform:0}),new j({srcEnum:HA(QA.linear,1,0,1,y.releaseTime),dest:a.releaseVolEnv,amt:1200,secSrcEnum:0,transform:0}),new j({srcEnum:HA(QA.linear,1,0,1,y.brightness),dest:a.initialFilterFc,amt:6e3,secSrcEnum:0,transform:0}),new j({srcEnum:HA(QA.linear,1,0,1,y.timbreHarmonicContent),dest:a.initialFilterQ,amt:250,secSrcEnum:0,transform:0})];var gA=128,Ve=147,Ft=new Int16Array(Ve).fill(0),dA=(t,A)=>Ft[t]=A<<7;dA(y.mainVolume,100);dA(y.balance,64);dA(y.expressionController,127);dA(y.pan,64);dA(y.timbreHarmonicContent,64);dA(y.releaseTime,64);dA(y.attackTime,64);dA(y.brightness,64);dA(y.soundController6,64);dA(y.soundController7,64);dA(y.soundController8,64);dA(y.soundController9,64);dA(y.generalPurposeController6,64);dA(y.generalPurposeController8,64);dA(gA+O.pitchWheel,64);dA(gA+O.pitchWheelRange,2);var aA={channelTuning:0,channelTransposeFine:1,modulationMultiplier:2,masterTuning:3,channelTuningSemitones:4},Rt=Object.keys(aA).length,Gt=new Float32Array(Rt);Gt[aA.modulationMultiplier]=1;var fA={Idle:0,RPCoarse:1,RPFine:2,NRPCoarse:3,NRPFine:4,DataCoarse:5,DataFine:6};function ks(t=!1){let A={midiControllers:new Int16Array(Ve),lockedControllers:Array(Ve).fill(!1),customControllers:new Float32Array(Rt),NRPCoarse:0,NRPFine:0,RPValue:0,dataEntryState:fA.Idle,voices:[],sustainedVoices:[],cachedVoices:[],preset:this.defaultPreset,presetUsesOverride:!1,channelTransposeKeyShift:0,channelOctaveTuning:new Int8Array(12),keyCentTuning:new Int16Array(128),channelVibrato:{delay:0,depth:0,rate:0},velocityOverride:0,lockGSNRPNParams:!1,holdPedal:!1,isMuted:!1,drumChannel:!1,lockPreset:!1};for(let e=0;e<128;e++)A.cachedVoices.push([]);this.workletProcessorChannels.push(A),this.resetControllers(this.workletProcessorChannels.length-1),this.sendChannelProperties(),t&&this.callEvent("newchannel",void 0)}function jA(t,A){t.lockPreset||(t.bank=A)}function PA(t){return t.drumChannel?128:t.bank}var xt={velocityOverride:128};var Ze={addMapping:0,deleteMapping:1,clearMappings:2},Xe=class{_keyMappings=[];handleMessage(A,e){switch(A){default:return;case Ze.addMapping:this.addMapping(...e);break;case Ze.clearMappings:this.clearMappings();break;case Ze.deleteMapping:this.deleteMapping(...e)}}addMapping(A,e,s){this._keyMappings[A]===void 0&&(this._keyMappings[A]=[]),this._keyMappings[A][e]=s}deleteMapping(A,e){this._keyMappings[A]?.[e]!==void 0&&(this._keyMappings[A][e]=void 0)}clearMappings(){this._keyMappings=[]}getVelocity(A,e){let s=this._keyMappings[A]?.[e];return s?s.velocity:-1}hasOverridePatch(A,e){let s=this._keyMappings[A]?.[e]?.patch?.bank;return s!==void 0&&s>0}getPatch(A,e){let s=this._keyMappings[A]?.[e];if(s)return s.patch;throw new Error("No modifier.")}};var ws="spessasynth-worklet-system",Fs=350,SA=9,We=16,_e="gs";var wA={loadNewSongList:0,pause:1,stop:2,play:3,setTime:4,changeMIDIMessageSending:5,setPlaybackRate:6,setLoop:7,changeSong:8,getMIDI:9,setSkipToFirstNote:10,setPreservePlaybackState:11},FA={midiEvent:0,songChange:1,textEvent:2,timeChange:3,pause:4,getMIDI:5,midiError:6};function $A(t,A){let e=0;for(let s=8*(A-1);s>=0;s-=8)e|=t[t.currentIndex++]<<s;return e>>>0}function Rs(t,A){if(this.ignoreEvents)return;if(this.sendMIDIMessages&&t.messageStatusByte>=128){this.sendMIDIMessage([t.messageStatusByte,...t.messageData]);return}let e=Re(t.messageStatusByte),s=this.midiPortChannelOffsets[this.midiPorts[A]]||0;switch(e.channel+=s,e.status){case F.noteOn:let n=t.messageData[1];if(n>0)this.synth.noteOn(e.channel,t.messageData[0],n),this.playingNotes.push({midiNote:t.messageData[0],channel:e.channel,velocity:n});else{this.synth.noteOff(e.channel,t.messageData[0]);let g=this.playingNotes.findIndex(C=>C.midiNote===t.messageData[0]&&C.channel===e.channel);g!==-1&&this.playingNotes.splice(g,1)}break;case F.noteOff:this.synth.noteOff(e.channel,t.messageData[0]);let o=this.playingNotes.findIndex(g=>g.midiNote===t.messageData[0]&&g.channel===e.channel);o!==-1&&this.playingNotes.splice(o,1);break;case F.pitchBend:this.synth.pitchWheel(e.channel,t.messageData[1],t.messageData[0]);break;case F.controllerChange:this.synth.controllerChange(e.channel,t.messageData[0],t.messageData[1]);break;case F.programChange:this.synth.programChange(e.channel,t.messageData[0]);break;case F.polyPressure:this.synth.polyPressure(e.channel,t.messageData[0],t.messageData[1]);break;case F.channelPressure:this.synth.channelPressure(e.channel,t.messageData[0]);break;case F.systemExclusive:this.synth.systemExclusive(t.messageData,s);break;case F.setTempo:this.oneTickToSeconds=60/(To(t)*this.midiData.timeDivision),this.oneTickToSeconds===0&&(this.oneTickToSeconds=60/(120*this.midiData.timeDivision),T("invalid tempo! falling back to 120 BPM"));break;case F.timeSignature:case F.endOfTrack:case F.midiChannelPrefix:case F.songPosition:case F.activeSensing:case F.keySignature:case F.sequenceNumber:case F.sequenceSpecific:break;case F.text:case F.lyric:case F.copyright:case F.trackName:case F.marker:case F.cuePoint:case F.instrumentName:case F.programName:this.post(FA.textEvent,[t.messageData,e.status]);break;case F.midiPort:this.assignMIDIPort(A,t.messageData[0]);break;case F.reset:this.synth.stopAllChannels(),this.synth.resetAllControllers();break;default:T(`%cUnrecognized Event: %c${t.messageStatusByte}%c status byte: %c${Object.keys(F).find(g=>F[g]===e.status)}`,r.warn,r.unrecognized,r.warn,r.value);break}}function Gs(){for(let t=0;t<16;t++)this.synth.createWorkletChannel(!0),t===SA&&this.synth.setDrums(this.synth.workletProcessorChannels.length-1,!0)}function To(t){return t.messageData.currentIndex=0,6e7/$A(t.messageData,3)}function xs(){let t=this.currentTime;for(;this.playedTime<t;){let A=this._findFirstEventIndex(),e=this.tracks[A][this.eventIndex[A]];if(this._processEvent(e,A),this.eventIndex[A]++,A=this._findFirstEventIndex(),this.tracks[A].length<=this.eventIndex[A]){if(this.loop){this.setTimeTicks(this.midiData.loop.start);return}this.eventIndex[A]--,this.pause(!0),this.songs.length>1&&this.nextSong();return}let s=this.tracks[A][this.eventIndex[A]];if(this.playedTime+=this.oneTickToSeconds*(s.ticks-e.ticks),this.midiData.loop.end<=e.ticks&&this.loop&&this.currentLoopCount>0){this.currentLoopCount--,this.setTimeTicks(this.midiData.loop.start);return}else if(t>=this.duration){if(this.loop&&this.currentLoopCount>0){this.currentLoopCount--,this.setTimeTicks(this.midiData.loop.start);return}this.eventIndex[A]--,this.pause(!0),this.songs.length>1&&this.nextSong();return}}}function Ms(){let t=0,A=1/0;return this.tracks.forEach((e,s)=>{this.eventIndex[s]>=e.length||e[this.eventIndex[s]].ticks<A&&(t=s,A=e[this.eventIndex[s]].ticks)}),t}var ze=class{constructor(A){this.timeDivision=A.timeDivision,this.duration=A.duration,this.tempoChanges=A.tempoChanges,this.copyright=A.copyright,this.tracksAmount=A.tracksAmount,this.lyrics=A.lyrics,this.firstNoteOn=A.firstNoteOn,this.keyRange=A.keyRange,this.lastVoiceEventTick=A.lastVoiceEventTick,this.midiPorts=A.midiPorts,this.midiPortChannelOffsets=A.midiPortChannelOffsets,this.usedChannelsOnTrack=A.usedChannelsOnTrack,this.loop=A.loop,this.midiName=A.midiName,this.fileName=A.fileName,this.rawMidiName=A.rawMidiName,this.isEmbedded=A.embeddedSoundFont!==void 0,this.RMIDInfo=A.RMIDInfo,this.bankOffset=A.bankOffset}},Hi={duration:99999,firstNoteOn:0,loop:{start:0,end:123456},lastVoiceEventTick:123456,lyrics:[],copyright:"",midiPorts:[],midiPortChannelOffsets:[],tracksAmount:0,tempoChanges:[{ticks:0,tempo:120}],fileName:"NOT_LOADED.mid",midiName:"Loading...",rawMidiName:new Uint8Array([76,111,97,100,105,110,103,46,46,46]),usedChannelsOnTrack:[],timeDivision:0,keyRange:{min:0,max:127},isEmbedded:!1,RMIDInfo:void 0,bankOffset:0};function k(t,A){let e=0;for(let s=0;s<A;s++)e|=t[t.currentIndex++]<<s*8;return e>>>0}function he(t,A,e){for(let s=0;s<e;s++)t[t.currentIndex++]=A>>s*8&255}function v(t,A){t[t.currentIndex++]=A&255,t[t.currentIndex++]=A>>8}function cA(t,A){he(t,A,4)}function Ae(t,A){let e=A<<8|t;return e>32767?e-65536:e}function Ns(t){return t>127?t-256:t}function Z(t,A,e=void 0,s=!0){if(e){let n=t.slice(t.currentIndex,t.currentIndex+A);return t.currentIndex+=A,new TextDecoder(e.replace(/[^\x20-\x7E]/g,"")).decode(n.buffer)}else{let n=!1,o="";for(let g=0;g<A;g++){let C=t[t.currentIndex++];if(!n){if(C<32||C>127){if(s){n=!0;continue}else if(C===0){n=!0;continue}}o+=String.fromCharCode(C)}}return o}}function RA(t,A,e=0){e>0&&A.length>e&&(A=A.slice(0,e));for(let s=0;s<A.length;s++)t[t.currentIndex++]=A.charCodeAt(s);if(e>A.length)for(let s=0;s<e-A.length;s++)t[t.currentIndex++]=0;return t}var eA=class{constructor(A,e,s){this.header=A,this.size=e,this.chunkData=s}};function X(t,A=!0,e=!1){let s=Z(t,4),n=k(t,4),o;return A&&(o=new Y(t.buffer.slice(t.currentIndex,t.currentIndex+n))),(A||e)&&(t.currentIndex+=n),n%2!==0&&t[t.currentIndex]===0&&t.currentIndex++,new eA(s,n,o)}function nA(t,A=void 0){let e=8+t.size;t.size%2!==0&&e++,A&&(e+=A.length);let s=new Y(e);return A&&(s.set(A,s.currentIndex),s.currentIndex+=A.length),RA(s,t.header),cA(s,e-8-(A?.length||0)),s.set(t.chunkData,s.currentIndex),s}function DA(t,A){return t.find(e=>e.header!=="LIST"?!1:(e.chunkData.currentIndex=0,Z(e.chunkData,4)===A))}function je(t){let A=0;for(;t;){let e=t[t.currentIndex++];if(A=A<<7|e&127,e>>7!==1)break}return A}var $e={name:"INAM",album:"IPRD",artist:"IART",genre:"IGNR",picture:"IPIC",copyright:"ICOP",creationDate:"ICRD",comment:"ICMT",engineer:"IENG",software:"ISFT",encoding:"IENC",midiEncoding:"MENC",bankOffset:"DBNK"};var At=class{constructor(){this.timeDivision=0,this.duration=0,this.tempoChanges=[{ticks:0,tempo:120}],this.copyright="",this.tracksAmount=0,this.lyrics=[],this.firstNoteOn=0,this.keyRange={min:0,max:127},this.lastVoiceEventTick=0,this.midiPorts=[0],this.midiPortChannelOffsets=[0],this.usedChannelsOnTrack=[],this.loop={start:0,end:0},this.midiName="",this.fileName="",this.rawMidiName=void 0,this.embeddedSoundFont=void 0,this.format=0,this.RMIDInfo={},this.bankOffset=0,this.tracks=[]}};function Qe(t,A){let e=0;for(;t>0;){let s=A.tempoChanges.find(o=>o.ticks<t),n=t-s.ticks;e+=n*60/(s.tempo*A.timeDivision),t-=n}return e}var Ho=new Uint8Array([65,16,69,18,16,0,0]),et=class extends At{constructor(A,e=""){super(),yA("%cParsing MIDI File...",r.info);let s=new Y(A),n,o=!1,g=!1,C=!1,Q=Z(s,4);if(s.currentIndex-=4,Q==="RIFF"){s.currentIndex+=8;let S=Z(s,4,void 0,!1);if(S!=="RMID")throw V(),new SyntaxError(`Invalid RMIDI Header! Expected "RMID", got "${S}"`);let D=X(s);if(D.header!=="data")throw V(),new SyntaxError(`Invalid RMIDI Chunk header! Expected "data", got "${S}"`);for(n=D.chunkData;s.currentIndex<=s.length;){let w=s.currentIndex,J=X(s,!0);if(J.header==="RIFF"){let R=Z(J.chunkData,4).toLowerCase();R==="sfbk"||R==="sfpk"||R==="dls "?(m("%cFound embedded soundfont!",r.recognized),this.embeddedSoundFont=s.slice(w,w+J.size).buffer):T(`Unknown RIFF chunk: "${R}"`),R==="dls "&&(C=!0)}else if(J.header==="LIST"&&Z(J.chunkData,4)==="INFO"){for(m("%cFound RMIDI INFO chunk!",r.recognized),this.RMIDInfo={};J.chunkData.currentIndex<=J.size;){let U=X(J.chunkData,!0);this.RMIDInfo[U.header]=U.chunkData}this.RMIDInfo.ICOP&&(o=!0,this.copyright=Z(this.RMIDInfo.ICOP,this.RMIDInfo.ICOP.length,void 0,!1).replaceAll(`
|
|
9
|
+
`}},kt=960,wt=QA.concave;function HA(t,A,e,s,n){return t<<10|A<<9|e<<8|s<<7|n}var Oe=[new j({srcEnum:HA(wt,0,1,0,O.noteOnVelocity),dest:a.initialAttenuation,amt:kt,secSrcEnum:0,transform:0}),new j({srcEnum:129,dest:a.vibLfoToPitch,amt:50,secSrcEnum:0,transform:0}),new j({srcEnum:HA(wt,0,1,1,y.mainVolume),dest:a.initialAttenuation,amt:kt,secSrcEnum:0,transform:0}),new j({srcEnum:13,dest:a.vibLfoToPitch,amt:50,secSrcEnum:0,transform:0}),new j({srcEnum:526,dest:a.fineTune,amt:12700,secSrcEnum:16,transform:0}),new j({srcEnum:650,dest:a.pan,amt:500,secSrcEnum:0,transform:0}),new j({srcEnum:HA(wt,0,1,1,y.expressionController),dest:a.initialAttenuation,amt:kt,secSrcEnum:0,transform:0}),new j({srcEnum:219,dest:a.reverbEffectsSend,amt:200,secSrcEnum:0,transform:0}),new j({srcEnum:221,dest:a.chorusEffectsSend,amt:200,secSrcEnum:0,transform:0}),new j({srcEnum:HA(QA.linear,0,0,0,O.polyPressure),dest:a.vibLfoToPitch,amt:50,secSrcEnum:0,transform:0}),new j({srcEnum:HA(QA.linear,0,0,1,y.tremoloDepth),dest:a.modLfoToVolume,amt:24,secSrcEnum:0,transform:0}),new j({srcEnum:HA(QA.linear,1,0,1,y.releaseTime),dest:a.releaseVolEnv,amt:1200,secSrcEnum:0,transform:0}),new j({srcEnum:HA(QA.linear,1,0,1,y.brightness),dest:a.initialFilterFc,amt:6e3,secSrcEnum:0,transform:0}),new j({srcEnum:HA(QA.linear,1,0,1,y.timbreHarmonicContent),dest:a.initialFilterQ,amt:250,secSrcEnum:0,transform:0})];var gA=128,Ve=147,Ft=new Int16Array(Ve).fill(0),dA=(t,A)=>Ft[t]=A<<7;dA(y.mainVolume,100);dA(y.balance,64);dA(y.expressionController,127);dA(y.pan,64);dA(y.timbreHarmonicContent,64);dA(y.releaseTime,64);dA(y.attackTime,64);dA(y.brightness,64);dA(y.soundController6,64);dA(y.soundController7,64);dA(y.soundController8,64);dA(y.soundController9,64);dA(y.generalPurposeController6,64);dA(y.generalPurposeController8,64);dA(gA+O.pitchWheel,64);dA(gA+O.pitchWheelRange,2);var aA={channelTuning:0,channelTransposeFine:1,modulationMultiplier:2,masterTuning:3,channelTuningSemitones:4},Rt=Object.keys(aA).length,Gt=new Float32Array(Rt);Gt[aA.modulationMultiplier]=1;var fA={Idle:0,RPCoarse:1,RPFine:2,NRPCoarse:3,NRPFine:4,DataCoarse:5,DataFine:6};function ks(t=!1){let A={midiControllers:new Int16Array(Ve),lockedControllers:Array(Ve).fill(!1),customControllers:new Float32Array(Rt),NRPCoarse:0,NRPFine:0,RPValue:0,dataEntryState:fA.Idle,voices:[],sustainedVoices:[],cachedVoices:[],preset:this.defaultPreset,presetUsesOverride:!1,channelTransposeKeyShift:0,channelOctaveTuning:new Int8Array(12),keyCentTuning:new Int16Array(128),channelVibrato:{delay:0,depth:0,rate:0},velocityOverride:0,lockGSNRPNParams:!1,holdPedal:!1,isMuted:!1,drumChannel:!1,lockPreset:!1};for(let e=0;e<128;e++)A.cachedVoices.push([]);this.workletProcessorChannels.push(A),this.resetControllers(this.workletProcessorChannels.length-1),this.sendChannelProperties(),t&&this.callEvent("newchannel",void 0)}function jA(t,A){t.lockPreset||(t.bank=A)}function PA(t){return t.drumChannel?128:t.bank}var xt={velocityOverride:128};var Ze={addMapping:0,deleteMapping:1,clearMappings:2},Xe=class{_keyMappings=[];handleMessage(A,e){switch(A){default:return;case Ze.addMapping:this.addMapping(...e);break;case Ze.clearMappings:this.clearMappings();break;case Ze.deleteMapping:this.deleteMapping(...e)}}addMapping(A,e,s){this._keyMappings[A]===void 0&&(this._keyMappings[A]=[]),this._keyMappings[A][e]=s}deleteMapping(A,e){this._keyMappings[A]?.[e]!==void 0&&(this._keyMappings[A][e]=void 0)}clearMappings(){this._keyMappings=[]}setMappings(A){this._keyMappings=A}getMappings(){return this._keyMappings}getVelocity(A,e){let s=this._keyMappings[A]?.[e];return s?s.velocity:-1}hasOverridePatch(A,e){let s=this._keyMappings[A]?.[e]?.patch?.bank;return s!==void 0&&s>0}getPatch(A,e){let s=this._keyMappings[A]?.[e];if(s)return s.patch;throw new Error("No modifier.")}};var ws="spessasynth-worklet-system",Fs=350,SA=9,We=16,_e="gs";var wA={loadNewSongList:0,pause:1,stop:2,play:3,setTime:4,changeMIDIMessageSending:5,setPlaybackRate:6,setLoop:7,changeSong:8,getMIDI:9,setSkipToFirstNote:10,setPreservePlaybackState:11},FA={midiEvent:0,songChange:1,textEvent:2,timeChange:3,pause:4,getMIDI:5,midiError:6};function $A(t,A){let e=0;for(let s=8*(A-1);s>=0;s-=8)e|=t[t.currentIndex++]<<s;return e>>>0}function Rs(t,A){if(this.ignoreEvents)return;if(this.sendMIDIMessages&&t.messageStatusByte>=128){this.sendMIDIMessage([t.messageStatusByte,...t.messageData]);return}let e=Re(t.messageStatusByte),s=this.midiPortChannelOffsets[this.midiPorts[A]]||0;switch(e.channel+=s,e.status){case F.noteOn:let n=t.messageData[1];if(n>0)this.synth.noteOn(e.channel,t.messageData[0],n),this.playingNotes.push({midiNote:t.messageData[0],channel:e.channel,velocity:n});else{this.synth.noteOff(e.channel,t.messageData[0]);let g=this.playingNotes.findIndex(C=>C.midiNote===t.messageData[0]&&C.channel===e.channel);g!==-1&&this.playingNotes.splice(g,1)}break;case F.noteOff:this.synth.noteOff(e.channel,t.messageData[0]);let o=this.playingNotes.findIndex(g=>g.midiNote===t.messageData[0]&&g.channel===e.channel);o!==-1&&this.playingNotes.splice(o,1);break;case F.pitchBend:this.synth.pitchWheel(e.channel,t.messageData[1],t.messageData[0]);break;case F.controllerChange:this.synth.controllerChange(e.channel,t.messageData[0],t.messageData[1]);break;case F.programChange:this.synth.programChange(e.channel,t.messageData[0]);break;case F.polyPressure:this.synth.polyPressure(e.channel,t.messageData[0],t.messageData[1]);break;case F.channelPressure:this.synth.channelPressure(e.channel,t.messageData[0]);break;case F.systemExclusive:this.synth.systemExclusive(t.messageData,s);break;case F.setTempo:this.oneTickToSeconds=60/(To(t)*this.midiData.timeDivision),this.oneTickToSeconds===0&&(this.oneTickToSeconds=60/(120*this.midiData.timeDivision),T("invalid tempo! falling back to 120 BPM"));break;case F.timeSignature:case F.endOfTrack:case F.midiChannelPrefix:case F.songPosition:case F.activeSensing:case F.keySignature:case F.sequenceNumber:case F.sequenceSpecific:break;case F.text:case F.lyric:case F.copyright:case F.trackName:case F.marker:case F.cuePoint:case F.instrumentName:case F.programName:this.post(FA.textEvent,[t.messageData,e.status]);break;case F.midiPort:this.assignMIDIPort(A,t.messageData[0]);break;case F.reset:this.synth.stopAllChannels(),this.synth.resetAllControllers();break;default:T(`%cUnrecognized Event: %c${t.messageStatusByte}%c status byte: %c${Object.keys(F).find(g=>F[g]===e.status)}`,r.warn,r.unrecognized,r.warn,r.value);break}}function Gs(){for(let t=0;t<16;t++)this.synth.createWorkletChannel(!0),t===SA&&this.synth.setDrums(this.synth.workletProcessorChannels.length-1,!0)}function To(t){return t.messageData.currentIndex=0,6e7/$A(t.messageData,3)}function xs(){let t=this.currentTime;for(;this.playedTime<t;){let A=this._findFirstEventIndex(),e=this.tracks[A][this.eventIndex[A]];if(this._processEvent(e,A),this.eventIndex[A]++,A=this._findFirstEventIndex(),this.tracks[A].length<=this.eventIndex[A]){if(this.loop){this.setTimeTicks(this.midiData.loop.start);return}this.eventIndex[A]--,this.pause(!0),this.songs.length>1&&this.nextSong();return}let s=this.tracks[A][this.eventIndex[A]];if(this.playedTime+=this.oneTickToSeconds*(s.ticks-e.ticks),this.midiData.loop.end<=e.ticks&&this.loop&&this.currentLoopCount>0){this.currentLoopCount--,this.setTimeTicks(this.midiData.loop.start);return}else if(t>=this.duration){if(this.loop&&this.currentLoopCount>0){this.currentLoopCount--,this.setTimeTicks(this.midiData.loop.start);return}this.eventIndex[A]--,this.pause(!0),this.songs.length>1&&this.nextSong();return}}}function Ms(){let t=0,A=1/0;return this.tracks.forEach((e,s)=>{this.eventIndex[s]>=e.length||e[this.eventIndex[s]].ticks<A&&(t=s,A=e[this.eventIndex[s]].ticks)}),t}var ze=class{constructor(A){this.timeDivision=A.timeDivision,this.duration=A.duration,this.tempoChanges=A.tempoChanges,this.copyright=A.copyright,this.tracksAmount=A.tracksAmount,this.lyrics=A.lyrics,this.firstNoteOn=A.firstNoteOn,this.keyRange=A.keyRange,this.lastVoiceEventTick=A.lastVoiceEventTick,this.midiPorts=A.midiPorts,this.midiPortChannelOffsets=A.midiPortChannelOffsets,this.usedChannelsOnTrack=A.usedChannelsOnTrack,this.loop=A.loop,this.midiName=A.midiName,this.fileName=A.fileName,this.rawMidiName=A.rawMidiName,this.isEmbedded=A.embeddedSoundFont!==void 0,this.RMIDInfo=A.RMIDInfo,this.bankOffset=A.bankOffset}},Hi={duration:99999,firstNoteOn:0,loop:{start:0,end:123456},lastVoiceEventTick:123456,lyrics:[],copyright:"",midiPorts:[],midiPortChannelOffsets:[],tracksAmount:0,tempoChanges:[{ticks:0,tempo:120}],fileName:"NOT_LOADED.mid",midiName:"Loading...",rawMidiName:new Uint8Array([76,111,97,100,105,110,103,46,46,46]),usedChannelsOnTrack:[],timeDivision:0,keyRange:{min:0,max:127},isEmbedded:!1,RMIDInfo:void 0,bankOffset:0};function k(t,A){let e=0;for(let s=0;s<A;s++)e|=t[t.currentIndex++]<<s*8;return e>>>0}function he(t,A,e){for(let s=0;s<e;s++)t[t.currentIndex++]=A>>s*8&255}function v(t,A){t[t.currentIndex++]=A&255,t[t.currentIndex++]=A>>8}function cA(t,A){he(t,A,4)}function Ae(t,A){let e=A<<8|t;return e>32767?e-65536:e}function Ns(t){return t>127?t-256:t}function Z(t,A,e=void 0,s=!0){if(e){let n=t.slice(t.currentIndex,t.currentIndex+A);return t.currentIndex+=A,new TextDecoder(e.replace(/[^\x20-\x7E]/g,"")).decode(n.buffer)}else{let n=!1,o="";for(let g=0;g<A;g++){let C=t[t.currentIndex++];if(!n){if(C<32||C>127){if(s){n=!0;continue}else if(C===0){n=!0;continue}}o+=String.fromCharCode(C)}}return o}}function RA(t,A,e=0){e>0&&A.length>e&&(A=A.slice(0,e));for(let s=0;s<A.length;s++)t[t.currentIndex++]=A.charCodeAt(s);if(e>A.length)for(let s=0;s<e-A.length;s++)t[t.currentIndex++]=0;return t}var eA=class{constructor(A,e,s){this.header=A,this.size=e,this.chunkData=s}};function X(t,A=!0,e=!1){let s=Z(t,4),n=k(t,4),o;return A&&(o=new Y(t.buffer.slice(t.currentIndex,t.currentIndex+n))),(A||e)&&(t.currentIndex+=n),n%2!==0&&t[t.currentIndex]===0&&t.currentIndex++,new eA(s,n,o)}function nA(t,A=void 0){let e=8+t.size;t.size%2!==0&&e++,A&&(e+=A.length);let s=new Y(e);return A&&(s.set(A,s.currentIndex),s.currentIndex+=A.length),RA(s,t.header),cA(s,e-8-(A?.length||0)),s.set(t.chunkData,s.currentIndex),s}function DA(t,A){return t.find(e=>e.header!=="LIST"?!1:(e.chunkData.currentIndex=0,Z(e.chunkData,4)===A))}function je(t){let A=0;for(;t;){let e=t[t.currentIndex++];if(A=A<<7|e&127,e>>7!==1)break}return A}var $e={name:"INAM",album:"IPRD",artist:"IART",genre:"IGNR",picture:"IPIC",copyright:"ICOP",creationDate:"ICRD",comment:"ICMT",engineer:"IENG",software:"ISFT",encoding:"IENC",midiEncoding:"MENC",bankOffset:"DBNK"};var At=class{constructor(){this.timeDivision=0,this.duration=0,this.tempoChanges=[{ticks:0,tempo:120}],this.copyright="",this.tracksAmount=0,this.lyrics=[],this.firstNoteOn=0,this.keyRange={min:0,max:127},this.lastVoiceEventTick=0,this.midiPorts=[0],this.midiPortChannelOffsets=[0],this.usedChannelsOnTrack=[],this.loop={start:0,end:0},this.midiName="",this.fileName="",this.rawMidiName=void 0,this.embeddedSoundFont=void 0,this.format=0,this.RMIDInfo={},this.bankOffset=0,this.tracks=[]}};function Qe(t,A){let e=0;for(;t>0;){let s=A.tempoChanges.find(o=>o.ticks<t),n=t-s.ticks;e+=n*60/(s.tempo*A.timeDivision),t-=n}return e}var Ho=new Uint8Array([65,16,69,18,16,0,0]),et=class extends At{constructor(A,e=""){super(),yA("%cParsing MIDI File...",r.info);let s=new Y(A),n,o=!1,g=!1,C=!1,Q=Z(s,4);if(s.currentIndex-=4,Q==="RIFF"){s.currentIndex+=8;let S=Z(s,4,void 0,!1);if(S!=="RMID")throw V(),new SyntaxError(`Invalid RMIDI Header! Expected "RMID", got "${S}"`);let D=X(s);if(D.header!=="data")throw V(),new SyntaxError(`Invalid RMIDI Chunk header! Expected "data", got "${S}"`);for(n=D.chunkData;s.currentIndex<=s.length;){let w=s.currentIndex,J=X(s,!0);if(J.header==="RIFF"){let R=Z(J.chunkData,4).toLowerCase();R==="sfbk"||R==="sfpk"||R==="dls "?(m("%cFound embedded soundfont!",r.recognized),this.embeddedSoundFont=s.slice(w,w+J.size).buffer):T(`Unknown RIFF chunk: "${R}"`),R==="dls "&&(C=!0)}else if(J.header==="LIST"&&Z(J.chunkData,4)==="INFO"){for(m("%cFound RMIDI INFO chunk!",r.recognized),this.RMIDInfo={};J.chunkData.currentIndex<=J.size;){let U=X(J.chunkData,!0);this.RMIDInfo[U.header]=U.chunkData}this.RMIDInfo.ICOP&&(o=!0,this.copyright=Z(this.RMIDInfo.ICOP,this.RMIDInfo.ICOP.length,void 0,!1).replaceAll(`
|
|
10
10
|
`," ")),this.RMIDInfo.INAM&&(this.rawMidiName=this.RMIDInfo[$e.name],this.midiName=Z(this.rawMidiName,this.rawMidiName.length,void 0,!1).replaceAll(`
|
|
11
11
|
`," "),g=!0),this.RMIDInfo.IALB&&!this.RMIDInfo.IPRD&&(this.RMIDInfo.IPRD=this.RMIDInfo.IALB),this.RMIDInfo.PRD&&!this.RMIDInfo.IALB&&(this.RMIDInfo.IALB=this.RMIDInfo.IPRD),this.bankOffset=1,this.RMIDInfo[$e.bankOffset]&&(this.bankOffset=k(this.RMIDInfo[$e.bankOffset],2))}}C&&(this.bankOffset=0)}else n=s;let B=this.readMIDIChunk(n);if(B.type!=="MThd")throw V(),new SyntaxError(`Invalid MIDI Header! Expected "MThd", got "${B.type}"`);if(B.size!==6)throw V(),new RangeError(`Invalid MIDI header chunk size! Expected 6, got ${B.size}`);this.format=$A(B.data,2),this.tracksAmount=$A(B.data,2),this.timeDivision=$A(B.data,2),this.keyRange={min:127,max:0},this.lyrics=[],this.tempoChanges=[{ticks:0,tempo:120}];let d=null,l=null;this.lastVoiceEventTick=0,this.midiPorts=[];let u=0;this.midiPortChannelOffsets=[],this.usedChannelsOnTrack=[],this.tracks=[];for(let S=0;S<this.tracksAmount;S++){let D=[],w=this.readMIDIChunk(n),J=new Set;if(this.midiPorts.push(-1),w.type!=="MTrk")throw V(),new SyntaxError(`Invalid track header! Expected "MTrk" got "${w.type}"`);let R,U=0;for(this.format===2&&S>0&&(U+=this.tracks[S-1][this.tracks[S-1].length-1].ticks);w.data.currentIndex<w.size;){U+=je(w.data);let N=w.data[w.data.currentIndex],i;if(R!==void 0&&N<128)i=R;else{if(!R&&N<128)throw V(),new SyntaxError(`Unexpected byte with no running byte. (${N})`);i=w.data[w.data.currentIndex++]}let tA=us(i),W;switch(tA){case-1:W=0;break;case-2:i=w.data[w.data.currentIndex++],W=je(w.data);break;case-3:W=je(w.data);break;default:if(U>this.lastVoiceEventTick&&(this.lastVoiceEventTick=U),W=ds[i>>4],(i&240)===F.noteOn){J.add(tA);let IA=w.data[w.data.currentIndex];this.keyRange.min=Math.min(this.keyRange.min,IA),this.keyRange.max=Math.max(this.keyRange.max,IA)}R=i;break}let K=new Y(W),$=w.data.slice(w.data.currentIndex,w.data.currentIndex+W);w.data.currentIndex+=W,K.set($,0);let EA=new Ce(U,i,K);switch(D.push(EA),tA){case-2:switch(i){case F.setTempo:this.tempoChanges.push({ticks:U,tempo:6e7/$A($,3)});break;case F.marker:switch(Z(K,K.length).trim().toLowerCase()){default:break;case"start":case"loopstart":d=U;break;case"loopend":l=U}K.currentIndex=0;break;case F.midiPort:let mA=K[0];this.midiPorts[S]=mA,this.midiPortChannelOffsets[mA]===void 0&&(this.midiPortChannelOffsets[mA]=u,u+=16);break;case F.copyright:o||(this.copyright+=Z(K,K.length,void 0,!1)+`
|
|
12
12
|
`);break;case F.lyric:this.lyrics.push(K)}break;case-3:if(K.slice(0,7).every((IA,mA)=>Ho[mA]===IA)){let IA=K.slice(7,$.length-3),mA=Z(IA,IA.length)+`
|
|
@@ -15,4 +15,4 @@ var cs=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(A,e)=>(
|
|
|
15
15
|
Converted from DLS to SF2 with SpessaSynth`,this.soundFontInfo.ISBJ&&(this.soundFontInfo.ICMT+=`
|
|
16
16
|
`+this.soundFontInfo.ISBJ,delete this.soundFontInfo.ISBJ);for(let[Q,B]of Object.entries(this.soundFontInfo))m(`%c"${Q}": %c"${B}"`,r.info,r.recognized);let o=s.find(Q=>Q.header==="colh");o||(V(),this.parsingError("No colh chunk!")),this.instrumentAmount=k(o.chunkData,4),m(`%cInstruments amount: %c${this.instrumentAmount}`,r.info,r.recognized);let g=DA(s,"wvpl");g||(V(),this.parsingError("No wvpl chunk!")),this.readDLSSamples(g);let C=DA(s,"lins");C||(V(),this.parsingError("No lins chunk!")),this.readDLSInstrumentList(C),this.presets.sort((Q,B)=>Q.program-B.program+(Q.bank-B.bank)),m(`%cParsing finished! %c"${this.soundFontInfo.INAM||"UNNAMED"}"%c has %c${this.presets.length} %cpresets,
|
|
17
17
|
%c${this.instruments.length}%c instruments and %c${this.samples.length}%c samples.`,r.info,r.recognized,r.info,r.recognized,r.info,r.recognized,r.info,r.recognized,r.info),V()}verifyHeader(A,e){A.header.toLowerCase()!==e.toLowerCase()&&(V(),this.parsingError(`Invalid DLS chunk header! Expected "${e.toLowerCase()}" got "${A.header.toLowerCase()}"`))}verifyText(A,e){A.toLowerCase()!==e.toLowerCase()&&(V(),this.parsingError(`FourCC error: Expected "${e.toLowerCase()}" got "${A.toLowerCase()}"`))}parsingError(A){throw new Error(`DLS parse error: ${A} The file may be corrupted.`)}};_A.prototype.readDLSInstrumentList=jn;_A.prototype.readDLSInstrument=$n;_A.prototype.readRegion=so;_A.prototype.readLart=to;_A.prototype.readDLSSamples=no;var qt=class extends me{constructor(A,e,s,n,o,g,C,Q,B,d,l,u,c){super(A,g,C,Q,B,d,n-e/2,o-e/2),this.sampleName=A,this.sampleStartIndex=e,this.sampleEndIndex=s,this.isSampleLoaded=!1,this.sampleID=u,this.sampleLength=this.sampleEndIndex-this.sampleStartIndex,this.sampleDataArray=l,this.sampleData=new Float32Array(0),this.isCompressed&&(this.sampleLoopStartIndex+=this.sampleStartIndex/2,this.sampleLoopEndIndex+=this.sampleStartIndex/2,this.sampleLength=99999999),this.isDataRaw=c}getRawData(){let A=this.sampleDataArray;if(this.isCompressed){if(this.compressedData)return this.compressedData;let e=A.currentIndex;return A.slice(this.sampleStartIndex/2+e,this.sampleEndIndex/2+e)}else{if(!this.isDataRaw)throw new Error("Writing SF2Pack samples is not supported.");let e=A.currentIndex;return A.slice(e+this.sampleStartIndex,e+this.sampleEndIndex)}}decodeVorbis(){if(this.sampleLength<1)return;let A=this.sampleDataArray,e=A.currentIndex,s=A.slice(this.sampleStartIndex/2+e,this.sampleEndIndex/2+e);this.sampleData=new Float32Array(0);try{let n=VA.decode(s.buffer);this.sampleData=n.data[0]}catch(n){throw new Error(`Ogg Vorbis decode error: ${n}`)}}getAudioData(){return this.isSampleLoaded?this.sampleData:this.sampleLength<1?new Float32Array(1):this.isCompressed?(this.decodeVorbis(),this.isSampleLoaded=!0,this.sampleData):this.isDataRaw?this.loadUncompressedData():this.getUncompressedReadyData()}loadUncompressedData(){if(this.isCompressed)return T("Trying to load a compressed sample via loadUncompressedData()... aborting!"),new Float32Array(0);let A=new Float32Array(this.sampleLength/2),e=this.sampleDataArray.currentIndex,s=new Int16Array(this.sampleDataArray.slice(e+this.sampleStartIndex,e+this.sampleEndIndex).buffer);for(let n=0;n<s.length;n++)A[n]=s[n]/32768;return this.sampleData=A,this.isSampleLoaded=!0,A}getUncompressedReadyData(){let A=this.sampleDataArray.slice(this.sampleStartIndex/2,this.sampleEndIndex/2);return this.sampleData=A,this.isSampleLoaded=!0,A}};function oo(t,A,e=!0){let s=[],n=0;for(;t.chunkData.length>t.chunkData.currentIndex;){let o=Xo(n,t.chunkData,A,e);s.push(o),n++}return s.length>1&&s.pop(),s}function Xo(t,A,e,s){let n=Z(A,20),o=k(A,4)*2,g=k(A,4)*2,C=k(A,4),Q=k(A,4),B=k(A,4),d=A[A.currentIndex++];d===255&&(d=60);let l=Ns(A[A.currentIndex++]),u=k(A,2),c=k(A,2);return new qt(n,o,g,C,Q,B,d,l,u,c,e,t,s)}var Pt=class extends b{constructor(A){super();let e=A.currentIndex;this.generatorType=A[e+1]<<8|A[e],this.generatorValue=Ae(A[e+2],A[e+3]),A.currentIndex+=4}};function Kt(t){let A=[];for(;t.chunkData.length>t.chunkData.currentIndex;)A.push(new Pt(t.chunkData));return A.length>1&&A.pop(),A}var Ot=class extends fe{constructor(A){super(),this.instrumentName=Z(A.chunkData,20).trim(),this.instrumentZoneIndex=k(A.chunkData,2),this.instrumentZonesAmount=0}getInstrumentZones(A,e){this.instrumentZonesAmount=A;for(let s=this.instrumentZoneIndex;s<this.instrumentZonesAmount+this.instrumentZoneIndex;s++)this.instrumentZones.push(e[s])}};function ro(t,A){let e=[];for(;t.chunkData.length>t.chunkData.currentIndex;){let s=new Ot(t);if(e.length>0){let n=s.instrumentZoneIndex-e[e.length-1].instrumentZoneIndex;e[e.length-1].getInstrumentZones(n,A)}e.push(s)}return e.length>1&&e.pop(),e}var Vt=class extends ee{constructor(A){super(),this.generatorZoneStartIndex=k(A,2),this.modulatorZoneStartIndex=k(A,2),this.modulatorZoneSize=0,this.generatorZoneSize=0,this.isGlobal=!0}setZoneSize(A,e){this.modulatorZoneSize=A,this.generatorZoneSize=e}getGenerators(A){for(let e=this.generatorZoneStartIndex;e<this.generatorZoneStartIndex+this.generatorZoneSize;e++)this.generators.push(A[e])}getModulators(A){for(let e=this.modulatorZoneStartIndex;e<this.modulatorZoneStartIndex+this.modulatorZoneSize;e++)this.modulators.push(A[e])}getSample(A){let e=this.generators.find(s=>s.generatorType===a.sampleID);e&&(this.sample=A[e.generatorValue],this.isGlobal=!1,this.sample.useCount++)}getKeyRange(){let A=this.generators.find(e=>e.generatorType===a.keyRange);A&&(this.keyRange.min=A.generatorValue&127,this.keyRange.max=A.generatorValue>>8&127)}getVelRange(){let A=this.generators.find(e=>e.generatorType===a.velRange);A&&(this.velRange.min=A.generatorValue&127,this.velRange.max=A.generatorValue>>8&127)}};function io(t,A,e,s){let n=[];for(;t.chunkData.length>t.chunkData.currentIndex;){let o=new Vt(t.chunkData);if(n.length>0){let g=o.modulatorZoneStartIndex-n[n.length-1].modulatorZoneStartIndex,C=o.generatorZoneStartIndex-n[n.length-1].generatorZoneStartIndex;n[n.length-1].setZoneSize(g,C),n[n.length-1].getGenerators(A),n[n.length-1].getModulators(e),n[n.length-1].getSample(s),n[n.length-1].getKeyRange(),n[n.length-1].getVelRange()}n.push(o)}return n.length>1&&n.pop(),n}var Zt=class extends de{constructor(A){super(),this.generatorZoneStartIndex=k(A,2),this.modulatorZoneStartIndex=k(A,2),this.modulatorZoneSize=0,this.generatorZoneSize=0,this.isGlobal=!0}setZoneSize(A,e){this.modulatorZoneSize=A,this.generatorZoneSize=e}getGenerators(A){for(let e=this.generatorZoneStartIndex;e<this.generatorZoneStartIndex+this.generatorZoneSize;e++)this.generators.push(A[e])}getModulators(A){for(let e=this.modulatorZoneStartIndex;e<this.modulatorZoneStartIndex+this.modulatorZoneSize;e++)this.modulators.push(A[e])}getInstrument(A){let e=this.generators.find(s=>s.generatorType===a.instrument);e&&(this.instrument=A[e.generatorValue],this.instrument.addUseCount(),this.isGlobal=!1)}getKeyRange(){let A=this.generators.find(e=>e.generatorType===a.keyRange);A&&(this.keyRange.min=A.generatorValue&127,this.keyRange.max=A.generatorValue>>8&127)}getVelRange(){let A=this.generators.find(e=>e.generatorType===a.velRange);A&&(this.velRange.min=A.generatorValue&127,this.velRange.max=A.generatorValue>>8&127)}};function ao(t,A,e,s){let n=[];for(;t.chunkData.length>t.chunkData.currentIndex;){let o=new Zt(t.chunkData);if(n.length>0){let g=o.modulatorZoneStartIndex-n[n.length-1].modulatorZoneStartIndex,C=o.generatorZoneStartIndex-n[n.length-1].generatorZoneStartIndex;n[n.length-1].setZoneSize(g,C),n[n.length-1].getGenerators(A),n[n.length-1].getModulators(e),n[n.length-1].getInstrument(s),n[n.length-1].getKeyRange(),n[n.length-1].getVelRange()}n.push(o)}return n.length>1&&n.pop(),n}var Xt=class extends ue{constructor(A,e){super(e),this.presetName=Z(A.chunkData,20).trim().replace(/\d{3}:\d{3}/,""),this.program=k(A.chunkData,2),this.bank=k(A.chunkData,2),this.presetZoneStartIndex=k(A.chunkData,2),this.library=k(A.chunkData,4),this.genre=k(A.chunkData,4),this.morphology=k(A.chunkData,4),this.presetZonesAmount=0}getPresetZones(A,e){this.presetZonesAmount=A;for(let s=this.presetZoneStartIndex;s<this.presetZonesAmount+this.presetZoneStartIndex;s++)this.presetZones.push(e[s])}};function Io(t,A,e){let s=[];for(;t.chunkData.length>t.chunkData.currentIndex;){let n=new Xt(t,e);if(s.length>0){let o=n.presetZoneStartIndex-s[s.length-1].presetZoneStartIndex;s[s.length-1].getPresetZones(o,A)}s.push(n)}return s.length>1&&s.pop(),s}var Wt=class extends j{constructor(A){super({srcEnum:k(A,2),dest:k(A,2),amt:Ae(A[A.currentIndex++],A[A.currentIndex++]),secSrcEnum:k(A,2),transform:k(A,2)})}};function it(t){let A=[];for(;t.chunkData.length>t.chunkData.currentIndex;)A.push(new Wt(t.chunkData));return A}var at=class extends ae{constructor(A,e=!0){super(),e&&console.warn("Using the constructor directly is deprecated. Use loadSoundFont instead."),this.dataArray=new Y(A),ne("%cParsing SoundFont...",r.info),this.dataArray||(V(),this.parsingError("No data provided!"));let s=X(this.dataArray,!1);this.verifyHeader(s,"riff");let n=Z(this.dataArray,4).toLowerCase();if(n!=="sfbk"&&n!=="sfpk")throw V(),new SyntaxError(`Invalid soundFont! Expected "sfbk" or "sfpk" got "${n}"`);let o=n==="sfpk",g=X(this.dataArray);for(this.verifyHeader(g,"list"),Z(g.chunkData,4);g.chunkData.length>g.chunkData.currentIndex;){let $=X(g.chunkData),EA;switch($.header.toLowerCase()){case"ifil":case"iver":EA=`${k($.chunkData,2)}.${k($.chunkData,2)}`,this.soundFontInfo[$.header]=EA;break;case"icmt":EA=Z($.chunkData,$.chunkData.length,void 0,!1),this.soundFontInfo[$.header]=EA;break;case"dmod":let IA=it($);IA.pop(),EA=`Modulators: ${IA.length}`;let mA=this.defaultModulators;this.defaultModulators=IA,this.defaultModulators.push(...mA.filter(be=>!this.defaultModulators.find(xA=>j.isIdentical(be,xA)))),this.soundFontInfo[$.header]=$.chunkData;break;default:EA=Z($.chunkData,$.chunkData.length),this.soundFontInfo[$.header]=EA}m(`%c"${$.header}": %c"${EA}"`,r.info,r.recognized)}let C=X(this.dataArray,!1);this.verifyHeader(C,"list"),this.verifyText(Z(this.dataArray,4),"sdta"),m("%cVerifying smpl chunk...",r.warn);let Q=X(this.dataArray,!1);this.verifyHeader(Q,"smpl");let B;if(o){m("%cSF2Pack detected, attempting to decode the smpl chunk...",r.info);try{B=VA.decode(this.dataArray.buffer.slice(this.dataArray.currentIndex,this.dataArray.currentIndex+C.size-12)).data[0]}catch($){throw V(),new Error(`SF2Pack Ogg Vorbis decode error: ${$}`)}m(`%cDecoded the smpl chunk! Length: %c${B.length}`,r.info,r.value)}else B=this.dataArray,this.sampleDataStartIndex=this.dataArray.currentIndex;m(`%cSkipping sample chunk, length: %c${C.size-12}`,r.info,r.value),this.dataArray.currentIndex+=C.size-12,m("%cLoading preset data chunk...",r.warn);let d=X(this.dataArray);this.verifyHeader(d,"list"),Z(d.chunkData,4);let l=X(d.chunkData);this.verifyHeader(l,"phdr");let u=X(d.chunkData);this.verifyHeader(u,"pbag");let c=X(d.chunkData);this.verifyHeader(c,"pmod");let p=X(d.chunkData);this.verifyHeader(p,"pgen");let S=X(d.chunkData);this.verifyHeader(S,"inst");let D=X(d.chunkData);this.verifyHeader(D,"ibag");let w=X(d.chunkData);this.verifyHeader(w,"imod");let J=X(d.chunkData);this.verifyHeader(J,"igen");let R=X(d.chunkData);this.verifyHeader(R,"shdr"),this.dataArray.currentIndex=this.sampleDataStartIndex,this.samples.push(...oo(R,B,!o));let U=Kt(J),N=it(w),i=io(D,U,N,this.samples);this.instruments=ro(S,i);let tA=Kt(p),W=it(c),K=ao(u,tA,W,this.instruments);this.presets.push(...Io(l,K,this.defaultModulators)),this.presets.sort(($,EA)=>$.program-EA.program+($.bank-EA.bank)),m(`%cParsing finished! %c"${this.soundFontInfo.INAM}"%c has %c${this.presets.length} %cpresets,
|
|
18
|
-
%c${this.instruments.length}%c instruments and %c${this.samples.length}%c samples.`,r.info,r.recognized,r.info,r.recognized,r.info,r.recognized,r.info,r.recognized,r.info),V(),o&&delete this.dataArray}verifyHeader(A,e){A.header.toLowerCase()!==e.toLowerCase()&&(V(),this.parsingError(`Invalid chunk header! Expected "${e.toLowerCase()}" got "${A.header.toLowerCase()}"`))}verifyText(A,e){A.toLowerCase()!==e.toLowerCase()&&(V(),this.parsingError(`Invalid FourCC: Expected "${e.toLowerCase()}" got "${A.toLowerCase()}"\``))}};function Me(t){let A=t.slice(8,12),e=new Y(A);return Z(e,4,void 0,!1).toLowerCase()==="dls "?new _A(t):new at(t,!1)}function go(t,A,e=!1){let s=this.workletProcessorChannels[t];if(s===void 0){T(`Trying to access channel ${t} which does not exist... ignoring!`);return}if(s.lockPreset)return;let n=PA(s),o,g;if(this.overrideSoundfont){let C=n===128?128:n-this.soundfontBankOffset,Q=this.overrideSoundfont.getPresetNoFallback(C,A);Q?(o=n,g=Q,s.presetUsesOverride=!0):(g=this.soundfontManager.getPreset(n,A),o=g.bank,s.presetUsesOverride=!1)}else g=this.soundfontManager.getPreset(n,A),o=g.bank,s.presetUsesOverride=!1;this.setPreset(t,g),this.callEvent("programchange",{channel:t,program:g.program,bank:o,userCalled:e})}function Co(t,A){if(this.overrideSoundfont){let e=t===128?128:t-this.soundfontBankOffset,s=this.overrideSoundfont.getPresetNoFallback(e,A);if(s)return s}return this.soundfontManager.getPreset(t,A)}function Eo(t,A){if(!this.workletProcessorChannels[t].lockPreset){delete this.workletProcessorChannels[t].preset,this.workletProcessorChannels[t].preset=A,this.workletProcessorChannels[t].cachedVoices=[];for(let e=0;e<128;e++)this.workletProcessorChannels[t].cachedVoices.push([])}}function Bo(t,A){let e=this.workletProcessorChannels[t];e.lockPreset||e.drumChannel!==A&&(A?(e.channelTransposeKeyShift=0,e.drumChannel=!0,this.setPreset(t,this.getPreset(PA(e),e.preset.program))):(e.drumChannel=!1,this.setPreset(t,this.getPreset(PA(e),e.preset.program))),e.presetUsesOverride=!1,this.callEvent("drumchange",{channel:t,isDrumChannel:e.drumChannel}),this.sendChannelProperties())}function ho(){let t=this.soundfontManager.getPresetList();this.overrideSoundfont!==void 0&&this.overrideSoundfont.presets.forEach(A=>{let e=A.bank===128?128:A.bank+this.soundfontBankOffset,s=t.find(n=>n.bank===e&&n.program===A.program);s!==void 0?s.presetName=A.presetName:t.push({presetName:A.presetName,bank:e,program:A.program})}),this.callEvent("presetlistchange",t)}function Qo(t=!0,A=!0){this.stopAllChannels(!0),A&&(delete this.overrideSoundfont,this.overrideSoundfont=void 0),this.defaultPreset=this.getPreset(0,0),this.drumPreset=this.getPreset(128,0);for(let e=0;e<this.workletProcessorChannels.length;e++){let s=this.workletProcessorChannels[e];s.cachedVoices=[];for(let n=0;n<128;n++)s.cachedVoices.push([]);(!A||A&&s.presetUsesOverride)&&(s.lockPreset=!1),this.programChange(e,s.preset.program)}t&&this.sendPresetList()}function co(t,A=!1){this.clearSoundFont(!1,A);try{A?(this.overrideSoundfont=Me(t),this.overrideSoundfont.setSampleIDOffset(this.soundfontManager.totalSoundfontOffset)):this.soundfontManager.reloadManager(t)}catch(e){this.post({messageType:uA.soundfontError,messageData:e});return}this.defaultPreset=this.getPreset(0,0),this.drumPreset=this.getPreset(128,0),this.workletProcessorChannels.forEach((e,s)=>{this.programChange(s,e.preset.program)}),this.post({messageType:uA.ready,messageData:void 0}),this.sendPresetList(),m("%cSpessaSynth is ready!",r.recognized)}function lo(t,A){this.soundfontBankOffset=A,this.reloadSoundFont(t,!0),this.overrideSoundfont.samples.forEach(e=>e.getAudioData()),this._snapshot!==void 0&&(this.applySynthesizerSnapshot(this._snapshot),this.resetAllControllers())}function uo(){let A={channelSnapshots:this.workletProcessorChannels.map(e=>({program:e.preset.program,bank:PA(e),lockPreset:e.lockPreset,patchName:e.preset.presetName,midiControllers:e.midiControllers,lockedControllers:e.lockedControllers,customControllers:e.customControllers,channelVibrato:e.channelVibrato,lockVibrato:e.lockGSNRPNParams,channelTransposeKeyShift:e.channelTransposeKeyShift,channelOctaveTuning:e.channelOctaveTuning,keyCentTuning:e.keyCentTuning,velocityOverride:e.velocityOverride,isMuted:e.isMuted,drumChannel:e.drumChannel})),mainVolume:this.midiVolume,pan:this.pan,transposition:this.transposition,system:this.system,interpolation:this.interpolationType};this.post({messageType:uA.synthesizerSnapshot,messageData:A})}function fo(t){for(this.system=t.system,this.setMasterGain(t.mainVolume),this.setMasterPan(t.pan),this.transposeAllChannels(t.transposition),this.interpolationType=t.interpolation;this.workletProcessorChannels.length<t.channelSnapshots.length;)this.createWorkletChannel();t.channelSnapshots.forEach((A,e)=>{let s=this.workletProcessorChannels[e];this.muteChannel(e,A.isMuted),this.setDrums(e,A.drumChannel),s.midiControllers=A.midiControllers,s.lockedControllers=A.lockedControllers,s.customControllers=A.customControllers,s.channelVibrato=A.channelVibrato,s.lockGSNRPNParams=A.lockVibrato,s.channelTransposeKeyShift=A.channelTransposeKeyShift,s.channelOctaveTuning=A.channelOctaveTuning,s.velocityOverride=A.velocityOverride,s.lockPreset=!1,jA(s,A.bank),this.programChange(e,A.program),s.lockPreset=A.lockPreset}),m("%cFinished restoring controllers!",r.info)}var It=class{constructor(A,e){this.ready=e,this.totalSoundfontOffset=0,this.reloadManager(A)}_assingSampleOffsets(){let A=0;this.soundfontList.forEach(e=>{e.soundfont.setSampleIDOffset(A),A+=e.soundfont.samples.length}),this.totalSoundfontOffset=A}generatePresetList(){this._assingSampleOffsets();let A={};for(let e=this.soundfontList.length-1;e>=0;e--){let s=this.soundfontList[e],n=new Set;for(let o of s.soundfont.presets){let g=`${o.bank+s.bankOffset}-${o.program}`;n.has(g)||(n.add(g),A[g]=o.presetName)}}this.presetList=[];for(let[e,s]of Object.entries(A)){let n=e.split("-");this.presetList.push({presetName:s,program:parseInt(n[1]),bank:parseInt(n[0])})}}handleMessage(A,e){switch(A){case Be.addNewSoundFont:this.addNewSoundFont(e[0],e[1],e[2]);break;case Be.reloadSoundFont:this.reloadManager(e);break;case Be.deleteSoundFont:this.deleteSoundFont(e);break;case Be.rearrangeSoundFonts:this.rearrangeSoundFonts(e)}}getPresetList(){return this.presetList.slice()}reloadManager(A){let e=Me(A);this.soundfontList=[],this.soundfontList.push({id:"main",bankOffset:0,soundfont:e}),this.generatePresetList(),this.ready()}deleteSoundFont(A){if(this.soundfontList.length===0){T("1 soundfont left. Aborting!");return}let e=this.soundfontList.findIndex(s=>s.id===A);if(e===-1){T(`No soundfont with id of "${A}" found. Aborting!`);return}delete this.soundfontList[e].soundfont.presets,delete this.soundfontList[e].soundfont.instruments,delete this.soundfontList[e].soundfont.samples,this.soundfontList.splice(e,1),this.generatePresetList()}addNewSoundFont(A,e,s){if(this.soundfontList.find(n=>n.id===e)!==void 0)throw new Error("Cannot overwrite the existing soundfont. Use soundfontManager.delete(id) instead.");this.soundfontList.push({id:e,soundfont:Me(A),bankOffset:s}),this.generatePresetList(),this.ready()}rearrangeSoundFonts(A){this.soundfontList.sort((e,s)=>A.indexOf(e.id)-A.indexOf(s.id)),this.generatePresetList()}getPreset(A,e){if(this.soundfontList.length<1)throw new Error("No soundfonts! This should never happen.");for(let s of this.soundfontList){let n=s.soundfont.getPresetNoFallback(A-s.bankOffset,e);if(n!==void 0)return n}if(A!==128){for(let s of this.soundfontList){let n=s.soundfont.presets.find(o=>o.program===e);if(n)return n}return this.soundfontList[0].soundfont.presets[0]}else{for(let s of this.soundfontList){let n=s.soundfont.presets.find(o=>o.bank===128);if(n)return n}return this.soundfontList[0].soundfont.presets[0]}}};var gt=class{sampleData;playbackStep=0;cursor=0;rootKey=0;loopStart=0;loopEnd=0;end=0;loopingMode=0;isLooping=!1;constructor(A,e,s,n,o,g,C,Q){this.sampleData=A,this.playbackStep=e,this.cursor=s,this.rootKey=n,this.loopStart=o,this.loopEnd=g,this.end=C,this.loopingMode=Q,this.isLooping=this.loopingMode===1||this.loopingMode===3}},Ne=class t{sample;filter=new le;generators;modulators=[];modulatedGenerators;finished=!1;isInRelease=!1;channelNumber=0;velocity=0;midiNote=0;pressure=0;targetKey=0;modulationEnvelope=new JA;volumeEnvelope;startTime=0;releaseStartTime=1/0;currentTuningCents=0;currentTuningCalculated=1;currentPan=.5;realKey;constructor(A,e,s,n,o,g,C,Q,B,d){this.sample=e,this.generators=B,this.modulatedGenerators=new Int16Array(B),this.modulators=d,this.velocity=n,this.midiNote=s,this.channelNumber=o,this.startTime=g,this.targetKey=C,this.realKey=Q,this.volumeEnvelope=new UA(A,B[a.sustainVolEnv])}static copy(A,e){let s=A.sample,n=new gt(s.sampleData,s.playbackStep,s.cursor,s.rootKey,s.loopStart,s.loopEnd,s.end,s.loopingMode);return new t(A.volumeEnvelope.sampleRate,n,A.midiNote,A.velocity,A.channelNumber,e,A.targetKey,A.realKey,A.generators,A.modulators.map(o=>j.copy(o)))}};function mo(t,A,e,s,n,o,g=!1){let C,Q=s.cachedVoices[A][e],B=this.keyModifierManager.hasOverridePatch(t,A);if(Q!==void 0&&!B)return Q.map(u=>Ne.copy(u,n));let d=!0,l=s.preset;if(B){d=!1;let u=this.keyModifierManager.getPatch(t,A);l=this.soundfontManager.getPreset(u.bank,u.program)}return C=l.getSamplesAndGenerators(A,e).reduce((u,c)=>{if(c.sample.sampleData===void 0)return T(`Discarding invalid sample: ${c.sample.sampleName}`),u;let p=new Int16Array(60);for(let N=0;N<60;N++)p[N]=Ds(N,c.presetGenerators,c.instrumentGenerators);p[a.initialAttenuation]=Math.floor(p[a.initialAttenuation]*.4);let S=c.sample.samplePitch;p[a.overridingRootKey]>-1&&(S=p[a.overridingRootKey]);let D=A;p[a.keyNum]>-1&&(D=p[a.keyNum]);let w=c.sample.sampleLoopStartIndex,J=c.sample.sampleLoopEndIndex,R=p[a.sampleModes],U=new gt(c.sample.getAudioData(),c.sample.sampleRate/sampleRate*Math.pow(2,c.sample.samplePitchCorrection/1200),0,S,w,J,Math.floor(c.sample.sampleData.length)-1,R);return p[a.velocity]>-1&&(e=p[a.velocity]),g&&Ss([{Sample:c.sample.sampleName,Generators:p,Modulators:c.modulators.map(N=>N.debugString()),Velocity:e,TargetKey:D,MidiNote:A,WorkletSample:U}]),u.push(new Ne(sampleRate,U,A,e,t,n,D,o,p,c.modulators.map(N=>j.copy(N)))),u},[]),d&&(s.cachedVoices[A][e]=C.map(u=>Ne.copy(u,n))),C}var Wo=4600,_o=2e3,po=Math.PI/2;function yo(t,A,e,s,n,o){if(isNaN(A[0]))return;let g=(Math.max(-500,Math.min(500,t.modulatedGenerators[a.pan]))+500)/1e3;t.currentPan+=(g-t.currentPan)*this.panSmoothingFactor;let C=this.currentGain,Q=Math.cos(po*t.currentPan)*C*this.panLeft,B=Math.sin(po*t.currentPan)*C*this.panRight,d=t.modulatedGenerators[a.reverbEffectsSend]/Wo*C,l=t.modulatedGenerators[a.chorusEffectsSend]/_o;if(d>0&&!this.oneOutputMode){let u=n[0],c=n[1];for(let p=0;p<A.length;p++)u[p]+=d*A[p],c[p]+=d*A[p]}if(l>0&&!this.oneOutputMode){let u=o[0],c=o[1],p=Q*l,S=B*l;for(let D=0;D<A.length;D++)u[D]+=p*A[D],c[D]+=S*A[D]}if(Q>0)for(let u=0;u<A.length;u++)e[u]+=Q*A[u];if(B>0)for(let u=0;u<A.length;u++)s[u]+=B*A[u]}var Yt=.03,Jt=1,H=class extends AudioWorkletProcessor{constructor(A){super(),this.oneOutputMode=A.processorOptions?.startRenderingData?.oneOutput===!0,this._outputsAmount=this.oneOutputMode?1:A.processorOptions.midiChannels,this.enableEventSystem=A.processorOptions.enableEventSystem,this.deviceID=TA,this.interpolationType=ce.fourthOrder,this.processTickCallback=void 0,this.sequencer=new iA(this),this.transposition=0,this.tunings=[];for(let e=0;e<127;e++)this.tunings.push([]);this.soundfontBankOffset=0,this.masterGain=Jt,this.midiVolume=1,this.voiceCap=Fs,this.pan=0,this.panLeft=.5,this.highPerformanceMode=!1,this.keyModifierManager=new Xe,this.overrideSoundfont=void 0,this.panRight=.5;try{this.soundfontManager=new It(A.processorOptions.soundfont,this.postReady.bind(this))}catch(e){throw this.post({messageType:uA.soundfontError,messageData:e}),e}this.sendPresetList(),this.defaultPreset=this.getPreset(0,0),this.drumPreset=this.getPreset(128,0),this.workletProcessorChannels=[];for(let e=0;e<A.processorOptions.midiChannels;e++)this.createWorkletChannel(!1);this.workletProcessorChannels[SA].preset=this.drumPreset,this.workletProcessorChannels[SA].drumChannel=!0,this.volumeEnvelopeSmoothingFactor=en*(sampleRate/44100),this.panSmoothingFactor=tn*(sampleRate/44100),this.system=_e,this.totalVoicesAmount=0,this._snapshot=A.processorOptions?.startRenderingData?.snapshot,this.port.onmessage=e=>this.handleMessage(e.data),A.processorOptions.startRenderingData&&(this._snapshot!==void 0&&(this.applySynthesizerSnapshot(this._snapshot),this.resetAllControllers()),m("%cRendering enabled! Starting render.",r.info),A.processorOptions.startRenderingData.parsedMIDI&&(A.processorOptions.startRenderingData?.loopCount!==void 0?(this.sequencer.loopCount=A.processorOptions.startRenderingData?.loopCount,this.sequencer.loop=!0):this.sequencer.loop=!1,this.sequencer.loadNewSongList([A.processorOptions.startRenderingData.parsedMIDI]))),VA.isInitialized.then(()=>{this.postReady(),m("%cSpessaSynth is ready!",r.recognized)})}get currentGain(){return this.masterGain*this.midiVolume}post(A){this.enableEventSystem&&this.port.postMessage(A)}postReady(){this.enableEventSystem&&this.port.postMessage({messageType:uA.ready,messageData:void 0})}debugMessage(){m({channels:this.workletProcessorChannels,voicesAmount:this.totalVoicesAmount,outputAmount:this._outputsAmount,dumpedSamples:this.workletDumpedSamplesList})}process(A,e){this.processTickCallback&&this.processTickCallback();let s=0;return this.workletProcessorChannels.forEach((n,o)=>{if(n.voices.length<1||n.isMuted)return;let g,C,Q,B,d;if(this.oneOutputMode){let u=e[0];g=o%16*2,C=u[g],Q=u[g+1]}else g=o%this._outputsAmount+2,C=e[g][0],Q=e[g][1],B=e[0],d=e[1];let l=n.voices;n.voices=[],l.forEach(u=>{this.renderVoice(n,u,C,Q,B,d),u.finished||n.voices.push(u)}),s+=n.voices.length}),s!==this.totalVoicesAmount&&(this.totalVoicesAmount=s,this.sendChannelProperties()),!0}};H.prototype.renderVoice=sn;H.prototype.releaseVoice=on;H.prototype.voiceKilling=nn;H.prototype.getWorkletVoices=mo;H.prototype.handleMessage=In;H.prototype.sendChannelProperties=Cn;H.prototype.callEvent=gn;H.prototype.systemExclusive=En;H.prototype.noteOn=hn;H.prototype.noteOff=Qn;H.prototype.polyPressure=wn;H.prototype.killNote=cn;H.prototype.stopAll=ln;H.prototype.stopAllChannels=un;H.prototype.muteChannel=Nn;H.prototype.setVibrato=Ln;H.prototype.disableAndLockGSNRPN=bn;H.prototype.dataEntryCoarse=Un;H.prototype.dataEntryFine=Tn;H.prototype.createWorkletChannel=ks;H.prototype.controllerChange=Rn;H.prototype.channelPressure=kn;H.prototype.resetAllControllers=Hn;H.prototype.resetControllers=Yn;H.prototype.resetParameters=Jn;H.prototype.setMasterGain=xn;H.prototype.setMasterPan=Mn;H.prototype.setMIDIVolume=Gn;H.prototype.transposeAllChannels=dn;H.prototype.transposeChannel=fn;H.prototype.setChannelTuning=mn;H.prototype.setChannelTuningSemitones=pn;H.prototype.setMasterTuning=yn;H.prototype.setModulationDepth=Sn;H.prototype.pitchWheel=Dn;H.prototype.setOctaveTuning=Fn;H.prototype.programChange=go;H.prototype.getPreset=Co;H.prototype.setPreset=Eo;H.prototype.setDrums=Bo;H.prototype.reloadSoundFont=co;H.prototype.clearSoundFont=Qo;H.prototype.setEmbeddedSoundFont=lo;H.prototype.sendPresetList=ho;H.prototype.sendSynthesizerSnapshot=uo;H.prototype.applySynthesizerSnapshot=fo;H.prototype.panVoice=yo;registerProcessor(ws,H);m("%cProcessor succesfully registered!",r.recognized);
|
|
18
|
+
%c${this.instruments.length}%c instruments and %c${this.samples.length}%c samples.`,r.info,r.recognized,r.info,r.recognized,r.info,r.recognized,r.info,r.recognized,r.info),V(),o&&delete this.dataArray}verifyHeader(A,e){A.header.toLowerCase()!==e.toLowerCase()&&(V(),this.parsingError(`Invalid chunk header! Expected "${e.toLowerCase()}" got "${A.header.toLowerCase()}"`))}verifyText(A,e){A.toLowerCase()!==e.toLowerCase()&&(V(),this.parsingError(`Invalid FourCC: Expected "${e.toLowerCase()}" got "${A.toLowerCase()}"\``))}};function Me(t){let A=t.slice(8,12),e=new Y(A);return Z(e,4,void 0,!1).toLowerCase()==="dls "?new _A(t):new at(t,!1)}function go(t,A,e=!1){let s=this.workletProcessorChannels[t];if(s===void 0){T(`Trying to access channel ${t} which does not exist... ignoring!`);return}if(s.lockPreset)return;let n=PA(s),o,g;if(this.overrideSoundfont){let C=n===128?128:n-this.soundfontBankOffset,Q=this.overrideSoundfont.getPresetNoFallback(C,A);Q?(o=n,g=Q,s.presetUsesOverride=!0):(g=this.soundfontManager.getPreset(n,A),o=g.bank,s.presetUsesOverride=!1)}else g=this.soundfontManager.getPreset(n,A),o=g.bank,s.presetUsesOverride=!1;this.setPreset(t,g),this.callEvent("programchange",{channel:t,program:g.program,bank:o,userCalled:e})}function Co(t,A){if(this.overrideSoundfont){let e=t===128?128:t-this.soundfontBankOffset,s=this.overrideSoundfont.getPresetNoFallback(e,A);if(s)return s}return this.soundfontManager.getPreset(t,A)}function Eo(t,A){if(!this.workletProcessorChannels[t].lockPreset){delete this.workletProcessorChannels[t].preset,this.workletProcessorChannels[t].preset=A,this.workletProcessorChannels[t].cachedVoices=[];for(let e=0;e<128;e++)this.workletProcessorChannels[t].cachedVoices.push([])}}function Bo(t,A){let e=this.workletProcessorChannels[t];e.lockPreset||e.drumChannel!==A&&(A?(e.channelTransposeKeyShift=0,e.drumChannel=!0,this.setPreset(t,this.getPreset(PA(e),e.preset.program))):(e.drumChannel=!1,this.setPreset(t,this.getPreset(PA(e),e.preset.program))),e.presetUsesOverride=!1,this.callEvent("drumchange",{channel:t,isDrumChannel:e.drumChannel}),this.sendChannelProperties())}function ho(){let t=this.soundfontManager.getPresetList();this.overrideSoundfont!==void 0&&this.overrideSoundfont.presets.forEach(A=>{let e=A.bank===128?128:A.bank+this.soundfontBankOffset,s=t.find(n=>n.bank===e&&n.program===A.program);s!==void 0?s.presetName=A.presetName:t.push({presetName:A.presetName,bank:e,program:A.program})}),this.callEvent("presetlistchange",t)}function Qo(t=!0,A=!0){this.stopAllChannels(!0),A&&(delete this.overrideSoundfont,this.overrideSoundfont=void 0),this.defaultPreset=this.getPreset(0,0),this.drumPreset=this.getPreset(128,0);for(let e=0;e<this.workletProcessorChannels.length;e++){let s=this.workletProcessorChannels[e];s.cachedVoices=[];for(let n=0;n<128;n++)s.cachedVoices.push([]);(!A||A&&s.presetUsesOverride)&&(s.lockPreset=!1),this.programChange(e,s.preset.program)}t&&this.sendPresetList()}function co(t,A=!1){this.clearSoundFont(!1,A);try{A?(this.overrideSoundfont=Me(t),this.overrideSoundfont.setSampleIDOffset(this.soundfontManager.totalSoundfontOffset)):this.soundfontManager.reloadManager(t)}catch(e){this.post({messageType:uA.soundfontError,messageData:e});return}this.defaultPreset=this.getPreset(0,0),this.drumPreset=this.getPreset(128,0),this.workletProcessorChannels.forEach((e,s)=>{this.programChange(s,e.preset.program)}),this.post({messageType:uA.ready,messageData:void 0}),this.sendPresetList(),m("%cSpessaSynth is ready!",r.recognized)}function lo(t,A){this.soundfontBankOffset=A,this.reloadSoundFont(t,!0),this.overrideSoundfont.samples.forEach(e=>e.getAudioData()),this._snapshot!==void 0&&(this.applySynthesizerSnapshot(this._snapshot),this.resetAllControllers())}function uo(){let A={channelSnapshots:this.workletProcessorChannels.map(e=>({program:e.preset.program,bank:PA(e),lockPreset:e.lockPreset,patchName:e.preset.presetName,midiControllers:e.midiControllers,lockedControllers:e.lockedControllers,customControllers:e.customControllers,channelVibrato:e.channelVibrato,lockVibrato:e.lockGSNRPNParams,channelTransposeKeyShift:e.channelTransposeKeyShift,channelOctaveTuning:e.channelOctaveTuning,keyCentTuning:e.keyCentTuning,velocityOverride:e.velocityOverride,isMuted:e.isMuted,drumChannel:e.drumChannel})),mainVolume:this.midiVolume,pan:this.pan,transposition:this.transposition,system:this.system,interpolation:this.interpolationType,keyMappings:this.keyModifierManager.getMappings()};this.post({messageType:uA.synthesizerSnapshot,messageData:A})}function fo(t){for(this.system=t.system,this.setMasterGain(t.mainVolume),this.setMasterPan(t.pan),this.transposeAllChannels(t.transposition),this.interpolationType=t.interpolation,this.keyModifierManager.setMappings(t.keyMappings);this.workletProcessorChannels.length<t.channelSnapshots.length;)this.createWorkletChannel();t.channelSnapshots.forEach((A,e)=>{let s=this.workletProcessorChannels[e];this.muteChannel(e,A.isMuted),this.setDrums(e,A.drumChannel),s.midiControllers=A.midiControllers,s.lockedControllers=A.lockedControllers,s.customControllers=A.customControllers,s.channelVibrato=A.channelVibrato,s.lockGSNRPNParams=A.lockVibrato,s.channelTransposeKeyShift=A.channelTransposeKeyShift,s.channelOctaveTuning=A.channelOctaveTuning,s.velocityOverride=A.velocityOverride,s.lockPreset=!1,jA(s,A.bank),this.programChange(e,A.program),s.lockPreset=A.lockPreset}),m("%cFinished restoring controllers!",r.info)}var It=class{constructor(A,e){this.ready=e,this.totalSoundfontOffset=0,this.reloadManager(A)}_assingSampleOffsets(){let A=0;this.soundfontList.forEach(e=>{e.soundfont.setSampleIDOffset(A),A+=e.soundfont.samples.length}),this.totalSoundfontOffset=A}generatePresetList(){this._assingSampleOffsets();let A={};for(let e=this.soundfontList.length-1;e>=0;e--){let s=this.soundfontList[e],n=new Set;for(let o of s.soundfont.presets){let g=`${o.bank+s.bankOffset}-${o.program}`;n.has(g)||(n.add(g),A[g]=o.presetName)}}this.presetList=[];for(let[e,s]of Object.entries(A)){let n=e.split("-");this.presetList.push({presetName:s,program:parseInt(n[1]),bank:parseInt(n[0])})}}handleMessage(A,e){switch(A){case Be.addNewSoundFont:this.addNewSoundFont(e[0],e[1],e[2]);break;case Be.reloadSoundFont:this.reloadManager(e);break;case Be.deleteSoundFont:this.deleteSoundFont(e);break;case Be.rearrangeSoundFonts:this.rearrangeSoundFonts(e)}}getPresetList(){return this.presetList.slice()}reloadManager(A){let e=Me(A);this.soundfontList=[],this.soundfontList.push({id:"main",bankOffset:0,soundfont:e}),this.generatePresetList(),this.ready()}deleteSoundFont(A){if(this.soundfontList.length===0){T("1 soundfont left. Aborting!");return}let e=this.soundfontList.findIndex(s=>s.id===A);if(e===-1){T(`No soundfont with id of "${A}" found. Aborting!`);return}delete this.soundfontList[e].soundfont.presets,delete this.soundfontList[e].soundfont.instruments,delete this.soundfontList[e].soundfont.samples,this.soundfontList.splice(e,1),this.generatePresetList()}addNewSoundFont(A,e,s){if(this.soundfontList.find(n=>n.id===e)!==void 0)throw new Error("Cannot overwrite the existing soundfont. Use soundfontManager.delete(id) instead.");this.soundfontList.push({id:e,soundfont:Me(A),bankOffset:s}),this.generatePresetList(),this.ready()}rearrangeSoundFonts(A){this.soundfontList.sort((e,s)=>A.indexOf(e.id)-A.indexOf(s.id)),this.generatePresetList()}getPreset(A,e){if(this.soundfontList.length<1)throw new Error("No soundfonts! This should never happen.");for(let s of this.soundfontList){let n=s.soundfont.getPresetNoFallback(A-s.bankOffset,e);if(n!==void 0)return n}if(A!==128){for(let s of this.soundfontList){let n=s.soundfont.presets.find(o=>o.program===e);if(n)return n}return this.soundfontList[0].soundfont.presets[0]}else{for(let s of this.soundfontList){let n=s.soundfont.presets.find(o=>o.bank===128);if(n)return n}return this.soundfontList[0].soundfont.presets[0]}}};var gt=class{sampleData;playbackStep=0;cursor=0;rootKey=0;loopStart=0;loopEnd=0;end=0;loopingMode=0;isLooping=!1;constructor(A,e,s,n,o,g,C,Q){this.sampleData=A,this.playbackStep=e,this.cursor=s,this.rootKey=n,this.loopStart=o,this.loopEnd=g,this.end=C,this.loopingMode=Q,this.isLooping=this.loopingMode===1||this.loopingMode===3}},Ne=class t{sample;filter=new le;generators;modulators=[];modulatedGenerators;finished=!1;isInRelease=!1;channelNumber=0;velocity=0;midiNote=0;pressure=0;targetKey=0;modulationEnvelope=new JA;volumeEnvelope;startTime=0;releaseStartTime=1/0;currentTuningCents=0;currentTuningCalculated=1;currentPan=.5;realKey;constructor(A,e,s,n,o,g,C,Q,B,d){this.sample=e,this.generators=B,this.modulatedGenerators=new Int16Array(B),this.modulators=d,this.velocity=n,this.midiNote=s,this.channelNumber=o,this.startTime=g,this.targetKey=C,this.realKey=Q,this.volumeEnvelope=new UA(A,B[a.sustainVolEnv])}static copy(A,e){let s=A.sample,n=new gt(s.sampleData,s.playbackStep,s.cursor,s.rootKey,s.loopStart,s.loopEnd,s.end,s.loopingMode);return new t(A.volumeEnvelope.sampleRate,n,A.midiNote,A.velocity,A.channelNumber,e,A.targetKey,A.realKey,A.generators,A.modulators.map(o=>j.copy(o)))}};function mo(t,A,e,s,n,o,g=!1){let C,Q=s.cachedVoices[A][e],B=this.keyModifierManager.hasOverridePatch(t,A);if(Q!==void 0&&!B)return Q.map(u=>Ne.copy(u,n));let d=!0,l=s.preset;if(B){d=!1;let u=this.keyModifierManager.getPatch(t,A);l=this.soundfontManager.getPreset(u.bank,u.program)}return C=l.getSamplesAndGenerators(A,e).reduce((u,c)=>{if(c.sample.sampleData===void 0)return T(`Discarding invalid sample: ${c.sample.sampleName}`),u;let p=new Int16Array(60);for(let N=0;N<60;N++)p[N]=Ds(N,c.presetGenerators,c.instrumentGenerators);p[a.initialAttenuation]=Math.floor(p[a.initialAttenuation]*.4);let S=c.sample.samplePitch;p[a.overridingRootKey]>-1&&(S=p[a.overridingRootKey]);let D=A;p[a.keyNum]>-1&&(D=p[a.keyNum]);let w=c.sample.sampleLoopStartIndex,J=c.sample.sampleLoopEndIndex,R=p[a.sampleModes],U=new gt(c.sample.getAudioData(),c.sample.sampleRate/sampleRate*Math.pow(2,c.sample.samplePitchCorrection/1200),0,S,w,J,Math.floor(c.sample.sampleData.length)-1,R);return p[a.velocity]>-1&&(e=p[a.velocity]),g&&Ss([{Sample:c.sample.sampleName,Generators:p,Modulators:c.modulators.map(N=>N.debugString()),Velocity:e,TargetKey:D,MidiNote:A,WorkletSample:U}]),u.push(new Ne(sampleRate,U,A,e,t,n,D,o,p,c.modulators.map(N=>j.copy(N)))),u},[]),d&&(s.cachedVoices[A][e]=C.map(u=>Ne.copy(u,n))),C}var Wo=4600,_o=2e3,po=Math.PI/2;function yo(t,A,e,s,n,o){if(isNaN(A[0]))return;let g=(Math.max(-500,Math.min(500,t.modulatedGenerators[a.pan]))+500)/1e3;t.currentPan+=(g-t.currentPan)*this.panSmoothingFactor;let C=this.currentGain,Q=Math.cos(po*t.currentPan)*C*this.panLeft,B=Math.sin(po*t.currentPan)*C*this.panRight,d=t.modulatedGenerators[a.reverbEffectsSend]/Wo*C,l=t.modulatedGenerators[a.chorusEffectsSend]/_o;if(d>0&&!this.oneOutputMode){let u=n[0],c=n[1];for(let p=0;p<A.length;p++)u[p]+=d*A[p],c[p]+=d*A[p]}if(l>0&&!this.oneOutputMode){let u=o[0],c=o[1],p=Q*l,S=B*l;for(let D=0;D<A.length;D++)u[D]+=p*A[D],c[D]+=S*A[D]}if(Q>0)for(let u=0;u<A.length;u++)e[u]+=Q*A[u];if(B>0)for(let u=0;u<A.length;u++)s[u]+=B*A[u]}var Yt=.03,Jt=1,H=class extends AudioWorkletProcessor{constructor(A){super(),this.oneOutputMode=A.processorOptions?.startRenderingData?.oneOutput===!0,this._outputsAmount=this.oneOutputMode?1:A.processorOptions.midiChannels,this.enableEventSystem=A.processorOptions.enableEventSystem,this.deviceID=TA,this.interpolationType=ce.fourthOrder,this.processTickCallback=void 0,this.sequencer=new iA(this),this.transposition=0,this.tunings=[];for(let e=0;e<127;e++)this.tunings.push([]);this.soundfontBankOffset=0,this.masterGain=Jt,this.midiVolume=1,this.voiceCap=Fs,this.pan=0,this.panLeft=.5,this.highPerformanceMode=!1,this.keyModifierManager=new Xe,this.overrideSoundfont=void 0,this.panRight=.5;try{this.soundfontManager=new It(A.processorOptions.soundfont,this.postReady.bind(this))}catch(e){throw this.post({messageType:uA.soundfontError,messageData:e}),e}this.sendPresetList(),this.defaultPreset=this.getPreset(0,0),this.drumPreset=this.getPreset(128,0),this.workletProcessorChannels=[];for(let e=0;e<A.processorOptions.midiChannels;e++)this.createWorkletChannel(!1);this.workletProcessorChannels[SA].preset=this.drumPreset,this.workletProcessorChannels[SA].drumChannel=!0,this.volumeEnvelopeSmoothingFactor=en*(sampleRate/44100),this.panSmoothingFactor=tn*(sampleRate/44100),this.system=_e,this.totalVoicesAmount=0,this._snapshot=A.processorOptions?.startRenderingData?.snapshot,this.port.onmessage=e=>this.handleMessage(e.data),A.processorOptions.startRenderingData&&(this._snapshot!==void 0&&(this.applySynthesizerSnapshot(this._snapshot),this.resetAllControllers()),m("%cRendering enabled! Starting render.",r.info),A.processorOptions.startRenderingData.parsedMIDI&&(A.processorOptions.startRenderingData?.loopCount!==void 0?(this.sequencer.loopCount=A.processorOptions.startRenderingData?.loopCount,this.sequencer.loop=!0):this.sequencer.loop=!1,this.sequencer.loadNewSongList([A.processorOptions.startRenderingData.parsedMIDI]))),VA.isInitialized.then(()=>{this.postReady(),m("%cSpessaSynth is ready!",r.recognized)})}get currentGain(){return this.masterGain*this.midiVolume}post(A){this.enableEventSystem&&this.port.postMessage(A)}postReady(){this.enableEventSystem&&this.port.postMessage({messageType:uA.ready,messageData:void 0})}debugMessage(){m({channels:this.workletProcessorChannels,voicesAmount:this.totalVoicesAmount,outputAmount:this._outputsAmount,dumpedSamples:this.workletDumpedSamplesList})}process(A,e){this.processTickCallback&&this.processTickCallback();let s=0;return this.workletProcessorChannels.forEach((n,o)=>{if(n.voices.length<1||n.isMuted)return;let g,C,Q,B,d;if(this.oneOutputMode){let u=e[0];g=o%16*2,C=u[g],Q=u[g+1]}else g=o%this._outputsAmount+2,C=e[g][0],Q=e[g][1],B=e[0],d=e[1];let l=n.voices;n.voices=[],l.forEach(u=>{this.renderVoice(n,u,C,Q,B,d),u.finished||n.voices.push(u)}),s+=n.voices.length}),s!==this.totalVoicesAmount&&(this.totalVoicesAmount=s,this.sendChannelProperties()),!0}};H.prototype.renderVoice=sn;H.prototype.releaseVoice=on;H.prototype.voiceKilling=nn;H.prototype.getWorkletVoices=mo;H.prototype.handleMessage=In;H.prototype.sendChannelProperties=Cn;H.prototype.callEvent=gn;H.prototype.systemExclusive=En;H.prototype.noteOn=hn;H.prototype.noteOff=Qn;H.prototype.polyPressure=wn;H.prototype.killNote=cn;H.prototype.stopAll=ln;H.prototype.stopAllChannels=un;H.prototype.muteChannel=Nn;H.prototype.setVibrato=Ln;H.prototype.disableAndLockGSNRPN=bn;H.prototype.dataEntryCoarse=Un;H.prototype.dataEntryFine=Tn;H.prototype.createWorkletChannel=ks;H.prototype.controllerChange=Rn;H.prototype.channelPressure=kn;H.prototype.resetAllControllers=Hn;H.prototype.resetControllers=Yn;H.prototype.resetParameters=Jn;H.prototype.setMasterGain=xn;H.prototype.setMasterPan=Mn;H.prototype.setMIDIVolume=Gn;H.prototype.transposeAllChannels=dn;H.prototype.transposeChannel=fn;H.prototype.setChannelTuning=mn;H.prototype.setChannelTuningSemitones=pn;H.prototype.setMasterTuning=yn;H.prototype.setModulationDepth=Sn;H.prototype.pitchWheel=Dn;H.prototype.setOctaveTuning=Fn;H.prototype.programChange=go;H.prototype.getPreset=Co;H.prototype.setPreset=Eo;H.prototype.setDrums=Bo;H.prototype.reloadSoundFont=co;H.prototype.clearSoundFont=Qo;H.prototype.setEmbeddedSoundFont=lo;H.prototype.sendPresetList=ho;H.prototype.sendSynthesizerSnapshot=uo;H.prototype.applySynthesizerSnapshot=fo;H.prototype.panVoice=yo;registerProcessor(ws,H);m("%cProcessor succesfully registered!",r.recognized);
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
/**
|
|
28
28
|
* @typedef {Object} SynthesizerSnapshot
|
|
29
29
|
* @property {ChannelSnapshot[]} channelSnapshots - the individual channel snapshots
|
|
30
|
+
* @property {KeyModifier[][]} keyMappings - key modifiers
|
|
30
31
|
* @property {number} mainVolume - main synth volume (set by MIDI), from 0 to 1
|
|
31
32
|
* @property {number} pan - master stereo panning, from -1 to 1
|
|
32
33
|
* @property {interpolationTypes} interpolation - the synth's interpolation type
|
|
@@ -82,7 +83,8 @@ export function sendSynthesizerSnapshot()
|
|
|
82
83
|
pan: this.pan,
|
|
83
84
|
transposition: this.transposition,
|
|
84
85
|
system: this.system,
|
|
85
|
-
interpolation: this.interpolationType
|
|
86
|
+
interpolation: this.interpolationType,
|
|
87
|
+
keyMappings: this.keyModifierManager.getMappings()
|
|
86
88
|
};
|
|
87
89
|
|
|
88
90
|
this.post({
|
|
@@ -106,6 +108,7 @@ export function applySynthesizerSnapshot(snapshot)
|
|
|
106
108
|
this.setMasterPan(snapshot.pan);
|
|
107
109
|
this.transposeAllChannels(snapshot.transposition);
|
|
108
110
|
this.interpolationType = snapshot.interpolation;
|
|
111
|
+
this.keyModifierManager.setMappings(snapshot.keyMappings);
|
|
109
112
|
|
|
110
113
|
// add channels if more needed
|
|
111
114
|
while (this.workletProcessorChannels.length < snapshot.channelSnapshots.length)
|
|
@@ -97,6 +97,22 @@ export class WorkletKeyModifierManager
|
|
|
97
97
|
this._keyMappings = [];
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
/**
|
|
101
|
+
* @param mappings {KeyModifier[][]}
|
|
102
|
+
*/
|
|
103
|
+
setMappings(mappings)
|
|
104
|
+
{
|
|
105
|
+
this._keyMappings = mappings;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @returns {KeyModifier[][]}
|
|
110
|
+
*/
|
|
111
|
+
getMappings()
|
|
112
|
+
{
|
|
113
|
+
return this._keyMappings;
|
|
114
|
+
}
|
|
115
|
+
|
|
100
116
|
/**
|
|
101
117
|
* @param channel {number}
|
|
102
118
|
* @param midiNote {number}
|