diff --git a/assets/index-toxedflk.js b/assets/index-LPfJkeRA.js similarity index 99% rename from assets/index-toxedflk.js rename to assets/index-LPfJkeRA.js index 5d98a49..3820910 100644 --- a/assets/index-toxedflk.js +++ b/assets/index-LPfJkeRA.js @@ -7,5 +7,5 @@ * @license MIT * @version 1.3.5 * @see {@link https://github.com/logue/Reverb.js} - */const W=1/2**32;class Oe{float(e=1){return this.int()*W*e}probability(e){return this.float()>>=0;const n=(t>>>0)-e;return n?e+this.int()%n:e}}const B=Math.random;class Te extends Oe{int(){return B()*4294967296>>>0}float(e=1){return B()*e}norm(e=1){return(B()-.5)*2*e}}const de=new Te,Ne={noise:"white",scale:1,peaks:2,randomAlgorithm:de,decay:2,delay:0,reverse:!1,time:2,filterType:"allpass",filterFreq:2200,filterQ:1,mix:.5,once:!1},Y={version:"1.3.5",date:"2023-11-20T03:01:00.334Z"},N={blue:"blue",brown:"red",green:"green",pink:"pink",red:"red",violet:"violet",white:"white"},F={bins:2,scale:1,rnd:de},z=(r,e,t)=>{const n=new Array(r);for(let s=0;sr.reduce((e,t)=>e+t,0);function*ue(r,e){const t=[r[Symbol.iterator](),e[Symbol.iterator]()];for(let n=0;;n^=1){const s=t[n].next();if(s.done)return;yield s.value}}function*D(r){const{bins:e,scale:t,rnd:n}={...F,...r},s=z(e,t,n);s.forEach((a,c)=>s[c]=c&1?a:-a);const i=1/e;let o=U(s);for(let a=0,c=-1;;++a>=e&&(a=0))o-=s[a],o+=s[a]=c*n.norm(t),c^=4294967294,yield c*o*i}const Ie=r=>ue(D(r),D(r)),Ge=r=>{let e=32;return r&=-r,r&&e--,r&65535&&(e-=16),r&16711935&&(e-=8),r&252645135&&(e-=4),r&858993459&&(e-=2),r&1431655765&&(e-=1),e};function*Re(r){const{bins:e,scale:t,rnd:n}={...F,bins:8,...r},s=z(e,t,n),i=1/e;let o=U(s);for(let a=0;;a=a+1>>>0){const c=Ge(a)%e;o-=s[c],o+=s[c]=n.norm(t),yield o*i}}function*j(r){const{bins:e,scale:t,rnd:n}={...F,...r},s=z(e,t,n),i=1/e;let o=U(s);for(let a=0;;++a>=e&&(a=0))o-=s[a],o+=s[a]=n.norm(t),yield o*i}const Fe=r=>ue(j(r),j(r));function*J(r){const{scale:e,rnd:t}={...F,...r};for(;;)yield t.norm(e)}const Le=(r,e)=>r!=null&&typeof r[e]=="function",Be=r=>Le(r,"xform")?r.xform():r,Pe=r=>r!=null&&typeof r[Symbol.iterator]=="function";class G{value;constructor(e){this.value=e}deref(){return this.value}}const Ve=r=>new G(r),qe=r=>r instanceof G,De=r=>r instanceof G?r:new G(r),ee=r=>r instanceof G?r.deref():r,je=(r,e)=>[r,t=>t,e];function $e(r){return r?[...r]:je(()=>[],(e,t)=>(e.push(t),e))}function*He(r,e){const t=Be(r)($e()),n=t[1],s=t[2];for(let i of e){const o=s([],i);if(qe(o)){yield*ee(n(o.deref()));return}o.length&&(yield*o)}yield*ee(n([]))}const Ze=(r,e)=>[r[0],r[1],e];function fe(r,e){return Pe(e)?He(fe(r),e):t=>{const n=t[2];let s=r;return Ze(t,(i,o)=>--s>0?n(i,o):s===0?De(n(i,o)):Ve(i))}}class A{static version=Y.version;static build=Y.date;ctx;wetGainNode;dryGainNode;filterNode;convolverNode;outputNode;options;isConnected;noise=J;constructor(e,t){this.ctx=e,this.options=Object.assign(Ne,t),this.wetGainNode=this.ctx.createGain(),this.dryGainNode=this.ctx.createGain(),this.filterNode=this.ctx.createBiquadFilter(),this.convolverNode=this.ctx.createConvolver(),this.outputNode=this.ctx.createGain(),this.isConnected=!1,this.filterType(this.options.filterType),this.setNoise(this.options.noise),this.buildImpulse(),this.mix(this.options.mix)}connect(e){return this.isConnected&&this.options.once?(this.isConnected=!1,this.outputNode):(this.convolverNode.connect(this.filterNode),this.filterNode.connect(this.wetGainNode),e.connect(this.convolverNode),e.connect(this.dryGainNode).connect(this.outputNode),e.connect(this.wetGainNode).connect(this.outputNode),this.isConnected=!0,this.outputNode)}disconnect(e){return this.isConnected&&(this.convolverNode.disconnect(this.filterNode),this.filterNode.disconnect(this.wetGainNode)),this.isConnected=!1,e}mix(e){if(!A.inRange(e,0,1))throw new RangeError("[Reverb.js] Dry/Wet ratio must be between 0 to 1.");this.options.mix=e,this.dryGainNode.gain.value=1-this.options.mix,this.wetGainNode.gain.value=this.options.mix}time(e){if(!A.inRange(e,1,50))throw new RangeError("[Reverb.js] Time length of inpulse response must be less than 50sec.");this.options.time=e,this.buildImpulse()}decay(e){if(!A.inRange(e,0,100))throw new RangeError("[Reverb.js] Inpulse Response decay level must be less than 100.");this.options.decay=e,this.buildImpulse()}delay(e){if(!A.inRange(e,0,100))throw new RangeError("[Reverb.js] Inpulse Response delay time must be less than 100.");this.options.delay=e,this.buildImpulse()}reverse(e){this.options.reverse=e,this.buildImpulse()}filterType(e="allpass"){this.filterNode.type=this.options.filterType=e}filterFreq(e){if(!A.inRange(e,20,2e4))throw new RangeError("[Reverb.js] Filter frequrncy must be between 20 and 20000.");this.options.filterFreq=e,this.filterNode.frequency.value=this.options.filterFreq}filterQ(e){if(!A.inRange(e,0,10))throw new RangeError("[Reverb.js] Filter quality value must be between 0 and 10.");this.options.filterQ=e,this.filterNode.Q.value=this.options.filterQ}peaks(e){this.options.peaks=e,this.buildImpulse()}scale(e){this.options.scale=e,this.buildImpulse()}randomAlgorithm(e){this.options.randomAlgorithm=e,this.buildImpulse()}setNoise(e){switch(this.options.noise=e,e){case N.blue:this.noise=D;break;case N.green:this.noise=Ie;break;case N.pink:this.noise=Re;break;case N.red:case N.brown:this.noise=j;break;case N.violet:this.noise=Fe;break;default:this.noise=J}this.buildImpulse()}setRandomAlgorythm(e){this.options.randomAlgorithm=e,this.buildImpulse()}static inRange(e,t,n){return(e-t)*(e-n)<=0}buildImpulse(){const e=this.ctx.sampleRate,t=Math.max(e*this.options.time,1),n=e*this.options.delay,s=this.ctx.createBuffer(2,t,e),i=new Float32Array(t),o=new Float32Array(t),a=this.getNoise(t),c=this.getNoise(t);for(let l=0;l>>0:(e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24)>>>0,t)),t+=n,this.padding&&(t-this.offset&1)===1&&t++,this.ip=t}getChunk(e){const t=this.chunkList[e];return t!==void 0?t:null}getNumberOfChunks(){return this.chunkList.length}}class ze{constructor(e,t,n){this.type=e,this.size=t,this.offset=n}}class R{constructor(e,t={}){this.input=e,this.parserOption=t.parserOption||{},this.sampleRate=t.sampleRate||22050,this.presetHeader=[],this.presetZone=[],this.presetZoneModulator=[],this.presetZoneGenerator=[],this.instrument=[],this.instrumentZone=[],this.instrumentZoneModulator=[],this.instrumentZoneGenerator=[],this.sampleHeader=[],this.GeneratorEnumeratorTable=Object.keys(R.getGeneratorTable())}static getGeneratorTable(){return Object.freeze({startAddrsOffset:0,endAddrsOffset:0,startloopAddrsOffset:0,endloopAddrsOffset:0,startAddrsCoarseOffset:0,modLfoToPitch:0,vibLfoToPitch:0,modEnvToPitch:0,initialFilterFc:13500,initialFilterQ:0,modLfoToFilterFc:0,modEnvToFilterFc:0,endAddrsCoarseOffset:0,modLfoToVolume:0,unused1:void 0,chorusEffectsSend:0,reverbEffectsSend:0,pan:0,unused2:void 0,unused3:void 0,unused4:void 0,delayModLFO:-12e3,freqModLFO:0,delayVibLFO:-12e3,freqVibLFO:0,delayModEnv:-12e3,attackModEnv:-12e3,holdModEnv:-12e3,decayModEnv:-12e3,sustainModEnv:0,releaseModEnv:-12e3,keynumToModEnvHold:0,keynumToModEnvDecay:0,delayVolEnv:-12e3,attackVolEnv:-12e3,holdVolEnv:-12e3,decayVolEnv:-12e3,sustainVolEnv:0,releaseVolEnv:-12e3,keynumToVolEnvHold:0,keynumToVolEnvDecay:0,instrument:null,reserved1:void 0,keyRange:null,velRange:null,startloopAddrsCoarseOffset:0,keynum:null,velocity:null,initialAttenuation:0,reserved2:void 0,endloopAddrsCoarseOffset:0,coarseTune:0,fineTune:0,sampleID:null,sampleModes:0,reserved3:void 0,scaleTuning:100,exclusiveClass:null,overridingRootKey:null,unuded5:void 0,endOper:void 0})}parse(){const e=new I(this.input,this.parserOption);if(e.parse(),e.chunkList.length!==1)throw new Error("wrong chunk length");const t=e.getChunk(0);if(t===null)throw new Error("chunk not found");this.parseRiffChunk(t),this.input=null}parseRiffChunk(e){const t=this.input;let n=e.offset;if(e.type!=="RIFF")throw new Error("invalid chunk type:"+e.type);const s=String.fromCharCode(t[n++],t[n++],t[n++],t[n++]);if(s!=="sfbk")throw new Error("invalid signature:"+s);const i=new I(t,{index:n,length:e.size-4});if(i.parse(),i.getNumberOfChunks()!==3)throw new Error("invalid sfbk structure");this.parseInfoList(i.getChunk(0)),this.parseSdtaList(i.getChunk(1)),this.parsePdtaList(i.getChunk(2))}parseInfoList(e){const t=this.input;let n=e.offset;if(e.type!=="LIST")throw new Error("invalid chunk type:"+e.type);const s=String.fromCharCode(t[n++],t[n++],t[n++],t[n++]);if(s!=="INFO")throw new Error("invalid signature:"+s);new I(t,{index:n,length:e.size-4}).parse()}parseSdtaList(e){const t=this.input;let n=e.offset;if(e.type!=="LIST")throw new Error("invalid chunk type:"+e.type);const s=String.fromCharCode(t[n++],t[n++],t[n++],t[n++]);if(s!=="sdta")throw new Error("invalid signature:"+s);const i=new I(t,{index:n,length:e.size-4});if(i.parse(),i.chunkList.length!==1)throw new Error("TODO");this.samplingData=i.getChunk(0)}parsePdtaList(e){const t=this.input;let n=e.offset;if(e.type!=="LIST")throw new Error("invalid chunk type:"+e.type);const s=String.fromCharCode(t[n++],t[n++],t[n++],t[n++]);if(s!=="pdta")throw new Error("invalid signature:"+s);const i=new I(t,{index:n,length:e.size-4});if(i.parse(),i.getNumberOfChunks()!==9)throw new Error("invalid pdta chunk");this.parsePhdr(i.getChunk(0)),this.parsePbag(i.getChunk(1)),this.parsePmod(i.getChunk(2)),this.parsePgen(i.getChunk(3)),this.parseInst(i.getChunk(4)),this.parseIbag(i.getChunk(5)),this.parseImod(i.getChunk(6)),this.parseIgen(i.getChunk(7)),this.parseShdr(i.getChunk(8))}parsePhdr(e){const t=this.input;let n=e.offset;const s=this.presetHeader=[],i=e.offset+e.size;if(e.type!=="phdr")throw new Error("invalid chunk type:"+e.type);for(;n>>0,genre:(t[n++]|t[n++]<<8|t[n++]<<16|t[n++]<<24)>>>0,morphology:(t[n++]|t[n++]<<8|t[n++]<<16|t[n++]<<24)>>>0})}parsePbag(e){const t=this.input;let n=e.offset;const s=this.presetZone=[],i=e.offset+e.size;if(e.type!=="pbag")throw new Error("invalid chunk type:"+e.type);for(;n>>0,l=(t[n++]<<0|t[n++]<<8|t[n++]<<16|t[n++]<<24)>>>0,d=(t[n++]<<0|t[n++]<<8|t[n++]<<16|t[n++]<<24)>>>0,u=(t[n++]<<0|t[n++]<<8|t[n++]<<16|t[n++]<<24)>>>0,f=(t[n++]<<0|t[n++]<<8|t[n++]<<16|t[n++]<<24)>>>0,h=t[n++],m=t[n++]<<24>>24,b=t[n++]|t[n++]<<8,p=t[n++]|t[n++]<<8;let y=new Int16Array(new Uint8Array(t.subarray(this.samplingData.offset+c*2,this.samplingData.offset+l*2)).buffer);if(d-=c,u-=c,f>0){const w=this.adjustSampleData(y,f);y=w.sample,f*=w.multiply,d*=w.multiply,u*=w.multiply}s.push(y),i.push({sampleName:a,start:c,end:l,startLoop:d,endLoop:u,sampleRate:f,originalPitch:h,pitchCorrection:m,sampleLink:b,sampleType:p})}}adjustSampleData(e,t){let n,s,i,o,a=1;for(;t>16,lo:t[n++],hi:t[n++]}});else switch(o){case"keyRange":case"velRange":case"keynum":case"velocity":a.push({type:o,value:{amount:null,lo:t[n++],hi:t[n++]}});break;default:a.push({type:o,value:{amount:t[n++]|t[n++]<<8<<16>>16}});break}n+=2,n+=2}return a}parseGenerator(e){const t=this.input;let n=e.offset;const s=e.offset+e.size;let i,o;const a=[];for(;n>16,lo:t[n++],hi:t[n++]}});continue}switch(o){case"keynum":case"keyRange":case"velRange":case"velocity":a.push({type:o,value:{amount:null,lo:t[n++],hi:t[n++]}});break;default:a.push({type:o,value:{amount:t[n++]|t[n++]<<8<<16>>16}});break}}return a}createInstrument(){const e=this.instrument,t=this.instrumentZone,n=[];let s,i,o,a,c,l,d,u,f;for(l=0,d=e.length;ln.forEach(s=>{s.target.dataset.isIntersecting=s.isIntersecting}),{}),this.timer=void 0,this.drag=!1}getAudioContext(){const e=new AudioContext,t=()=>{document.removeEventListener("touchstart",t);const n=e.createBufferSource();n.start(),n.stop()};return document.addEventListener("touchstart",t),e}init(e="GM"){this.gainMaster.disconnect(),this.refreshInstruments(this.input),this.mode=e;for(let t=0;t<16;++t)this.setPercussionPart(t,t===9),this.programChange(t,0),this.volumeChange(t,100),this.panpotChange(t,64),this.pitchBend(t,0,64),this.pitchBendSensitivity(t,2),this.hold(t,0),this.expression(t,127),this.bankSelectMsb(t,t===9?127:0),this.bankSelectLsb(t,t===9?127:0),this.attackTime(t,64),this.decayTime(t,64),this.sustinTime(t,64),this.releaseTime(t,64),this.harmonicContent(t,64),this.cutOffFrequency(t,64),this.reverbDepth(t,40),this.modulationDepth(t,0),this.updateBankSelect(t),this.updateProgramSelect(t);this.setPercussionPart(9,!0);for(let t=0;t<128;++t)this.percussionVolume[t]=127;if(this.setMasterVolume(8192),this.gainMaster.connect(this.ctx.destination),this.element){const t=this.element.querySelector(".header .keys div");t.innerText=e+" Mode",this.element.querySelectorAll(".instrument .bank > select").forEach(s=>s.disabled=e==="GM"),this.element.dataset.mode=e}}async close(){await this.ctx.close()}refreshInstruments(e){this.input=e,this.parser=new R(e,{sampleRate:this.ctx.sampleRate}),this.bankSet=this.createAllInstruments()}createAllInstruments(){const e=this.parser;e.parse();const t=e.createPreset(),n=e.createInstrument(),s=[];let i,o,a,c,l;const d=[];return t.forEach(u=>{c=u.header.preset,o=u.header.bank,l=u.name.replace(/\0*$/,""),typeof u.instrument=="number"&&(a=n[u.instrument],a.name.replace(/\0*$/,"")!=="EOI"&&(s[o]=s[o]??[],i=s[o],i[c]={},i[c].name=l,a.info.forEach(f=>this.createNoteInfo(e,f,i[c])),d[o]||(d[o]=[]),d[o][c]=l))}),this.programSet=d,s}createNoteInfo(e,t,n){const s=t.generator;if(!s.keyRange||!s.sampleID)return;const i=this.getModGenAmount(s,"delayVolEnv"),o=this.getModGenAmount(s,"attackVolEnv"),a=this.getModGenAmount(s,"holdVolEnv"),c=this.getModGenAmount(s,"decayVolEnv"),l=this.getModGenAmount(s,"sustainVolEnv"),d=this.getModGenAmount(s,"releaseVolEnv"),u=this.getModGenAmount(s,"delayModEnv"),f=this.getModGenAmount(s,"attackModEnv"),h=this.getModGenAmount(s,"holdModEnv"),m=this.getModGenAmount(s,"decayModEnv"),b=this.getModGenAmount(s,"sustainModEnv"),p=this.getModGenAmount(s,"releaseModEnv"),y=this.getModGenAmount(s,"scaleTuning")/100,w=this.getModGenAmount(s,"coarseTune")+this.getModGenAmount(s,"fineTune")/100,k=this.getModGenAmount(s,"sampleModes");for(let v=s.keyRange.lo,E=s.keyRange.hi;v<=E;++v){if(n[v])continue;const C=this.getModGenAmount(s,"sampleID"),S=e.sampleHeader[C];n[v]={sample:e.sample[C],sampleRate:S.sampleRate,sampleModes:k,basePlaybackRate:1.0594630943592953**((v-this.getModGenAmount(s,"overridingRootKey")+w+S.pitchCorrection/100)*y),modEnvToPitch:this.getModGenAmount(s,"modEnvToPitch")/100,scaleTuning:y,start:this.getModGenAmount(s,"startAddrsCoarseOffset")*32768+this.getModGenAmount(s,"startAddrsOffset"),end:this.getModGenAmount(s,"endAddrsCoarseOffset")*32768+this.getModGenAmount(s,"endAddrsOffset"),loopStart:S.startLoop+this.getModGenAmount(s,"startloopAddrsCoarseOffset")*32768+this.getModGenAmount(s,"startloopAddrsOffset"),loopEnd:S.endLoop+this.getModGenAmount(s,"endloopAddrsCoarseOffset")*32768+this.getModGenAmount(s,"endloopAddrsOffset"),volDelay:2**(i/1200),volAttack:2**(o/1200),volHold:2**(a/1200)*2**((60-v)*this.getModGenAmount(s,"keynumToVolEnvHold")/1200),volDecay:2**(c/1200)*2**((60-v)*this.getModGenAmount(s,"keynumToVolEnvDecay")/1200),volSustain:l/1e3,volRelease:2**(d/1200),modDelay:2**(u/1200),modAttack:2**(f/1200),modHold:2**(h/1200)*2**((60-v)*this.getModGenAmount(s,"keynumToModEnvHold")/1200),modDecay:2**(m/1200)*2**((60-v)*this.getModGenAmount(s,"keynumToModEnvDecay")/1200),modSustain:b/1e3,modRelease:2**(p/1200),initialFilterFc:8.176*Math.pow(2,this.getModGenAmount(s,"initialFilterFc")/1200),modEnvToFilterFc:this.getModGenAmount(s,"modEnvToFilterFc")/100,initialFilterQ:this.getModGenAmount(s,"initialFilterQ")/10,reverbEffectSend:this.getModGenAmount(s,"reverbEffectSend")/10,initialAttenuation:this.getModGenAmount(s,"initialAttenuation")/10,freqVibLFO:8.176*Math.pow(2,this.getModGenAmount(s,"freqVibLFO")/1200),pan:this.getModGenAmount(s,"pan")/1200}}}getModGenAmount(e,t){return e[t]?e[t].amount:R.getGeneratorTable()[t]}start(){this.connect(),this.bufSrc.start(0),this.setMasterVolume(16383)}setMasterVolume(e){this.masterVolume=e,this.gainMaster.gain.value=this.baseVolume*(e/16384)}connect(){this.bufSrc.connect(this.gainMaster)}disconnect(){this.bufSrc.disconnect(this.gainMaster),this.bufSrc.buffer=null}drawSynth(){const e=window.document,t=this.element=e.createElement("div");t.className="synthesizer";const n=e.createElement("div");n.className="instrument",this.items=["mute","bank","program","volume","expression","panpot","pitchBend","pitchBendSensitivity","reverbDepth","keys"];const s="ontouchstart"in window?"touchstart":"mousedown",i="ontouchend"in window?"touchend":"mouseup";for(let l=0;l<16;l++){const d=e.createElement("div");d.className="channel",d.addEventListener(s,()=>{this.hold(l,0)});for(const u in this.items){if(!Object.hasOwn(this.items,u))continue;const f=e.createElement("div");switch(f.className=this.items[u],this.items[u]){case"mute":{const h=e.createElement("div");h.className="form-check form-check-inline";const m=e.createElement("input");m.ariaLabel=`Ch.${l+1} Mute`,m.setAttribute("type","checkbox"),m.className="form-check-input",m.id="mute"+l+"ch",m.value=l.toString(),m.addEventListener("change",p=>{this.mute(l,p.target.checked)},!1),h.appendChild(m);const b=e.createElement("label");b.className="form-check-label",b.textContent=(l+1).toString(),b.setAttribute("for","mute"+l+"ch"),h.appendChild(b),f.appendChild(h);break}case"bank":{const h=e.createElement("select");h.ariaLabel=`Ch.${l+1} Bank Select`,h.className="form-select form-select-sm bank-select",h.addEventListener("change",((m,b)=>p=>{const y=d.querySelector(".program select");m.bankChange(b,p.target.value),m.programChange(b,parseInt(y.value))})(this,l),!1),f.appendChild(h);break}case"program":{const h=e.createElement("select");h.className="form-select form-select-sm",h.ariaLabel=`Ch.${l+1} Program Change`,h.addEventListener("change",((m,b)=>p=>{m.programChange(b,p.target.value)})(this,l),!1),f.appendChild(h);break}case"volume":{const h=document.createElement("var");h.ariaLabel=`Ch.${l+1} Volume`,h.innerText="100",f.appendChild(h);break}case"expression":{const h=document.createElement("var");h.ariaLabel=`Ch.${l+1} Expression`,h.innerText="127",f.appendChild(h);break}case"pitchBendSensitivity":{const h=document.createElement("var");h.ariaLabel=`Ch.${l+1} Pitch Bend Sensitivity`,h.innerText="2",f.appendChild(h);break}case"reverbDepth":{const h=document.createElement("var");h.ariaLabel=`Ch.${l+1} Reverb Depth`,h.innerText="40",f.appendChild(h);break}case"panpot":{const h=e.createElement("div");h.role="progressbar",h.ariaLabel=`Ch.${l+1} Panpod`,h.ariaValueMin="0",h.ariaValueNow="64",h.ariaValueMax="127",h.className="progress";const m=e.createElement("div");m.className="progress-bar",h.appendChild(m),f.appendChild(h);break}case"pitchBend":{const h=e.createElement("div");h.className="progress",h.role="progressbar",h.ariaLabel=`Ch.${l+1} Pitch Bend`,h.ariaValueMin="-8192",h.ariaValueNow="0",h.ariaValueMax="8192",h.className="progress";const m=e.createElement("div");m.className="progress-bar progress-bar-animated",h.appendChild(m),f.appendChild(h);break}case"keys":{for(let h=0;h<127;h++){const m=e.createElement("div"),b=h%12;m.className="key "+([1,3,6,8,10].includes(b)?"semitone":"tone"),f.appendChild(m),m.addEventListener(s,((p,y,w)=>k=>{k.preventDefault(),p.drag=!0,p.noteOn(y,w,127)})(this,l,h)),m.addEventListener("mouseover",((p,y,w)=>k=>{k.preventDefault(),p.drag&&p.noteOn(y,w,127)})(this,l,h)),m.addEventListener("mouseout",((p,y,w)=>k=>{k.preventDefault(),p.noteOff(y,w)})(this,l,h)),m.addEventListener(i,((p,y,w)=>k=>{k.preventDefault(),p.drag=!1,p.noteOff(y,w)})(this,l,h))}break}}d.appendChild(f)}n.appendChild(d),this.intersection.observe(d)}const o=["Ch.","Bank","Program","Vol.","Exp.","Panpot","Pitch Bend","","Rev.",""],a=e.createElement("div");a.className="header";for(const l in this.items){if(!Object.hasOwn(this.items,l))continue;const d=e.createElement("div");d.className=this.items[l],d.textContent=o[l],this.items[l]==="keys"&&(d.appendChild(document.createElement("code")),d.appendChild(document.createElement("div"))),a.appendChild(d)}return n.prepend(a),t.appendChild(n),new ResizeObserver(l=>{this.items.forEach(u=>{const f=t.querySelector(`.header .${u}`),h=t.querySelector(`.channel .${u}`);f.style.width=h.offsetWidth+"px"});const d=t.querySelector(".header .keys");d.style.display=document.documentElement.clientWidth<=680?"none":"flex"}).observe(t),t}updateSynthElement(e,t,n){if(!this.element)return;const s=this.element.querySelectorAll(".instrument > .channel");if(s[e].dataset.isIntersecting){const i=s[e].querySelector(`.key:nth-child(${t+1})`);n===0?(i.classList.contains("note-on")&&i.classList.remove("note-on"),i.style.opacity="1"):(i.classList.add("note-on"),i.style.opacity=(n/127).toFixed(2))}}updateBankSelect(e){if(!this.element)return;const t=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".bank > select");for(;t.firstChild;)t.removeChild(t.firstChild);for(const n in this.programSet){if(!Object.hasOwn(this.programSet,n))continue;const s=document.createElement("option");s.value=n,s.textContent=("000"+parseInt(n)).slice(-3),parseInt(n)===this.channelBank[e]&&(s.selected=!0),t.appendChild(s)}}updateProgramSelect(e){if(!this.element)return;const t=this.element.querySelectorAll(".instrument > .channel")[e],n=this.channelBank[e],s=t.querySelector(".bank > select"),i=t.querySelector(".program > select");for(s.value=this.channelBank[e].toString();i.firstChild;)i.removeChild(i.firstChild);for(const o in this.programSet[n]){if(!Object.hasOwn(this.programSet[n],o))continue;const a=document.createElement("option");a.value=o,a.textContent=`${("000"+(parseInt(o)+1)).slice(-3)}:${this.programSet[n][o]}`,parseInt(o)===this.channelInstrument[e]&&(a.selected=!0),i.appendChild(a)}}noteOn(e,t,n=100){const s=this.channelBank[e],i=typeof this.bankSet[s]=="object"?this.bankSet[s]:this.bankSet[0];let o;if(typeof i[this.channelInstrument[e]]=="object"?o=i[this.channelInstrument[e]]:this.percussionPart[e]?o=this.bankSet[this.mode==="XG"?127:128][0]:o=this.bankSet[0][this.channelInstrument[e]],o[t]===void 0){console.warn("instrument not found: bank=%s instrument=%s channel=%s key=%s",s,this.channelInstrument[e],e,t);return}const a=o[t];let c=this.channelPanpot[e]===0?Math.floor(Math.random()*127):this.channelPanpot[e]-64;c/=c<0?64:63,a.channel=e,a.key=t,a.velocity=n,a.panpot=c,a.volume=this.channelVolume[e]/127,a.pitchBend=this.channelPitchBend[e]-8192,a.expression=this.channelExpression[e],a.pitchBendSensitivity=Math.round(this.channelPitchBendSensitivity[e]),a.mute=this.channelMute[e],a.releaseTime=this.channelRelease[e],a.cutOffFrequency=this.cutOffFrequency[e],a.harmonicContent=this.harmonicContent[e],a.reverb=this.reverb[e],a.modulation=this.modulation[e],s>=127&&((t===42||t===44)&&this.noteOff(e,46),t===80&&this.noteOff(e,81),o.volume*=this.percussionVolume[t]/127);const l=new Ae(this.ctx,this.gainMaster,a);l.noteOn(),this.currentNoteOn[e].push(l),this.updateSynthElement(e,t,n)}noteOff(e,t){let n,s;const i=this.currentNoteOn[e];let o;const a=this.channelHold[e];for(n=0,s=i.length;n64;let i,o,a;if(!s)for(o=0,a=n.length;o .channel");if(!c[e])return;this.channelHold[e]?c[e].classList.add("hold"):c[e].classList.contains("hold")&&c[e].classList.remove("hold")}}bankSelectMsb(e,t){this.percussionPart[e]=t>=125,this.channelBank[e]=e===9?128:0,this.mode!=="GM"&&(this.mode==="XG"?t===64?this.channelBank[e]=125:t===126||t===127?this.channelBank[e]=t:t===128&&(this.channelBank[e]=127):(this.channelBank[e]=e===9?128:t,this.percussionPart[e]=t===128),this.updateBankSelect(e))}bankSelectLsb(e,t){this.mode==="XG"&&(this.percussionPart[e]||(this.channelBank[e]=t),this.updateBankSelect(e))}programChange(e,t){if(this.channelInstrument[e]=t,this.bankChange(e,this.channelBank[e]),this.element){const n=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".program > select");n.value=t.toString()}}bankChange(e,t){const n=this.mode==="XG"||this.mode==="GM"?127:128;if(this.mode==="GM"&&(t=0),e===9&&(t=n),this.bankSet[t]?this.channelBank[e]=t:this.channelBank[e]=this.percussionPart[e]?n:0,this.element){const s=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".bank > select");s.value=t.toString()}this.updateProgramSelect(e)}volumeChange(e,t){if(this.element){const n=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".volume var");n.innerText=t.toString()}this.channelVolume[e]=t}expression(e,t){let n,s;const i=this.currentNoteOn[e];for(n=0,s=i.length;n .channel")[e].querySelector(".expression var");o.innerText=t.toString()}this.channelExpression[e]=t}panpotChange(e,t){if(this.channelPanpot[e]=t,this.element){const n=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".panpot");n.ariaValueNow=t.toString();const s=n.querySelector(".progress-bar"),i=t/127*100;if(s.style.width=`${i}%`,s.classList.remove("left","right"),s.title=t.toString(),t===64)return;n.classList.add(t<63?"left":"right")}}pitchBend(e,t,n){const s=t&127|(n&127)<<7;let i,o;const a=this.currentNoteOn[e],c=s-8192;for(i=0,o=a.length;i .channel")[e].querySelector(".pitchBend");l.ariaValueNow=s.toString();const d=l.querySelector(".progress-bar");if(d.style.width=`${Math.floor(s/16384*100)}%`,d.title=c.toString(),d.classList.remove("high","low"),c===0)return;d.classList.add(c<0?"low":"high")}}pitchBendSensitivity(e,t){if(this.element){const n=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".pitchBendSensitivity > var");n.innerText=t.toString()}this.channelPitchBendSensitivity[e]=t}attackTime(e,t){this.channelAttack[e]=t}decayTime(e,t){this.channelDecay[e]=t}sustinTime(e,t){this.channelSustin[e]=t}releaseTime(e,t){this.channelRelease[e]=t}harmonicContent(e,t){this.channelHarmonicContent[e]=t}cutOffFrequency(e,t){this.channelCutOffFrequency[e]=t}reverbDepth(e,t){if(this.reverb[e].mix(t/127),this.element){const n=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".reverbDepth var");n.innerText=t.toString()}}modulationDepth(e,t){if(this.element){const n=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".pitchBend .progress-bar");t!==0?n.classList.add("progress-bar-striped"):n.classList.remove("progress-bar-striped")}this.modulation[e]=t}getPitchBendSensitivity(e){return this.channelPitchBendSensitivity[e]}drumInstrumentLevel(e,t){this.percussionVolume[e]=t}allNoteOff(e){const t=this.currentNoteOn[e];for(this.hold(e,0);t.length>0;)this.noteOff(e,t[0].key)}allSoundOff(e){const t=this.currentNoteOn[e];let n;for(;t.length>0;)n=t.shift(),this.noteOff(e,n.key),n.release(),n.disconnect();this.hold(e,0)}resetAllControl(e){this.allNoteOff(e),this.expression(e,127),this.pitchBend(e,0,64)}mute(e,t){const n=this.currentNoteOn[e];let s,i;if(this.channelMute[e]=t,t)for(s=0,i=n.length;sString.fromCharCode(n)).join(""),this.timer=setTimeout(()=>{t.innerText=""},5e4)}}class _{static CACHE_NAME="wml";constructor(e,t,n,s){this.url=e,this.cache=n,this.callback=s,this.alert=document.createElement("div"),this.alert.className="alert alert-warning",this.message=document.createElement("p"),this.message.innerText="Now Loading...",this.progressOuter=document.createElement("div"),this.progressOuter.className="progress",this.progressOuter.role="progressbar",this.progressOuter.ariaLabel="Loading Progress",this.progressOuter.ariaValueMin="0",this.progressOuter.ariaValueNow="0",this.progressOuter.ariaValueMax="100",this.progress=document.createElement("div"),this.progress.className="progress-bar",this.progressOuter.appendChild(this.progress),this.alert.appendChild(this.message),this.alert.appendChild(this.progressOuter),t.appendChild(this.alert)}onProgress(e,t){const n=Math.floor(e/t*100);this.progress.style.width=`${n}%`,this.progress.innerText=`${n}%`}onComplete(e){this.alert.className="alert alert-info",this.message.innerText="Initializing...",this.progress.className="progress-bar progress-bar-striped progress-bar-animated",this.progress.style.width="100%",this.callback(new Uint8Array(e))}onError(e=void 0){requestAnimationFrame(()=>{this.alert.className="alert alert-danger",this.message.innerText="An error occurred while loading SoundFont. See the console log for details. In addition, it may be cured by deleting the cache of the browser.",this.progressOuter.style.display="none"})}async fetch(){const e=await window.caches.open(_.CACHE_NAME),t=await e.match(this.url);if(this.cache&&t){this.onComplete(await t.arrayBuffer());return}const n=await fetch(this.url,{method:"GET"}).catch(u=>this.onError(u));if(!n||n&&!n.ok)return;const s=n.clone(),i=parseInt(n.headers.get("Content-Length")),o=s.body.getReader();let a=0;const c=[];for(;;){const{done:u,value:f}=await o.read();if(u)break;c.push(f),a+=f.length,this.message.innerText=`Now Loading... (${a} of ${i} byte)`,this.onProgress(a,i)}const l=new Uint8Array(a);let d=0;for(const u of c)l.set(u,d),d+=u.length;await e.put(this.url,n),this.onComplete(l)}}class me{constructor(e={}){this.NrpnMsb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],this.NrpnLsb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],this.RpnMsb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],this.RpnLsb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],this.ready=!1,this.synth=void 0,this.messageHandler=this.onMessage.bind(this),this.rpnMode=!0,this.option={},this.option.drawSynth=e.drawSynth!=="false",this.option.cache=e.cache??!0,this.option.targetOrigin=e.targetOrigin??"*",this.option.colorMode=e.colorMode??"auto",this.url=e.url??"https://cdn.jsdelivr.net/npm/@logue/sf2synth@latest/dist/Yamaha XG Sound Set.sf2",this.placeholder=e.placeholder?document.getElementById(e.placeholder):window.document.body,this.setColorMode(this.option.colorMode),this.window=null,window.opener?this.window=window.opener:window.parent!==window?this.window=window.parent:this.window=window}async setup(e=void 0){for(;this.placeholder.firstChild;)this.placeholder.removeChild(this.placeholder.firstChild);e&&(this.url=e),await new _(this.url,this.placeholder,this.option.cache,n=>this.setupByBuffer(n)).fetch()}getUrl(){return this.url}setupByBuffer(e){for(;this.placeholder.firstChild;)this.placeholder.removeChild(this.placeholder.firstChild);if(this.synth?this.synth.refreshInstruments(e):(this.synth=new Ue(e),this.synth.start()),this.option.drawSynth)this.placeholder.appendChild(this.synth.drawSynth());else{const t=document.createElement("div");t.className="alert alert-success",t.role="alert",t.innerText="Ready.",this.placeholder.appendChild(t)}this.synth.init(),this.onReady()}callback(){}onReady(){window.removeEventListener("message",this.messageHandler),this.callback(),window.addEventListener("message",this.messageHandler,!1),this.window.postMessage("link,ready",this.option.targetOrigin)}onMessage(e){const t=typeof e.data.split=="function"?e.data.split(","):[],n=t.length!==0?t.shift():"";let s;switch(n){case"midi":this.processMidiMessage(t.map(i=>parseInt(i,16)));break;case"link":if(this.window===void 0)return;switch(s=t.shift(),s){case"reqpatch":this.window.postMessage("link,patch",this.option.targetOrigin);break;case"setpatch":case"ready":this.window.postMessage("link,ready",this.option.targetOrigin);break;case"progress":this.window.postMessage("link,progress",this.option.targetOrigin);break;default:console.error("unknown link message:",s);break}break;default:console.error("unknown message type")}}setLoadCallback(e){this.callback=e}processMidiMessage(e){const t=e[0]&15,n=this.synth;switch(e[0]&240){case 128:n.noteOff(t,e[1],e[2]);break;case 144:e[2]>0?n.noteOn(t,e[1],e[2]):n.noteOff(t,e[1],0);break;case 176:{const s=e[2];switch(e[1]){case 0:n.bankSelectMsb(t,s);break;case 1:n.modulationDepth(t,s);break;case 5:break;case 6:if(this.rpnMode)switch(this.RpnMsb[t]){case 0:switch(this.RpnLsb[t]){case 0:n.pitchBendSensitivity(t,s);break}break}else switch(this.NrpnMsb[t]){case 26:n.drumInstrumentLevel(this.NrpnLsb[t],s);break}break;case 38:if(this.rpnMode)switch(this.RpnMsb[t]){case 0:switch(this.RpnLsb[t]){case 0:n.pitchBendSensitivity(t,n.getPitchBendSensitivity(t)+s/100);break}break}break;case 7:n.volumeChange(t,s);break;case 10:n.panpotChange(t,s);break;case 120:n.allSoundOff(t);break;case 121:n.resetAllControl(t);break;case 32:n.bankSelectLsb(t,s);break;case 71:n.harmonicContent(t,s);break;case 96:break;case 97:break;case 98:this.rpnMode=!1,this.NrpnLsb[t]=s;break;case 99:this.rpnMode=!1,this.NrpnMsb[t]=s;break;case 100:this.rpnMode=!0,this.RpnLsb[t]=s;break;case 101:this.rpnMode=!0,this.RpnMsb[t]=s;break;case 64:n.hold(t,s);break;case 11:n.expression(t,s);break;case 72:n.decayTime(t,s);break;case 73:n.releaseTime(t,s);break;case 74:n.attackTime(t,s);break;case 75:n.cutOffFrequency(t,s);break;case 91:n.reverbDepth(t,s);break}break}case 192:n.programChange(t,e[1]);break;case 224:n.pitchBend(t,e[1],e[2]);break;case 240:{e.splice(1,1);const s=e[1],i=e[2],o=e[3];if(s===126||i===9)switch(o){case 1:n.init("GM"),console.info("\x1B[34mGM System On\x1B[0m");break;case 2:console.info("\x1B[34mGM System Off\x1B[0m");break;case 3:console.info("\x1B[34mGM (v2) System On\x1B[0m"),n.init("GM2");break;default:console.log("\x1B[34mGM\x1B[0m: "+this.dumpMessage(e))}else s===127?o===1?n.setMasterVolume(e[4]+(e[5]<<7)):console.log("\x1B[34mRealtime\x1B[0m: "+this.dumpMessage(e)):s===125&&e[4]===1&&(e[5]===1?this.setColorMode("light"):e[5]===2?this.setColorMode("dark"):this.setColorMode("auto"));if(o===66){const a=e[6]-15,c=e[7],l=e[8];switch(c){case 0:if(a===0){const d=e.splice(8);d.pop(),d.pop(),n.processMidiMessage(d)}else console.log("\x1B[31mGS Bitmap message\x1B[0m:"+this.dumpMessage(e));break;case 4:n.setMasterVolume(l*64);break;case 21:{a===0?n.setPercussionPart(9,l!==0):a>=10?n.setPercussionPart(a-1,l!==0):n.setPercussionPart(a,l!==0);break}case 25:console.info("\x1B[31mGS Volume On/Off\x1B[0m: "+a,l);break;case 48:console.info("\x1B[31mGS Reverb\x1B[0m: "+this.dumpMessage(e));break;case 56:console.info("\x1B[31mGS Chorus\x1B[0m: "+this.dumpMessage(e));break;case 69:console.info("\x1B[31mGS Bitmap\x1B[0m: "+this.dumpMessage(e));break;case 127:n.init("GS"),console.info("\x1B[31mGS Reset\x1B[0m");break;default:console.log("\x1B[31mGS\x1B[0m: "+this.dumpMessage(e))}}else if(o===76){const a=e[4],c=e[5];switch(a){case 0:e[6]===126&&(n.init("XG"),console.info("\x1B[32mXG Reset\x1B[0m"));break;case 2:console.log("\x1B[32mXG Effect\x1B[0m: "+this.dumpMessage(e));break;case 3:console.log("\x1B[32mXG Insertion Effect\x1B[0m: "+this.dumpMessage(e));break;case 4:n.setMasterVolume(e[9]*64);break;case 6:{const l=e.splice(8);l.pop(),n.processMidiMessage(l);break}case 7:console.log("\x1B[32mXG Bitmap\x1B[0m: "+this.dumpMessage(e));break;case 8:n.setPercussionPart(c,e[8]!==0);break;default:console.log("\x1B[32mXG\x1B[0m: ",this.dumpMessage(e))}}break}default:n.setPercussionPart(9,!0);break}}dumpMessage(e){const t=[];let n=0;for(const s of e){let i="";switch(n){case 0:i="\x1B[35m";break;case 1:case 2:case 3:i="\x1B[33m";break;default:i=e.length-1===n?"\x1B[35m":"\x1B[36m";break}t.push(i+s.toString(16).toUpperCase().padStart(2,"0")),n++}return t.join(" ")+"\x1B[0m"}setColorMode(e){e?(e==="auto"&&(e=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"),document.documentElement.setAttribute("data-bs-theme",e)):(document.documentElement.setAttribute("data-bs-theme","auto"),document.documentElement.removeAttribute("data-bs-theme"))}}class _e extends me{constructor(e={}){super(e),this.midi=void 0}async setup(e){this.midi=await window.navigator.requestMIDIAccess({sysex:!0}),await super.setup(e)}onReady(){super.callback(),this.midi.inputs.forEach(e=>e.onmidimessage=t=>super.processMidiMessage(Array.from(t.data)))}}const te={version:"0.6.1",date:"2023-11-29T01:03:54.716Z"},$={version:te.version,build:te.date,WebMidiLink:me,WebMidiApi:_e,Parser:R};let pe={drawSynth:!0,placeholder:"placeholder",colorMode:"auto",...q.parse(window.location.search),...q.parse(window.location.hash)};const O=new $.WebMidiLink(pe);document.addEventListener("DOMContentLoaded",r=>{const e=document.getElementById("file"),t=document.getElementById("drag"),n=document.getElementById("build"),s=document.getElementById("toggleDarkMode");O.setLoadCallback(()=>{t.classList.remove("bg-info"),document.getElementById("soundfont").innerText=decodeURIComponent(O.getUrl()).match(".+/(.+?)([?#;].*)?$")[1]}),n.dateTime=$.build,n.innerText=new Date($.build).toLocaleString(),O.setup();const i=window.matchMedia("(prefers-color-scheme: dark)");i.addListener(()=>{document.documentElement.getAttribute("data-bs-theme")||(O.setColorMode(pe.colorMode),s.checked=i.matches)});const o=a=>{const c=new FileReader;c.readAsArrayBuffer(a),c.onload=l=>{document.getElementById("soundfont").innerText=a.name;const d=new Uint8Array(l.target.result);O.setupByBuffer(d)}};e.addEventListener("change",a=>{a.preventDefault(),o(e.files[0]),e.value=""},!1),t.addEventListener("drop",a=>{const c=a.dataTransfer;c.files.length&&(a.preventDefault(),a.stopPropagation(),o(c.files[0])),t.classList.remove("bg-info")},!1),t.addEventListener("dragover",a=>{a.preventDefault(),a.stopPropagation(),t.classList.add("bg-info")},!1),t.addEventListener("dragleave",a=>{a.preventDefault(),a.stopPropagation(),t.classList.remove("bg-info")},!1),s.addEventListener("change",a=>{O.setColorMode(a.target.checked?"dark":"light")})},!1);window.addEventListener("hashchange",()=>{const r=q.parse(window.location.hash);r&&O.setup(r)},!1); -//# sourceMappingURL=index-toxedflk.js.map + */const W=1/2**32;class Oe{float(e=1){return this.int()*W*e}probability(e){return this.float()>>=0;const n=(t>>>0)-e;return n?e+this.int()%n:e}}const B=Math.random;class Te extends Oe{int(){return B()*4294967296>>>0}float(e=1){return B()*e}norm(e=1){return(B()-.5)*2*e}}const de=new Te,Ne={noise:"white",scale:1,peaks:2,randomAlgorithm:de,decay:2,delay:0,reverse:!1,time:2,filterType:"allpass",filterFreq:2200,filterQ:1,mix:.5,once:!1},Y={version:"1.3.5",date:"2023-11-20T03:01:00.334Z"},N={blue:"blue",brown:"red",green:"green",pink:"pink",red:"red",violet:"violet",white:"white"},F={bins:2,scale:1,rnd:de},z=(r,e,t)=>{const n=new Array(r);for(let s=0;sr.reduce((e,t)=>e+t,0);function*ue(r,e){const t=[r[Symbol.iterator](),e[Symbol.iterator]()];for(let n=0;;n^=1){const s=t[n].next();if(s.done)return;yield s.value}}function*D(r){const{bins:e,scale:t,rnd:n}={...F,...r},s=z(e,t,n);s.forEach((a,c)=>s[c]=c&1?a:-a);const i=1/e;let o=U(s);for(let a=0,c=-1;;++a>=e&&(a=0))o-=s[a],o+=s[a]=c*n.norm(t),c^=4294967294,yield c*o*i}const Ie=r=>ue(D(r),D(r)),Ge=r=>{let e=32;return r&=-r,r&&e--,r&65535&&(e-=16),r&16711935&&(e-=8),r&252645135&&(e-=4),r&858993459&&(e-=2),r&1431655765&&(e-=1),e};function*Re(r){const{bins:e,scale:t,rnd:n}={...F,bins:8,...r},s=z(e,t,n),i=1/e;let o=U(s);for(let a=0;;a=a+1>>>0){const c=Ge(a)%e;o-=s[c],o+=s[c]=n.norm(t),yield o*i}}function*j(r){const{bins:e,scale:t,rnd:n}={...F,...r},s=z(e,t,n),i=1/e;let o=U(s);for(let a=0;;++a>=e&&(a=0))o-=s[a],o+=s[a]=n.norm(t),yield o*i}const Fe=r=>ue(j(r),j(r));function*J(r){const{scale:e,rnd:t}={...F,...r};for(;;)yield t.norm(e)}const Le=(r,e)=>r!=null&&typeof r[e]=="function",Be=r=>Le(r,"xform")?r.xform():r,Pe=r=>r!=null&&typeof r[Symbol.iterator]=="function";class G{value;constructor(e){this.value=e}deref(){return this.value}}const Ve=r=>new G(r),qe=r=>r instanceof G,De=r=>r instanceof G?r:new G(r),ee=r=>r instanceof G?r.deref():r,je=(r,e)=>[r,t=>t,e];function $e(r){return r?[...r]:je(()=>[],(e,t)=>(e.push(t),e))}function*He(r,e){const t=Be(r)($e()),n=t[1],s=t[2];for(let i of e){const o=s([],i);if(qe(o)){yield*ee(n(o.deref()));return}o.length&&(yield*o)}yield*ee(n([]))}const Ze=(r,e)=>[r[0],r[1],e];function fe(r,e){return Pe(e)?He(fe(r),e):t=>{const n=t[2];let s=r;return Ze(t,(i,o)=>--s>0?n(i,o):s===0?De(n(i,o)):Ve(i))}}class A{static version=Y.version;static build=Y.date;ctx;wetGainNode;dryGainNode;filterNode;convolverNode;outputNode;options;isConnected;noise=J;constructor(e,t){this.ctx=e,this.options=Object.assign(Ne,t),this.wetGainNode=this.ctx.createGain(),this.dryGainNode=this.ctx.createGain(),this.filterNode=this.ctx.createBiquadFilter(),this.convolverNode=this.ctx.createConvolver(),this.outputNode=this.ctx.createGain(),this.isConnected=!1,this.filterType(this.options.filterType),this.setNoise(this.options.noise),this.buildImpulse(),this.mix(this.options.mix)}connect(e){return this.isConnected&&this.options.once?(this.isConnected=!1,this.outputNode):(this.convolverNode.connect(this.filterNode),this.filterNode.connect(this.wetGainNode),e.connect(this.convolverNode),e.connect(this.dryGainNode).connect(this.outputNode),e.connect(this.wetGainNode).connect(this.outputNode),this.isConnected=!0,this.outputNode)}disconnect(e){return this.isConnected&&(this.convolverNode.disconnect(this.filterNode),this.filterNode.disconnect(this.wetGainNode)),this.isConnected=!1,e}mix(e){if(!A.inRange(e,0,1))throw new RangeError("[Reverb.js] Dry/Wet ratio must be between 0 to 1.");this.options.mix=e,this.dryGainNode.gain.value=1-this.options.mix,this.wetGainNode.gain.value=this.options.mix}time(e){if(!A.inRange(e,1,50))throw new RangeError("[Reverb.js] Time length of inpulse response must be less than 50sec.");this.options.time=e,this.buildImpulse()}decay(e){if(!A.inRange(e,0,100))throw new RangeError("[Reverb.js] Inpulse Response decay level must be less than 100.");this.options.decay=e,this.buildImpulse()}delay(e){if(!A.inRange(e,0,100))throw new RangeError("[Reverb.js] Inpulse Response delay time must be less than 100.");this.options.delay=e,this.buildImpulse()}reverse(e){this.options.reverse=e,this.buildImpulse()}filterType(e="allpass"){this.filterNode.type=this.options.filterType=e}filterFreq(e){if(!A.inRange(e,20,2e4))throw new RangeError("[Reverb.js] Filter frequrncy must be between 20 and 20000.");this.options.filterFreq=e,this.filterNode.frequency.value=this.options.filterFreq}filterQ(e){if(!A.inRange(e,0,10))throw new RangeError("[Reverb.js] Filter quality value must be between 0 and 10.");this.options.filterQ=e,this.filterNode.Q.value=this.options.filterQ}peaks(e){this.options.peaks=e,this.buildImpulse()}scale(e){this.options.scale=e,this.buildImpulse()}randomAlgorithm(e){this.options.randomAlgorithm=e,this.buildImpulse()}setNoise(e){switch(this.options.noise=e,e){case N.blue:this.noise=D;break;case N.green:this.noise=Ie;break;case N.pink:this.noise=Re;break;case N.red:case N.brown:this.noise=j;break;case N.violet:this.noise=Fe;break;default:this.noise=J}this.buildImpulse()}setRandomAlgorythm(e){this.options.randomAlgorithm=e,this.buildImpulse()}static inRange(e,t,n){return(e-t)*(e-n)<=0}buildImpulse(){const e=this.ctx.sampleRate,t=Math.max(e*this.options.time,1),n=e*this.options.delay,s=this.ctx.createBuffer(2,t,e),i=new Float32Array(t),o=new Float32Array(t),a=this.getNoise(t),c=this.getNoise(t);for(let l=0;l>>0:(e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24)>>>0,t)),t+=n,this.padding&&(t-this.offset&1)===1&&t++,this.ip=t}getChunk(e){const t=this.chunkList[e];return t!==void 0?t:null}getNumberOfChunks(){return this.chunkList.length}}class ze{constructor(e,t,n){this.type=e,this.size=t,this.offset=n}}class R{constructor(e,t={}){this.input=e,this.parserOption=t.parserOption||{},this.sampleRate=t.sampleRate||22050,this.presetHeader=[],this.presetZone=[],this.presetZoneModulator=[],this.presetZoneGenerator=[],this.instrument=[],this.instrumentZone=[],this.instrumentZoneModulator=[],this.instrumentZoneGenerator=[],this.sampleHeader=[],this.GeneratorEnumeratorTable=Object.keys(R.getGeneratorTable())}static getGeneratorTable(){return Object.freeze({startAddrsOffset:0,endAddrsOffset:0,startloopAddrsOffset:0,endloopAddrsOffset:0,startAddrsCoarseOffset:0,modLfoToPitch:0,vibLfoToPitch:0,modEnvToPitch:0,initialFilterFc:13500,initialFilterQ:0,modLfoToFilterFc:0,modEnvToFilterFc:0,endAddrsCoarseOffset:0,modLfoToVolume:0,unused1:void 0,chorusEffectsSend:0,reverbEffectsSend:0,pan:0,unused2:void 0,unused3:void 0,unused4:void 0,delayModLFO:-12e3,freqModLFO:0,delayVibLFO:-12e3,freqVibLFO:0,delayModEnv:-12e3,attackModEnv:-12e3,holdModEnv:-12e3,decayModEnv:-12e3,sustainModEnv:0,releaseModEnv:-12e3,keynumToModEnvHold:0,keynumToModEnvDecay:0,delayVolEnv:-12e3,attackVolEnv:-12e3,holdVolEnv:-12e3,decayVolEnv:-12e3,sustainVolEnv:0,releaseVolEnv:-12e3,keynumToVolEnvHold:0,keynumToVolEnvDecay:0,instrument:null,reserved1:void 0,keyRange:null,velRange:null,startloopAddrsCoarseOffset:0,keynum:null,velocity:null,initialAttenuation:0,reserved2:void 0,endloopAddrsCoarseOffset:0,coarseTune:0,fineTune:0,sampleID:null,sampleModes:0,reserved3:void 0,scaleTuning:100,exclusiveClass:null,overridingRootKey:null,unuded5:void 0,endOper:void 0})}parse(){const e=new I(this.input,this.parserOption);if(e.parse(),e.chunkList.length!==1)throw new Error("wrong chunk length");const t=e.getChunk(0);if(t===null)throw new Error("chunk not found");this.parseRiffChunk(t),this.input=null}parseRiffChunk(e){const t=this.input;let n=e.offset;if(e.type!=="RIFF")throw new Error("invalid chunk type:"+e.type);const s=String.fromCharCode(t[n++],t[n++],t[n++],t[n++]);if(s!=="sfbk")throw new Error("invalid signature:"+s);const i=new I(t,{index:n,length:e.size-4});if(i.parse(),i.getNumberOfChunks()!==3)throw new Error("invalid sfbk structure");this.parseInfoList(i.getChunk(0)),this.parseSdtaList(i.getChunk(1)),this.parsePdtaList(i.getChunk(2))}parseInfoList(e){const t=this.input;let n=e.offset;if(e.type!=="LIST")throw new Error("invalid chunk type:"+e.type);const s=String.fromCharCode(t[n++],t[n++],t[n++],t[n++]);if(s!=="INFO")throw new Error("invalid signature:"+s);new I(t,{index:n,length:e.size-4}).parse()}parseSdtaList(e){const t=this.input;let n=e.offset;if(e.type!=="LIST")throw new Error("invalid chunk type:"+e.type);const s=String.fromCharCode(t[n++],t[n++],t[n++],t[n++]);if(s!=="sdta")throw new Error("invalid signature:"+s);const i=new I(t,{index:n,length:e.size-4});if(i.parse(),i.chunkList.length!==1)throw new Error("TODO");this.samplingData=i.getChunk(0)}parsePdtaList(e){const t=this.input;let n=e.offset;if(e.type!=="LIST")throw new Error("invalid chunk type:"+e.type);const s=String.fromCharCode(t[n++],t[n++],t[n++],t[n++]);if(s!=="pdta")throw new Error("invalid signature:"+s);const i=new I(t,{index:n,length:e.size-4});if(i.parse(),i.getNumberOfChunks()!==9)throw new Error("invalid pdta chunk");this.parsePhdr(i.getChunk(0)),this.parsePbag(i.getChunk(1)),this.parsePmod(i.getChunk(2)),this.parsePgen(i.getChunk(3)),this.parseInst(i.getChunk(4)),this.parseIbag(i.getChunk(5)),this.parseImod(i.getChunk(6)),this.parseIgen(i.getChunk(7)),this.parseShdr(i.getChunk(8))}parsePhdr(e){const t=this.input;let n=e.offset;const s=this.presetHeader=[],i=e.offset+e.size;if(e.type!=="phdr")throw new Error("invalid chunk type:"+e.type);for(;n>>0,genre:(t[n++]|t[n++]<<8|t[n++]<<16|t[n++]<<24)>>>0,morphology:(t[n++]|t[n++]<<8|t[n++]<<16|t[n++]<<24)>>>0})}parsePbag(e){const t=this.input;let n=e.offset;const s=this.presetZone=[],i=e.offset+e.size;if(e.type!=="pbag")throw new Error("invalid chunk type:"+e.type);for(;n>>0,l=(t[n++]<<0|t[n++]<<8|t[n++]<<16|t[n++]<<24)>>>0,d=(t[n++]<<0|t[n++]<<8|t[n++]<<16|t[n++]<<24)>>>0,u=(t[n++]<<0|t[n++]<<8|t[n++]<<16|t[n++]<<24)>>>0,f=(t[n++]<<0|t[n++]<<8|t[n++]<<16|t[n++]<<24)>>>0,h=t[n++],m=t[n++]<<24>>24,b=t[n++]|t[n++]<<8,p=t[n++]|t[n++]<<8;let y=new Int16Array(new Uint8Array(t.subarray(this.samplingData.offset+c*2,this.samplingData.offset+l*2)).buffer);if(d-=c,u-=c,f>0){const w=this.adjustSampleData(y,f);y=w.sample,f*=w.multiply,d*=w.multiply,u*=w.multiply}s.push(y),i.push({sampleName:a,start:c,end:l,startLoop:d,endLoop:u,sampleRate:f,originalPitch:h,pitchCorrection:m,sampleLink:b,sampleType:p})}}adjustSampleData(e,t){let n,s,i,o,a=1;for(;t>16,lo:t[n++],hi:t[n++]}});else switch(o){case"keyRange":case"velRange":case"keynum":case"velocity":a.push({type:o,value:{amount:null,lo:t[n++],hi:t[n++]}});break;default:a.push({type:o,value:{amount:t[n++]|t[n++]<<8<<16>>16}});break}n+=2,n+=2}return a}parseGenerator(e){const t=this.input;let n=e.offset;const s=e.offset+e.size;let i,o;const a=[];for(;n>16,lo:t[n++],hi:t[n++]}});continue}switch(o){case"keynum":case"keyRange":case"velRange":case"velocity":a.push({type:o,value:{amount:null,lo:t[n++],hi:t[n++]}});break;default:a.push({type:o,value:{amount:t[n++]|t[n++]<<8<<16>>16}});break}}return a}createInstrument(){const e=this.instrument,t=this.instrumentZone,n=[];let s,i,o,a,c,l,d,u,f;for(l=0,d=e.length;ln.forEach(s=>{s.target.dataset.isIntersecting=s.isIntersecting}),{}),this.timer=void 0,this.drag=!1}getAudioContext(){const e=new AudioContext,t=()=>{document.removeEventListener("touchstart",t);const n=e.createBufferSource();n.start(),n.stop()};return document.addEventListener("touchstart",t),e}init(e="GM"){this.gainMaster.disconnect(),this.refreshInstruments(this.input),this.mode=e;for(let t=0;t<16;++t)this.setPercussionPart(t,t===9),this.programChange(t,0),this.volumeChange(t,100),this.panpotChange(t,64),this.pitchBend(t,0,64),this.pitchBendSensitivity(t,2),this.hold(t,0),this.expression(t,127),this.bankSelectMsb(t,t===9?127:0),this.bankSelectLsb(t,t===9?127:0),this.attackTime(t,64),this.decayTime(t,64),this.sustinTime(t,64),this.releaseTime(t,64),this.harmonicContent(t,64),this.cutOffFrequency(t,64),this.reverbDepth(t,40),this.modulationDepth(t,0),this.updateBankSelect(t),this.updateProgramSelect(t);this.setPercussionPart(9,!0);for(let t=0;t<128;++t)this.percussionVolume[t]=127;if(this.setMasterVolume(8192),this.gainMaster.connect(this.ctx.destination),this.element){const t=this.element.querySelector(".header .keys div");t.innerText=e+" Mode",this.element.querySelectorAll(".instrument .bank > select").forEach(s=>s.disabled=e==="GM"),this.element.dataset.mode=e}}async close(){await this.ctx.close()}refreshInstruments(e){this.input=e,this.parser=new R(e,{sampleRate:this.ctx.sampleRate}),this.bankSet=this.createAllInstruments()}createAllInstruments(){const e=this.parser;e.parse();const t=e.createPreset(),n=e.createInstrument(),s=[];let i,o,a,c,l;const d=[];return t.forEach(u=>{c=u.header.preset,o=u.header.bank,l=u.name.replace(/\0*$/,""),typeof u.instrument=="number"&&(a=n[u.instrument],a.name.replace(/\0*$/,"")!=="EOI"&&(s[o]=s[o]??[],i=s[o],i[c]={},i[c].name=l,a.info.forEach(f=>this.createNoteInfo(e,f,i[c])),d[o]||(d[o]=[]),d[o][c]=l))}),this.programSet=d,s}createNoteInfo(e,t,n){const s=t.generator;if(!s.keyRange||!s.sampleID)return;const i=this.getModGenAmount(s,"delayVolEnv"),o=this.getModGenAmount(s,"attackVolEnv"),a=this.getModGenAmount(s,"holdVolEnv"),c=this.getModGenAmount(s,"decayVolEnv"),l=this.getModGenAmount(s,"sustainVolEnv"),d=this.getModGenAmount(s,"releaseVolEnv"),u=this.getModGenAmount(s,"delayModEnv"),f=this.getModGenAmount(s,"attackModEnv"),h=this.getModGenAmount(s,"holdModEnv"),m=this.getModGenAmount(s,"decayModEnv"),b=this.getModGenAmount(s,"sustainModEnv"),p=this.getModGenAmount(s,"releaseModEnv"),y=this.getModGenAmount(s,"scaleTuning")/100,w=this.getModGenAmount(s,"coarseTune")+this.getModGenAmount(s,"fineTune")/100,k=this.getModGenAmount(s,"sampleModes");for(let v=s.keyRange.lo,E=s.keyRange.hi;v<=E;++v){if(n[v])continue;const C=this.getModGenAmount(s,"sampleID"),S=e.sampleHeader[C];n[v]={sample:e.sample[C],sampleRate:S.sampleRate,sampleModes:k,basePlaybackRate:1.0594630943592953**((v-this.getModGenAmount(s,"overridingRootKey")+w+S.pitchCorrection/100)*y),modEnvToPitch:this.getModGenAmount(s,"modEnvToPitch")/100,scaleTuning:y,start:this.getModGenAmount(s,"startAddrsCoarseOffset")*32768+this.getModGenAmount(s,"startAddrsOffset"),end:this.getModGenAmount(s,"endAddrsCoarseOffset")*32768+this.getModGenAmount(s,"endAddrsOffset"),loopStart:S.startLoop+this.getModGenAmount(s,"startloopAddrsCoarseOffset")*32768+this.getModGenAmount(s,"startloopAddrsOffset"),loopEnd:S.endLoop+this.getModGenAmount(s,"endloopAddrsCoarseOffset")*32768+this.getModGenAmount(s,"endloopAddrsOffset"),volDelay:2**(i/1200),volAttack:2**(o/1200),volHold:2**(a/1200)*2**((60-v)*this.getModGenAmount(s,"keynumToVolEnvHold")/1200),volDecay:2**(c/1200)*2**((60-v)*this.getModGenAmount(s,"keynumToVolEnvDecay")/1200),volSustain:l/1e3,volRelease:2**(d/1200),modDelay:2**(u/1200),modAttack:2**(f/1200),modHold:2**(h/1200)*2**((60-v)*this.getModGenAmount(s,"keynumToModEnvHold")/1200),modDecay:2**(m/1200)*2**((60-v)*this.getModGenAmount(s,"keynumToModEnvDecay")/1200),modSustain:b/1e3,modRelease:2**(p/1200),initialFilterFc:8.176*Math.pow(2,this.getModGenAmount(s,"initialFilterFc")/1200),modEnvToFilterFc:this.getModGenAmount(s,"modEnvToFilterFc")/100,initialFilterQ:this.getModGenAmount(s,"initialFilterQ")/10,reverbEffectSend:this.getModGenAmount(s,"reverbEffectSend")/10,initialAttenuation:this.getModGenAmount(s,"initialAttenuation")/10,freqVibLFO:8.176*Math.pow(2,this.getModGenAmount(s,"freqVibLFO")/1200),pan:this.getModGenAmount(s,"pan")/1200}}}getModGenAmount(e,t){return e[t]?e[t].amount:R.getGeneratorTable()[t]}start(){this.connect(),this.bufSrc.start(0),this.setMasterVolume(16383)}setMasterVolume(e){this.masterVolume=e,this.gainMaster.gain.value=this.baseVolume*(e/16384)}connect(){this.bufSrc.connect(this.gainMaster)}disconnect(){this.bufSrc.disconnect(this.gainMaster),this.bufSrc.buffer=null}drawSynth(){const e=window.document,t=this.element=e.createElement("div");t.className="synthesizer";const n=e.createElement("div");n.className="instrument",this.items=["mute","bank","program","volume","expression","panpot","pitchBend","pitchBendSensitivity","reverbDepth","keys"];const s="ontouchstart"in window?"touchstart":"mousedown",i="ontouchend"in window?"touchend":"mouseup";for(let l=0;l<16;l++){const d=e.createElement("div");d.className="channel",d.addEventListener(s,()=>{this.hold(l,0)});for(const u in this.items){if(!Object.hasOwn(this.items,u))continue;const f=e.createElement("div");switch(f.className=this.items[u],this.items[u]){case"mute":{const h=e.createElement("div");h.className="form-check form-check-inline";const m=e.createElement("input");m.ariaLabel=`Ch.${l+1} Mute`,m.setAttribute("type","checkbox"),m.className="form-check-input",m.id="mute"+l+"ch",m.value=l.toString(),m.addEventListener("change",p=>{this.mute(l,p.target.checked)},!1),h.appendChild(m);const b=e.createElement("label");b.className="form-check-label",b.textContent=(l+1).toString(),b.setAttribute("for","mute"+l+"ch"),h.appendChild(b),f.appendChild(h);break}case"bank":{const h=e.createElement("select");h.ariaLabel=`Ch.${l+1} Bank Select`,h.className="form-select form-select-sm bank-select",h.addEventListener("change",((m,b)=>p=>{const y=d.querySelector(".program select");m.bankChange(b,p.target.value),m.programChange(b,parseInt(y.value))})(this,l),!1),f.appendChild(h);break}case"program":{const h=e.createElement("select");h.className="form-select form-select-sm",h.ariaLabel=`Ch.${l+1} Program Change`,h.addEventListener("change",((m,b)=>p=>{m.programChange(b,p.target.value)})(this,l),!1),f.appendChild(h);break}case"volume":{const h=document.createElement("var");h.ariaLabel=`Ch.${l+1} Volume`,h.innerText="100",f.appendChild(h);break}case"expression":{const h=document.createElement("var");h.ariaLabel=`Ch.${l+1} Expression`,h.innerText="127",f.appendChild(h);break}case"pitchBendSensitivity":{const h=document.createElement("var");h.ariaLabel=`Ch.${l+1} Pitch Bend Sensitivity`,h.innerText="2",f.appendChild(h);break}case"reverbDepth":{const h=document.createElement("var");h.ariaLabel=`Ch.${l+1} Reverb Depth`,h.innerText="40",f.appendChild(h);break}case"panpot":{const h=e.createElement("div");h.role="progressbar",h.ariaLabel=`Ch.${l+1} Panpod`,h.ariaValueMin="0",h.ariaValueNow="64",h.ariaValueMax="127",h.className="progress";const m=e.createElement("div");m.className="progress-bar",h.appendChild(m),f.appendChild(h);break}case"pitchBend":{const h=e.createElement("div");h.className="progress",h.role="progressbar",h.ariaLabel=`Ch.${l+1} Pitch Bend`,h.ariaValueMin="-8192",h.ariaValueNow="0",h.ariaValueMax="8192",h.className="progress";const m=e.createElement("div");m.className="progress-bar progress-bar-animated",h.appendChild(m),f.appendChild(h);break}case"keys":{for(let h=0;h<127;h++){const m=e.createElement("div"),b=h%12;m.className="key "+([1,3,6,8,10].includes(b)?"semitone":"tone"),f.appendChild(m),m.addEventListener(s,((p,y,w)=>k=>{k.preventDefault(),p.drag=!0,p.noteOn(y,w,127)})(this,l,h)),m.addEventListener("mouseover",((p,y,w)=>k=>{k.preventDefault(),p.drag&&p.noteOn(y,w,127)})(this,l,h)),m.addEventListener("mouseout",((p,y,w)=>k=>{k.preventDefault(),p.noteOff(y,w)})(this,l,h)),m.addEventListener(i,((p,y,w)=>k=>{k.preventDefault(),p.drag=!1,p.noteOff(y,w)})(this,l,h))}break}}d.appendChild(f)}n.appendChild(d),this.intersection.observe(d)}const o=["Ch.","Bank","Program","Vol.","Exp.","Panpot","Pitch Bend","","Rev.",""],a=e.createElement("div");a.className="header";for(const l in this.items){if(!Object.hasOwn(this.items,l))continue;const d=e.createElement("div");d.className=this.items[l],d.textContent=o[l],this.items[l]==="keys"&&(d.appendChild(document.createElement("code")),d.appendChild(document.createElement("div"))),a.appendChild(d)}return n.prepend(a),t.appendChild(n),new ResizeObserver(l=>{this.items.forEach(u=>{const f=t.querySelector(`.header .${u}`),h=t.querySelector(`.channel .${u}`);f.style.width=h.offsetWidth+"px"});const d=t.querySelector(".header .keys");d.style.display=document.documentElement.clientWidth<=680?"none":"flex"}).observe(t),t}updateSynthElement(e,t,n){if(!this.element)return;const s=this.element.querySelectorAll(".instrument > .channel");if(s[e].dataset.isIntersecting){const i=s[e].querySelector(`.key:nth-child(${t+1})`);n===0?(i.classList.contains("note-on")&&i.classList.remove("note-on"),i.style.opacity="1"):(i.classList.add("note-on"),i.style.opacity=(n/127).toFixed(2))}}updateBankSelect(e){if(!this.element)return;const t=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".bank > select");for(;t.firstChild;)t.removeChild(t.firstChild);for(const n in this.programSet){if(!Object.hasOwn(this.programSet,n))continue;const s=document.createElement("option");s.value=n,s.textContent=("000"+parseInt(n)).slice(-3),parseInt(n)===this.channelBank[e]&&(s.selected=!0),t.appendChild(s)}}updateProgramSelect(e){if(!this.element)return;const t=this.element.querySelectorAll(".instrument > .channel")[e],n=this.channelBank[e],s=t.querySelector(".bank > select"),i=t.querySelector(".program > select");for(s.value=this.channelBank[e].toString();i.firstChild;)i.removeChild(i.firstChild);for(const o in this.programSet[n]){if(!Object.hasOwn(this.programSet[n],o))continue;const a=document.createElement("option");a.value=o,a.textContent=`${("000"+(parseInt(o)+1)).slice(-3)}:${this.programSet[n][o]}`,parseInt(o)===this.channelInstrument[e]&&(a.selected=!0),i.appendChild(a)}}noteOn(e,t,n=100){const s=this.channelBank[e],i=typeof this.bankSet[s]=="object"?this.bankSet[s]:this.bankSet[0];let o;if(typeof i[this.channelInstrument[e]]=="object"?o=i[this.channelInstrument[e]]:this.percussionPart[e]?o=this.bankSet[this.mode==="XG"?127:128][0]:o=this.bankSet[0][this.channelInstrument[e]],o[t]===void 0){console.warn("instrument not found: bank=%s instrument=%s channel=%s key=%s",s,this.channelInstrument[e],e,t);return}const a=o[t];let c=this.channelPanpot[e]===0?Math.floor(Math.random()*127):this.channelPanpot[e]-64;c/=c<0?64:63,a.channel=e,a.key=t,a.velocity=n,a.panpot=c,a.volume=this.channelVolume[e]/127,a.pitchBend=this.channelPitchBend[e]-8192,a.expression=this.channelExpression[e],a.pitchBendSensitivity=Math.round(this.channelPitchBendSensitivity[e]),a.mute=this.channelMute[e],a.releaseTime=this.channelRelease[e],a.cutOffFrequency=this.cutOffFrequency[e],a.harmonicContent=this.harmonicContent[e],a.reverb=this.reverb[e],a.modulation=this.modulation[e],s>=127&&((t===42||t===44)&&this.noteOff(e,46),t===80&&this.noteOff(e,81),o.volume*=this.percussionVolume[t]/127);const l=new Ae(this.ctx,this.gainMaster,a);l.noteOn(),this.currentNoteOn[e].push(l),this.updateSynthElement(e,t,n)}noteOff(e,t){let n,s;const i=this.currentNoteOn[e];let o;const a=this.channelHold[e];for(n=0,s=i.length;n64;let i,o,a;if(!s)for(o=0,a=n.length;o .channel");if(!c[e])return;this.channelHold[e]?c[e].classList.add("hold"):c[e].classList.contains("hold")&&c[e].classList.remove("hold")}}bankSelectMsb(e,t){this.percussionPart[e]=t>=125,this.channelBank[e]=e===9?128:0,this.mode!=="GM"&&(this.mode==="XG"?t===64?this.channelBank[e]=125:t===126||t===127?this.channelBank[e]=t:t===128&&(this.channelBank[e]=127):(this.channelBank[e]=e===9?128:t,this.percussionPart[e]=t===128),this.updateBankSelect(e))}bankSelectLsb(e,t){this.mode==="XG"&&(this.percussionPart[e]||(this.channelBank[e]=t),this.updateBankSelect(e))}programChange(e,t){if(this.channelInstrument[e]=t,this.bankChange(e,this.channelBank[e]),this.element){const n=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".program > select");n.value=t.toString()}}bankChange(e,t){const n=this.mode==="XG"||this.mode==="GM"?127:128;if(this.mode==="GM"&&(t=0),e===9&&(t=n),this.bankSet[t]?this.channelBank[e]=t:this.channelBank[e]=this.percussionPart[e]?n:0,this.element){const s=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".bank > select");s.value=t.toString()}this.updateProgramSelect(e)}volumeChange(e,t){if(this.element){const n=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".volume var");n.innerText=t.toString()}this.channelVolume[e]=t}expression(e,t){let n,s;const i=this.currentNoteOn[e];for(n=0,s=i.length;n .channel")[e].querySelector(".expression var");o.innerText=t.toString()}this.channelExpression[e]=t}panpotChange(e,t){if(this.channelPanpot[e]=t,this.element){const n=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".panpot");n.ariaValueNow=t.toString();const s=n.querySelector(".progress-bar"),i=t/127*100;if(s.style.width=`${i}%`,s.classList.remove("left","right"),s.title=t.toString(),t===64)return;n.classList.add(t<63?"left":"right")}}pitchBend(e,t,n){const s=t&127|(n&127)<<7;let i,o;const a=this.currentNoteOn[e],c=s-8192;for(i=0,o=a.length;i .channel")[e].querySelector(".pitchBend");l.ariaValueNow=s.toString();const d=l.querySelector(".progress-bar");if(d.style.width=`${Math.floor(s/16384*100)}%`,d.title=c.toString(),d.classList.remove("high","low"),c===0)return;d.classList.add(c<0?"low":"high")}}pitchBendSensitivity(e,t){if(this.element){const n=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".pitchBendSensitivity > var");n.innerText=t.toString()}this.channelPitchBendSensitivity[e]=t}attackTime(e,t){this.channelAttack[e]=t}decayTime(e,t){this.channelDecay[e]=t}sustinTime(e,t){this.channelSustin[e]=t}releaseTime(e,t){this.channelRelease[e]=t}harmonicContent(e,t){this.channelHarmonicContent[e]=t}cutOffFrequency(e,t){this.channelCutOffFrequency[e]=t}reverbDepth(e,t){if(this.reverb[e].mix(t/127),this.element){const n=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".reverbDepth var");n.innerText=t.toString()}}modulationDepth(e,t){if(this.element){const n=this.element.querySelectorAll(".instrument > .channel")[e].querySelector(".pitchBend .progress-bar");t!==0?n.classList.add("progress-bar-striped"):n.classList.remove("progress-bar-striped")}this.modulation[e]=t}getPitchBendSensitivity(e){return this.channelPitchBendSensitivity[e]}drumInstrumentLevel(e,t){this.percussionVolume[e]=t}allNoteOff(e){const t=this.currentNoteOn[e];for(this.hold(e,0);t.length>0;)this.noteOff(e,t[0].key)}allSoundOff(e){const t=this.currentNoteOn[e];let n;for(;t.length>0;)n=t.shift(),this.noteOff(e,n.key),n.release(),n.disconnect();this.hold(e,0)}resetAllControl(e){this.allNoteOff(e),this.expression(e,127),this.pitchBend(e,0,64)}mute(e,t){const n=this.currentNoteOn[e];let s,i;if(this.channelMute[e]=t,t)for(s=0,i=n.length;sString.fromCharCode(n)).join(""),this.timer=setTimeout(()=>{t.innerText=""},5e4)}}class _{static CACHE_NAME="wml";constructor(e,t,n,s){this.url=e,this.cache=n,this.callback=s,this.alert=document.createElement("div"),this.alert.className="alert alert-warning",this.message=document.createElement("p"),this.message.innerText="Now Loading...",this.progressOuter=document.createElement("div"),this.progressOuter.className="progress",this.progressOuter.role="progressbar",this.progressOuter.ariaLabel="Loading Progress",this.progressOuter.ariaValueMin="0",this.progressOuter.ariaValueNow="0",this.progressOuter.ariaValueMax="100",this.progress=document.createElement("div"),this.progress.className="progress-bar",this.progressOuter.appendChild(this.progress),this.alert.appendChild(this.message),this.alert.appendChild(this.progressOuter),t.appendChild(this.alert)}onProgress(e,t){const n=Math.floor(e/t*100);this.progress.style.width=`${n}%`,this.progress.innerText=`${n}%`}onComplete(e){this.alert.className="alert alert-info",this.message.innerText="Initializing...",this.progress.className="progress-bar progress-bar-striped progress-bar-animated",this.progress.style.width="100%",this.callback(new Uint8Array(e))}onError(e=void 0){requestAnimationFrame(()=>{this.alert.className="alert alert-danger",this.message.innerText="An error occurred while loading SoundFont. See the console log for details. In addition, it may be cured by deleting the cache of the browser.",this.progressOuter.style.display="none"})}async fetch(){const e=await window.caches.open(_.CACHE_NAME),t=await e.match(this.url);if(this.cache&&t){this.onComplete(await t.arrayBuffer());return}const n=await fetch(this.url,{method:"GET"}).catch(u=>this.onError(u));if(!n||n&&!n.ok)return;const s=n.clone(),i=parseInt(n.headers.get("Content-Length")),o=s.body.getReader();let a=0;const c=[];for(;;){const{done:u,value:f}=await o.read();if(u)break;c.push(f),a+=f.length,this.message.innerText=`Now Loading... (${a} of ${i} byte)`,this.onProgress(a,i)}const l=new Uint8Array(a);let d=0;for(const u of c)l.set(u,d),d+=u.length;await e.put(this.url,n),this.onComplete(l)}}class me{constructor(e={}){this.NrpnMsb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],this.NrpnLsb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],this.RpnMsb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],this.RpnLsb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],this.ready=!1,this.synth=void 0,this.messageHandler=this.onMessage.bind(this),this.rpnMode=!0,this.option={},this.option.drawSynth=e.drawSynth!=="false",this.option.cache=e.cache??!0,this.option.targetOrigin=e.targetOrigin??"*",this.option.colorMode=e.colorMode??"auto",this.url=e.url??"https://cdn.jsdelivr.net/npm/@logue/sf2synth@latest/dist/Yamaha XG Sound Set.sf2",this.placeholder=e.placeholder?document.getElementById(e.placeholder):window.document.body,this.setColorMode(this.option.colorMode),this.window=null,window.opener?this.window=window.opener:window.parent!==window?this.window=window.parent:this.window=window}async setup(e=void 0){for(;this.placeholder.firstChild;)this.placeholder.removeChild(this.placeholder.firstChild);e&&(this.url=e),await new _(this.url,this.placeholder,this.option.cache,n=>this.setupByBuffer(n)).fetch()}getUrl(){return this.url}setupByBuffer(e){for(;this.placeholder.firstChild;)this.placeholder.removeChild(this.placeholder.firstChild);if(this.synth?this.synth.refreshInstruments(e):(this.synth=new Ue(e),this.synth.start()),this.option.drawSynth)this.placeholder.appendChild(this.synth.drawSynth());else{const t=document.createElement("div");t.className="alert alert-success",t.role="alert",t.innerText="Ready.",this.placeholder.appendChild(t)}this.synth.init(),this.onReady()}callback(){}onReady(){window.removeEventListener("message",this.messageHandler),this.callback(),window.addEventListener("message",this.messageHandler,!1),this.window.postMessage("link,ready",this.option.targetOrigin)}onMessage(e){const t=typeof e.data.split=="function"?e.data.split(","):[],n=t.length!==0?t.shift():"";let s;switch(n){case"midi":this.processMidiMessage(t.map(i=>parseInt(i,16)));break;case"link":if(this.window===void 0)return;switch(s=t.shift(),s){case"reqpatch":this.window.postMessage("link,patch",this.option.targetOrigin);break;case"setpatch":case"ready":this.window.postMessage("link,ready",this.option.targetOrigin);break;case"progress":this.window.postMessage("link,progress",this.option.targetOrigin);break;default:console.error("unknown link message:",s);break}break;default:console.error("unknown message type")}}setLoadCallback(e){this.callback=e}processMidiMessage(e){const t=e[0]&15,n=this.synth;switch(e[0]&240){case 128:n.noteOff(t,e[1],e[2]);break;case 144:e[2]>0?n.noteOn(t,e[1],e[2]):n.noteOff(t,e[1],0);break;case 176:{const s=e[2];switch(e[1]){case 0:n.bankSelectMsb(t,s);break;case 1:n.modulationDepth(t,s);break;case 5:break;case 6:if(this.rpnMode)switch(this.RpnMsb[t]){case 0:switch(this.RpnLsb[t]){case 0:n.pitchBendSensitivity(t,s);break}break}else switch(this.NrpnMsb[t]){case 26:n.drumInstrumentLevel(this.NrpnLsb[t],s);break}break;case 38:if(this.rpnMode)switch(this.RpnMsb[t]){case 0:switch(this.RpnLsb[t]){case 0:n.pitchBendSensitivity(t,n.getPitchBendSensitivity(t)+s/100);break}break}break;case 7:n.volumeChange(t,s);break;case 10:n.panpotChange(t,s);break;case 120:n.allSoundOff(t);break;case 121:n.resetAllControl(t);break;case 32:n.bankSelectLsb(t,s);break;case 71:n.harmonicContent(t,s);break;case 96:break;case 97:break;case 98:this.rpnMode=!1,this.NrpnLsb[t]=s;break;case 99:this.rpnMode=!1,this.NrpnMsb[t]=s;break;case 100:this.rpnMode=!0,this.RpnLsb[t]=s;break;case 101:this.rpnMode=!0,this.RpnMsb[t]=s;break;case 64:n.hold(t,s);break;case 11:n.expression(t,s);break;case 72:n.decayTime(t,s);break;case 73:n.releaseTime(t,s);break;case 74:n.attackTime(t,s);break;case 75:n.cutOffFrequency(t,s);break;case 91:n.reverbDepth(t,s);break}break}case 192:n.programChange(t,e[1]);break;case 224:n.pitchBend(t,e[1],e[2]);break;case 240:{e.splice(1,1);const s=e[1],i=e[2],o=e[3];if(s===126||i===9)switch(o){case 1:n.init("GM"),console.info("\x1B[34mGM System On\x1B[0m");break;case 2:console.info("\x1B[34mGM System Off\x1B[0m");break;case 3:console.info("\x1B[34mGM (v2) System On\x1B[0m"),n.init("GM2");break;default:console.log("\x1B[34mGM\x1B[0m: "+this.dumpMessage(e))}else s===127?o===1?n.setMasterVolume(e[4]+(e[5]<<7)):console.log("\x1B[34mRealtime\x1B[0m: "+this.dumpMessage(e)):s===125&&e[4]===1&&(e[5]===1?this.setColorMode("light"):e[5]===2?this.setColorMode("dark"):this.setColorMode("auto"));if(o===66){const a=e[6]-15,c=e[7],l=e[8];switch(c){case 0:if(a===0){const d=e.splice(8);d.pop(),d.pop(),n.processMidiMessage(d)}else console.log("\x1B[31mGS Bitmap message\x1B[0m:"+this.dumpMessage(e));break;case 4:n.setMasterVolume(l*64);break;case 21:{a===0?n.setPercussionPart(9,l!==0):a>=10?n.setPercussionPart(a-1,l!==0):n.setPercussionPart(a,l!==0);break}case 25:console.info("\x1B[31mGS Volume On/Off\x1B[0m: "+a,l);break;case 48:console.info("\x1B[31mGS Reverb\x1B[0m: "+this.dumpMessage(e));break;case 56:console.info("\x1B[31mGS Chorus\x1B[0m: "+this.dumpMessage(e));break;case 69:console.info("\x1B[31mGS Bitmap\x1B[0m: "+this.dumpMessage(e));break;case 127:n.init("GS"),console.info("\x1B[31mGS Reset\x1B[0m");break;default:console.log("\x1B[31mGS\x1B[0m: "+this.dumpMessage(e))}}else if(o===76){const a=e[4],c=e[5];switch(a){case 0:e[6]===126&&(n.init("XG"),console.info("\x1B[32mXG Reset\x1B[0m"));break;case 2:console.log("\x1B[32mXG Effect\x1B[0m: "+this.dumpMessage(e));break;case 3:console.log("\x1B[32mXG Insertion Effect\x1B[0m: "+this.dumpMessage(e));break;case 4:n.setMasterVolume(e[9]*64);break;case 6:{const l=e.splice(8);l.pop(),n.processMidiMessage(l);break}case 7:console.log("\x1B[32mXG Bitmap\x1B[0m: "+this.dumpMessage(e));break;case 8:n.setPercussionPart(c,e[8]!==0);break;default:console.log("\x1B[32mXG\x1B[0m: ",this.dumpMessage(e))}}break}default:n.setPercussionPart(9,!0);break}}dumpMessage(e){const t=[];let n=0;for(const s of e){let i="";switch(n){case 0:i="\x1B[35m";break;case 1:case 2:case 3:i="\x1B[33m";break;default:i=e.length-1===n?"\x1B[35m":"\x1B[36m";break}t.push(i+s.toString(16).toUpperCase().padStart(2,"0")),n++}return t.join(" ")+"\x1B[0m"}setColorMode(e){e?(e==="auto"&&(e=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"),document.documentElement.setAttribute("data-bs-theme",e)):(document.documentElement.setAttribute("data-bs-theme","auto"),document.documentElement.removeAttribute("data-bs-theme"))}}class _e extends me{constructor(e={}){super(e),this.midi=void 0}async setup(e){this.midi=await window.navigator.requestMIDIAccess({sysex:!0}),await super.setup(e)}onReady(){super.callback(),this.midi.inputs.forEach(e=>e.onmidimessage=t=>super.processMidiMessage(Array.from(t.data)))}}const te={version:"0.6.2",date:"2023-11-29T01:17:37.499Z"},$={version:te.version,build:te.date,WebMidiLink:me,WebMidiApi:_e,Parser:R};let pe={drawSynth:!0,placeholder:"placeholder",colorMode:"auto",...q.parse(window.location.search),...q.parse(window.location.hash)};const O=new $.WebMidiLink(pe);document.addEventListener("DOMContentLoaded",r=>{const e=document.getElementById("file"),t=document.getElementById("drag"),n=document.getElementById("build"),s=document.getElementById("toggleDarkMode");O.setLoadCallback(()=>{t.classList.remove("bg-info"),document.getElementById("soundfont").innerText=decodeURIComponent(O.getUrl()).match(".+/(.+?)([?#;].*)?$")[1]}),n.dateTime=$.build,n.innerText=new Date($.build).toLocaleString(),O.setup();const i=window.matchMedia("(prefers-color-scheme: dark)");i.addListener(()=>{document.documentElement.getAttribute("data-bs-theme")||(O.setColorMode(pe.colorMode),s.checked=i.matches)});const o=a=>{const c=new FileReader;c.readAsArrayBuffer(a),c.onload=l=>{document.getElementById("soundfont").innerText=a.name;const d=new Uint8Array(l.target.result);O.setupByBuffer(d)}};e.addEventListener("change",a=>{a.preventDefault(),o(e.files[0]),e.value=""},!1),t.addEventListener("drop",a=>{const c=a.dataTransfer;c.files.length&&(a.preventDefault(),a.stopPropagation(),o(c.files[0])),t.classList.remove("bg-info")},!1),t.addEventListener("dragover",a=>{a.preventDefault(),a.stopPropagation(),t.classList.add("bg-info")},!1),t.addEventListener("dragleave",a=>{a.preventDefault(),a.stopPropagation(),t.classList.remove("bg-info")},!1),s.addEventListener("change",a=>{O.setColorMode(a.target.checked?"dark":"light")})},!1);window.addEventListener("hashchange",()=>{const r=q.parse(window.location.hash);r&&O.setup(r)},!1); +//# sourceMappingURL=index-LPfJkeRA.js.map diff --git a/assets/index-toxedflk.js.map b/assets/index-LPfJkeRA.js.map similarity index 99% rename from assets/index-toxedflk.js.map rename to assets/index-LPfJkeRA.js.map index ca4d5ab..d248d05 100644 --- a/assets/index-toxedflk.js.map +++ b/assets/index-LPfJkeRA.js.map @@ -1 +1 @@ -{"version":3,"file":"index-toxedflk.js","sources":["../../node_modules/decode-uri-component/index.js","../../node_modules/split-on-first/index.js","../../node_modules/filter-obj/index.js","../../node_modules/query-string/base.js","../../src/sound_font_synth_note.js","../../node_modules/@logue/reverb/dist/Reverb.es.js","../../src/riff.js","../../src/sf2.js","../../src/sound_font_synth.js","../../src/loader.js","../../src/wml.js","../../src/web_midi_api.js","../../src/meta.js","../../src/index.js","../../index.html?html-proxy&index=0.js"],"sourcesContent":["const token = '%[a-f0-9]{2}';\nconst singleMatcher = new RegExp('(' + token + ')|([^%]+?)', 'gi');\nconst multiMatcher = new RegExp('(' + token + ')+', 'gi');\n\nfunction decodeComponents(components, split) {\n\ttry {\n\t\t// Try to decode the entire string first\n\t\treturn [decodeURIComponent(components.join(''))];\n\t} catch {\n\t\t// Do nothing\n\t}\n\n\tif (components.length === 1) {\n\t\treturn components;\n\t}\n\n\tsplit = split || 1;\n\n\t// Split the array in 2 parts\n\tconst left = components.slice(0, split);\n\tconst right = components.slice(split);\n\n\treturn Array.prototype.concat.call([], decodeComponents(left), decodeComponents(right));\n}\n\nfunction decode(input) {\n\ttry {\n\t\treturn decodeURIComponent(input);\n\t} catch {\n\t\tlet tokens = input.match(singleMatcher) || [];\n\n\t\tfor (let i = 1; i < tokens.length; i++) {\n\t\t\tinput = decodeComponents(tokens, i).join('');\n\n\t\t\ttokens = input.match(singleMatcher) || [];\n\t\t}\n\n\t\treturn input;\n\t}\n}\n\nfunction customDecodeURIComponent(input) {\n\t// Keep track of all the replacements and prefill the map with the `BOM`\n\tconst replaceMap = {\n\t\t'%FE%FF': '\\uFFFD\\uFFFD',\n\t\t'%FF%FE': '\\uFFFD\\uFFFD',\n\t};\n\n\tlet match = multiMatcher.exec(input);\n\twhile (match) {\n\t\ttry {\n\t\t\t// Decode as big chunks as possible\n\t\t\treplaceMap[match[0]] = decodeURIComponent(match[0]);\n\t\t} catch {\n\t\t\tconst result = decode(match[0]);\n\n\t\t\tif (result !== match[0]) {\n\t\t\t\treplaceMap[match[0]] = result;\n\t\t\t}\n\t\t}\n\n\t\tmatch = multiMatcher.exec(input);\n\t}\n\n\t// Add `%C2` at the end of the map to make sure it does not replace the combinator before everything else\n\treplaceMap['%C2'] = '\\uFFFD';\n\n\tconst entries = Object.keys(replaceMap);\n\n\tfor (const key of entries) {\n\t\t// Replace all decoded components\n\t\tinput = input.replace(new RegExp(key, 'g'), replaceMap[key]);\n\t}\n\n\treturn input;\n}\n\nexport default function decodeUriComponent(encodedURI) {\n\tif (typeof encodedURI !== 'string') {\n\t\tthrow new TypeError('Expected `encodedURI` to be of type `string`, got `' + typeof encodedURI + '`');\n\t}\n\n\ttry {\n\t\t// Try the built in decoder first\n\t\treturn decodeURIComponent(encodedURI);\n\t} catch {\n\t\t// Fallback to a more advanced decoder\n\t\treturn customDecodeURIComponent(encodedURI);\n\t}\n}\n","export default function splitOnFirst(string, separator) {\n\tif (!(typeof string === 'string' && typeof separator === 'string')) {\n\t\tthrow new TypeError('Expected the arguments to be of type `string`');\n\t}\n\n\tif (string === '' || separator === '') {\n\t\treturn [];\n\t}\n\n\tconst separatorIndex = string.indexOf(separator);\n\n\tif (separatorIndex === -1) {\n\t\treturn [];\n\t}\n\n\treturn [\n\t\tstring.slice(0, separatorIndex),\n\t\tstring.slice(separatorIndex + separator.length)\n\t];\n}\n","export function includeKeys(object, predicate) {\n\tconst result = {};\n\n\tif (Array.isArray(predicate)) {\n\t\tfor (const key of predicate) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(object, key);\n\t\t\tif (descriptor?.enumerable) {\n\t\t\t\tObject.defineProperty(result, key, descriptor);\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// `Reflect.ownKeys()` is required to retrieve symbol properties\n\t\tfor (const key of Reflect.ownKeys(object)) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(object, key);\n\t\t\tif (descriptor.enumerable) {\n\t\t\t\tconst value = object[key];\n\t\t\t\tif (predicate(key, value, object)) {\n\t\t\t\t\tObject.defineProperty(result, key, descriptor);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function excludeKeys(object, predicate) {\n\tif (Array.isArray(predicate)) {\n\t\tconst set = new Set(predicate);\n\t\treturn includeKeys(object, key => !set.has(key));\n\t}\n\n\treturn includeKeys(object, (key, value, object) => !predicate(key, value, object));\n}\n","import decodeComponent from 'decode-uri-component';\nimport splitOnFirst from 'split-on-first';\nimport {includeKeys} from 'filter-obj';\n\nconst isNullOrUndefined = value => value === null || value === undefined;\n\n// eslint-disable-next-line unicorn/prefer-code-point\nconst strictUriEncode = string => encodeURIComponent(string).replace(/[!'()*]/g, x => `%${x.charCodeAt(0).toString(16).toUpperCase()}`);\n\nconst encodeFragmentIdentifier = Symbol('encodeFragmentIdentifier');\n\nfunction encoderForArrayFormat(options) {\n\tswitch (options.arrayFormat) {\n\t\tcase 'index': {\n\t\t\treturn key => (result, value) => {\n\t\t\t\tconst index = result.length;\n\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| (options.skipNull && value === null)\n\t\t\t\t\t|| (options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...result, [encode(key, options), '[', index, ']'].join(''),\n\t\t\t\t\t];\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\t...result,\n\t\t\t\t\t[encode(key, options), '[', encode(index, options), ']=', encode(value, options)].join(''),\n\t\t\t\t];\n\t\t\t};\n\t\t}\n\n\t\tcase 'bracket': {\n\t\t\treturn key => (result, value) => {\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| (options.skipNull && value === null)\n\t\t\t\t\t|| (options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...result,\n\t\t\t\t\t\t[encode(key, options), '[]'].join(''),\n\t\t\t\t\t];\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\t...result,\n\t\t\t\t\t[encode(key, options), '[]=', encode(value, options)].join(''),\n\t\t\t\t];\n\t\t\t};\n\t\t}\n\n\t\tcase 'colon-list-separator': {\n\t\t\treturn key => (result, value) => {\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| (options.skipNull && value === null)\n\t\t\t\t\t|| (options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...result,\n\t\t\t\t\t\t[encode(key, options), ':list='].join(''),\n\t\t\t\t\t];\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\t...result,\n\t\t\t\t\t[encode(key, options), ':list=', encode(value, options)].join(''),\n\t\t\t\t];\n\t\t\t};\n\t\t}\n\n\t\tcase 'comma':\n\t\tcase 'separator':\n\t\tcase 'bracket-separator': {\n\t\t\tconst keyValueSep = options.arrayFormat === 'bracket-separator'\n\t\t\t\t? '[]='\n\t\t\t\t: '=';\n\n\t\t\treturn key => (result, value) => {\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| (options.skipNull && value === null)\n\t\t\t\t\t|| (options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\t// Translate null to an empty string so that it doesn't serialize as 'null'\n\t\t\t\tvalue = value === null ? '' : value;\n\n\t\t\t\tif (result.length === 0) {\n\t\t\t\t\treturn [[encode(key, options), keyValueSep, encode(value, options)].join('')];\n\t\t\t\t}\n\n\t\t\t\treturn [[result, encode(value, options)].join(options.arrayFormatSeparator)];\n\t\t\t};\n\t\t}\n\n\t\tdefault: {\n\t\t\treturn key => (result, value) => {\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| (options.skipNull && value === null)\n\t\t\t\t\t|| (options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...result,\n\t\t\t\t\t\tencode(key, options),\n\t\t\t\t\t];\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\t...result,\n\t\t\t\t\t[encode(key, options), '=', encode(value, options)].join(''),\n\t\t\t\t];\n\t\t\t};\n\t\t}\n\t}\n}\n\nfunction parserForArrayFormat(options) {\n\tlet result;\n\n\tswitch (options.arrayFormat) {\n\t\tcase 'index': {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tresult = /\\[(\\d*)]$/.exec(key);\n\n\t\t\t\tkey = key.replace(/\\[\\d*]$/, '');\n\n\t\t\t\tif (!result) {\n\t\t\t\t\taccumulator[key] = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = {};\n\t\t\t\t}\n\n\t\t\t\taccumulator[key][result[1]] = value;\n\t\t\t};\n\t\t}\n\n\t\tcase 'bracket': {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tresult = /(\\[])$/.exec(key);\n\t\t\t\tkey = key.replace(/\\[]$/, '');\n\n\t\t\t\tif (!result) {\n\t\t\t\t\taccumulator[key] = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = [value];\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\taccumulator[key] = [...accumulator[key], value];\n\t\t\t};\n\t\t}\n\n\t\tcase 'colon-list-separator': {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tresult = /(:list)$/.exec(key);\n\t\t\t\tkey = key.replace(/:list$/, '');\n\n\t\t\t\tif (!result) {\n\t\t\t\t\taccumulator[key] = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = [value];\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\taccumulator[key] = [...accumulator[key], value];\n\t\t\t};\n\t\t}\n\n\t\tcase 'comma':\n\t\tcase 'separator': {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tconst isArray = typeof value === 'string' && value.includes(options.arrayFormatSeparator);\n\t\t\t\tconst isEncodedArray = (typeof value === 'string' && !isArray && decode(value, options).includes(options.arrayFormatSeparator));\n\t\t\t\tvalue = isEncodedArray ? decode(value, options) : value;\n\t\t\t\tconst newValue = isArray || isEncodedArray ? value.split(options.arrayFormatSeparator).map(item => decode(item, options)) : (value === null ? value : decode(value, options));\n\t\t\t\taccumulator[key] = newValue;\n\t\t\t};\n\t\t}\n\n\t\tcase 'bracket-separator': {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tconst isArray = /(\\[])$/.test(key);\n\t\t\t\tkey = key.replace(/\\[]$/, '');\n\n\t\t\t\tif (!isArray) {\n\t\t\t\t\taccumulator[key] = value ? decode(value, options) : value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst arrayValue = value === null\n\t\t\t\t\t? []\n\t\t\t\t\t: value.split(options.arrayFormatSeparator).map(item => decode(item, options));\n\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = arrayValue;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\taccumulator[key] = [...accumulator[key], ...arrayValue];\n\t\t\t};\n\t\t}\n\n\t\tdefault: {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\taccumulator[key] = [...[accumulator[key]].flat(), value];\n\t\t\t};\n\t\t}\n\t}\n}\n\nfunction validateArrayFormatSeparator(value) {\n\tif (typeof value !== 'string' || value.length !== 1) {\n\t\tthrow new TypeError('arrayFormatSeparator must be single character string');\n\t}\n}\n\nfunction encode(value, options) {\n\tif (options.encode) {\n\t\treturn options.strict ? strictUriEncode(value) : encodeURIComponent(value);\n\t}\n\n\treturn value;\n}\n\nfunction decode(value, options) {\n\tif (options.decode) {\n\t\treturn decodeComponent(value);\n\t}\n\n\treturn value;\n}\n\nfunction keysSorter(input) {\n\tif (Array.isArray(input)) {\n\t\treturn input.sort();\n\t}\n\n\tif (typeof input === 'object') {\n\t\treturn keysSorter(Object.keys(input))\n\t\t\t.sort((a, b) => Number(a) - Number(b))\n\t\t\t.map(key => input[key]);\n\t}\n\n\treturn input;\n}\n\nfunction removeHash(input) {\n\tconst hashStart = input.indexOf('#');\n\tif (hashStart !== -1) {\n\t\tinput = input.slice(0, hashStart);\n\t}\n\n\treturn input;\n}\n\nfunction getHash(url) {\n\tlet hash = '';\n\tconst hashStart = url.indexOf('#');\n\tif (hashStart !== -1) {\n\t\thash = url.slice(hashStart);\n\t}\n\n\treturn hash;\n}\n\nfunction parseValue(value, options) {\n\tif (options.parseNumbers && !Number.isNaN(Number(value)) && (typeof value === 'string' && value.trim() !== '')) {\n\t\tvalue = Number(value);\n\t} else if (options.parseBooleans && value !== null && (value.toLowerCase() === 'true' || value.toLowerCase() === 'false')) {\n\t\tvalue = value.toLowerCase() === 'true';\n\t}\n\n\treturn value;\n}\n\nexport function extract(input) {\n\tinput = removeHash(input);\n\tconst queryStart = input.indexOf('?');\n\tif (queryStart === -1) {\n\t\treturn '';\n\t}\n\n\treturn input.slice(queryStart + 1);\n}\n\nexport function parse(query, options) {\n\toptions = {\n\t\tdecode: true,\n\t\tsort: true,\n\t\tarrayFormat: 'none',\n\t\tarrayFormatSeparator: ',',\n\t\tparseNumbers: false,\n\t\tparseBooleans: false,\n\t\t...options,\n\t};\n\n\tvalidateArrayFormatSeparator(options.arrayFormatSeparator);\n\n\tconst formatter = parserForArrayFormat(options);\n\n\t// Create an object with no prototype\n\tconst returnValue = Object.create(null);\n\n\tif (typeof query !== 'string') {\n\t\treturn returnValue;\n\t}\n\n\tquery = query.trim().replace(/^[?#&]/, '');\n\n\tif (!query) {\n\t\treturn returnValue;\n\t}\n\n\tfor (const parameter of query.split('&')) {\n\t\tif (parameter === '') {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst parameter_ = options.decode ? parameter.replace(/\\+/g, ' ') : parameter;\n\n\t\tlet [key, value] = splitOnFirst(parameter_, '=');\n\n\t\tif (key === undefined) {\n\t\t\tkey = parameter_;\n\t\t}\n\n\t\t// Missing `=` should be `null`:\n\t\t// http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters\n\t\tvalue = value === undefined ? null : (['comma', 'separator', 'bracket-separator'].includes(options.arrayFormat) ? value : decode(value, options));\n\t\tformatter(decode(key, options), value, returnValue);\n\t}\n\n\tfor (const [key, value] of Object.entries(returnValue)) {\n\t\tif (typeof value === 'object' && value !== null) {\n\t\t\tfor (const [key2, value2] of Object.entries(value)) {\n\t\t\t\tvalue[key2] = parseValue(value2, options);\n\t\t\t}\n\t\t} else {\n\t\t\treturnValue[key] = parseValue(value, options);\n\t\t}\n\t}\n\n\tif (options.sort === false) {\n\t\treturn returnValue;\n\t}\n\n\t// TODO: Remove the use of `reduce`.\n\t// eslint-disable-next-line unicorn/no-array-reduce\n\treturn (options.sort === true ? Object.keys(returnValue).sort() : Object.keys(returnValue).sort(options.sort)).reduce((result, key) => {\n\t\tconst value = returnValue[key];\n\t\tif (Boolean(value) && typeof value === 'object' && !Array.isArray(value)) {\n\t\t\t// Sort object keys, not values\n\t\t\tresult[key] = keysSorter(value);\n\t\t} else {\n\t\t\tresult[key] = value;\n\t\t}\n\n\t\treturn result;\n\t}, Object.create(null));\n}\n\nexport function stringify(object, options) {\n\tif (!object) {\n\t\treturn '';\n\t}\n\n\toptions = {encode: true,\n\t\tstrict: true,\n\t\tarrayFormat: 'none',\n\t\tarrayFormatSeparator: ',', ...options};\n\n\tvalidateArrayFormatSeparator(options.arrayFormatSeparator);\n\n\tconst shouldFilter = key => (\n\t\t(options.skipNull && isNullOrUndefined(object[key]))\n\t\t|| (options.skipEmptyString && object[key] === '')\n\t);\n\n\tconst formatter = encoderForArrayFormat(options);\n\n\tconst objectCopy = {};\n\n\tfor (const [key, value] of Object.entries(object)) {\n\t\tif (!shouldFilter(key)) {\n\t\t\tobjectCopy[key] = value;\n\t\t}\n\t}\n\n\tconst keys = Object.keys(objectCopy);\n\n\tif (options.sort !== false) {\n\t\tkeys.sort(options.sort);\n\t}\n\n\treturn keys.map(key => {\n\t\tconst value = object[key];\n\n\t\tif (value === undefined) {\n\t\t\treturn '';\n\t\t}\n\n\t\tif (value === null) {\n\t\t\treturn encode(key, options);\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tif (value.length === 0 && options.arrayFormat === 'bracket-separator') {\n\t\t\t\treturn encode(key, options) + '[]';\n\t\t\t}\n\n\t\t\treturn value\n\t\t\t\t.reduce(formatter(key), [])\n\t\t\t\t.join('&');\n\t\t}\n\n\t\treturn encode(key, options) + '=' + encode(value, options);\n\t}).filter(x => x.length > 0).join('&');\n}\n\nexport function parseUrl(url, options) {\n\toptions = {\n\t\tdecode: true,\n\t\t...options,\n\t};\n\n\tlet [url_, hash] = splitOnFirst(url, '#');\n\n\tif (url_ === undefined) {\n\t\turl_ = url;\n\t}\n\n\treturn {\n\t\turl: url_?.split('?')?.[0] ?? '',\n\t\tquery: parse(extract(url), options),\n\t\t...(options && options.parseFragmentIdentifier && hash ? {fragmentIdentifier: decode(hash, options)} : {}),\n\t};\n}\n\nexport function stringifyUrl(object, options) {\n\toptions = {\n\t\tencode: true,\n\t\tstrict: true,\n\t\t[encodeFragmentIdentifier]: true,\n\t\t...options,\n\t};\n\n\tconst url = removeHash(object.url).split('?')[0] || '';\n\tconst queryFromUrl = extract(object.url);\n\n\tconst query = {\n\t\t...parse(queryFromUrl, {sort: false}),\n\t\t...object.query,\n\t};\n\n\tlet queryString = stringify(query, options);\n\tif (queryString) {\n\t\tqueryString = `?${queryString}`;\n\t}\n\n\tlet hash = getHash(object.url);\n\tif (object.fragmentIdentifier) {\n\t\tconst urlObjectForFragmentEncode = new URL(url);\n\t\turlObjectForFragmentEncode.hash = object.fragmentIdentifier;\n\t\thash = options[encodeFragmentIdentifier] ? urlObjectForFragmentEncode.hash : `#${object.fragmentIdentifier}`;\n\t}\n\n\treturn `${url}${queryString}${hash}`;\n}\n\nexport function pick(input, filter, options) {\n\toptions = {\n\t\tparseFragmentIdentifier: true,\n\t\t[encodeFragmentIdentifier]: false,\n\t\t...options,\n\t};\n\n\tconst {url, query, fragmentIdentifier} = parseUrl(input, options);\n\n\treturn stringifyUrl({\n\t\turl,\n\t\tquery: includeKeys(query, filter),\n\t\tfragmentIdentifier,\n\t}, options);\n}\n\nexport function exclude(input, filter, options) {\n\tconst exclusionFilter = Array.isArray(filter) ? key => !filter.includes(key) : (key, value) => !filter(key, value);\n\n\treturn pick(input, exclusionFilter, options);\n}\n","/**\n * SynthesizerNote Class\n *\n * @author imaya\n * @private\n */\nexport default class SynthesizerNote {\n /**\n * @param {AudioContext} ctx\n * @param {AudioNode} destination\n * @param {{\n * channel: number;\n * key: number;\n * sample: Uint8Array;\n * basePlaybackRate: number;\n * loopStart: number;\n * loopEnd: number;\n * volume: number;\n * panpot: number;\n * }} instrument\n */\n constructor(ctx, destination, instrument) {\n /** @type {AudioContext} */\n this.ctx = ctx;\n /** @type {AudioNode} */\n this.destination = destination;\n /**\n * @type {{\n * channel: number;\n * key: number;\n * sample: Uint8Array;\n * basePlaybackRate: number;\n * loopStart: number;\n * loopEnd: number;\n * volume: number;\n * panpot: number;\n * }}\n */\n this.instrument = instrument;\n /** @type {number} */\n this.channel = instrument['channel'];\n /** @type {number} */\n this.key = instrument['key'];\n /** @type {number} */\n this.velocity = instrument['velocity'];\n /** @type {Uint8Array} */\n this.buffer = instrument['sample'];\n /** @type {number} */\n this.playbackRate = instrument['basePlaybackRate'];\n /** @type {number} */\n this.loopStart = instrument['loopStart'];\n /** @type {number} */\n this.loopEnd = instrument['loopEnd'];\n /** @type {number} */\n this.sampleRate = instrument['sampleRate'];\n /** @type {number} */\n this.volume = instrument['volume'];\n /** @type {number} */\n this.panpot = instrument['panpot'];\n /** @type {number} */\n this.pitchBend = instrument['pitchBend'];\n /** @type {number} */\n this.pitchBendSensitivity = instrument['pitchBendSensitivity'];\n /** @type {number} */\n this.modEnvToPitch = instrument['modEnvToPitch'];\n /** @type {number} */\n this.expression = instrument['expression'];\n /** @type {number} */\n this.modulation = instrument['modulation'];\n /** @type {number} */\n this.cutOffFrequency = instrument['cutOffFrequency'];\n /** @type {number} */\n this.hermonicContent = instrument['hermonicContent'];\n\n /** @type {import('@logue/reverb').default} */\n this.reverb = instrument['reverb'];\n\n // state\n /** @type {number} */\n this.startTime = ctx.currentTime;\n /** @type {number} */\n this.computedPlaybackRate = this.playbackRate | 0;\n /** @type {boolean} */\n this.noteOffState = false;\n\n // ---------------------------------------------------------------------------\n // audio node\n // ---------------------------------------------------------------------------\n\n /** @type {AudioBuffer} */\n this.audioBuffer = null;\n /** @type {AudioBufferSourceNode} */\n this.bufferSource = ctx.createBufferSource();\n /** @type {PannerNode} */\n this.panner = ctx.createPanner();\n /** @type {GainNode} */\n this.outputGainNode = ctx.createGain();\n /** @type {GainNode} */\n this.expressionGainNode = ctx.createGain();\n /** @type {BiquadFilterNode} */\n this.filter = ctx.createBiquadFilter();\n /** @type {BiquadFilterNode} */\n this.modulator = ctx.createBiquadFilter();\n }\n\n /** Note on */\n noteOn() {\n /** @type {AudioContext} */\n const ctx = this.ctx;\n /**\n * @type {{\n * channel: number;\n * key: number;\n * sample: Uint8Array;\n * basePlaybackRate: number;\n * loopStart: number;\n * loopEnd: number;\n * volume: number;\n * panpot: number;\n * }}\n */\n const instrument = this.instrument;\n /** @type {number} */\n const now = this.ctx.currentTime || 0;\n /** @type {number} */\n const volDelay = now + instrument['volDelay'];\n /** @type {number} */\n const modDelay = now + instrument['modDelay'];\n /** @type {number} */\n const volAttack = volDelay + instrument['volAttack'];\n /** @type {number} */\n const modAttack = volDelay + instrument['modAttack'];\n /** @type {number} */\n const volHold = volAttack + instrument['volHold'];\n /** @type {number} */\n const modHold = modAttack + instrument['modHold'];\n /** @type {number} */\n const volDecay = volHold + instrument['volDecay'];\n /** @type {number} */\n const modDecay = modHold + instrument['modDecay'];\n /** @type {number} */\n const loopStart = instrument['loopStart'] / this.sampleRate;\n /** @type {number} */\n const loopEnd = instrument['loopEnd'] / this.sampleRate;\n /** @type {number} */\n const startTime = instrument['start'] / this.sampleRate;\n // TODO: ドラムパートのPanが変化した場合、その計算をしなければならない\n // http://cpansearch.perl.org/src/PJB/MIDI-SoundFont-1.08/doc/sfspec21.html#8.4.6\n /** @type {number} */\n const pan = instrument['pan'] !== 0 ? instrument['pan'] : this.panpot;\n\n const sample = this.buffer.subarray(\n 0,\n this.buffer.length + instrument['end']\n );\n /** @type {AudioBuffer} */\n const buffer = (this.audioBuffer = ctx.createBuffer(\n 1,\n sample.length,\n this.sampleRate\n ));\n /** @type {Float32Array} */\n const channelData = buffer.getChannelData(0);\n channelData.set(sample);\n\n // buffer source\n /** @type {AudioBufferSourceNode} */\n const bufferSource = this.bufferSource;\n bufferSource.buffer = buffer;\n bufferSource.loop = instrument['sampleModes'] || 0;\n bufferSource.loopStart = loopStart;\n bufferSource.loopEnd = loopEnd;\n this.updatePitchBend(this.pitchBend);\n\n // Output\n /** @type {GainNode} */\n const output = this.outputGainNode;\n\n // expression\n this.expressionGainNode.gain.value = this.expression / 127;\n\n // panpot\n /** @type {PannerNode} */\n const panner = this.panner;\n panner.panningModel = 'equalpower';\n panner.distanceModel = 'inverse';\n panner.positionX.setValueAtTime(Math.sin((pan * Math.PI) / 2), 0);\n panner.positionY.setValueAtTime(0, 0);\n panner.positionZ.setValueAtTime(Math.cos((pan * Math.PI) / 2), 0);\n\n // ---------------------------------------------------------------------------\n // Delay, Attack, Hold, Decay, Sustain\n // ---------------------------------------------------------------------------\n\n /** @type {number} */\n let volume =\n this.volume *\n (this.velocity / 127) *\n (1 - instrument['initialAttenuation'] / 1000);\n if (volume < 0) {\n volume = 0;\n }\n\n /** @type {AudioParam} volume envelope */\n const outputGain = output.gain;\n outputGain.setValueAtTime(0, now);\n outputGain.setValueAtTime(0, volDelay);\n outputGain.setTargetAtTime(volume, volDelay, instrument['volAttack']);\n outputGain.setValueAtTime(volume, volHold);\n outputGain.linearRampToValueAtTime(\n volume * (1 - instrument['volSustain']),\n volDecay\n );\n\n // modulation envelope\n /** @type {number} */\n const baseFreq = instrument['initialFilterFc'];\n /** @type {number} */\n const peekFreq =\n instrument['initialFilterFc'] + instrument['modEnvToFilterFc'];\n /** @type {number} */\n const sustainFreq =\n baseFreq + (peekFreq - baseFreq) * (1 - instrument['modSustain']);\n\n /** @type {BiquadFilterNode} */\n const modulator = this.modulator;\n modulator.Q.setValueAtTime(10 ** (instrument['initialFilterQ'] / 200), now);\n modulator.frequency.value = baseFreq;\n modulator.type = 'lowpass';\n modulator.frequency.setTargetAtTime(\n baseFreq / 127,\n this.ctx.currentTime,\n 0.5\n );\n modulator.frequency.setValueAtTime(baseFreq, now);\n modulator.frequency.setValueAtTime(baseFreq, modDelay);\n modulator.frequency.setTargetAtTime(\n peekFreq,\n modDelay,\n parseFloat(instrument['modAttack'])\n );\n modulator.frequency.setValueAtTime(peekFreq, modHold);\n modulator.frequency.exponentialRampToValueAtTime(sustainFreq, modDecay);\n\n // Vibrato\n /* * @type {GainNode} LFO Depth * /\n const lfoDepth = this.ctx.createGain();\n /* * @type {OscillatorNode} LFO Oscillator * /\n const lfo = this.ctx.createOscillator();\n // Set parameters for LFO\n lfo.type = 'sine';\n lfoDepth.gain.value = 1;\n lfo.frequency.value = this.instrument['freqVibLFO'];\n\n if (this.modulation) {\n // Effector (Vibrato) ON\n lfo.start(0);\n } else {\n // Effector (Vibrato) Off\n lfo.stop(0);\n }\n // OscillatorNode (LFO) -> GainNode (Depth) -> frequency (AudioParam)\n lfo.connect(lfoDepth);\n\n // connect\n bufferSource.connect(lfoDepth);\n lfoDepth.connect(modulator);\n modulator.connect(panner);\n panner.connect(this.expressionGainNode);\n */\n bufferSource.connect(modulator);\n modulator.connect(panner);\n panner.connect(this.expressionGainNode);\n\n if (!instrument['mute']) {\n this.connect();\n }\n\n this.expressionGainNode.connect(output);\n\n // fire\n bufferSource.start(0, startTime);\n }\n\n /**\n * @param {number} val\n * @return {number}\n */\n amountToFreq(val) {\n return 2 ** ((val - 6900) / 1200) * 440;\n }\n\n /** Note off */\n noteOff() {\n this.noteOffState = true;\n }\n\n /** @return {boolean} */\n isNoteOff() {\n return this.noteOffState;\n }\n\n /** @return {void} */\n release() {\n /**\n * @type {{\n * channel: number;\n * key: number;\n * sample: Uint8Array;\n * basePlaybackRate: number;\n * loopStart: number;\n * loopEnd: number;\n * volume: number;\n * panpot: number;\n * }}\n */\n const instrument = this.instrument;\n /** @type {AudioBufferSourceNode} */\n const bufferSource = this.bufferSource;\n /** @type {GainNode} */\n const output = this.outputGainNode;\n /** @type {number} */\n const now = this.ctx.currentTime;\n /** @type {number} */\n const release = instrument['releaseTime'] - 64;\n\n // ---------------------------------------------------------------------------\n // volume release time\n // ---------------------------------------------------------------------------\n /** @type {number} */\n const volEndTimeTmp = instrument['volRelease'] * output.gain.value;\n /** @type {number} */\n const volEndTime =\n now + volEndTimeTmp * (1 + release / (release < 0 ? 64 : 63));\n // now + instrument['volRelease'] * (1 - instrument['volSustain']);\n\n // ---------------------------------------------------------------------------\n // modulation release time\n // ---------------------------------------------------------------------------\n /** @type {BiquadFilterNode} */\n const modulator = this.modulator;\n /** @type {number} */\n const baseFreq = instrument['initialFilterFc'];\n /** @type {number} */\n const peekFreq =\n instrument['initialFilterFc'] + instrument['modEnvToFilterFc'];\n /** @type {number} */\n const modEndTime =\n now +\n instrument['modRelease'] *\n (baseFreq === peekFreq\n ? 1\n : (modulator.frequency.value - baseFreq) / (peekFreq - baseFreq));\n\n // const modEndTime =\n // now + instrument['modRelease'] * (1 - instrument['modSustain']);\n\n if (!this.audioBuffer) {\n return;\n }\n\n // ---------------------------------------------------------------------------\n // Release\n // ---------------------------------------------------------------------------\n\n switch (instrument['sampleModes']) {\n case 0:\n // ループしない\n bufferSource.loop = false;\n break;\n case 1:\n // ループさせる\n output.gain.cancelScheduledValues(0);\n output.gain.setValueAtTime(output.gain.value, now);\n output.gain.linearRampToValueAtTime(0, volEndTime);\n\n modulator.frequency.cancelScheduledValues(0);\n modulator.frequency.setValueAtTime(modulator.frequency.value, now);\n modulator.frequency.exponentialRampToValueAtTime(baseFreq, modEndTime);\n\n bufferSource.playbackRate.cancelScheduledValues(0);\n bufferSource.playbackRate.setValueAtTime(\n bufferSource.playbackRate.value,\n now\n );\n bufferSource.playbackRate.exponentialRampToValueAtTime(\n this.computedPlaybackRate,\n modEndTime\n );\n\n bufferSource.stop(volEndTime);\n break;\n case 2:\n // 未定義\n throw Error('[SynthesizerNote] Detect unused sampleModes');\n case 3:\n // ノートオフまでループさせる\n output.gain.cancelScheduledValues(0);\n output.gain.setValueAtTime(output.gain.value, now);\n output.gain.linearRampToValueAtTime(0, volEndTime);\n\n modulator.frequency.cancelScheduledValues(0);\n modulator.frequency.setValueAtTime(modulator.frequency.value, now);\n modulator.frequency.exponentialRampToValueAtTime(baseFreq, modEndTime);\n\n bufferSource.playbackRate.cancelScheduledValues(0);\n bufferSource.playbackRate.setValueAtTime(\n bufferSource.playbackRate.value,\n now\n );\n bufferSource.playbackRate.exponentialRampToValueAtTime(\n this.computedPlaybackRate,\n modEndTime\n );\n bufferSource.loop = false;\n bufferSource.buffer = null;\n break;\n default:\n throw Error(\n `[SynthesizerNote] ${instrument['sampleModes']} is undefined sampleModes.`\n );\n }\n }\n\n /** Connect AudioContext */\n connect() {\n this.reverb.connect(this.outputGainNode).connect(this.destination);\n }\n\n /** Disconnect AudioContext */\n disconnect() {\n this.outputGainNode.disconnect(0);\n }\n\n /** Caluclate playback rate */\n schedulePlaybackRate() {\n /** @type {AudioParam} */\n const playbackRate = this.bufferSource.playbackRate;\n /** @type {number} */\n const computed = this.computedPlaybackRate;\n /** @type {number} */\n const start = this.startTime;\n /** @type {Object} */\n const instrument = this.instrument;\n /** @type {number} */\n const modAttack = start + instrument['modAttack'];\n /** @type {number} */\n const modDecay = modAttack + instrument['modDecay'];\n /** @type {number} */\n const peekPitch =\n computed *\n 1.0594630943592953 ** // Math.pow(2, 1 / 12)\n (this.modEnvToPitch * this.instrument['scaleTuning']);\n\n playbackRate.cancelScheduledValues(0);\n playbackRate.setValueAtTime(computed, start);\n playbackRate.linearRampToValueAtTime(peekPitch, modAttack);\n playbackRate.linearRampToValueAtTime(\n computed + (peekPitch - computed) * (1 - instrument['modSustain']),\n modDecay\n );\n }\n\n /** @param {number} expression */\n updateExpression(expression) {\n this.expressionGainNode.gain.value = (this.expression = expression) / 127;\n }\n\n /** @param {number} pitchBend */\n updatePitchBend(pitchBend) {\n this.computedPlaybackRate =\n this.playbackRate *\n 1.0594630943592953 ** // Math.pow(2, 1 / 12)\n ((pitchBend / (pitchBend < 0 ? 8192 : 8191)) *\n this.pitchBendSensitivity *\n this.instrument['scaleTuning']);\n this.schedulePlaybackRate();\n }\n}\n","/**\n * @logue/reverb\n *\n * @description JavaScript Reverb effect class\n * @author Logue \n * @copyright 2019-2023 By Masashi Yoshikawa All rights reserved.\n * @license MIT\n * @version 1.3.5\n * @see {@link https://github.com/logue/Reverb.js}\n */\n\nconst INV_MAX = 1 / 2 ** 32;\nclass ARandom {\n float(norm = 1) {\n return this.int() * INV_MAX * norm;\n }\n probability(p) {\n return this.float() < p;\n }\n norm(norm = 1) {\n return (this.int() * INV_MAX - 0.5) * 2 * norm;\n }\n normMinMax(min, max) {\n const x = this.minmax(min, max);\n return this.float() < 0.5 ? x : -x;\n }\n minmax(min, max) {\n return this.float() * (max - min) + min;\n }\n minmaxInt(min, max) {\n min |= 0;\n const range = (max | 0) - min;\n return range ? min + (this.int() % range) : min;\n }\n minmaxUint(min, max) {\n min >>>= 0;\n const range = (max >>> 0) - min;\n return range ? min + (this.int() % range) : min;\n }\n}\n\nconst random = Math.random;\n/**\n * A `Math.random()` based {@link IRandom} implementation. Also @see\n * {@link SYSTEM}.\n */\nclass SystemRandom extends ARandom {\n int() {\n return (random() * 4294967296) /* 2**32 */ >>> 0;\n }\n float(norm = 1) {\n return random() * norm;\n }\n norm(norm = 1) {\n return (random() - 0.5) * 2 * norm;\n }\n}\n/**\n * Used as default PRNG throughout most other thi.ng projects, though usually is\n * configurable.\n */\nconst SYSTEM = new SystemRandom();\n\nconst defaults = {\n noise: \"white\",\n scale: 1,\n peaks: 2,\n randomAlgorithm: SYSTEM,\n decay: 2,\n delay: 0,\n reverse: false,\n time: 2,\n filterType: \"allpass\",\n filterFreq: 2200,\n filterQ: 1,\n mix: 0.5,\n once: false\n};\n\nconst Meta = {\n version: \"1.3.5\",\n date: \"2023-11-20T03:01:00.334Z\"\n};\n\nconst Noise = {\n /** Blue noise */\n blue: \"blue\",\n /** Brown noise (same as red noise) */\n brown: \"red\",\n /** Green noise */\n green: \"green\",\n /** Pink noise */\n pink: \"pink\",\n /** Red noise */\n red: \"red\",\n /** Violet noise */\n violet: \"violet\",\n /** White noise */\n white: \"white\"\n};\n\nconst DEFAULT_OPTS = {\n bins: 2,\n scale: 1,\n rnd: SYSTEM,\n};\n\nconst preseed = (n, scale, rnd) => {\n const state = new Array(n);\n for (let i = 0; i < n; i++) {\n state[i] = rnd.norm(scale);\n }\n return state;\n};\nconst sum = (src) => src.reduce((sum, x) => sum + x, 0);\nfunction* interleave(a, b) {\n const src = [a[Symbol.iterator](), b[Symbol.iterator]()];\n for (let i = 0; true; i ^= 1) {\n const next = src[i].next();\n if (next.done)\n return;\n yield next.value;\n }\n}\n\n/**\n * High-pass filtered noise. Opposite of {@link red}.\n *\n * @param opts -\n */\nfunction* blue(opts) {\n const { bins, scale, rnd } = {\n ...DEFAULT_OPTS,\n ...opts,\n };\n const state = preseed(bins, scale, rnd);\n state.forEach((x, i) => (state[i] = i & 1 ? x : -x));\n const invN = 1 / bins;\n let acc = sum(state);\n for (let i = 0, sign = -1; true; ++i >= bins && (i = 0)) {\n acc -= state[i];\n acc += state[i] = sign * rnd.norm(scale);\n sign ^= 0xfffffffe;\n yield sign * acc * invN;\n }\n}\n\n/**\n * Band-pass filtered noise (interleaved blue noise). Opposite of\n * {@link violet}.\n *\n * @param opts -\n */\nconst green = (opts) => interleave(blue(opts), blue(opts));\n\n/**\n * Returns number of 1 bits in `x`.\n *\n * @param x -\n */\nconst ctz32 = (x) => {\n let c = 32;\n x &= -x;\n x && c--;\n x & 0x0000ffff && (c -= 16);\n x & 0x00ff00ff && (c -= 8);\n x & 0x0f0f0f0f && (c -= 4);\n x & 0x33333333 && (c -= 2);\n x & 0x55555555 && (c -= 1);\n return c;\n};\n\n/**\n * Exponential decay (1/f) noise, based on Voss-McCarthy algorithm.\n *\n * @remarks\n * The number of internal states should be in the [4..32] range (default: 8).\n * Due to JS integer limitations, `n` > 32 are meaningless.\n *\n * References:\n *\n * - https://www.dsprelated.com/showarticle/908.php\n * - https://www.firstpr.com.au/dsp/pink-noise/#Voss-McCartney\n *\n * @param opts -\n */\nfunction* pink(opts) {\n const { bins, scale, rnd } = {\n ...DEFAULT_OPTS,\n bins: 8,\n ...opts,\n };\n const state = preseed(bins, scale, rnd);\n const invN = 1 / bins;\n let acc = sum(state);\n for (let i = 0; true; i = (i + 1) >>> 0) {\n const id = ctz32(i) % bins;\n acc -= state[id];\n acc += state[id] = rnd.norm(scale);\n yield acc * invN;\n }\n}\n\n/**\n * Low-pass filtered noise (same as brown noise). Opposite of {@link blue}.\n *\n * @param opts -\n */\nfunction* red(opts) {\n const { bins, scale, rnd } = {\n ...DEFAULT_OPTS,\n ...opts,\n };\n const state = preseed(bins, scale, rnd);\n const invN = 1 / bins;\n let acc = sum(state);\n for (let i = 0; true; ++i >= bins && (i = 0)) {\n acc -= state[i];\n acc += state[i] = rnd.norm(scale);\n yield acc * invN;\n }\n}\n\n/**\n * Band-stop filtered noise (interleaved red noise). Opposite of {@link green}.\n *\n * @param opts -\n */\nconst violet = (opts) => interleave(red(opts), red(opts));\n\n/**\n * Unfiltered noise w/ uniform distribution. Merely yields samples from\n * given PRNG.\n *\n * @param opts -\n */\nfunction* white(opts) {\n const { scale, rnd } = { ...DEFAULT_OPTS, ...opts };\n while (true) {\n yield rnd.norm(scale);\n }\n}\n\nconst implementsFunction = (x, fn) => x != null && typeof x[fn] === \"function\";\n\nconst ensureTransducer = (x) => implementsFunction(x, \"xform\") ? x.xform() : x;\n\nconst isIterable = (x) => x != null && typeof x[Symbol.iterator] === \"function\";\n\nclass Reduced {\n value;\n constructor(val) {\n this.value = val;\n }\n deref() {\n return this.value;\n }\n}\nconst reduced = (x) => new Reduced(x);\nconst isReduced = (x) => x instanceof Reduced;\nconst ensureReduced = (x) => x instanceof Reduced ? x : new Reduced(x);\nconst unreduced = (x) => (x instanceof Reduced ? x.deref() : x);\n\n/**\n * Convenience helper for building a full {@link Reducer} using the identity\n * function (i.e. `(x) => x`) as completion step (true for 90% of all\n * bundled transducers).\n *\n * @param init - init step of reducer\n * @param rfn - reduction step of reducer\n */\nconst reducer = (init, rfn) => [init, (acc) => acc, rfn];\n\nfunction push(xs) {\n return xs\n ? [...xs]\n : reducer(() => [], (acc, x) => (acc.push(x), acc));\n}\n\n/**\n * Takes a transducer and input iterable. Returns iterator of\n * transformed results.\n *\n * @param xform -\n * @param xs -\n */\nfunction* iterator(xform, xs) {\n const rfn = ensureTransducer(xform)(push());\n const complete = rfn[1];\n const reduce = rfn[2];\n for (let x of xs) {\n const y = reduce([], x);\n if (isReduced(y)) {\n yield* unreduced(complete(y.deref()));\n return;\n }\n if (y.length) {\n yield* y;\n }\n }\n yield* unreduced(complete([]));\n}\n\n/**\n * Reducer composition helper, internally used by various transducers\n * during initialization. Takes existing reducer `rfn` (a 3-tuple) and a\n * reducing function `fn`. Returns a new reducer tuple.\n *\n * @remarks\n * `rfn[2]` reduces values of type `B` into an accumulator of type `A`.\n * `fn` accepts values of type `C` and produces interim results of type\n * `B`, which are then (possibly) passed to the \"inner\" `rfn[2]`\n * function. Therefore the resulting reducer takes inputs of `C` and an\n * accumulator of type `A`.\n *\n * It is assumed that `fn` internally calls `rfn[2]` to pass its own\n * results for further processing by the nested reducer `rfn`.\n *\n * @example\n * ```ts\n * compR(rfn, fn)\n * // [rfn[0], rfn[1], fn]\n * ```\n *\n * @param rfn -\n * @param fn -\n */\nconst compR = (rfn, fn) => [rfn[0], rfn[1], fn];\n\nfunction take(n, src) {\n return isIterable(src)\n ? iterator(take(n), src)\n : (rfn) => {\n const r = rfn[2];\n let m = n;\n return compR(rfn, (acc, x) => --m > 0\n ? r(acc, x)\n : m === 0\n ? ensureReduced(r(acc, x))\n : reduced(acc));\n };\n}\n\nclass Reverb {\n /** Version strings */\n static version = Meta.version;\n /** Build date */\n static build = Meta.date;\n /** AudioContext */\n ctx;\n /** Wet Level (Reverberated node) */\n wetGainNode;\n /** Dry Level (Original sound node) */\n dryGainNode;\n /** Impulse response filter */\n filterNode;\n /** Convolution node for applying impulse response */\n convolverNode;\n /** Output gain node */\n outputNode;\n /** Option */\n options;\n /** Connected flag */\n isConnected;\n /** Noise Generator */\n noise = white;\n /**\n * Constructor\n *\n * @param ctx - Root AudioContext\n * @param options - Configure\n */\n constructor(ctx, options) {\n this.ctx = ctx;\n this.options = Object.assign(defaults, options);\n this.wetGainNode = this.ctx.createGain();\n this.dryGainNode = this.ctx.createGain();\n this.filterNode = this.ctx.createBiquadFilter();\n this.convolverNode = this.ctx.createConvolver();\n this.outputNode = this.ctx.createGain();\n this.isConnected = false;\n this.filterType(this.options.filterType);\n this.setNoise(this.options.noise);\n this.buildImpulse();\n this.mix(this.options.mix);\n }\n /**\n * Connect the node for the reverb effect to the original sound node.\n *\n * @param sourceNode - Input source node\n */\n connect(sourceNode) {\n if (this.isConnected && this.options.once) {\n this.isConnected = false;\n return this.outputNode;\n }\n this.convolverNode.connect(this.filterNode);\n this.filterNode.connect(this.wetGainNode);\n sourceNode.connect(this.convolverNode);\n sourceNode.connect(this.dryGainNode).connect(this.outputNode);\n sourceNode.connect(this.wetGainNode).connect(this.outputNode);\n this.isConnected = true;\n return this.outputNode;\n }\n /**\n * Disconnect the reverb node\n *\n * @param sourceNode - Input source node\n */\n disconnect(sourceNode) {\n if (this.isConnected) {\n this.convolverNode.disconnect(this.filterNode);\n this.filterNode.disconnect(this.wetGainNode);\n }\n this.isConnected = false;\n return sourceNode;\n }\n /**\n * Dry/Wet ratio\n *\n * @param mix - Ratio (0~1)\n */\n mix(mix) {\n if (!Reverb.inRange(mix, 0, 1)) {\n throw new RangeError(\"[Reverb.js] Dry/Wet ratio must be between 0 to 1.\");\n }\n this.options.mix = mix;\n this.dryGainNode.gain.value = 1 - this.options.mix;\n this.wetGainNode.gain.value = this.options.mix;\n }\n /**\n * Set Impulse Response time length (second)\n *\n * @param value - IR length\n */\n time(value) {\n if (!Reverb.inRange(value, 1, 50)) {\n throw new RangeError(\n \"[Reverb.js] Time length of inpulse response must be less than 50sec.\"\n );\n }\n this.options.time = value;\n this.buildImpulse();\n }\n /**\n * Impulse response decay rate.\n *\n * @param value - Decay value\n */\n decay(value) {\n if (!Reverb.inRange(value, 0, 100)) {\n throw new RangeError(\n \"[Reverb.js] Inpulse Response decay level must be less than 100.\"\n );\n }\n this.options.decay = value;\n this.buildImpulse();\n }\n /**\n * Delay before reverberation starts\n *\n * @param value - Time[ms]\n */\n delay(value) {\n if (!Reverb.inRange(value, 0, 100)) {\n throw new RangeError(\n \"[Reverb.js] Inpulse Response delay time must be less than 100.\"\n );\n }\n this.options.delay = value;\n this.buildImpulse();\n }\n /**\n * Reverse the impulse response.\n *\n * @param reverse - Reverse IR\n */\n reverse(reverse) {\n this.options.reverse = reverse;\n this.buildImpulse();\n }\n /**\n * Filter for impulse response\n *\n * @param type - Filiter Type\n */\n filterType(type = \"allpass\") {\n this.filterNode.type = this.options.filterType = type;\n }\n /**\n * Filter frequency applied to impulse response\n *\n * @param freq - Frequency\n */\n filterFreq(freq) {\n if (!Reverb.inRange(freq, 20, 2e4)) {\n throw new RangeError(\n \"[Reverb.js] Filter frequrncy must be between 20 and 20000.\"\n );\n }\n this.options.filterFreq = freq;\n this.filterNode.frequency.value = this.options.filterFreq;\n }\n /**\n * Filter quality.\n *\n * @param q - Quality\n */\n filterQ(q) {\n if (!Reverb.inRange(q, 0, 10)) {\n throw new RangeError(\n \"[Reverb.js] Filter quality value must be between 0 and 10.\"\n );\n }\n this.options.filterQ = q;\n this.filterNode.Q.value = this.options.filterQ;\n }\n /**\n * set IR source noise peaks\n *\n * @param p - Peaks\n */\n peaks(p) {\n this.options.peaks = p;\n this.buildImpulse();\n }\n /**\n * set IR source noise scale.\n *\n * @param s - Scale\n */\n scale(s) {\n this.options.scale = s;\n this.buildImpulse();\n }\n /**\n * set IR source noise generator.\n *\n * @param a - Algorithm\n */\n randomAlgorithm(a) {\n this.options.randomAlgorithm = a;\n this.buildImpulse();\n }\n /**\n * Inpulse Response Noise algorithm.\n *\n * @param type - IR noise algorithm type.\n */\n setNoise(type) {\n this.options.noise = type;\n switch (type) {\n case Noise.blue:\n this.noise = blue;\n break;\n case Noise.green:\n this.noise = green;\n break;\n case Noise.pink:\n this.noise = pink;\n break;\n case Noise.red:\n case Noise.brown:\n this.noise = red;\n break;\n case Noise.violet:\n this.noise = violet;\n break;\n default:\n this.noise = white;\n }\n this.buildImpulse();\n }\n /**\n * Set Random Algorythm\n *\n * @param algorithm - Algorythm\n */\n setRandomAlgorythm(algorithm) {\n this.options.randomAlgorithm = algorithm;\n this.buildImpulse();\n }\n /**\n * Return true if in range, otherwise false\n *\n * @param x - Target value\n * @param min - Minimum value\n * @param max - Maximum value\n */\n static inRange(x, min, max) {\n return (x - min) * (x - max) <= 0;\n }\n /** Utility function for building an impulse response from the module parameters. */\n buildImpulse() {\n const rate = this.ctx.sampleRate;\n const duration = Math.max(rate * this.options.time, 1);\n const delayDuration = rate * this.options.delay;\n const impulse = this.ctx.createBuffer(2, duration, rate);\n const impulseL = new Float32Array(duration);\n const impulseR = new Float32Array(duration);\n const noiseL = this.getNoise(duration);\n const noiseR = this.getNoise(duration);\n for (let i = 0; i < duration; i++) {\n let n = 0;\n if (i < delayDuration) {\n impulseL[i] = 0;\n impulseR[i] = 0;\n n = this.options.reverse ?? false ? duration - (i - delayDuration) : i - delayDuration;\n } else {\n n = this.options.reverse ?? false ? duration - i : i;\n }\n impulseL[i] = (noiseL[i] ?? 0) * (1 - n / duration) ** this.options.decay;\n impulseR[i] = (noiseR[i] ?? 0) * (1 - n / duration) ** this.options.decay;\n }\n impulse.getChannelData(0).set(impulseL);\n impulse.getChannelData(1).set(impulseR);\n this.convolverNode.buffer = impulse;\n }\n /**\n * Noise source\n *\n * @param duration - length of IR.\n */\n getNoise(duration) {\n return [\n ...take(\n duration,\n this.noise({\n bins: this.options.peaks,\n scale: this.options.scale,\n rnd: this.options.randomAlgorithm\n })\n )\n ];\n }\n}\n\nexport { Reverb as default };\n","/**\n * Riff Parser class\n *\n * @author imaya\n */\nexport class Riff {\n /**\n * @param {ArrayBuffer} input Input buffer.\n * @param {Object} [optParams] Option parameters.\n */\n constructor(input, optParams = {}) {\n /** @type {ArrayBuffer} */\n this.input = input;\n /** @type {number} */\n this.ip = optParams.index || 0;\n /** @type {number} */\n this.length = optParams.length || input.byteLength - this.ip;\n /** @type {RiffChunk[]} */\n this.chunkList = [];\n /** @type {number} */\n this.offset = this.ip;\n /** @type {boolean} */\n this.padding = optParams.padding !== void 0 ? optParams.padding : true;\n /** @type {boolean} */\n this.bigEndian =\n optParams.bigEndian !== void 0 ? optParams.bigEndian : false;\n }\n\n /** @returns {void} */\n parse() {\n /** @type {number} */\n const length = this.length + this.offset;\n\n this.chunkList = [];\n\n while (this.ip < length) {\n this.parseChunk();\n }\n }\n\n /** @returns {void} */\n parseChunk() {\n /** @type {ArrayBuffer} */\n const input = this.input;\n /** @type {number} */\n let ip = this.ip;\n /** @type {number} */\n let size;\n\n this.chunkList.push(\n new RiffChunk(\n String.fromCharCode(input[ip++], input[ip++], input[ip++], input[ip++]),\n (size = this.bigEndian\n ? ((input[ip++] << 24) |\n (input[ip++] << 16) |\n (input[ip++] << 8) |\n input[ip++]) >>>\n 0\n : (input[ip++] |\n (input[ip++] << 8) |\n (input[ip++] << 16) |\n (input[ip++] << 24)) >>>\n 0),\n ip\n )\n );\n\n ip += size;\n\n // padding\n if (this.padding && ((ip - this.offset) & 1) === 1) {\n ip++;\n }\n\n this.ip = ip;\n }\n\n /**\n * @param {number} index Chunk index.\n * @returns {RiffChunk | null}\n */\n getChunk(index) {\n /** @type {RiffChunk} */\n const chunk = this.chunkList[index];\n\n return chunk !== undefined ? chunk : null;\n }\n\n /** @returns {number} */\n getNumberOfChunks() {\n return this.chunkList.length;\n }\n}\n\n/**\n * Riff Chunk Structure\n *\n * @interface\n */\nexport class RiffChunk {\n /**\n * @param {string} type\n * @param {number} size\n * @param {number} offset\n */\n constructor(type, size, offset) {\n /** @type {string} */\n this.type = type;\n /** @type {number} */\n this.size = size;\n /** @type {number} */\n this.offset = offset;\n }\n}\n","import { Riff } from './riff.js';\n\n/**\n * SoundFont Parser Class\n *\n * @author imaya\n */\nexport default class Parser {\n /**\n * @param {Uint8Array} input\n * @param {Object} [optParams]\n */\n constructor(input, optParams = {}) {\n /** @type {Uint8Array} */\n this.input = input;\n /** @type {object} */\n this.parserOption = optParams.parserOption || {};\n /** @type {number} */\n this.sampleRate = optParams.sampleRate || 22050; // よくわからんが、OSで指定されているサンプルレートを入れないと音が切れ切れになる。\n\n /** @type {object[]} */\n this.presetHeader = [];\n /** @type {object[]} */\n this.presetZone = [];\n /** @type {object[]} */\n this.presetZoneModulator = [];\n /** @type {object[]} */\n this.presetZoneGenerator = [];\n /** @type {object[]} */\n this.instrument = [];\n /** @type {object[]} */\n this.instrumentZone = [];\n /** @type {object[]} */\n this.instrumentZoneModulator = [];\n /** @type {object[]} */\n this.instrumentZoneGenerator = [];\n /** @type {object[]} */\n this.sampleHeader = [];\n /** @type {string[]} */\n this.GeneratorEnumeratorTable = Object.keys(Parser.getGeneratorTable());\n }\n\n /** @return {Record} ジェネレータとデフォルト値 */\n static getGeneratorTable() {\n return Object.freeze({\n /** @type {number} サンプルヘッダの音声波形データ開始位置に加算されるオフセット(下位16bit) */\n startAddrsOffset: 0,\n /** @type {number} サンプルヘッダの音声波形データ終了位置に加算されるオフセット(下位16bit) */\n endAddrsOffset: 0,\n /** @type {number} サンプルヘッダの音声波形データループ開始位置に加算されるオフセット(下位16bit) */\n startloopAddrsOffset: 0,\n /** @type {number} サンプルヘッダの音声波形データループ開始位置に加算されるオフセット(下位16bit) */\n endloopAddrsOffset: 0,\n /** @type {number} サンプルヘッダの音声波形データ開始位置に加算されるオフセット(上位16bit) */\n startAddrsCoarseOffset: 0,\n /** @type {number} LFOによるピッチの揺れ幅 */\n modLfoToPitch: 0,\n /** @type {number} モジュレーションホイール用LFOからピッチに対しての影響量 */\n vibLfoToPitch: 0,\n /** @type {number} フィルタ・ピッチ用エンベロープからピッチに対しての影響量 */\n modEnvToPitch: 0,\n /** @type {number} フィルタのカットオフ周波数 */\n initialFilterFc: 13500,\n /** @type {number} フィルターのQ値(レゾナンス) */\n initialFilterQ: 0,\n /** @type {number} LFOによるフィルターカットオフ周波数の揺れ幅 */\n modLfoToFilterFc: 0,\n /** @type {number} フィルタ・ピッチ用エンベロープからフィルターカットオフに対しての影響量 */\n modEnvToFilterFc: 0,\n /** @type {number} サンプルヘッダの音声波形データ終了位置に加算されるオフセット(上位16bit) */\n endAddrsCoarseOffset: 0,\n /** @type {number} LFOによるボリュームの揺れ幅 */\n modLfoToVolume: 0,\n /** @type {undefined} 未使用1 */\n unused1: undefined, // 14\n /** @type {number} コーラスエフェクトのセンドレベル */\n chorusEffectsSend: 0,\n /** @type {number} リバーブエフェクトのセンドレベル */\n reverbEffectsSend: 0,\n /** @type {number} パンの位置 */\n pan: 0,\n /** @type {undefined} 未使用2 */\n unused2: undefined,\n /** @type {undefined} 未使用3 */\n unused3: undefined,\n /** @type {undefined} 未使用4 */\n unused4: undefined,\n /** @type {number} LFOの揺れが始まるまでの時間 */\n delayModLFO: -12000,\n /** @type {number} LFOの揺れの周期 */\n freqModLFO: 0,\n /** @type {number} ホイールの揺れが始まるまでの時間 */\n delayVibLFO: -12000,\n /** @type {number} ホイールの揺れの周期 */\n freqVibLFO: 0,\n /** @type {number} フィルタ・ピッチ用エンベロープのディレイ(アタックが始まるまでの時間) */\n delayModEnv: -12000,\n /** @type {number} フィルタ・ピッチ用エンベロープのアタック時間 */\n attackModEnv: -12000,\n /** @type {number} フィルタ・ピッチ用エンベロープのホールド時間(アタックが終わってからディケイが始まるまでの時間) */\n holdModEnv: -12000,\n /** @type {number} フィルタ・ピッチ用エンベロープのディケイ時間 */\n decayModEnv: -12000,\n /** @type {number} フィルタ・ピッチ用エンベロープのサステイン量 */\n sustainModEnv: 0,\n /** @type {number} フィルタ・ピッチ用エンベロープのリリース時間 */\n releaseModEnv: -12000,\n /** @type {number} キー(ノートNo)によるフィルタ・ピッチ用エンベロープのホールド時間への影響 */\n keynumToModEnvHold: 0,\n /** @type {number} キー(ノートNo)によるフィルタ・ピッチ用エンベロープのディケイ時間への影響 */\n keynumToModEnvDecay: 0,\n /** @type {number} アンプ用エンベロープのディレイ(アタックが始まるまでの時間) */\n delayVolEnv: -12000,\n /** @type {number} アンプ用エンベロープのアタック時間 */\n attackVolEnv: -12000,\n /** @type {number} アンプ用エンベロープのホールド時間(アタックが終わってからディケイが始まるまでの時間) */\n holdVolEnv: -12000,\n /** @type {number} アンプ用エンベロープのディケイ時間 */\n decayVolEnv: -12000,\n /** @type {number} アンプ用エンベロープのサステイン量 */\n sustainVolEnv: 0,\n /** @type {number} アンプ用エンベロープのリリース時間 */\n releaseVolEnv: -12000,\n /** @type {number} キー(ノートNo)によるアンプ用エンベロープのホールド時間への影響 */\n keynumToVolEnvHold: 0,\n /** @type {number} キー(ノートNo)によるアンプ用エンベロープのディケイ時間への影響 */\n keynumToVolEnvDecay: 0,\n /** @type {number} 割り当てるインストルメント(楽器) */\n instrument: null,\n /** @type {undefined} 予約済み1 */\n reserved1: undefined, // 42\n /** @type {number} マッピングするキー(ノートNo)の範囲 */\n keyRange: null,\n /** @type {number} マッピングするベロシティの範囲 */\n velRange: null,\n /** @type {number} サンプルヘッダの音声波形データループ開始位置に加算されるオフセット(上位16bit) */\n startloopAddrsCoarseOffset: 0,\n /** @type {number} どのキー(ノートNo)でも強制的に指定したキー(ノートNo)に変更する */\n keynum: null,\n /** @type {number} どのベロシティでも強制的に指定したベロシティに変更する */\n velocity: null,\n /** @type {number} 調整する音量 */\n initialAttenuation: 0,\n /** @type {undefined} 予約済み2 */\n reserved2: undefined, // 49\n /** @type {number} サンプルヘッダの音声波形データループ終了位置に加算されるオフセット(上位16bit) */\n endloopAddrsCoarseOffset: 0,\n /** @type {number} 半音単位での音程の調整 */\n coarseTune: 0,\n /** @type {number} cent単位での音程の調整 */\n fineTune: 0,\n /** @type {number} 割り当てるサンプル(音声波形) */\n sampleID: null,\n /** @type {number} サンプル(音声波形)をループさせるか等のフラグ */\n sampleModes: 0,\n /** @type {undefined} 予約済み3 */\n reserved3: undefined, // 55\n /** @type {number} キー(ノートNo)が+1されるごとに音程を何centあげるかの音階情報 */\n scaleTuning: 100,\n /** @type {number} 同時に音を鳴らさないようにするための排他ID(ハイハットのOpen、Close等に使用) */\n exclusiveClass: null,\n /** @type {number} サンプル(音声波形)の音程の上書き情報 */\n overridingRootKey: null,\n /** @type {undefined} 未使用5 */\n unuded5: undefined, // 59\n /** @type {undefined} 最後を示すオペレータ */\n endOper: undefined,\n });\n }\n\n /** @export */\n parse() {\n /** @type {Riff} */\n const parser = new Riff(this.input, this.parserOption);\n\n // parse RIFF chunk\n parser.parse();\n if (parser.chunkList.length !== 1) {\n throw new Error('wrong chunk length');\n }\n\n /** @type {import('./riff.js').RiffChunk | null} */\n const chunk = parser.getChunk(0);\n if (chunk === null) {\n throw new Error('chunk not found');\n }\n\n this.parseRiffChunk(chunk);\n this.input = null;\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseRiffChunk(chunk) {\n /** @type {ArrayBuffer} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n\n // check parse target\n if (chunk.type !== 'RIFF') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n // check signature\n /** @type {string} */\n const signature = String.fromCharCode(\n data[ip++],\n data[ip++],\n data[ip++],\n data[ip++]\n );\n if (signature !== 'sfbk') {\n throw new Error('invalid signature:' + signature);\n }\n\n // read structure\n /** @type {import('./riff.js').Riff} */\n const parser = new Riff(data, { index: ip, length: chunk.size - 4 });\n parser.parse();\n if (parser.getNumberOfChunks() !== 3) {\n throw new Error('invalid sfbk structure');\n }\n\n // INFO-list\n this.parseInfoList(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(0))\n );\n\n // sdta-list\n this.parseSdtaList(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(1))\n );\n\n // pdta-list\n this.parsePdtaList(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(2))\n );\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseInfoList(chunk) {\n /** @type {ArrayBuffer} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n\n // check parse target\n if (chunk.type !== 'LIST') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n // check signature\n /** @type {string} */\n const signature = String.fromCharCode(\n data[ip++],\n data[ip++],\n data[ip++],\n data[ip++]\n );\n if (signature !== 'INFO') {\n throw new Error('invalid signature:' + signature);\n }\n\n // read structure\n /** @type {import('./riff.js').Riff} */\n const parser = new Riff(data, { index: ip, length: chunk.size - 4 });\n parser.parse();\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseSdtaList(chunk) {\n /** @type {ArrayBuffer} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n\n // check parse target\n if (chunk.type !== 'LIST') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n // check signature\n /** @type {string} */\n const signature = String.fromCharCode(\n data[ip++],\n data[ip++],\n data[ip++],\n data[ip++]\n );\n if (signature !== 'sdta') {\n throw new Error('invalid signature:' + signature);\n }\n\n // read structure\n /** @type {import('./riff.js').Riff} */\n const parser = new Riff(data, { index: ip, length: chunk.size - 4 });\n parser.parse();\n if (parser.chunkList.length !== 1) {\n throw new Error('TODO');\n }\n this.samplingData =\n /** @type {{ type: string; size: number; offset: number }} */\n (parser.getChunk(0));\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parsePdtaList(chunk) {\n /** @type {Uint8Array} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n\n // check parse target\n if (chunk.type !== 'LIST') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n // check signature\n /** @type {string} */\n const signature = String.fromCharCode(\n data[ip++],\n data[ip++],\n data[ip++],\n data[ip++]\n );\n if (signature !== 'pdta') {\n throw new Error('invalid signature:' + signature);\n }\n\n // read structure\n /** @type {import('./riff.js').Riff} */\n const parser = new Riff(data, { index: ip, length: chunk.size - 4 });\n parser.parse();\n\n // check number of chunks\n if (parser.getNumberOfChunks() !== 9) {\n throw new Error('invalid pdta chunk');\n }\n\n this.parsePhdr(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(0))\n );\n this.parsePbag(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(1))\n );\n this.parsePmod(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(2))\n );\n this.parsePgen(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(3))\n );\n this.parseInst(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(4))\n );\n this.parseIbag(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(5))\n );\n this.parseImod(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(6))\n );\n this.parseIgen(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(7))\n );\n this.parseShdr(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(8))\n );\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parsePhdr(chunk) {\n /** @type {Uint8Array} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n /** @type {Object[]} */\n const presetHeader = (this.presetHeader = []);\n /** @type {number} */\n const size = chunk.offset + chunk.size;\n\n // check parse target\n if (chunk.type !== 'phdr') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n while (ip < size) {\n presetHeader.push({\n presetName: String.fromCharCode.apply(\n null,\n data.subarray(ip, (ip += 20))\n ),\n preset: data[ip++] | (data[ip++] << 8),\n bank: data[ip++] | (data[ip++] << 8),\n presetBagIndex: data[ip++] | (data[ip++] << 8),\n library:\n (data[ip++] |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0,\n genre:\n (data[ip++] |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0,\n morphology:\n (data[ip++] |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0,\n });\n }\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parsePbag(chunk) {\n /** @type {ArrayBuffer} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n /** @type {Object[]} */\n const presetZone = (this.presetZone = []);\n /** @type {number} */\n const size = chunk.offset + chunk.size;\n\n // check parse target\n if (chunk.type !== 'pbag') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n while (ip < size) {\n presetZone.push({\n presetGeneratorIndex: data[ip++] | (data[ip++] << 8),\n presetModulatorIndex: data[ip++] | (data[ip++] << 8),\n });\n }\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parsePmod(chunk) {\n // check parse target\n if (chunk.type !== 'pmod') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n this.presetZoneModulator = this.parseModulator(chunk);\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parsePgen(chunk) {\n // check parse target\n if (chunk.type !== 'pgen') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n this.presetZoneGenerator = this.parseGenerator(chunk);\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseInst(chunk) {\n /** @type {Uint8Array} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n /** @type {Object[]} */\n const instrument = (this.instrument = []);\n /** @type {number} */\n const size = chunk.offset + chunk.size;\n\n // check parse target\n if (chunk.type !== 'inst') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n while (ip < size) {\n instrument.push({\n instrumentName: String.fromCharCode.apply(\n null,\n data.subarray(ip, (ip += 20))\n ),\n instrumentBagIndex: data[ip++] | (data[ip++] << 8),\n });\n }\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseIbag(chunk) {\n /** @type {ArrayBuffer} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n /** @type {Object[]} */\n const instrumentZone = (this.instrumentZone = []);\n /** @type {number} */\n const size = chunk.offset + chunk.size;\n\n // check parse target\n if (chunk.type !== 'ibag') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n while (ip < size) {\n instrumentZone.push({\n instrumentGeneratorIndex: data[ip++] | (data[ip++] << 8),\n instrumentModulatorIndex: data[ip++] | (data[ip++] << 8),\n });\n }\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseImod(chunk) {\n // check parse target\n if (chunk.type !== 'imod') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n this.instrumentZoneModulator = this.parseModulator(chunk);\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseIgen(chunk) {\n // check parse target\n if (chunk.type !== 'igen') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n this.instrumentZoneGenerator = this.parseGenerator(chunk);\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseShdr(chunk) {\n /** @type {Uint8Array} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n /** @type {Object[]} */\n const samples = (this.sample = []);\n /** @type {Object[]} */\n const sampleHeader = (this.sampleHeader = []);\n /** @type {number} */\n const size = chunk.offset + chunk.size;\n /** @type {string} */\n let sampleName;\n /** @type {number} */\n let start;\n /** @type {number} */\n let end;\n /** @type {number} */\n let startLoop;\n /** @type {number} */\n let endLoop;\n /** @type {number} */\n let sampleRate;\n /** @type {number} */\n let originalPitch;\n /** @type {number} */\n let pitchCorrection;\n /** @type {number} */\n let sampleLink;\n /** @type {number} */\n let sampleType;\n\n // check parse target\n if (chunk.type !== 'shdr') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n while (ip < size) {\n sampleName = String.fromCharCode.apply(\n null,\n data.subarray(ip, (ip += 20))\n );\n start =\n ((data[ip++] << 0) |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0;\n end =\n ((data[ip++] << 0) |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0;\n startLoop =\n ((data[ip++] << 0) |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0;\n endLoop =\n ((data[ip++] << 0) |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0;\n sampleRate =\n ((data[ip++] << 0) |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0;\n originalPitch = data[ip++];\n pitchCorrection = (data[ip++] << 24) >> 24;\n sampleLink = data[ip++] | (data[ip++] << 8);\n sampleType = data[ip++] | (data[ip++] << 8);\n\n let sample = new Int16Array(\n new Uint8Array(\n data.subarray(\n this.samplingData.offset + start * 2,\n this.samplingData.offset + end * 2\n )\n ).buffer\n );\n\n startLoop -= start;\n endLoop -= start;\n\n if (sampleRate > 0) {\n const adjust = this.adjustSampleData(sample, sampleRate);\n sample = adjust.sample;\n sampleRate *= adjust.multiply;\n startLoop *= adjust.multiply;\n endLoop *= adjust.multiply;\n }\n\n samples.push(sample);\n\n sampleHeader.push({\n sampleName: sampleName,\n start: start,\n end: end,\n startLoop: startLoop,\n endLoop: endLoop,\n sampleRate: sampleRate,\n originalPitch: originalPitch,\n pitchCorrection: pitchCorrection,\n sampleLink: sampleLink,\n sampleType: sampleType,\n });\n }\n }\n\n /**\n * @param {Int16Array} sample\n * @param {number} sampleRate\n * @return {object}\n */\n adjustSampleData(sample, sampleRate) {\n /** @type {Int16Array} */\n let newSample;\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n /** @type {number} */\n let j;\n /** @type {number} */\n let multiply = 1;\n\n // buffer\n while (sampleRate < this.sampleRate) {\n // AudioContextのサンプルレートに変更\n newSample = new Int16Array(sample.length * 2);\n for (i = j = 0, il = sample.length; i < il; ++i) {\n newSample[j++] = sample[i];\n newSample[j++] = sample[i];\n }\n sample = newSample;\n multiply *= 2;\n sampleRate *= 2;\n }\n\n return {\n sample: sample,\n multiply: multiply,\n };\n }\n\n /**\n * @param {import('./riff.js').RiffChunk} chunk\n * @return {Object[]}\n */\n parseModulator(chunk) {\n /** @type {ArrayBuffer} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n /** @type {number} */\n const size = chunk.offset + chunk.size;\n /** @type {number} */\n let code;\n /** @type {string} */\n let key;\n /** @type {Object[]} */\n const output = [];\n\n while (ip < size) {\n // Src Oper\n // TODO\n ip += 2;\n\n // Dest Oper\n code = data[ip++] | (data[ip++] << 8);\n key = this.GeneratorEnumeratorTable[code];\n if (key === void 0) {\n // Amount\n output.push({\n type: key,\n value: {\n code: code,\n amount: data[ip] | (((data[ip + 1] << 8) << 16) >> 16),\n lo: data[ip++],\n hi: data[ip++],\n },\n });\n } else {\n // Amount\n switch (key) {\n case 'keyRange':\n /* FALLTHROUGH */\n case 'velRange':\n /* FALLTHROUGH */\n case 'keynum':\n /* FALLTHROUGH */\n case 'velocity':\n output.push({\n type: key,\n value: {\n amount: null,\n lo: data[ip++],\n hi: data[ip++],\n },\n });\n break;\n default:\n output.push({\n type: key,\n value: {\n amount: data[ip++] | (((data[ip++] << 8) << 16) >> 16),\n },\n });\n break;\n }\n }\n\n // AmtSrcOper\n // TODO\n ip += 2;\n\n // Trans Oper\n // TODO\n ip += 2;\n }\n\n return output;\n }\n\n /**\n * @param {import('./riff.js').RiffChunk} chunk\n * @return {Object[]}\n */\n parseGenerator(chunk) {\n /** @type {ArrayBuffer} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n /** @type {number} */\n const size = chunk.offset + chunk.size;\n /** @type {number} */\n let code;\n /** @type {string} */\n let key;\n /** @type {Object[]} */\n const output = [];\n\n while (ip < size) {\n code = data[ip++] | (data[ip++] << 8);\n key = this.GeneratorEnumeratorTable[code];\n if (key === void 0) {\n output.push({\n type: key,\n value: {\n code: code,\n amount: data[ip] | (((data[ip + 1] << 8) << 16) >> 16),\n lo: data[ip++],\n hi: data[ip++],\n },\n });\n continue;\n }\n\n switch (key) {\n case 'keynum':\n /* FALLTHROUGH */\n case 'keyRange':\n /* FALLTHROUGH */\n case 'velRange':\n /* FALLTHROUGH */\n case 'velocity':\n output.push({\n type: key,\n value: {\n amount: null,\n lo: data[ip++],\n hi: data[ip++],\n },\n });\n break;\n default:\n output.push({\n type: key,\n value: {\n amount: data[ip++] | (((data[ip++] << 8) << 16) >> 16),\n },\n });\n break;\n }\n }\n\n return output;\n }\n\n /** @return {object[]} */\n createInstrument() {\n /** @type {Object[]} */\n const instrument = this.instrument;\n /** @type {Object[]} */\n const zone = this.instrumentZone;\n /** @type {Object[]} */\n const output = [];\n /** @type {number} */\n let bagIndex;\n /** @type {number} */\n let bagIndexEnd;\n /** @type {Object[]} */\n let zoneInfo;\n /** @type {{ generator: Object; generatorInfo: Object[] }} */\n let instrumentGenerator;\n /** @type {{ modulator: Object; modulatorInfo: Object[] }} */\n let instrumentModulator;\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n /** @type {number} */\n let j;\n /** @type {number} */\n let jl;\n\n // instrument -> instrument bag -> generator / modulator\n for (i = 0, il = instrument.length; i < il; ++i) {\n bagIndex = instrument[i].instrumentBagIndex;\n bagIndexEnd = instrument[i + 1]\n ? instrument[i + 1].instrumentBagIndex\n : zone.length;\n zoneInfo = [];\n\n // instrument bag\n for (j = bagIndex, jl = bagIndexEnd; j < jl; ++j) {\n instrumentGenerator = this.createInstrumentGenerator_(zone, j);\n instrumentModulator = this.createInstrumentModulator_(zone, j);\n\n zoneInfo.push({\n generator: instrumentGenerator.generator,\n generatorSequence: instrumentGenerator.generatorInfo,\n modulator: instrumentModulator.modulator,\n modulatorSequence: instrumentModulator.modulatorInfo,\n });\n }\n\n output.push({\n name: instrument[i].instrumentName,\n info: zoneInfo,\n });\n }\n\n return output;\n }\n\n /** @return {object[]} */\n createPreset() {\n /** @type {Object[]} */\n const preset = this.presetHeader;\n /** @type {Object[]} */\n const zone = this.presetZone;\n /** @type {Object[]} */\n const output = [];\n /** @type {number} */\n let bagIndex;\n /** @type {number} */\n let bagIndexEnd;\n /** @type {Object[]} */\n let zoneInfo;\n /** @type {number} */\n let instrument;\n /** @type {{ generator: Object; generatorInfo: Object[] }} */\n let presetGenerator;\n /** @type {{ modulator: Object; modulatorInfo: Object[] }} */\n let presetModulator;\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n /** @type {number} */\n let j;\n /** @type {number} */\n let jl;\n\n // preset -> preset bag -> generator / modulator\n for (i = 0, il = preset.length; i < il; ++i) {\n bagIndex = preset[i].presetBagIndex;\n bagIndexEnd = preset[i + 1] ? preset[i + 1].presetBagIndex : zone.length;\n zoneInfo = [];\n\n // preset bag\n for (j = bagIndex, jl = bagIndexEnd; j < jl; ++j) {\n presetGenerator = this.createPresetGenerator_(zone, j);\n presetModulator = this.createPresetModulator_(zone, j);\n\n zoneInfo.push({\n generator: presetGenerator.generator,\n generatorSequence: presetGenerator.generatorInfo,\n modulator: presetModulator.modulator,\n modulatorSequence: presetModulator.modulatorInfo,\n });\n\n instrument =\n presetGenerator.generator['instrument'] !== void 0\n ? presetGenerator.generator['instrument'].amount\n : presetModulator.modulator['instrument'] !== void 0\n ? presetModulator.modulator['instrument'].amount\n : null;\n }\n\n output.push({\n name: preset[i].presetName,\n info: zoneInfo,\n header: preset[i],\n instrument: instrument,\n });\n }\n\n return output;\n }\n\n /**\n *\n * @private\n * @param {Object[]} zone\n * @param {number} index\n * @returns {{ generator: Object; generatorInfo: Object[] }}\n */\n createInstrumentGenerator_(zone, index) {\n const modgen = this.createBagModGen_(\n zone,\n zone[index].instrumentGeneratorIndex,\n zone[index + 1]\n ? zone[index + 1].instrumentGeneratorIndex\n : this.instrumentZoneGenerator.length,\n this.instrumentZoneGenerator\n );\n\n return {\n generator: modgen.modgen,\n generatorInfo: modgen.modgenInfo,\n };\n }\n\n /**\n *\n * @private\n * @param {Object[]} zone\n * @param {number} index\n * @returns {{ modulator: Object; modulatorInfo: Object[] }}\n */\n createInstrumentModulator_(zone, index) {\n const modgen = this.createBagModGen_(\n zone,\n zone[index].presetModulatorIndex,\n zone[index + 1]\n ? zone[index + 1].instrumentModulatorIndex\n : this.instrumentZoneModulator.length,\n this.instrumentZoneModulator\n );\n\n return {\n modulator: modgen.modgen,\n modulatorInfo: modgen.modgenInfo,\n };\n }\n\n /**\n *\n * @private\n * @param {Object[]} zone\n * @param {number} index\n * @returns {{ generator: Object; generatorInfo: Object[] }}\n */\n createPresetGenerator_(zone, index) {\n const modgen = this.createBagModGen_(\n zone,\n zone[index].presetGeneratorIndex,\n zone[index + 1]\n ? zone[index + 1].presetGeneratorIndex\n : this.presetZoneGenerator.length,\n this.presetZoneGenerator\n );\n\n return {\n generator: modgen.modgen,\n generatorInfo: modgen.modgenInfo,\n };\n }\n\n /**\n *\n * @private\n * @param {Object[]} zone\n * @param {number} index\n * @returns {{ modulator: Object; modulatorInfo: Object[] }}\n */\n createPresetModulator_(zone, index) {\n /** @type {{ modgen: Object; modgenInfo: Object[] }} */\n const modgen = this.createBagModGen_(\n zone,\n zone[index].presetModulatorIndex,\n zone[index + 1]\n ? zone[index + 1].presetModulatorIndex\n : this.presetZoneModulator.length,\n this.presetZoneModulator\n );\n\n return {\n modulator: modgen.modgen,\n modulatorInfo: modgen.modgenInfo,\n };\n }\n\n /**\n *\n * @private\n * @param {Object[]} _zone\n * @param {number} indexStart\n * @param {number} indexEnd\n * @param {Array} zoneModGen\n * @returns {{ modgen: Object; modgenInfo: Object[] }}\n */\n createBagModGen_(_zone, indexStart, indexEnd, zoneModGen) {\n /** @type {Object[]} */\n const modgenInfo = [];\n /** @type {Object} */\n const modgen = {\n unknown: [],\n keyRange: {\n amount: null,\n hi: 127,\n lo: 0,\n },\n }; // TODO\n /** @type {Object} */\n let info;\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n\n for (i = indexStart, il = indexEnd; i < il; ++i) {\n info = zoneModGen[i];\n modgenInfo.push(info);\n\n if (info.type === 'unknown') {\n modgen.unknown.push(info.value);\n } else {\n modgen[info.type] = info.value;\n }\n }\n\n return {\n modgen: modgen,\n modgenInfo: modgenInfo,\n };\n }\n}\n","import SynthesizerNote from './sound_font_synth_note';\nimport Reverb from '@logue/reverb';\nimport Parser from './sf2';\n\n/**\n * Synthesizer Class\n *\n * @author imaya\n */\nexport default class Synthesizer {\n /** @param {Uint8Array} input */\n constructor(input) {\n /** @type {number} */\n let i;\n /** @type {Uint8Array} */\n this.input = input;\n /** @type {Parser} */\n this.parser = undefined;\n /** @type {number} */\n this.bank = 0;\n /** @type {Object} */\n this.bankSet = {};\n /** @type {number} */\n this.bufferSize = 2048;\n /** @type {AudioContext} */\n this.ctx = this.getAudioContext();\n /** @type {GainNode} */\n this.gainMaster = this.ctx.createGain();\n /** @type {AudioBufferSourceNode} */\n this.bufSrc = this.ctx.createBufferSource();\n /** @type {number[]} */\n this.channelInstrument = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n /** @type {number[]} */\n this.channelBank = [0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0];\n /** @type {number[]} */\n this.channelVolume = [\n 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,\n 100,\n ];\n /** @type {number[]} */\n this.channelPanpot = [\n 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n ];\n /** @type {number[]} */\n this.channelPitchBend = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n /** @type {number[]} */\n this.channelPitchBendSensitivity = [\n 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n ];\n /** @type {number[]} */\n this.channelExpression = [\n 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,\n 127,\n ];\n /** @type {number[]} */\n this.channelAttack = [\n 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n ];\n /** @type {number[]} */\n this.channelDecay = [\n 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n ];\n /** @type {number[]} */\n this.channelSustin = [\n 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n ];\n /** @type {number[]} */\n this.channelRelease = [\n 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n ];\n\n /** @type {boolean[]} */\n this.channelHold = [\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n ];\n /** @type {number[]} */\n this.channelHarmonicContent = [\n 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n ];\n /** @type {number[]} */\n this.channelCutOffFrequency = [\n 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n ];\n\n /** @type {'GM'|'GM2'|'XG'|'GS'} */\n this.mode = 'GM2';\n\n /** @type {string[][]} */\n this.programSet = [];\n\n /** @type {boolean[]} */\n this.channelMute = [\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n ];\n /** @type {SynthesizerNote[][]} */\n this.currentNoteOn = [\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n ];\n /** @type {number} @const */\n this.baseVolume = 1 / 0xffff;\n /** @type {number} */\n this.masterVolume = 16384;\n\n /** @type {boolean[]} */\n this.percussionPart = [\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n true,\n false,\n false,\n false,\n false,\n false,\n false,\n ];\n\n /** @type {number[]} */\n this.percussionVolume = [];\n while (i === 127) {\n this.percussionVolume[i] = 127;\n i++;\n }\n\n /** @type {string[][]} */\n this.programSet = [];\n\n /** @type {Reverb[]} リバーブエフェクト(チャンネル毎に用意する) */\n this.reverb = [];\n\n /** @type {number[]} モジュレーション(ビブラート) */\n this.modulation = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n\n /** @type {BiquadFilterNode[]} フィルタ */\n this.filter = [];\n\n for (i = 0; i < 16; ++i) {\n // @ts-ignore\n this.reverb[i] = new Reverb(this.ctx, { noise: 'violet' });\n // フィルタを定義\n this.filter[i] = this.ctx.createBiquadFilter();\n }\n\n /** 表示項目 */\n this.items = [];\n\n /** @type {IntersectionObserver} 交差していない */\n this.intersection = new IntersectionObserver(\n entries =>\n entries.forEach(entry => {\n // @ts-ignore\n entry.target.dataset.isIntersecting = entry.isIntersecting;\n }),\n {}\n );\n\n /** @type {NodeJS.Timeout} タイマーのスレッド */\n this.timer = undefined;\n /** @type {boolean} */\n this.drag = false;\n }\n\n /** @return {AudioContext} */\n getAudioContext() {\n /** @type {AudioContext} */\n const ctx = new AudioContext();\n\n // Defreeze AudioContext for iOS.\n const initAudioContext = () => {\n document.removeEventListener('touchstart', initAudioContext);\n /** @type {AudioBufferSourceNode} wake up AudioContext */\n const emptySource = ctx.createBufferSource();\n emptySource.start();\n emptySource.stop();\n };\n\n document.addEventListener('touchstart', initAudioContext);\n\n return ctx;\n }\n\n /**\n * System Reset\n *\n * @param {'GM'|'GM2'|'XG'|'GS'} mode 音源モード\n */\n init(mode = 'GM') {\n this.gainMaster.disconnect();\n\n this.refreshInstruments(this.input);\n\n this.mode = mode;\n\n for (let i = 0; i < 16; ++i) {\n this.setPercussionPart(i, i === 9);\n this.programChange(i, 0);\n this.volumeChange(i, 100);\n this.panpotChange(i, 64);\n this.pitchBend(i, 0x00, 0x40); // 8192\n this.pitchBendSensitivity(i, 2);\n this.hold(i, 0);\n this.expression(i, 127);\n this.bankSelectMsb(i, i === 9 ? 127 : 0);\n this.bankSelectLsb(i, i === 9 ? 127 : 0);\n this.attackTime(i, 64);\n this.decayTime(i, 64);\n this.sustinTime(i, 64);\n this.releaseTime(i, 64);\n this.harmonicContent(i, 64);\n this.cutOffFrequency(i, 64);\n this.reverbDepth(i, 40);\n this.modulationDepth(i, 0);\n\n this.updateBankSelect(i);\n this.updateProgramSelect(i);\n }\n\n this.setPercussionPart(9, true);\n\n for (let i = 0; i < 128; ++i) {\n this.percussionVolume[i] = 127;\n }\n\n this.setMasterVolume(8192);\n\n this.gainMaster.connect(this.ctx.destination);\n\n if (this.element) {\n /** @type {HTMLDivElement} */\n const modeElement = this.element.querySelector('.header .keys div');\n modeElement.innerText = mode + ' Mode';\n /** @type {NodeListOf} */\n const bankSelectElement = this.element.querySelectorAll(\n `.instrument .bank > select`\n );\n\n bankSelectElement.forEach(element => (element.disabled = mode === 'GM'));\n this.element.dataset.mode = mode;\n }\n }\n\n /** Close AudioContext */\n async close() {\n await this.ctx.close();\n }\n\n /** @param {Uint8Array} input */\n refreshInstruments(input) {\n this.input = input;\n this.parser = new Parser(input, {\n sampleRate: this.ctx.sampleRate,\n });\n this.bankSet = this.createAllInstruments();\n }\n\n /** @returns {Object[][]} */\n createAllInstruments() {\n /** @type {Parser} */\n const parser = this.parser;\n parser.parse();\n /** @type {Array} TODO */\n const presets = parser.createPreset();\n /** @type {Array} TODO */\n const instruments = parser.createInstrument();\n /** @type {Array} */\n const banks = [];\n /** @type {Record} */\n let bank;\n /** @type {number} */\n let bankNumber;\n /** @type {Object} */\n let instrument;\n /** @type {number} */\n let presetNumber;\n /** @type {string} */\n let presetName;\n\n const programSet = [];\n\n presets.forEach(preset => {\n presetNumber = preset.header.preset;\n bankNumber = preset.header.bank;\n presetName = preset.name.replace(/\\0*$/, '');\n\n if (typeof preset.instrument !== 'number') {\n return;\n }\n\n instrument = instruments[preset.instrument];\n if (instrument.name.replace(/\\0*$/, '') === 'EOI') {\n return;\n }\n\n // select bank\n banks[bankNumber] = banks[bankNumber] ?? [];\n bank = banks[bankNumber];\n bank[presetNumber] = {};\n bank[presetNumber].name = presetName;\n\n instrument.info.forEach(info =>\n this.createNoteInfo(parser, info, bank[presetNumber])\n );\n\n if (!programSet[bankNumber]) {\n programSet[bankNumber] = [];\n }\n programSet[bankNumber][presetNumber] = presetName;\n });\n\n this.programSet = programSet;\n\n return banks;\n }\n\n /**\n * @param {Parser} parser\n * @param {any} info\n * @param {any} preset\n */\n createNoteInfo(parser, info, preset) {\n /** @type {*} */\n const generator = info.generator;\n\n if (!generator.keyRange || !generator.sampleID) {\n return;\n }\n\n // デフォルト値\n // https://www.utsbox.com/?p=2390\n\n /** @type {number} 33: DelayVolEnv */\n const volDelay = this.getModGenAmount(generator, 'delayVolEnv');\n /** @type {number} 34: AttackVolEnv */\n const volAttack = this.getModGenAmount(generator, 'attackVolEnv');\n /** @type {number} 35: HoldVolEnv */\n const volHold = this.getModGenAmount(generator, 'holdVolEnv');\n /** @type {number} 36: DecayVolEnv */\n const volDecay = this.getModGenAmount(generator, 'decayVolEnv');\n /** @type {number} 37: SustainVolEnv */\n const volSustain = this.getModGenAmount(generator, 'sustainVolEnv');\n /** @type {number} 38: ReleaseVolEnv */\n const volRelease = this.getModGenAmount(generator, 'releaseVolEnv');\n /** @type {number} 25: DelayModEnv */\n const modDelay = this.getModGenAmount(generator, 'delayModEnv');\n /** @type {number} 26: AttackModEnv */\n const modAttack = this.getModGenAmount(generator, 'attackModEnv');\n /** @type {number} 27: HoldModEnv */\n const modHold = this.getModGenAmount(generator, 'holdModEnv');\n /** @type {number} 28: DecayModEnv */\n const modDecay = this.getModGenAmount(generator, 'decayModEnv');\n /** @type {number} 29: SustainModEnv */\n const modSustain = this.getModGenAmount(generator, 'sustainModEnv');\n /** @type {number} 30: ReleaseModEnv */\n const modRelease = this.getModGenAmount(generator, 'releaseModEnv');\n /** @type {number} 56: ScaleTuning */\n const scale = this.getModGenAmount(generator, 'scaleTuning') / 100;\n /** @type {number} */\n const tune =\n this.getModGenAmount(generator, 'coarseTune') +\n this.getModGenAmount(generator, 'fineTune') / 100;\n /** @type {number} */\n const sampleModes = this.getModGenAmount(generator, 'sampleModes');\n\n for (\n let i = generator.keyRange.lo, il = generator.keyRange.hi;\n i <= il;\n ++i\n ) {\n if (preset[i]) {\n continue;\n }\n /** @type {number} */\n const sampleId = this.getModGenAmount(generator, 'sampleID');\n /** @type {object} */\n const sampleHeader = parser.sampleHeader[sampleId];\n\n preset[i] = {\n sample: parser.sample[sampleId],\n sampleRate: sampleHeader.sampleRate,\n // 54\n sampleModes: sampleModes,\n basePlaybackRate:\n 1.0594630943592953 ** // Math.pow(2, 1 / 12)\n ((i -\n this.getModGenAmount(generator, 'overridingRootKey') +\n tune +\n sampleHeader.pitchCorrection / 100) *\n scale),\n modEnvToPitch: this.getModGenAmount(generator, 'modEnvToPitch') / 100,\n scaleTuning: scale,\n start:\n this.getModGenAmount(generator, 'startAddrsCoarseOffset') * 32768 +\n this.getModGenAmount(generator, 'startAddrsOffset'),\n end:\n this.getModGenAmount(generator, 'endAddrsCoarseOffset') * 32768 +\n this.getModGenAmount(generator, 'endAddrsOffset'),\n loopStart:\n // (sampleHeader.startLoop - sampleHeader.start) +\n sampleHeader.startLoop +\n this.getModGenAmount(generator, 'startloopAddrsCoarseOffset') *\n 32768 +\n this.getModGenAmount(generator, 'startloopAddrsOffset'),\n loopEnd:\n // (sampleHeader.endLoop - sampleHeader.start) +\n sampleHeader.endLoop +\n this.getModGenAmount(generator, 'endloopAddrsCoarseOffset') * 32768 +\n this.getModGenAmount(generator, 'endloopAddrsOffset'),\n volDelay: 2 ** (volDelay / 1200),\n volAttack: 2 ** (volAttack / 1200),\n volHold:\n 2 ** (volHold / 1200) *\n 2 **\n (((60 - i) *\n this.getModGenAmount(generator, 'keynumToVolEnvHold')) /\n 1200),\n volDecay:\n 2 ** (volDecay / 1200) *\n 2 **\n (((60 - i) *\n this.getModGenAmount(generator, 'keynumToVolEnvDecay')) /\n 1200),\n volSustain: volSustain / 1000,\n volRelease: 2 ** (volRelease / 1200),\n modDelay: 2 ** (modDelay / 1200),\n modAttack: 2 ** (modAttack / 1200),\n modHold:\n 2 ** (modHold / 1200) *\n 2 **\n (((60 - i) *\n this.getModGenAmount(generator, 'keynumToModEnvHold')) /\n 1200),\n modDecay:\n 2 ** (modDecay / 1200) *\n 2 **\n (((60 - i) *\n this.getModGenAmount(generator, 'keynumToModEnvDecay')) /\n 1200),\n modSustain: modSustain / 1000,\n modRelease: 2 ** (modRelease / 1200),\n initialFilterFc:\n 8.176 *\n Math.pow(\n 2,\n this.getModGenAmount(generator, 'initialFilterFc') / 1200\n ),\n modEnvToFilterFc:\n this.getModGenAmount(generator, 'modEnvToFilterFc') / 100,\n initialFilterQ: this.getModGenAmount(generator, 'initialFilterQ') / 10,\n reverbEffectSend:\n this.getModGenAmount(generator, 'reverbEffectSend') / 10,\n initialAttenuation:\n this.getModGenAmount(generator, 'initialAttenuation') / 10,\n freqVibLFO:\n 8.176 *\n Math.pow(2, this.getModGenAmount(generator, 'freqVibLFO') / 1200),\n pan: this.getModGenAmount(generator, 'pan') / 1200,\n };\n }\n }\n\n /**\n * @param {Object} generator\n * @param {string} enumeratorType\n * @return {number}\n */\n getModGenAmount(generator, enumeratorType) {\n return generator[enumeratorType]\n ? generator[enumeratorType].amount\n : Parser.getGeneratorTable()[enumeratorType];\n }\n\n /**\n * Start Tone Generator\n */\n start() {\n this.connect();\n this.bufSrc.start(0);\n this.setMasterVolume(16383);\n }\n\n /** @param {number} volume */\n setMasterVolume(volume) {\n this.masterVolume = volume;\n this.gainMaster.gain.value = this.baseVolume * (volume / 16384);\n }\n\n /** Connect root AudioContext */\n connect() {\n this.bufSrc.connect(this.gainMaster);\n }\n\n /** Disconnect root AudioContext */\n disconnect() {\n this.bufSrc.disconnect(this.gainMaster);\n this.bufSrc.buffer = null;\n }\n\n /** @return {HTMLDivElement} */\n drawSynth() {\n /** @type {Document} */\n const doc = window.document;\n /** @type {HTMLDivElement} */\n const wrapper = (this.element = doc.createElement('div'));\n wrapper.className = 'synthesizer';\n /** @type {HTMLDivElement} */\n const instElem = doc.createElement('div');\n instElem.className = 'instrument';\n /** @type {string[]} */\n this.items = [\n 'mute',\n 'bank',\n 'program',\n 'volume',\n 'expression',\n 'panpot',\n 'pitchBend',\n 'pitchBendSensitivity',\n 'reverbDepth',\n 'keys',\n ];\n /** @type {string} */\n const eventStart = 'ontouchstart' in window ? 'touchstart' : 'mousedown';\n /** @type {string} */\n const eventEnd = 'ontouchend' in window ? 'touchend' : 'mouseup';\n\n for (let channel = 0; channel < 16; channel++) {\n /** @type {HTMLDivElement} */\n const channelElem = doc.createElement('div');\n channelElem.className = 'channel';\n // ホールドを無効化する処理\n channelElem.addEventListener(eventStart, () => {\n this.hold(channel, 0);\n });\n for (const item in this.items) {\n if (!Object.hasOwn(this.items, item)) {\n continue;\n }\n /** @type {HTMLDivElement} */\n const itemElem = doc.createElement('div');\n itemElem.className = this.items[item];\n\n switch (this.items[item]) {\n case 'mute': {\n /** @type {HTMLDivElement | null} */\n const checkboxElement = doc.createElement('div');\n checkboxElement.className = 'form-check form-check-inline';\n /** @type {HTMLInputElement | null} */\n const checkbox = doc.createElement('input');\n checkbox.ariaLabel = `Ch.${channel + 1} Mute`;\n checkbox.setAttribute('type', 'checkbox');\n checkbox.className = 'form-check-input';\n checkbox.id = 'mute' + channel + 'ch';\n checkbox.value = channel.toString();\n checkbox.addEventListener(\n 'change',\n event => {\n // @ts-ignore\n this.mute(channel, event.target.checked);\n },\n false\n );\n checkboxElement.appendChild(checkbox);\n /** @type {HTMLLabelElement} */\n const labelElem = doc.createElement('label');\n\n labelElem.className = 'form-check-label';\n labelElem.textContent = (channel + 1).toString();\n labelElem.setAttribute('for', 'mute' + channel + 'ch');\n checkboxElement.appendChild(labelElem);\n itemElem.appendChild(checkboxElement);\n break;\n }\n case 'bank': {\n /** @type {HTMLSelectElement} Bank select */\n const bankSelect = doc.createElement('select');\n bankSelect.ariaLabel = `Ch.${channel + 1} Bank Select`;\n bankSelect.className = 'form-select form-select-sm bank-select';\n bankSelect.addEventListener(\n 'change',\n ((synth, ch) => event => {\n /** @type {HTMLSelectElement} */\n const program = channelElem.querySelector('.program select');\n // console.log(ch, event.target.value, program);\n // @ts-ignore\n synth.bankChange(ch, event.target.value);\n synth.programChange(ch, parseInt(program.value));\n })(this, channel),\n false\n );\n itemElem.appendChild(bankSelect);\n break;\n }\n case 'program': {\n /** @type {HTMLSelectElement} Program change */\n const select = doc.createElement('select');\n select.className = 'form-select form-select-sm';\n select.ariaLabel = `Ch.${channel + 1} Program Change`;\n select.addEventListener(\n 'change',\n ((synth, ch) => event => {\n // @ts-ignore\n synth.programChange(ch, event.target.value);\n })(this, channel),\n false\n );\n itemElem.appendChild(select);\n break;\n }\n case 'volume': {\n /** @type {HTMLElement} */\n const volumeElem = document.createElement('var');\n volumeElem.ariaLabel = `Ch.${channel + 1} Volume`;\n volumeElem.innerText = '100';\n itemElem.appendChild(volumeElem);\n break;\n }\n case 'expression': {\n /** @type {HTMLElement} */\n const expressionElem = document.createElement('var');\n expressionElem.ariaLabel = `Ch.${channel + 1} Expression`;\n expressionElem.innerText = '127';\n itemElem.appendChild(expressionElem);\n break;\n }\n case 'pitchBendSensitivity': {\n /** @type {HTMLElement} */\n const pitchSensElem = document.createElement('var');\n pitchSensElem.ariaLabel = `Ch.${\n channel + 1\n } Pitch Bend Sensitivity`;\n pitchSensElem.innerText = '2';\n itemElem.appendChild(pitchSensElem);\n break;\n }\n case 'reverbDepth': {\n /** @type {HTMLElement} */\n const reverbDepthElem = document.createElement('var');\n reverbDepthElem.ariaLabel = `Ch.${channel + 1} Reverb Depth`;\n reverbDepthElem.innerText = '40';\n itemElem.appendChild(reverbDepthElem);\n break;\n }\n case 'panpot': {\n /** @type {HTMLDivElement} */\n const panpotOuter = doc.createElement('div');\n panpotOuter.role = 'progressbar';\n panpotOuter.ariaLabel = `Ch.${channel + 1} Panpod`;\n panpotOuter.ariaValueMin = '0';\n panpotOuter.ariaValueNow = '64';\n panpotOuter.ariaValueMax = '127';\n panpotOuter.className = 'progress';\n const panpot = doc.createElement('div');\n // 緑色\n panpot.className = 'progress-bar';\n panpotOuter.appendChild(panpot);\n itemElem.appendChild(panpotOuter);\n break;\n }\n case 'pitchBend': {\n /** @type {HTMLDivElement} */\n const pitchOuter = doc.createElement('div');\n pitchOuter.className = 'progress';\n pitchOuter.role = 'progressbar';\n pitchOuter.ariaLabel = `Ch.${channel + 1} Pitch Bend`;\n pitchOuter.ariaValueMin = '-8192';\n pitchOuter.ariaValueNow = '0';\n pitchOuter.ariaValueMax = '8192';\n pitchOuter.className = 'progress';\n /** @type {HTMLDivElement} */\n const pitch = doc.createElement('div');\n // 黄色\n pitch.className = 'progress-bar progress-bar-animated';\n pitchOuter.appendChild(pitch);\n itemElem.appendChild(pitchOuter);\n break;\n }\n case 'keys': {\n // 鍵盤の描画\n for (let key = 0; key < 127; key++) {\n /** @type {HTMLDivElement} */\n const keyElem = doc.createElement('div');\n /** @type {number} */\n const n = key % 12;\n // 白鍵と黒鍵の色分け\n keyElem.className =\n 'key ' + ([1, 3, 6, 8, 10].includes(n) ? 'semitone' : 'tone');\n itemElem.appendChild(keyElem);\n\n // イベント割当\n keyElem.addEventListener(\n eventStart,\n ((synth, ch, k) => event => {\n event.preventDefault();\n synth.drag = true;\n synth.noteOn(ch, k, 127);\n })(this, channel, key)\n );\n keyElem.addEventListener(\n 'mouseover',\n ((synth, ch, k) => event => {\n event.preventDefault();\n if (synth.drag) {\n synth.noteOn(ch, k, 127);\n }\n })(this, channel, key)\n );\n keyElem.addEventListener(\n 'mouseout',\n ((synth, ch, k) => event => {\n event.preventDefault();\n synth.noteOff(ch, k);\n })(this, channel, key)\n );\n keyElem.addEventListener(\n eventEnd,\n ((synth, ch, k) => event => {\n event.preventDefault();\n synth.drag = false;\n synth.noteOff(ch, k);\n })(this, channel, key)\n );\n }\n break;\n }\n }\n channelElem.appendChild(itemElem);\n }\n instElem.appendChild(channelElem);\n this.intersection.observe(channelElem);\n }\n // ヘッダー行の描画\n const itemName = [\n 'Ch.',\n 'Bank',\n 'Program',\n 'Vol.',\n 'Exp.',\n 'Panpot',\n 'Pitch Bend',\n '',\n 'Rev.',\n '',\n ];\n /** @type {HTMLDivElement} */\n const headerElem = doc.createElement('div');\n headerElem.className = 'header';\n for (const item in this.items) {\n if (!Object.hasOwn(this.items, item)) {\n continue;\n }\n /** @type {HTMLDivElement} */\n const itemElem = doc.createElement('div');\n itemElem.className = this.items[item];\n itemElem.textContent = itemName[item];\n if (this.items[item] === 'keys') {\n // MIDI音源のLCDのテキスト領域エミュレーター\n itemElem.appendChild(document.createElement('code'));\n // GM / GS / XG表記\n itemElem.appendChild(document.createElement('div'));\n }\n headerElem.appendChild(itemElem);\n }\n instElem.prepend(headerElem);\n wrapper.appendChild(instElem);\n\n // ヘッダー行のリサイズ\n const ro = new ResizeObserver(_entries => {\n this.items.forEach(item => {\n /** @type {HTMLElement} */\n const headerItem = wrapper.querySelector(`.header .${item}`);\n /** @type {HTMLElement} */\n const channelItem = wrapper.querySelector(`.channel .${item}`);\n\n headerItem.style.width = channelItem.offsetWidth + 'px';\n });\n /** @type {HTMLElement} */\n const keysItem = wrapper.querySelector(`.header .keys`);\n\n keysItem.style.display =\n document.documentElement.clientWidth <= 680 ? 'none' : 'flex';\n });\n ro.observe(wrapper);\n\n return wrapper;\n }\n\n /**\n * シンセサイザーのDOMの更新\n *\n * @param {number} channel\n * @param {number} key\n * @param {number} velocity\n */\n updateSynthElement(channel, key, velocity) {\n if (!this.element) {\n return;\n }\n /** @type {NodeListOf} */\n const channelElems = this.element.querySelectorAll(\n `.instrument > .channel`\n );\n\n if (channelElems[channel].dataset.isIntersecting) {\n /** @type {HTMLDivElement} */\n const keyElem = channelElems[channel].querySelector(\n `.key:nth-child(${key + 1})`\n );\n if (velocity === 0) {\n if (keyElem.classList.contains('note-on')) {\n keyElem.classList.remove('note-on');\n }\n keyElem.style.opacity = '1';\n } else {\n keyElem.classList.add('note-on');\n // ベロシティに応じて透過度を調整\n keyElem.style.opacity = (velocity / 127).toFixed(2);\n }\n }\n }\n\n /**\n * バンクセレクタの選択ボックスの処理\n *\n * @param {number} channel\n */\n updateBankSelect(channel) {\n if (!this.element) {\n return;\n }\n /** @type {HTMLElement} */\n const bankElement = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.bank > select');\n\n while (bankElement.firstChild)\n bankElement.removeChild(bankElement.firstChild);\n\n for (const bankNo in this.programSet) {\n if (!Object.hasOwn(this.programSet, bankNo)) {\n continue;\n }\n const option = document.createElement('option');\n option.value = bankNo;\n option.textContent = ('000' + parseInt(bankNo)).slice(-3);\n if (parseInt(bankNo) === this.channelBank[channel]) {\n option.selected = true;\n }\n bankElement.appendChild(option);\n }\n }\n\n /**\n * プログラムチェンジの選択ボックスの処理\n *\n * @param {number} channel\n */\n updateProgramSelect(channel) {\n if (!this.element) {\n return;\n }\n const dom = this.element.querySelectorAll(`.instrument > .channel`)[\n channel\n ];\n\n /** @type {number} */\n const bankIndex = this.channelBank[channel];\n /** @type {HTMLSelectElement} */\n const bankElement = dom.querySelector('.bank > select');\n /** @type {HTMLSelectElement} */\n const programElement = dom.querySelector('.program > select');\n\n bankElement.value = this.channelBank[channel].toString();\n while (programElement.firstChild)\n programElement.removeChild(programElement.firstChild);\n\n for (const programNo in this.programSet[bankIndex]) {\n if (!Object.hasOwn(this.programSet[bankIndex], programNo)) {\n continue;\n }\n // TODO: 存在しないプログラムの場合、現状では空白になってしまう\n /** @type {HTMLOptionElement} */\n const option = document.createElement('option');\n option.value = programNo;\n option.textContent = `${('000' + (parseInt(programNo) + 1)).slice(-3)}:${\n this.programSet[bankIndex][programNo]\n }`;\n if (parseInt(programNo) === this.channelInstrument[channel]) {\n option.selected = true;\n }\n programElement.appendChild(option);\n }\n }\n\n /**\n * ノートオン\n *\n * @param {number} channel NoteOn するチャンネル.\n * @param {number} key NoteOn するキー.\n * @param {number} velocity 強さ.\n */\n noteOn(channel, key, velocity = 100) {\n /** @type {number} */\n const bankIndex = this.channelBank[channel];\n // バンクに楽器が存在しない場合は、原則的にバンク0の楽器を選択する。\n // ただし、SFX(Bank 64)は発音しない、\n // パーカッション(Bank127~128) の場合、0のStandard Kitの音を鳴らさなければならない)\n /** @type {Object} */\n const bank =\n typeof this.bankSet[bankIndex] === 'object'\n ? this.bankSet[bankIndex]\n : this.bankSet[0];\n\n /** @type {Object} */\n let instrument;\n\n if (typeof bank[this.channelInstrument[channel]] === 'object') {\n // 音色が存在する場合\n instrument = bank[this.channelInstrument[channel]];\n } else if (this.percussionPart[channel]) {\n // パーカッションバンクが選択されている場合で音色が存在しない場合Standard Kitを選択\n instrument = this.bankSet[this.mode === 'XG' ? 127 : 128][0];\n } else {\n // 通常の音色が選択されている状態で音色が存在しない場合バンク0を選択\n instrument = this.bankSet[0][this.channelInstrument[channel]];\n }\n\n if (instrument[key] === void 0) {\n // TODO\n console.warn(\n 'instrument not found: bank=%s instrument=%s channel=%s key=%s',\n bankIndex,\n this.channelInstrument[channel],\n channel,\n key\n );\n return;\n }\n /** @type {Object} */\n const instrumentKey = instrument[key];\n /** @type {number} */\n let panpot =\n this.channelPanpot[channel] === 0\n ? Math.floor(Math.random() * 127) // パンが0の場合ランダムとなる。\n : this.channelPanpot[channel] - 64;\n panpot /= panpot < 0 ? 64 : 63;\n\n // create note information\n instrumentKey['channel'] = channel;\n instrumentKey['key'] = key;\n instrumentKey['velocity'] = velocity;\n instrumentKey['panpot'] = panpot;\n instrumentKey['volume'] = this.channelVolume[channel] / 127;\n instrumentKey['pitchBend'] = this.channelPitchBend[channel] - 8192;\n instrumentKey['expression'] = this.channelExpression[channel];\n instrumentKey['pitchBendSensitivity'] = Math.round(\n this.channelPitchBendSensitivity[channel]\n );\n instrumentKey['mute'] = this.channelMute[channel];\n instrumentKey['releaseTime'] = this.channelRelease[channel];\n instrumentKey['cutOffFrequency'] = this.cutOffFrequency[channel];\n instrumentKey['harmonicContent'] = this.harmonicContent[channel];\n instrumentKey['reverb'] = this.reverb[channel];\n instrumentKey['modulation'] = this.modulation[channel];\n\n // percussion\n if (bankIndex >= 127) {\n // ドラムパートのハイハットクローズはここで定義するべきではない。\n if (key === 42 || key === 44) {\n // 42: Closed Hi-Hat\n // 44: Pedal Hi-Hat\n // 46: Open Hi-Hat\n this.noteOff(channel, 46);\n }\n if (key === 80) {\n // 80: Mute Triangle\n // 81: Open Triangle\n this.noteOff(channel, 81);\n }\n instrument['volume'] *= this.percussionVolume[key] / 127;\n }\n\n // note on\n /** @type {SynthesizerNote} */\n const note = new SynthesizerNote(this.ctx, this.gainMaster, instrumentKey);\n // TODO: 本来パンポットはここで指定する\n note.noteOn();\n this.currentNoteOn[channel].push(note);\n\n this.updateSynthElement(channel, key, velocity);\n }\n\n /**\n * ノートオフ\n *\n * @param {number} channel NoteOff するチャンネル.\n * @param {number} key NoteOff するキー.\n */\n noteOff(channel, key) {\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n /** @type {SynthesizerNote[]} */\n const currentNoteOn = this.currentNoteOn[channel];\n /** @type {SynthesizerNote} */\n let note;\n /** @type {boolean} */\n const hold = this.channelHold[channel];\n\n for (i = 0, il = currentNoteOn.length; i < il; ++i) {\n note = currentNoteOn[i];\n if (note.key === key) {\n note.noteOff();\n // hold している時は NoteOff にはするがリリースはしない\n if (!hold) {\n note.release();\n currentNoteOn.splice(i, 1);\n --i;\n --il;\n }\n }\n }\n this.updateSynthElement(channel, key, 0);\n }\n\n /**\n * ホールド(ダンパーペダル)\n *\n * @param {number} channel ホールドするチャンネル\n * @param {number} value 値\n */\n hold(channel, value) {\n /** @type {SynthesizerNote[]} */\n const currentNoteOn = this.currentNoteOn[channel];\n /** @type {boolean} 0以外はonである。 */\n const hold = (this.channelHold[channel] = value > 64);\n /** @type {SynthesizerNote} */\n let note;\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n\n if (!hold) {\n for (i = 0, il = currentNoteOn.length; i < il; ++i) {\n note = currentNoteOn[i];\n if (note.isNoteOff()) {\n note.release();\n currentNoteOn.splice(i, 1);\n --i;\n --il;\n }\n }\n }\n\n if (this.element) {\n /** @type {NodeListOf} */\n const channelElements = this.element.querySelectorAll(\n `.instrument > .channel`\n );\n\n if (!channelElements[channel]) {\n return;\n }\n if (this.channelHold[channel]) {\n channelElements[channel].classList.add('hold');\n } else if (channelElements[channel].classList.contains('hold')) {\n channelElements[channel].classList.remove('hold');\n }\n }\n }\n\n /**\n * バンクセレクトMSB(GS音源/GM Level2用)\n *\n * @param {number} channel チャンネルのバンクセレクトMSB\n * @param {number} value 値\n */\n bankSelectMsb(channel, value) {\n // 125より値が大きい場合、パーカッションとして処理\n this.percussionPart[channel] = value >= 125;\n // 念の為バンクを0にリセット\n this.channelBank[channel] = channel === 9 ? 128 : 0;\n\n if (this.mode === 'GM') {\n // GM音源モードのときはバンク・セレクトを無視\n return;\n } else if (this.mode === 'XG') {\n // XG音源は、MSB→LSBの優先順でバンクセレクトをする。\n if (value === 64) {\n // Bank Select MSB #64 (Voice Type: SFX)\n this.channelBank[channel] = 125;\n } else if (value === 126 || value === 127) {\n // Bank Select MSB #126 (Voice Type: Drum)\n // Bank Select MSB #127 (Voice Type: Drum)\n this.channelBank[channel] = value;\n } else if (value === 128) {\n this.channelBank[channel] = 127;\n }\n } else {\n // GS音源\n // ※チャンネル10のバンク・セレクト命令は無視する。\n this.channelBank[channel] = channel === 9 ? 128 : value;\n this.percussionPart[channel] = value === 128;\n }\n this.updateBankSelect(channel);\n }\n\n /**\n * バンクセレクトLSB(XG音源)\n *\n * @param {number} channel チャンネルのバンクセレクトLSB\n * @param {number} value 値\n */\n bankSelectLsb(channel, value) {\n // XG音源以外は処理しない\n if (this.mode !== 'XG') {\n return;\n }\n\n if (!this.percussionPart[channel]) {\n // ドラムパートではバンクセレクトLSB命令を無視する。\n this.channelBank[channel] = value;\n }\n\n this.updateBankSelect(channel);\n }\n\n /**\n * プログラムチェンジ\n *\n * @param {number} channel 音色を変更するチャンネル.\n * @param {number} instrument 音色番号.\n */\n programChange(channel, instrument) {\n this.channelInstrument[channel] = instrument;\n\n this.bankChange(channel, this.channelBank[channel]);\n if (this.element) {\n /** @type {HTMLSelectElement} */\n const select = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.program > select');\n\n select.value = instrument.toString();\n }\n }\n\n /**\n * バンクセレクト\n *\n * @param {number} channel 音色を変更するチャンネル.\n * @param {number} bank バンク・セレクト.\n */\n bankChange(channel, bank) {\n /** パーカッションバンク */\n const percussionBank = this.mode === 'XG' || this.mode === 'GM' ? 127 : 128;\n if (this.mode === 'GM') {\n // GMの場合バンクセレクトを無効化\n bank = 0;\n }\n if (channel === 9) {\n // GS、XGフラグが立っていない(拡張音源ではない)場合は、ch10はドラム固定、それ以外は0とする。\n bank = percussionBank;\n }\n if (this.bankSet[bank]) {\n this.channelBank[channel] = bank;\n } else {\n // 存在しない場合0を選択\n this.channelBank[channel] = this.percussionPart[channel]\n ? percussionBank\n : 0;\n }\n // }\n\n if (this.element) {\n /** @type {HTMLSelectElement} バンクセレクトの値 */\n const bankSelect = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.bank > select');\n bankSelect.value = bank.toString();\n }\n // TODO: 厳密にはMIDI音源はプログラムチェンジがあったときに、バンク・セレクトの値が反映されるのでこの実装は正しくない。\n this.updateProgramSelect(channel);\n }\n\n /**\n * ボリューム\n *\n * @param {number} channel 音量を変更するチャンネル.\n * @param {number} volume 音量(0-127).\n */\n volumeChange(channel, volume) {\n if (this.element) {\n /** @type {HTMLElement} */\n const volumeVariable = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.volume var');\n volumeVariable.innerText = volume.toString();\n }\n\n this.channelVolume[channel] = volume;\n }\n\n /**\n * エクスプレッション\n *\n * @param {number} channel 音量を変更するチャンネル.\n * @param {number} expression 音量(0-127).\n */\n expression(channel, expression) {\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n /** @type {SynthesizerNote[]} */\n const currentNoteOn = this.currentNoteOn[channel];\n\n for (i = 0, il = currentNoteOn.length; i < il; ++i) {\n currentNoteOn[i].updateExpression(expression);\n }\n\n if (this.element) {\n /** @type {HTMLElement} */\n const expressionVariabe = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.expression var');\n\n expressionVariabe.innerText = expression.toString();\n }\n\n this.channelExpression[channel] = expression;\n }\n\n /**\n * パンポット\n *\n * @param {number} channel Panpot を変更するチャンネル.\n * @param {number} panpot Panpot(0-127).\n */\n panpotChange(channel, panpot) {\n this.channelPanpot[channel] = panpot;\n if (this.element) {\n const dom = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.panpot');\n dom.ariaValueNow = panpot.toString();\n /** @type {HTMLDivElement} */\n const progressBar = dom.querySelector('.progress-bar');\n const percentage = (panpot / 127) * 100;\n progressBar.style.width = `${percentage}%`;\n progressBar.classList.remove('left', 'right');\n progressBar.title = panpot.toString();\n if (panpot === 64) {\n return;\n }\n dom.classList.add(panpot < 63 ? 'left' : 'right');\n }\n }\n\n /**\n * ピッチベンド\n *\n * @param {number} channel ピッチベンドを変更するチャンネル.\n * @param {number} lowerByte\n * @param {number} higherByte\n */\n pitchBend(channel, lowerByte, higherByte) {\n /** @type {number} */\n const bend = (lowerByte & 0x7f) | ((higherByte & 0x7f) << 7);\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n /** @type {import('./sound_font_synth_note').default[]} */\n const currentNoteOn = this.currentNoteOn[channel];\n /** @type {number} */\n const calculated = bend - 8192;\n\n for (i = 0, il = currentNoteOn.length; i < il; ++i) {\n currentNoteOn[i].updatePitchBend(calculated);\n }\n\n this.channelPitchBend[channel] = bend;\n\n if (this.element) {\n /** @type {HTMLDivElement} */\n const dom = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.pitchBend');\n dom.ariaValueNow = bend.toString();\n /** @type {HTMLDivElement} */\n const progressBar = dom.querySelector('.progress-bar');\n progressBar.style.width = `${Math.floor((bend / 16384) * 100)}%`;\n progressBar.title = calculated.toString();\n progressBar.classList.remove('high', 'low');\n if (calculated === 0) {\n return;\n }\n progressBar.classList.add(calculated < 0 ? 'low' : 'high');\n }\n }\n\n /**\n * ピッチベンド・センシビリティ\n *\n * @param {number} channel Pitch bend sensitivity を変更するチャンネル.\n * @param {number} sensitivity\n */\n pitchBendSensitivity(channel, sensitivity) {\n if (this.element) {\n /** @type {HTMLElement} */\n const pitchBendSensitivityVariable = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.pitchBendSensitivity > var');\n pitchBendSensitivityVariable.innerText = sensitivity.toString();\n }\n this.channelPitchBendSensitivity[channel] = sensitivity;\n }\n\n /**\n * アタックタイム\n *\n * @param {number} channel\n * @param {number} attackTime\n */\n attackTime(channel, attackTime) {\n this.channelAttack[channel] = attackTime;\n }\n\n /**\n * ディケイタイム\n *\n * @param {number} channel\n * @param {number} decayTime\n */\n decayTime(channel, decayTime) {\n this.channelDecay[channel] = decayTime;\n }\n\n /**\n * サスティンタイム\n *\n * @param {number} channel\n * @param {number} sustinTime\n */\n sustinTime(channel, sustinTime) {\n this.channelSustin[channel] = sustinTime;\n }\n\n /**\n * リリースタイム\n *\n * @param {number} channel\n * @param {number} releaseTime\n */\n releaseTime(channel, releaseTime) {\n this.channelRelease[channel] = releaseTime;\n }\n\n /**\n * ハーモニックコンテント(ブライトネス)\n *\n * @param {number} channel\n * @param {number} value\n */\n harmonicContent(channel, value) {\n this.channelHarmonicContent[channel] = value;\n }\n\n /**\n * カットオフフリクエンシー\n *\n * @param {number} channel\n * @param {number} value\n */\n cutOffFrequency(channel, value) {\n this.channelCutOffFrequency[channel] = value;\n }\n\n /**\n * リバーブエフェクト\n *\n * @param {number} channel\n * @param {number} depth\n */\n reverbDepth(channel, depth) {\n // リバーブ深度は、ドライ/ウェット比とする。\n this.reverb[channel].mix(depth / 127);\n\n if (this.element) {\n /** @type {HTMLElement} */\n const reverbVariable = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.reverbDepth var');\n reverbVariable.innerText = depth.toString();\n }\n }\n\n /**\n * モジュレーション(ビブラート)デプス\n *\n * @param {number} channel\n * @param {number} depth\n */\n modulationDepth(channel, depth) {\n if (this.element) {\n const dom = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.pitchBend .progress-bar');\n\n // モデレーターが0でないときは、ピッチに斜め線を入れる\n if (depth !== 0) {\n dom.classList.add('progress-bar-striped');\n } else {\n dom.classList.remove('progress-bar-striped');\n }\n }\n this.modulation[channel] = depth;\n }\n\n /**\n * @param {number} channel Pitch bend sensitivity を取得するチャンネル.\n * @return {number}\n */\n getPitchBendSensitivity(channel) {\n return this.channelPitchBendSensitivity[channel];\n }\n\n /**\n * @param {number} key\n * @param {number} volume\n */\n drumInstrumentLevel(key, volume) {\n this.percussionVolume[key] = volume;\n }\n\n /**\n * オールノートオフ\n *\n * @param {number} channel NoteOff するチャンネル.\n */\n allNoteOff(channel) {\n /** @type {SynthesizerNote[]} */\n const currentNoteOn = this.currentNoteOn[channel];\n\n // ホールドを解除\n this.hold(channel, 0);\n\n // 再生中の音をすべて止める\n while (currentNoteOn.length > 0) {\n this.noteOff(channel, currentNoteOn[0].key);\n }\n }\n\n /**\n * オールサウンドオフ\n *\n * @param {number} channel 音を消すチャンネル.\n */\n allSoundOff(channel) {\n /** @type {SynthesizerNote[]} */\n const currentNoteOn = this.currentNoteOn[channel];\n /** @type {SynthesizerNote} */\n let note;\n\n while (currentNoteOn.length > 0) {\n note = currentNoteOn.shift();\n this.noteOff(channel, note.key);\n note.release();\n note.disconnect();\n }\n\n // ホールドを解除\n this.hold(channel, 0);\n }\n\n /**\n * リセットオールコントロール\n *\n * @param {number} channel リセットするチャンネル\n */\n resetAllControl(channel) {\n // 実装不十分では?\n this.allNoteOff(channel);\n this.expression(channel, 127);\n this.pitchBend(channel, 0x00, 0x40);\n }\n\n /**\n * ミュート\n *\n * @param {number} channel ミュートの設定を変更するチャンネル.\n * @param {boolean} mute ミュートにするなら true.\n */\n mute(channel, mute) {\n /** @type {SynthesizerNote[]} */\n const currentNoteOn = this.currentNoteOn[channel];\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n\n this.channelMute[channel] = mute;\n\n if (mute) {\n for (i = 0, il = currentNoteOn.length; i < il; ++i) {\n currentNoteOn[i].disconnect();\n }\n } else {\n for (i = 0, il = currentNoteOn.length; i < il; ++i) {\n currentNoteOn[i].connect();\n }\n }\n }\n\n /**\n * パーカッションチャネルにする\n *\n * @param {number} channel パーカッションチャネルとしてセットするチャンネル\n * @param {boolean} sw パーカッションチャネルか通常かのスイッチ\n */\n setPercussionPart(channel, sw) {\n this.channelBank[channel] =\n this.mode === 'GS' || this.mode === 'GM2' ? 128 : 127;\n\n this.percussionPart[channel] = sw;\n this.updateBankSelect(channel);\n }\n\n /**\n * MIDI音源のメッセージ欄に送られるsysExを解析\n *\n * @param {number[]} message\n */\n processMidiMessage(message) {\n clearTimeout(this.timer);\n /** @type {HTMLElement} */\n const dom = this.element.querySelector('.header .keys code');\n dom.innerText = message.map(e => String.fromCharCode(e)).join('');\n\n // 10秒後に削除\n this.timer = setTimeout(() => {\n dom.innerText = '';\n }, 50000);\n }\n}\n","/**\n * @classdesc File Loader Class\n * @private\n * @author Logue \n */\nexport default class Loader {\n /** キャッシュの名前空間 */\n static CACHE_NAME = 'wml';\n /**\n * コンストラクタ\n *\n * @constructor\n * @param {string} url\n * @param {HTMLDivElement} placeholder\n * @param {boolean} cache\n * @param {Function} callback\n */\n constructor(url, placeholder, cache, callback) {\n this.url = url;\n this.cache = cache;\n this.callback = callback;\n\n /** @type {HTMLDivElement} */\n this.alert = document.createElement('div');\n this.alert.className = 'alert alert-warning';\n\n /** @type {HTMLParagraphElement} */\n this.message = document.createElement('p');\n this.message.innerText = 'Now Loading...';\n\n /** @type {HTMLDivElement} */\n this.progressOuter = document.createElement('div');\n this.progressOuter.className = 'progress';\n this.progressOuter.role = 'progressbar';\n this.progressOuter.ariaLabel = `Loading Progress`;\n this.progressOuter.ariaValueMin = '0';\n this.progressOuter.ariaValueNow = '0';\n this.progressOuter.ariaValueMax = '100';\n\n /** @type {HTMLDivElement} */\n this.progress = document.createElement('div');\n this.progress.className = 'progress-bar';\n\n this.progressOuter.appendChild(this.progress);\n this.alert.appendChild(this.message);\n this.alert.appendChild(this.progressOuter);\n\n placeholder.appendChild(this.alert);\n }\n\n /**\n * ダウンロード中のハンドラ\n * @param {number} current\n * @param {number} total\n * @private\n */\n onProgress(current, total) {\n const percentCompleted = Math.floor((current / total) * 100);\n this.progress.style.width = `${percentCompleted}%`;\n this.progress.innerText = `${percentCompleted}%`;\n }\n\n /**\n * ロード完了時のハンドラ\n *\n * @param {ArrayBuffer} buffer\n * @private\n */\n onComplete(buffer) {\n this.alert.className = 'alert alert-info';\n this.message.innerText = 'Initializing...';\n this.progress.className =\n 'progress-bar progress-bar-striped progress-bar-animated';\n this.progress.style.width = '100%';\n // コールバック実行\n this.callback(new Uint8Array(buffer));\n }\n\n /**\n * エラー時のハンドラ\n *\n * @param {Error | undefined} error エラー内容\n * @private\n */\n onError(error = undefined) {\n requestAnimationFrame(() => {\n this.alert.className = 'alert alert-danger';\n this.message.innerText =\n 'An error occurred while loading SoundFont. See the console log for details. In addition, it may be cured by deleting the cache of the browser.';\n this.progressOuter.style.display = 'none';\n });\n }\n\n /**\n * データ取得\n * @public\n */\n async fetch() {\n /** @type {Cache} */\n const cache = await window.caches.open(Loader.CACHE_NAME);\n /** @type {Response} */\n const cached = await cache.match(this.url);\n\n if (this.cache && cached) {\n // キャッシュが存在する場合、キャッシュの値を返す\n this.onComplete(await cached.arrayBuffer());\n return;\n }\n\n /** @type {void | Response} キャッシュがない場合Fetchで取得 */\n const response = await fetch(this.url, {\n method: 'GET',\n }).catch(e => this.onError(e));\n\n if (!response || (response && !response.ok)) {\n return;\n }\n\n /** @type {Response} キャッシュ用レスポンス */\n const cloned = response.clone();\n\n /** @type {number} ファイルの容量 */\n const contentLength = parseInt(response.headers.get('Content-Length'));\n\n /** @type {ReadableStreamDefaultReader} ファイルリーダー */\n const reader = cloned.body.getReader();\n\n /** @type {number} 読み込まれたチャンクの長さ */\n let receivedLength = 0;\n\n /** @type {Uint8Array[]} 受信したバイナリチャンクの配列(本文を構成します) */\n const chunks = [];\n\n // eslint-disable-next-line\n while (true) {\n // 最後のチャンクも場合、done は true。\n // value はチャンクバイトの Uint8Array\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n chunks.push(value);\n receivedLength += value.length;\n\n this.message.innerText = `Now Loading... (${receivedLength} of ${contentLength} byte)`;\n\n // Content lengthヘッダーが出力されている場合プログレスバーを表示\n this.onProgress(receivedLength, contentLength);\n }\n\n /** @type {Uint8Array} 全チャンク */\n const chunksAll = new Uint8Array(receivedLength);\n /** @type {number} 現在の読み込んだチャンク位置 */\n let position = 0;\n for (const chunk of chunks) {\n chunksAll.set(chunk, position);\n position += chunk.length;\n }\n\n // キャッシュへ保存\n await cache.put(this.url, response);\n // 完了時のイベントを実行\n this.onComplete(chunksAll);\n }\n}\n","import Synthesizer from './sound_font_synth';\nimport Loader from './loader';\n\n/**\n * WebMidiLink Class\n *\n * @author imaya\n */\nexport default class WebMidiLink {\n /** @param {object} option */\n constructor(option = {}) {\n /** @type {number[]} */\n this.NrpnMsb = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n /** @type {number[]} */\n this.NrpnLsb = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n /** @type {number[]} */\n this.RpnMsb = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n /** @type {number[]} */\n this.RpnLsb = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n /** @type {boolean} */\n this.ready = false;\n /** @type {Synthesizer} */\n this.synth = undefined;\n /** @type {Function} */\n this.messageHandler = this.onMessage.bind(this);\n /** @type {boolean} */\n this.rpnMode = true;\n /** @type {object} */\n this.option = {};\n /** @type {boolean} Display synthsizer Web UI */\n this.option.drawSynth = option.drawSynth !== 'false';\n /** @type {boolean} Use Cache API */\n this.option.cache = option.cache ?? true;\n /** @type {string} CORS */\n this.option.targetOrigin = option.targetOrigin ?? '*';\n /** @type {'dark'|'light'|'auto'|undefined} Color mode */\n this.option.colorMode = option.colorMode ?? 'auto';\n /** @type {string} SoundFont URL */\n this.url =\n option.url ??\n 'https://cdn.jsdelivr.net/npm/@logue/sf2synth@latest/dist/Yamaha XG Sound Set.sf2';\n\n /** @type {HTMLDivElement} */\n // @ts-ignore\n this.placeholder = option.placeholder\n ? document.getElementById(option.placeholder)\n : window.document.body;\n this.setColorMode(this.option.colorMode);\n /** @type {Window} */\n this.window = null;\n\n if (window.opener) {\n this.window = window.opener;\n } else if (window.parent !== window) {\n this.window = window.parent;\n } else {\n this.window = window;\n }\n }\n\n /**\n * Setup Soundfont by URL.\n *\n * @param {string?} url SoundFont URL\n * @public\n */\n async setup(url = undefined) {\n // DOMをクリア\n while (this.placeholder.firstChild) {\n this.placeholder.removeChild(this.placeholder.firstChild);\n }\n if (url) {\n // URLが明示的に指定されていた場合\n this.url = url;\n }\n\n /** 読み込み */\n const loader = new Loader(\n this.url,\n this.placeholder,\n this.option.cache,\n (/** @type {ArrayBuffer} */ buffer) => this.setupByBuffer(buffer)\n );\n await loader.fetch();\n }\n\n /**\n * Get SoundFont URL.\n *\n * @return {string}\n */\n getUrl() {\n return this.url;\n }\n\n /**\n * Setup SoundFont by ArrayBuffer.\n *\n * @param {ArrayBuffer} buffer\n */\n setupByBuffer(buffer) {\n // DOMをクリア\n while (this.placeholder.firstChild) {\n this.placeholder.removeChild(this.placeholder.firstChild);\n }\n\n if (!this.synth) {\n // 読み込まれていないときシンセサイザをセットアップ\n // @ts-ignore\n this.synth = new Synthesizer(buffer);\n // 待受開始\n this.synth.start();\n } else {\n // 別のSoundFontが読み込まれたときリロード\n // @ts-ignore\n this.synth.refreshInstruments(buffer);\n }\n if (this.option.drawSynth) {\n // キーボードなどを描画\n this.placeholder.appendChild(this.synth.drawSynth());\n } else {\n /** @type {HTMLDivElement} キーボードを描画しないときはReadyだけを表示する。 */\n const readyElem = document.createElement('div');\n readyElem.className = 'alert alert-success';\n readyElem.role = 'alert';\n readyElem.innerText = 'Ready.';\n this.placeholder.appendChild(readyElem);\n }\n // シンセサイザを初期化\n this.synth.init();\n\n this.onReady();\n }\n\n /**\n * Callback\n *\n * @protected\n */\n callback() {\n return;\n }\n\n /**\n * SoundFont Load Ready\n *\n * @protected\n */\n onReady() {\n // 一旦MIDI Link待受を解除\n // @ts-ignore\n window.removeEventListener('message', this.messageHandler);\n // コールバック実行\n this.callback();\n // MIDI Link待ち受け開始\n // @ts-ignore\n window.addEventListener('message', this.messageHandler, false);\n // ホスト側に準備完了通知を送信\n this.window.postMessage('link,ready', this.option.targetOrigin);\n }\n\n /**\n * WebMidiLink信号をパース\n *\n * @param {Event} ev\n * @private\n */\n onMessage(ev) {\n /** @type {Array} */\n // @ts-ignore\n const msg = typeof ev.data.split === 'function' ? ev.data.split(',') : [];\n /** @type {string} */\n // @ts-ignore\n const type = msg.length !== 0 ? msg.shift() : '';\n /** @type {string} */\n let command;\n\n switch (type) {\n case 'midi':\n this.processMidiMessage(msg.map(hex => parseInt(hex, 16)));\n break;\n case 'link':\n if (this.window === void 0) {\n return;\n }\n command = msg.shift();\n switch (command) {\n case 'reqpatch':\n // TODO: dummy data\n this.window.postMessage('link,patch', this.option.targetOrigin);\n break;\n case 'setpatch':\n case 'ready':\n this.window.postMessage('link,ready', this.option.targetOrigin);\n // TODO: NOP\n break;\n case 'progress':\n // ※この命令は、WebMidiLinkの仕様に含まれていません。\n this.window.postMessage('link,progress', this.option.targetOrigin);\n break;\n default:\n console.error('unknown link message:', command);\n break;\n }\n break;\n default:\n console.error('unknown message type');\n }\n }\n\n /**\n * MIDI準備完了時のコールバック処理を登録する\n *\n * @param {()=>{}} callback コールバック関数\n * @public\n */\n setLoadCallback(callback) {\n this.callback = callback;\n }\n\n /**\n * MIDI信号を解析し、シンセサイザーを操作する\n *\n * @param {number[]} message\n * @protected\n */\n processMidiMessage(message) {\n /** @type {number} */\n const channel = message[0] & 0x0f;\n /** @type {Synthesizer} */\n const synth = this.synth;\n\n // http://amei.or.jp/midistandardcommittee/MIDI1.0.pdf\n switch (message[0] & 0xf0) {\n case 0x80: // NoteOff: 8n kk vv\n // @ts-ignore\n synth.noteOff(channel, message[1], message[2]);\n break;\n case 0x90: // NoteOn: 9n kk vv\n if (message[2] > 0) {\n synth.noteOn(channel, message[1], message[2]);\n } else {\n // @ts-ignore\n synth.noteOff(channel, message[1], 0);\n }\n break;\n case 0xb0: {\n // Control Change: Bn cc dd\n /** @type {number} */\n const value = message[2];\n switch (message[1]) {\n case 0x00: // Bank Select MSB: Bn 00 dd\n synth.bankSelectMsb(channel, value);\n break;\n case 0x01: // Modulation Depth\n synth.modulationDepth(channel, value);\n break;\n case 0x05: // Portament Time\n break;\n case 0x06: // Data Entry(MSB): Bn 06 dd\n if (this.rpnMode) {\n // RPN\n switch (this.RpnMsb[channel]) {\n case 0:\n switch (this.RpnLsb[channel]) {\n case 0: // Pitch Bend Sensitivity\n synth.pitchBendSensitivity(channel, value);\n break;\n case 1:\n // console.log(\"fine\");\n break;\n case 2:\n // console.log(\"coarse\");\n break;\n default:\n // console.log(\"default\");\n break;\n }\n break;\n default:\n // console.log(\"default:\", this.RpnMsb[channel], this.RpnLsb[channel]);\n break;\n }\n } else {\n // NRPN\n switch (this.NrpnMsb[channel]) {\n case 26: // Drum Instrument Level\n synth.drumInstrumentLevel(this.NrpnLsb[channel], value);\n break;\n default:\n // console.log(\"default:\", this.RpnMsb[channel], this.RpnLsb[channel]);\n break;\n }\n }\n break;\n case 0x26: // Data Entry(LSB): Bn 26 dd\n if (this.rpnMode) {\n // RPN\n switch (this.RpnMsb[channel]) {\n case 0:\n switch (this.RpnLsb[channel]) {\n case 0: // Pitch Bend Sensitivity\n synth.pitchBendSensitivity(\n channel,\n synth.getPitchBendSensitivity(channel) + value / 100\n );\n break;\n case 1:\n // console.log(\"fine\");\n break;\n case 2:\n // console.log(\"coarse\");\n break;\n }\n break;\n }\n }\n\n // NRPN で LSB が必要なものは今のところない\n break;\n\n case 0x07: // Volume Change: Bn 07 dd\n synth.volumeChange(channel, value);\n break;\n case 0x0a: // Panpot Change: Bn 0A dd\n synth.panpotChange(channel, value);\n break;\n case 0x78: // All Sound Off: Bn 78 00]\n synth.allSoundOff(channel);\n break;\n case 0x79: // Reset All Control: Bn 79 00\n synth.resetAllControl(channel);\n break;\n case 0x20: // BankSelect LSB: Bn 00 dd\n synth.bankSelectLsb(channel, value);\n break;\n case 0x47: // Harmonic Content\n synth.harmonicContent(channel, value);\n break;\n case 0x60: //\n // console.log(60);\n break;\n case 0x61: //\n // console.log(61);\n break;\n case 0x62: // NRPN LSB\n this.rpnMode = false;\n this.NrpnLsb[channel] = value;\n break;\n case 0x63: // NRPN MSB\n this.rpnMode = false;\n this.NrpnMsb[channel] = value;\n break;\n case 0x64: // RPN LSB\n this.rpnMode = true;\n this.RpnLsb[channel] = value;\n break;\n case 0x65: // RPN MSB\n this.rpnMode = true;\n this.RpnMsb[channel] = value;\n break;\n case 0x40: // Hold\n synth.hold(channel, value);\n break;\n case 0x0b: // Expression\n synth.expression(channel, value);\n break;\n case 0x48: // DecayTyme\n synth.decayTime(channel, value);\n break;\n case 0x49: // ReleaseTime\n synth.releaseTime(channel, value);\n break;\n case 0x4a: // Attack time\n synth.attackTime(channel, value);\n break;\n case 0x4b: // Brightness\n synth.cutOffFrequency(channel, value);\n break;\n case 0x5b: // Effect1 Depth(Reverb Send Level)\n synth.reverbDepth(channel, value);\n break;\n default:\n // not supported\n break;\n }\n break;\n }\n case 0xc0: // Program Change: Cn pp\n synth.programChange(channel, message[1]);\n break;\n case 0xe0: // Pitch Bend\n synth.pitchBend(channel, message[1], message[2]);\n break;\n case 0xf0: {\n // delete checksum\n message.splice(1, 1);\n\n // System Exclusive Message\n // [1] F0\n // [2] https://www.amei.or.jp/report/report6.html\n // [3] \n // [4] \n // [5] \n // [6] \n // [7] \n // [8] \n // [9] \n // [10] \n // [11] [IGNORE]\n // [12] F7 EOX [IGNORE]\n // console.log(this.dumpMessage(message));\n\n /**\n * @type {number} System Exclusive Manufacture's ID Number\n * @see {@link https://electronicmusic.fandom.com/wiki/List_of_MIDI_Manufacturer_IDs}\n */\n const manufacturerId = message[1];\n /** @type {number} Device ID (GM extended=0x10 / ポケミク=0x79 / Any=0x7F) */\n const device = message[2];\n /** @type {number} Model ID: (GM=0x09 / GS=0x42 / XG=0x4C) */\n const model = message[3];\n\n if (manufacturerId === 0x7e || device === 0x09) {\n // Gneral MIDI\n // http://amei.or.jp/midistandardcommittee/Recommended_Practice/GM2_japanese.pdf\n // console.log('GM:', this.dumpMessage(message));\n // Non Realtime\n switch (model) {\n case 0x01:\n // GM System On\n synth.init('GM');\n console.info('\\x1b[34mGM System On\\x1b[0m');\n break;\n case 0x02:\n // GM System Off\n console.info('\\x1b[34mGM System Off\\x1b[0m');\n // Throuh\n break;\n case 0x03:\n // GM2 System On\n console.info('\\x1b[34mGM (v2) System On\\x1b[0m');\n synth.init('GM2');\n break;\n default:\n // @ts-ignore\n console.log('\\x1b[34mGM\\x1b[0m: ' + this.dumpMessage(message));\n }\n } else if (manufacturerId === 0x7f) {\n // Realtime\n if (model === 0x01) {\n // master volume: F0 7F 7F 04 01 [value] [value] F7\n synth.setMasterVolume(message[4] + (message[5] << 7));\n } else {\n // @ts-ignore\n console.log(\n '\\x1b[34mRealtime\\x1b[0m: ' + this.dumpMessage(message)\n );\n }\n } else if (manufacturerId === 0x7d) {\n // smfplayer / sf2synth固有命令は、プライベート/非営利用途用のManufacturer IDである0x7Dを使用する。\n // プログラム上意味はないが、GM互換であるため、deviceID:0x10、ModelID:0x00とする。\n // よって、F0 7D 10 00 [...] 7Fで定義\n\n if (message[4] === 0x01) {\n // カラーモード切替\n // F0 7D 10 00 01 [value]\n if (message[5] === 0x01) {\n // 明示的にライトモード\n this.setColorMode('light');\n } else if (message[5] === 0x02) {\n // 明示的にダークモード\n this.setColorMode('dark');\n } else {\n // OSの設定に合わせる\n this.setColorMode('auto');\n }\n }\n }\n\n if (model === 0x42) {\n // Roland GS\n // http://lib.roland.co.jp/support/jp/manuals/res/1809974/SC-88VL_j.pdf\n // deviceは10、modelIDは42固定。\n // F0 41 10 42 12 [addr] [part] [key] [value] [checksum] F7\n // (DeviceID = 10, ModelID = 42, CommandID = 12)\n\n // QuickTime音源や、WindowsMIDI音源は、GS互換音源なのでmanufacturerIdが41とは限らない\n\n /* * @param {number} GsAddress GSアドレス(未使用)\n const GsAddress = message[6];\n */\n /** @type {number} GSパート番号 */\n const GsPart = message[6] - 0x0f;\n /** @type {number} GSのキーパラメータ */\n const GsKey = message[7];\n /** @type {number} GSの値 */\n const GsValue = message[8];\n // TODO\n switch (GsKey) {\n case 0x00:\n // TEXT INSERT FOR SC (ASCI code)\n // http://kurizill.g1.xrea.com/memorandum/midi2.htm\n // F0 41 10 45 12 10 [page] 00 [...value] [checksum] F7\n // ex. F0 41 10 45 12 10 00 00 [48 65 6C 6C 6F] 21 F7 = Hello\n\n // device IDの値は0x45固定だがその判定処理は省略\n\n if (GsPart === 0x00) {\n // ページが0x00の場合、LCDに表示するメッセージとする\n // @ts-ignore\n const msg = message.splice(8);\n // Remove F7\n msg.pop();\n // Remove Checksum\n msg.pop();\n synth.processMidiMessage(msg);\n } else {\n // GS音源のLCDの16x16のビットマップ画像\n // @ts-ignore\n console.log(\n '\\x1b[31mGS Bitmap message\\x1b[0m:' +\n this.dumpMessage(message)\n );\n }\n break;\n case 0x04:\n // GS Master Volume:\n // F0 41 10 42 12 40 00 04 [value] [checksum] F7\n // console.log('GS Volume:', this.dumpMessage(message));\n synth.setMasterVolume(GsValue * 64);\n break;\n\n case 0x15: {\n // GS Dram part: F0 41 10 42 12 40 1[part no] [Map] [checksum] F7\n // Notice: [sum] is ignroe in this program.\n\n if (GsPart === 0) {\n // 10 Ch.\n synth.setPercussionPart(9, GsValue !== 0x00);\n } else if (GsPart >= 10) {\n // 1~9 Ch.\n synth.setPercussionPart(GsPart - 1, GsValue !== 0x00);\n } else {\n // 11~16 Ch.\n synth.setPercussionPart(GsPart, GsValue !== 0x00);\n }\n break;\n }\n case 0x19:\n // VOLUME ON/OFF (PART LEVEL)\n // F0 41 10 42 12 40 1[part no] 19 [value] [checksum] F7\n console.info(\n '\\x1b[31mGS Volume On/Off\\x1b[0m: ' + GsPart,\n GsValue\n );\n break;\n case 0x30:\n // Reverb Effect\n console.info(\n '\\x1b[31mGS Reverb\\x1b[0m: ' + this.dumpMessage(message)\n );\n break;\n case 0x38:\n // Chorus Effect\n console.info(\n '\\x1b[31mGS Chorus\\x1b[0m: ' + this.dumpMessage(message)\n );\n break;\n case 0x45:\n // Bitmap icon 16x16 ?\n console.info(\n '\\x1b[31mGS Bitmap\\x1b[0m: ' + this.dumpMessage(message)\n );\n break;\n case 0x7f:\n // GS Reset: F0 41 10 42 12 40 00 7F 00 [checksum] F7\n synth.init('GS');\n console.info('\\x1b[31mGS Reset\\x1b[0m');\n break;\n default:\n // @ts-ignore\n console.log('\\x1b[31mGS\\x1b[0m: ' + this.dumpMessage(message));\n }\n } else if (model === 0x4c) {\n // YAMAHA XG\n // F0 43 10 4C [...] F7\n // https://jp.yamaha.com/files/download/other_assets/9/321739/read_aoyama.pdf\n // https://jp.yamaha.com/files/download/other_assets/1/316861/MU100J1.pdf\n\n // カシオとKORGはXG互換音源を作っていたためmanufacturerIdが43とは限らない\n\n /** @type {number} Xg音源のキー */\n const XgKey = message[4];\n /** @type {number} Xg音源のパート */\n const XgPart = message[5];\n\n switch (XgKey) {\n case 0x00:\n // XG Reset:\n // F0 43 1n 4C 00 00 7E 00 F7\n if (message[6] === 0x7e) {\n synth.init('XG');\n console.info('\\x1b[32mXG Reset\\x1b[0m');\n }\n break;\n case 0x02:\n // Effect\n // https://jp.yamaha.com/files/download/other_assets/5/321745/efctparamlist.pdf\n // F0 43 10 4C 02 01 [type] [value] F7\n //\n // type\n // 02: Reverb\n // リバーブエフェクトのインパルス応答を選択する\n // 40: Variation\n // F0 43 10 4C 02 01 40 [type] 00 F7\n // インサーションエフェクトとして使用するモードと全チャンネルにかけるシステムエフェクトモード場合がある。\n // アンプシミュレーターやディストーション、フェイザー、ディレイなど飛び道具的なエフェクトはここに入っていた。\n // 41: バリエーションエフェクトの種類\n // [value]にエフェクトの種類\n // 5B: バリエーションエフェクトをかけるパート\n // F0 43 10 4C 02 01 5B [part] F7\n // [value]が0でインサーションエフェクト、1でシステムエフェクトモードに切り替える。\n // インサーションエフェクトが実装される前(MU100よりも前の機種)は、ディレイ・エフェクトで使う場合が多かった。\n console.log(\n '\\x1b[32mXG Effect\\x1b[0m: ' + this.dumpMessage(message)\n );\n break;\n case 0x03:\n // Insertion Effect\n // F0 43 10 4C 03 [type] [value] F7\n // MU100以降の機種で実装されている。最大2系統。1チャンネルのみ指定可能。\n console.log(\n '\\x1b[32mXG Insertion Effect\\x1b[0m: ' +\n this.dumpMessage(message)\n );\n break;\n case 0x04:\n // XG Master Volume:\n // F0 43 1n 4C 00 00 04 [value] F7\n synth.setMasterVolume(message[9] * 64);\n break;\n case 0x06: {\n // Text:\n // F0 43 1n 4C 06 00 00 [text] F7\n // ex. F0 43 1n 4C 06 00 00 48 65 6C 6C 6F 21 F7 = Hello\n // @ts-ignore\n const msg = message.splice(8);\n // Remove F7\n msg.pop();\n synth.processMidiMessage(msg);\n break;\n }\n case 0x07:\n // Bitmap Window\n // F0 43 10 4C 07 00 00 [bitmap] F7\n // 音源のアイコン描画領域に描画する16x16のビットマップ画像。\n // 7bitごとに左上から描画する。仕様がややこしいので処理しない\n console.log(\n '\\x1b[32mXG Bitmap\\x1b[0m: ' + this.dumpMessage(message)\n );\n break;\n case 0x08:\n // XG Dram Part:\n // F0 43 10 4C 08 [partNum] 07 [map] F7\n // 厳密には[map]は1以上の値が入り、3+1系統までしか使えない(MU2000の場合)が、本プログラムでは制限しない。\n synth.setPercussionPart(XgPart, message[8] !== 0x00);\n break;\n\n default:\n // @ts-ignore\n console.log('\\x1b[32mXG\\x1b[0m: ', this.dumpMessage(message));\n }\n }\n break;\n }\n default:\n // not supported\n synth.setPercussionPart(9, true);\n break;\n }\n }\n\n /**\n * Dump System Exclusive Message\n *\n * @private\n * @param {number[]} messages\n * @return {string}\n */\n dumpMessage(messages) {\n const ret = [];\n let i = 0;\n for (const msg of messages) {\n let str = '';\n switch (i) {\n case 0:\n // 青\n str = '\\x1b[35m';\n break;\n case 1:\n case 2:\n case 3:\n // 黄色\n str = '\\x1b[33m';\n break;\n default:\n // 末尾の場合は青、それ以外はシアン\n str = messages.length - 1 === i ? '\\x1b[35m' : '\\x1b[36m';\n break;\n }\n\n ret.push(str + msg.toString(16).toUpperCase().padStart(2, '0'));\n i++;\n }\n return ret.join(' ') + '\\x1b[0m';\n }\n\n /**\n * Change Color mode\n *\n * @param {'dark'|'light'|'auto'|undefined} mode Color Mode\n * @public\n */\n setColorMode(mode) {\n // Mode was given\n if (mode) {\n if (mode === 'auto') {\n mode = window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light';\n }\n // Update data-* attr on html\n document.documentElement.setAttribute('data-bs-theme', mode);\n }\n // No mode given (e.g. reset)\n else {\n document.documentElement.setAttribute('data-bs-theme', 'auto');\n // Remove data-* attr from html\n document.documentElement.removeAttribute('data-bs-theme');\n }\n }\n}\n","import WebMidiLink from './wml';\n\n/**\n * Web MIDI API Reciever Class.\n *\n * @author Logue \n */\nexport default class WebMidiApi extends WebMidiLink {\n /**\n * @inheritdoc\n */\n constructor(option = {}) {\n super(option);\n /** @type {WebMidi.MIDIAccess | undefined} */\n this.midi = undefined;\n }\n\n /**\n * @inheritdoc\n * @param {string} url\n */\n async setup(url) {\n this.midi = await window.navigator.requestMIDIAccess({ sysex: true });\n await super.setup(url);\n }\n\n /**\n * @inheritdoc\n */\n onReady() {\n // コールバック実行\n super.callback();\n // Web MIDI APIを待ち受け\n this.midi.inputs.forEach(\n (\n /** @type {{ onmidimessage: (msg: WebMidi.MIDIMessageEvent) => void; }} */ input\n ) =>\n (input.onmidimessage = msg =>\n super.processMidiMessage(Array.from(msg.data)))\n );\n }\n}\n","// This file is auto-generated by the build system.\nconst meta = {\n version: '0.6.1',\n date: '2023-11-29T01:03:54.716Z',\n};\nexport default meta;\n","import WebMidiLink from './wml';\nimport WebMidiApi from './web_midi_api';\nimport Parser from './sf2';\nimport Meta from './meta.js';\nimport './wml.scss';\n\nconst SoundFont = {\n version: Meta.version,\n build: Meta.date,\n WebMidiLink,\n WebMidiApi,\n Parser,\n};\n\nexport default SoundFont;\n","\n import qs from 'query-string';\n import SoundFont from '/src/index';\n\n /** sf2synth.js Option */\n let options = {\n ...{\n // URL to SoundFont File\n // url: 'https://cdn.jsdelivr.net/npm/@logue/sf2synth@latest/dist/Yamaha XG Sound Set.sf2',\n // Show Keyboard\n drawSynth: true,\n // Target dom id\n placeholder: 'placeholder',\n // Color Mode (auto, dark, light)\n colorMode: 'auto',\n },\n ...qs.parse(window.location.search),\n ...qs.parse(window.location.hash),\n };\n\n /** @type {typeof import(\"./src/wml\").WebMidiLink } WebMidiLink */\n const wml = new SoundFont.WebMidiLink(options);\n\n document.addEventListener(\n 'DOMContentLoaded',\n event => {\n /** @type {HTMLInputElement} File Input Form */\n const fileInput = document.getElementById('file');\n /** @type {HTMLDivElement} drag area */\n const dragArea = document.getElementById('drag');\n /** @type {HTMLTimeElement} Build Date */\n const build = document.getElementById('build');\n /** @type {HTMLInputElement} */\n const toggleDarkMode = document.getElementById('toggleDarkMode');\n /** @type {HTMLSelectElement} */\n // const selector = document.getElementById('selector');\n\n wml.setLoadCallback(() => {\n dragArea.classList.remove('bg-info');\n document.getElementById('soundfont').innerText = decodeURIComponent(\n wml.getUrl()\n ).match('.+/(.+?)([?#;].*)?$')[1];\n });\n\n // Apply build time\n build.dateTime = SoundFont.build;\n build.innerText = new Date(SoundFont.build).toLocaleString();\n\n wml.setup();\n\n // Keep an eye out for System Light/Dark Mode Changes\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n mediaQuery.addListener(() => {\n // Ignore change if there's an override set\n if (document.documentElement.getAttribute('data-bs-theme')) {\n return;\n }\n\n // Apply color mode.\n wml.setColorMode(options.colorMode);\n\n // Make sure the checkbox is up-to-date\n toggleDarkMode.checked = mediaQuery.matches;\n });\n\n /**\n * Load sound font\n *\n * @param {File} file\n */\n const handleSoundFont = file => {\n const reader = new FileReader();\n reader.readAsArrayBuffer(file);\n\n reader.onload = e => {\n document.getElementById('soundfont').innerText = file.name;\n const data = new Uint8Array(e.target.result);\n wml.setupByBuffer(data);\n };\n };\n\n // When select SoundFont file\n fileInput.addEventListener(\n 'change',\n event => {\n event.preventDefault();\n handleSoundFont(fileInput.files[0]);\n fileInput.value = '';\n },\n false\n );\n\n // When SoundFont Drag and Drop.\n dragArea.addEventListener(\n 'drop',\n event => {\n const dt = event.dataTransfer;\n if (dt.files.length) {\n event.preventDefault();\n event.stopPropagation();\n handleSoundFont(dt.files[0]);\n }\n dragArea.classList.remove('bg-info');\n },\n false\n );\n dragArea.addEventListener(\n 'dragover',\n event => {\n event.preventDefault();\n event.stopPropagation();\n dragArea.classList.add('bg-info');\n },\n false\n );\n dragArea.addEventListener(\n 'dragleave',\n event => {\n event.preventDefault();\n event.stopPropagation();\n dragArea.classList.remove('bg-info');\n },\n false\n );\n\n // Toggle Dark mode\n toggleDarkMode.addEventListener('change', e => {\n wml.setColorMode(e.target.checked ? 'dark' : 'light');\n });\n\n /*\n selector.addEventListener('change', () => {\n console.log(selector.value);\n wml.setup(\n `https://cdn.jsdelivr.net/npm/@logue/sf2synth@latest/dist/${selector.value}`\n );\n });\n */\n },\n false\n );\n\n window.addEventListener(\n 'hashchange',\n () => {\n const url = qs.parse(window.location.hash);\n if (url) {\n wml.setup(url);\n }\n },\n false\n );\n "],"names":["token","singleMatcher","multiMatcher","decodeComponents","components","split","left","right","decode","input","tokens","i","customDecodeURIComponent","replaceMap","match","result","entries","key","decodeUriComponent","encodedURI","splitOnFirst","string","separator","separatorIndex","includeKeys","object","predicate","descriptor","value","isNullOrUndefined","strictUriEncode","x","encodeFragmentIdentifier","encoderForArrayFormat","options","index","encode","keyValueSep","parserForArrayFormat","accumulator","isArray","isEncodedArray","newValue","item","arrayValue","validateArrayFormatSeparator","decodeComponent","keysSorter","a","b","removeHash","hashStart","getHash","url","hash","parseValue","extract","queryStart","parse","query","formatter","returnValue","parameter","parameter_","key2","value2","stringify","shouldFilter","objectCopy","keys","parseUrl","url_","stringifyUrl","queryFromUrl","queryString","urlObjectForFragmentEncode","pick","filter","fragmentIdentifier","exclude","exclusionFilter","SynthesizerNote","ctx","destination","instrument","now","volDelay","modDelay","volAttack","modAttack","volHold","modHold","volDecay","modDecay","loopStart","loopEnd","startTime","pan","sample","buffer","bufferSource","output","panner","volume","outputGain","baseFreq","peekFreq","sustainFreq","modulator","val","release","volEndTimeTmp","volEndTime","modEndTime","playbackRate","computed","start","peekPitch","expression","pitchBend","INV_MAX","ARandom","norm","p","min","max","range","random","SystemRandom","SYSTEM","defaults","Meta","Noise","DEFAULT_OPTS","preseed","n","scale","rnd","state","sum","src","interleave","next","blue","opts","bins","invN","acc","sign","green","ctz32","c","pink","id","red","violet","white","implementsFunction","fn","ensureTransducer","isIterable","Reduced","reduced","isReduced","ensureReduced","unreduced","reducer","init","rfn","push","xs","iterator","xform","complete","reduce","y","compR","take","r","m","Reverb","sourceNode","mix","reverse","type","freq","q","s","algorithm","rate","duration","delayDuration","impulse","impulseL","impulseR","noiseL","noiseR","Riff","optParams","length","ip","size","RiffChunk","chunk","offset","Parser","parser","data","signature","presetHeader","presetZone","instrumentZone","samples","sampleHeader","sampleName","end","startLoop","endLoop","sampleRate","originalPitch","pitchCorrection","sampleLink","sampleType","adjust","newSample","il","j","multiply","code","zone","bagIndex","bagIndexEnd","zoneInfo","instrumentGenerator","instrumentModulator","jl","preset","presetGenerator","presetModulator","modgen","_zone","indexStart","indexEnd","zoneModGen","modgenInfo","info","Synthesizer","entry","initAudioContext","emptySource","mode","modeElement","element","presets","instruments","banks","bank","bankNumber","presetNumber","presetName","programSet","generator","volSustain","volRelease","modSustain","modRelease","tune","sampleModes","sampleId","enumeratorType","doc","wrapper","instElem","eventStart","eventEnd","channel","channelElem","itemElem","checkboxElement","checkbox","event","labelElem","bankSelect","synth","ch","program","select","volumeElem","expressionElem","pitchSensElem","reverbDepthElem","panpotOuter","panpot","pitchOuter","pitch","keyElem","k","itemName","headerElem","_entries","headerItem","channelItem","keysItem","velocity","channelElems","bankElement","bankNo","option","dom","bankIndex","programElement","programNo","instrumentKey","note","currentNoteOn","hold","channelElements","percussionBank","volumeVariable","expressionVariabe","progressBar","percentage","lowerByte","higherByte","bend","calculated","sensitivity","pitchBendSensitivityVariable","attackTime","decayTime","sustinTime","releaseTime","depth","reverbVariable","mute","sw","message","e","Loader","placeholder","cache","callback","current","total","percentCompleted","error","cached","response","cloned","contentLength","reader","receivedLength","chunks","done","chunksAll","position","WebMidiLink","readyElem","ev","msg","command","hex","manufacturerId","device","model","GsPart","GsKey","GsValue","XgKey","XgPart","messages","ret","str","WebMidiApi","meta","SoundFont","qs","wml","fileInput","dragArea","build","toggleDarkMode","mediaQuery","handleSoundFont","file","dt"],"mappings":"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","x_google_ignoreList":[0,1,2,3,5]} \ No newline at end of file +{"version":3,"file":"index-LPfJkeRA.js","sources":["../../node_modules/decode-uri-component/index.js","../../node_modules/split-on-first/index.js","../../node_modules/filter-obj/index.js","../../node_modules/query-string/base.js","../../src/sound_font_synth_note.js","../../node_modules/@logue/reverb/dist/Reverb.es.js","../../src/riff.js","../../src/sf2.js","../../src/sound_font_synth.js","../../src/loader.js","../../src/wml.js","../../src/web_midi_api.js","../../src/meta.js","../../src/index.js","../../index.html?html-proxy&index=0.js"],"sourcesContent":["const token = '%[a-f0-9]{2}';\nconst singleMatcher = new RegExp('(' + token + ')|([^%]+?)', 'gi');\nconst multiMatcher = new RegExp('(' + token + ')+', 'gi');\n\nfunction decodeComponents(components, split) {\n\ttry {\n\t\t// Try to decode the entire string first\n\t\treturn [decodeURIComponent(components.join(''))];\n\t} catch {\n\t\t// Do nothing\n\t}\n\n\tif (components.length === 1) {\n\t\treturn components;\n\t}\n\n\tsplit = split || 1;\n\n\t// Split the array in 2 parts\n\tconst left = components.slice(0, split);\n\tconst right = components.slice(split);\n\n\treturn Array.prototype.concat.call([], decodeComponents(left), decodeComponents(right));\n}\n\nfunction decode(input) {\n\ttry {\n\t\treturn decodeURIComponent(input);\n\t} catch {\n\t\tlet tokens = input.match(singleMatcher) || [];\n\n\t\tfor (let i = 1; i < tokens.length; i++) {\n\t\t\tinput = decodeComponents(tokens, i).join('');\n\n\t\t\ttokens = input.match(singleMatcher) || [];\n\t\t}\n\n\t\treturn input;\n\t}\n}\n\nfunction customDecodeURIComponent(input) {\n\t// Keep track of all the replacements and prefill the map with the `BOM`\n\tconst replaceMap = {\n\t\t'%FE%FF': '\\uFFFD\\uFFFD',\n\t\t'%FF%FE': '\\uFFFD\\uFFFD',\n\t};\n\n\tlet match = multiMatcher.exec(input);\n\twhile (match) {\n\t\ttry {\n\t\t\t// Decode as big chunks as possible\n\t\t\treplaceMap[match[0]] = decodeURIComponent(match[0]);\n\t\t} catch {\n\t\t\tconst result = decode(match[0]);\n\n\t\t\tif (result !== match[0]) {\n\t\t\t\treplaceMap[match[0]] = result;\n\t\t\t}\n\t\t}\n\n\t\tmatch = multiMatcher.exec(input);\n\t}\n\n\t// Add `%C2` at the end of the map to make sure it does not replace the combinator before everything else\n\treplaceMap['%C2'] = '\\uFFFD';\n\n\tconst entries = Object.keys(replaceMap);\n\n\tfor (const key of entries) {\n\t\t// Replace all decoded components\n\t\tinput = input.replace(new RegExp(key, 'g'), replaceMap[key]);\n\t}\n\n\treturn input;\n}\n\nexport default function decodeUriComponent(encodedURI) {\n\tif (typeof encodedURI !== 'string') {\n\t\tthrow new TypeError('Expected `encodedURI` to be of type `string`, got `' + typeof encodedURI + '`');\n\t}\n\n\ttry {\n\t\t// Try the built in decoder first\n\t\treturn decodeURIComponent(encodedURI);\n\t} catch {\n\t\t// Fallback to a more advanced decoder\n\t\treturn customDecodeURIComponent(encodedURI);\n\t}\n}\n","export default function splitOnFirst(string, separator) {\n\tif (!(typeof string === 'string' && typeof separator === 'string')) {\n\t\tthrow new TypeError('Expected the arguments to be of type `string`');\n\t}\n\n\tif (string === '' || separator === '') {\n\t\treturn [];\n\t}\n\n\tconst separatorIndex = string.indexOf(separator);\n\n\tif (separatorIndex === -1) {\n\t\treturn [];\n\t}\n\n\treturn [\n\t\tstring.slice(0, separatorIndex),\n\t\tstring.slice(separatorIndex + separator.length)\n\t];\n}\n","export function includeKeys(object, predicate) {\n\tconst result = {};\n\n\tif (Array.isArray(predicate)) {\n\t\tfor (const key of predicate) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(object, key);\n\t\t\tif (descriptor?.enumerable) {\n\t\t\t\tObject.defineProperty(result, key, descriptor);\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// `Reflect.ownKeys()` is required to retrieve symbol properties\n\t\tfor (const key of Reflect.ownKeys(object)) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(object, key);\n\t\t\tif (descriptor.enumerable) {\n\t\t\t\tconst value = object[key];\n\t\t\t\tif (predicate(key, value, object)) {\n\t\t\t\t\tObject.defineProperty(result, key, descriptor);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function excludeKeys(object, predicate) {\n\tif (Array.isArray(predicate)) {\n\t\tconst set = new Set(predicate);\n\t\treturn includeKeys(object, key => !set.has(key));\n\t}\n\n\treturn includeKeys(object, (key, value, object) => !predicate(key, value, object));\n}\n","import decodeComponent from 'decode-uri-component';\nimport splitOnFirst from 'split-on-first';\nimport {includeKeys} from 'filter-obj';\n\nconst isNullOrUndefined = value => value === null || value === undefined;\n\n// eslint-disable-next-line unicorn/prefer-code-point\nconst strictUriEncode = string => encodeURIComponent(string).replace(/[!'()*]/g, x => `%${x.charCodeAt(0).toString(16).toUpperCase()}`);\n\nconst encodeFragmentIdentifier = Symbol('encodeFragmentIdentifier');\n\nfunction encoderForArrayFormat(options) {\n\tswitch (options.arrayFormat) {\n\t\tcase 'index': {\n\t\t\treturn key => (result, value) => {\n\t\t\t\tconst index = result.length;\n\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| (options.skipNull && value === null)\n\t\t\t\t\t|| (options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...result, [encode(key, options), '[', index, ']'].join(''),\n\t\t\t\t\t];\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\t...result,\n\t\t\t\t\t[encode(key, options), '[', encode(index, options), ']=', encode(value, options)].join(''),\n\t\t\t\t];\n\t\t\t};\n\t\t}\n\n\t\tcase 'bracket': {\n\t\t\treturn key => (result, value) => {\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| (options.skipNull && value === null)\n\t\t\t\t\t|| (options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...result,\n\t\t\t\t\t\t[encode(key, options), '[]'].join(''),\n\t\t\t\t\t];\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\t...result,\n\t\t\t\t\t[encode(key, options), '[]=', encode(value, options)].join(''),\n\t\t\t\t];\n\t\t\t};\n\t\t}\n\n\t\tcase 'colon-list-separator': {\n\t\t\treturn key => (result, value) => {\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| (options.skipNull && value === null)\n\t\t\t\t\t|| (options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...result,\n\t\t\t\t\t\t[encode(key, options), ':list='].join(''),\n\t\t\t\t\t];\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\t...result,\n\t\t\t\t\t[encode(key, options), ':list=', encode(value, options)].join(''),\n\t\t\t\t];\n\t\t\t};\n\t\t}\n\n\t\tcase 'comma':\n\t\tcase 'separator':\n\t\tcase 'bracket-separator': {\n\t\t\tconst keyValueSep = options.arrayFormat === 'bracket-separator'\n\t\t\t\t? '[]='\n\t\t\t\t: '=';\n\n\t\t\treturn key => (result, value) => {\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| (options.skipNull && value === null)\n\t\t\t\t\t|| (options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\t// Translate null to an empty string so that it doesn't serialize as 'null'\n\t\t\t\tvalue = value === null ? '' : value;\n\n\t\t\t\tif (result.length === 0) {\n\t\t\t\t\treturn [[encode(key, options), keyValueSep, encode(value, options)].join('')];\n\t\t\t\t}\n\n\t\t\t\treturn [[result, encode(value, options)].join(options.arrayFormatSeparator)];\n\t\t\t};\n\t\t}\n\n\t\tdefault: {\n\t\t\treturn key => (result, value) => {\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| (options.skipNull && value === null)\n\t\t\t\t\t|| (options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...result,\n\t\t\t\t\t\tencode(key, options),\n\t\t\t\t\t];\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\t...result,\n\t\t\t\t\t[encode(key, options), '=', encode(value, options)].join(''),\n\t\t\t\t];\n\t\t\t};\n\t\t}\n\t}\n}\n\nfunction parserForArrayFormat(options) {\n\tlet result;\n\n\tswitch (options.arrayFormat) {\n\t\tcase 'index': {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tresult = /\\[(\\d*)]$/.exec(key);\n\n\t\t\t\tkey = key.replace(/\\[\\d*]$/, '');\n\n\t\t\t\tif (!result) {\n\t\t\t\t\taccumulator[key] = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = {};\n\t\t\t\t}\n\n\t\t\t\taccumulator[key][result[1]] = value;\n\t\t\t};\n\t\t}\n\n\t\tcase 'bracket': {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tresult = /(\\[])$/.exec(key);\n\t\t\t\tkey = key.replace(/\\[]$/, '');\n\n\t\t\t\tif (!result) {\n\t\t\t\t\taccumulator[key] = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = [value];\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\taccumulator[key] = [...accumulator[key], value];\n\t\t\t};\n\t\t}\n\n\t\tcase 'colon-list-separator': {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tresult = /(:list)$/.exec(key);\n\t\t\t\tkey = key.replace(/:list$/, '');\n\n\t\t\t\tif (!result) {\n\t\t\t\t\taccumulator[key] = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = [value];\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\taccumulator[key] = [...accumulator[key], value];\n\t\t\t};\n\t\t}\n\n\t\tcase 'comma':\n\t\tcase 'separator': {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tconst isArray = typeof value === 'string' && value.includes(options.arrayFormatSeparator);\n\t\t\t\tconst isEncodedArray = (typeof value === 'string' && !isArray && decode(value, options).includes(options.arrayFormatSeparator));\n\t\t\t\tvalue = isEncodedArray ? decode(value, options) : value;\n\t\t\t\tconst newValue = isArray || isEncodedArray ? value.split(options.arrayFormatSeparator).map(item => decode(item, options)) : (value === null ? value : decode(value, options));\n\t\t\t\taccumulator[key] = newValue;\n\t\t\t};\n\t\t}\n\n\t\tcase 'bracket-separator': {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tconst isArray = /(\\[])$/.test(key);\n\t\t\t\tkey = key.replace(/\\[]$/, '');\n\n\t\t\t\tif (!isArray) {\n\t\t\t\t\taccumulator[key] = value ? decode(value, options) : value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst arrayValue = value === null\n\t\t\t\t\t? []\n\t\t\t\t\t: value.split(options.arrayFormatSeparator).map(item => decode(item, options));\n\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = arrayValue;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\taccumulator[key] = [...accumulator[key], ...arrayValue];\n\t\t\t};\n\t\t}\n\n\t\tdefault: {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\taccumulator[key] = [...[accumulator[key]].flat(), value];\n\t\t\t};\n\t\t}\n\t}\n}\n\nfunction validateArrayFormatSeparator(value) {\n\tif (typeof value !== 'string' || value.length !== 1) {\n\t\tthrow new TypeError('arrayFormatSeparator must be single character string');\n\t}\n}\n\nfunction encode(value, options) {\n\tif (options.encode) {\n\t\treturn options.strict ? strictUriEncode(value) : encodeURIComponent(value);\n\t}\n\n\treturn value;\n}\n\nfunction decode(value, options) {\n\tif (options.decode) {\n\t\treturn decodeComponent(value);\n\t}\n\n\treturn value;\n}\n\nfunction keysSorter(input) {\n\tif (Array.isArray(input)) {\n\t\treturn input.sort();\n\t}\n\n\tif (typeof input === 'object') {\n\t\treturn keysSorter(Object.keys(input))\n\t\t\t.sort((a, b) => Number(a) - Number(b))\n\t\t\t.map(key => input[key]);\n\t}\n\n\treturn input;\n}\n\nfunction removeHash(input) {\n\tconst hashStart = input.indexOf('#');\n\tif (hashStart !== -1) {\n\t\tinput = input.slice(0, hashStart);\n\t}\n\n\treturn input;\n}\n\nfunction getHash(url) {\n\tlet hash = '';\n\tconst hashStart = url.indexOf('#');\n\tif (hashStart !== -1) {\n\t\thash = url.slice(hashStart);\n\t}\n\n\treturn hash;\n}\n\nfunction parseValue(value, options) {\n\tif (options.parseNumbers && !Number.isNaN(Number(value)) && (typeof value === 'string' && value.trim() !== '')) {\n\t\tvalue = Number(value);\n\t} else if (options.parseBooleans && value !== null && (value.toLowerCase() === 'true' || value.toLowerCase() === 'false')) {\n\t\tvalue = value.toLowerCase() === 'true';\n\t}\n\n\treturn value;\n}\n\nexport function extract(input) {\n\tinput = removeHash(input);\n\tconst queryStart = input.indexOf('?');\n\tif (queryStart === -1) {\n\t\treturn '';\n\t}\n\n\treturn input.slice(queryStart + 1);\n}\n\nexport function parse(query, options) {\n\toptions = {\n\t\tdecode: true,\n\t\tsort: true,\n\t\tarrayFormat: 'none',\n\t\tarrayFormatSeparator: ',',\n\t\tparseNumbers: false,\n\t\tparseBooleans: false,\n\t\t...options,\n\t};\n\n\tvalidateArrayFormatSeparator(options.arrayFormatSeparator);\n\n\tconst formatter = parserForArrayFormat(options);\n\n\t// Create an object with no prototype\n\tconst returnValue = Object.create(null);\n\n\tif (typeof query !== 'string') {\n\t\treturn returnValue;\n\t}\n\n\tquery = query.trim().replace(/^[?#&]/, '');\n\n\tif (!query) {\n\t\treturn returnValue;\n\t}\n\n\tfor (const parameter of query.split('&')) {\n\t\tif (parameter === '') {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst parameter_ = options.decode ? parameter.replace(/\\+/g, ' ') : parameter;\n\n\t\tlet [key, value] = splitOnFirst(parameter_, '=');\n\n\t\tif (key === undefined) {\n\t\t\tkey = parameter_;\n\t\t}\n\n\t\t// Missing `=` should be `null`:\n\t\t// http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters\n\t\tvalue = value === undefined ? null : (['comma', 'separator', 'bracket-separator'].includes(options.arrayFormat) ? value : decode(value, options));\n\t\tformatter(decode(key, options), value, returnValue);\n\t}\n\n\tfor (const [key, value] of Object.entries(returnValue)) {\n\t\tif (typeof value === 'object' && value !== null) {\n\t\t\tfor (const [key2, value2] of Object.entries(value)) {\n\t\t\t\tvalue[key2] = parseValue(value2, options);\n\t\t\t}\n\t\t} else {\n\t\t\treturnValue[key] = parseValue(value, options);\n\t\t}\n\t}\n\n\tif (options.sort === false) {\n\t\treturn returnValue;\n\t}\n\n\t// TODO: Remove the use of `reduce`.\n\t// eslint-disable-next-line unicorn/no-array-reduce\n\treturn (options.sort === true ? Object.keys(returnValue).sort() : Object.keys(returnValue).sort(options.sort)).reduce((result, key) => {\n\t\tconst value = returnValue[key];\n\t\tif (Boolean(value) && typeof value === 'object' && !Array.isArray(value)) {\n\t\t\t// Sort object keys, not values\n\t\t\tresult[key] = keysSorter(value);\n\t\t} else {\n\t\t\tresult[key] = value;\n\t\t}\n\n\t\treturn result;\n\t}, Object.create(null));\n}\n\nexport function stringify(object, options) {\n\tif (!object) {\n\t\treturn '';\n\t}\n\n\toptions = {encode: true,\n\t\tstrict: true,\n\t\tarrayFormat: 'none',\n\t\tarrayFormatSeparator: ',', ...options};\n\n\tvalidateArrayFormatSeparator(options.arrayFormatSeparator);\n\n\tconst shouldFilter = key => (\n\t\t(options.skipNull && isNullOrUndefined(object[key]))\n\t\t|| (options.skipEmptyString && object[key] === '')\n\t);\n\n\tconst formatter = encoderForArrayFormat(options);\n\n\tconst objectCopy = {};\n\n\tfor (const [key, value] of Object.entries(object)) {\n\t\tif (!shouldFilter(key)) {\n\t\t\tobjectCopy[key] = value;\n\t\t}\n\t}\n\n\tconst keys = Object.keys(objectCopy);\n\n\tif (options.sort !== false) {\n\t\tkeys.sort(options.sort);\n\t}\n\n\treturn keys.map(key => {\n\t\tconst value = object[key];\n\n\t\tif (value === undefined) {\n\t\t\treturn '';\n\t\t}\n\n\t\tif (value === null) {\n\t\t\treturn encode(key, options);\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tif (value.length === 0 && options.arrayFormat === 'bracket-separator') {\n\t\t\t\treturn encode(key, options) + '[]';\n\t\t\t}\n\n\t\t\treturn value\n\t\t\t\t.reduce(formatter(key), [])\n\t\t\t\t.join('&');\n\t\t}\n\n\t\treturn encode(key, options) + '=' + encode(value, options);\n\t}).filter(x => x.length > 0).join('&');\n}\n\nexport function parseUrl(url, options) {\n\toptions = {\n\t\tdecode: true,\n\t\t...options,\n\t};\n\n\tlet [url_, hash] = splitOnFirst(url, '#');\n\n\tif (url_ === undefined) {\n\t\turl_ = url;\n\t}\n\n\treturn {\n\t\turl: url_?.split('?')?.[0] ?? '',\n\t\tquery: parse(extract(url), options),\n\t\t...(options && options.parseFragmentIdentifier && hash ? {fragmentIdentifier: decode(hash, options)} : {}),\n\t};\n}\n\nexport function stringifyUrl(object, options) {\n\toptions = {\n\t\tencode: true,\n\t\tstrict: true,\n\t\t[encodeFragmentIdentifier]: true,\n\t\t...options,\n\t};\n\n\tconst url = removeHash(object.url).split('?')[0] || '';\n\tconst queryFromUrl = extract(object.url);\n\n\tconst query = {\n\t\t...parse(queryFromUrl, {sort: false}),\n\t\t...object.query,\n\t};\n\n\tlet queryString = stringify(query, options);\n\tif (queryString) {\n\t\tqueryString = `?${queryString}`;\n\t}\n\n\tlet hash = getHash(object.url);\n\tif (object.fragmentIdentifier) {\n\t\tconst urlObjectForFragmentEncode = new URL(url);\n\t\turlObjectForFragmentEncode.hash = object.fragmentIdentifier;\n\t\thash = options[encodeFragmentIdentifier] ? urlObjectForFragmentEncode.hash : `#${object.fragmentIdentifier}`;\n\t}\n\n\treturn `${url}${queryString}${hash}`;\n}\n\nexport function pick(input, filter, options) {\n\toptions = {\n\t\tparseFragmentIdentifier: true,\n\t\t[encodeFragmentIdentifier]: false,\n\t\t...options,\n\t};\n\n\tconst {url, query, fragmentIdentifier} = parseUrl(input, options);\n\n\treturn stringifyUrl({\n\t\turl,\n\t\tquery: includeKeys(query, filter),\n\t\tfragmentIdentifier,\n\t}, options);\n}\n\nexport function exclude(input, filter, options) {\n\tconst exclusionFilter = Array.isArray(filter) ? key => !filter.includes(key) : (key, value) => !filter(key, value);\n\n\treturn pick(input, exclusionFilter, options);\n}\n","/**\n * SynthesizerNote Class\n *\n * @author imaya\n * @private\n */\nexport default class SynthesizerNote {\n /**\n * @param {AudioContext} ctx\n * @param {AudioNode} destination\n * @param {{\n * channel: number;\n * key: number;\n * sample: Uint8Array;\n * basePlaybackRate: number;\n * loopStart: number;\n * loopEnd: number;\n * volume: number;\n * panpot: number;\n * }} instrument\n */\n constructor(ctx, destination, instrument) {\n /** @type {AudioContext} */\n this.ctx = ctx;\n /** @type {AudioNode} */\n this.destination = destination;\n /**\n * @type {{\n * channel: number;\n * key: number;\n * sample: Uint8Array;\n * basePlaybackRate: number;\n * loopStart: number;\n * loopEnd: number;\n * volume: number;\n * panpot: number;\n * }}\n */\n this.instrument = instrument;\n /** @type {number} */\n this.channel = instrument['channel'];\n /** @type {number} */\n this.key = instrument['key'];\n /** @type {number} */\n this.velocity = instrument['velocity'];\n /** @type {Uint8Array} */\n this.buffer = instrument['sample'];\n /** @type {number} */\n this.playbackRate = instrument['basePlaybackRate'];\n /** @type {number} */\n this.loopStart = instrument['loopStart'];\n /** @type {number} */\n this.loopEnd = instrument['loopEnd'];\n /** @type {number} */\n this.sampleRate = instrument['sampleRate'];\n /** @type {number} */\n this.volume = instrument['volume'];\n /** @type {number} */\n this.panpot = instrument['panpot'];\n /** @type {number} */\n this.pitchBend = instrument['pitchBend'];\n /** @type {number} */\n this.pitchBendSensitivity = instrument['pitchBendSensitivity'];\n /** @type {number} */\n this.modEnvToPitch = instrument['modEnvToPitch'];\n /** @type {number} */\n this.expression = instrument['expression'];\n /** @type {number} */\n this.modulation = instrument['modulation'];\n /** @type {number} */\n this.cutOffFrequency = instrument['cutOffFrequency'];\n /** @type {number} */\n this.hermonicContent = instrument['hermonicContent'];\n\n /** @type {import('@logue/reverb').default} */\n this.reverb = instrument['reverb'];\n\n // state\n /** @type {number} */\n this.startTime = ctx.currentTime;\n /** @type {number} */\n this.computedPlaybackRate = this.playbackRate | 0;\n /** @type {boolean} */\n this.noteOffState = false;\n\n // ---------------------------------------------------------------------------\n // audio node\n // ---------------------------------------------------------------------------\n\n /** @type {AudioBuffer} */\n this.audioBuffer = null;\n /** @type {AudioBufferSourceNode} */\n this.bufferSource = ctx.createBufferSource();\n /** @type {PannerNode} */\n this.panner = ctx.createPanner();\n /** @type {GainNode} */\n this.outputGainNode = ctx.createGain();\n /** @type {GainNode} */\n this.expressionGainNode = ctx.createGain();\n /** @type {BiquadFilterNode} */\n this.filter = ctx.createBiquadFilter();\n /** @type {BiquadFilterNode} */\n this.modulator = ctx.createBiquadFilter();\n }\n\n /** Note on */\n noteOn() {\n /** @type {AudioContext} */\n const ctx = this.ctx;\n /**\n * @type {{\n * channel: number;\n * key: number;\n * sample: Uint8Array;\n * basePlaybackRate: number;\n * loopStart: number;\n * loopEnd: number;\n * volume: number;\n * panpot: number;\n * }}\n */\n const instrument = this.instrument;\n /** @type {number} */\n const now = this.ctx.currentTime || 0;\n /** @type {number} */\n const volDelay = now + instrument['volDelay'];\n /** @type {number} */\n const modDelay = now + instrument['modDelay'];\n /** @type {number} */\n const volAttack = volDelay + instrument['volAttack'];\n /** @type {number} */\n const modAttack = volDelay + instrument['modAttack'];\n /** @type {number} */\n const volHold = volAttack + instrument['volHold'];\n /** @type {number} */\n const modHold = modAttack + instrument['modHold'];\n /** @type {number} */\n const volDecay = volHold + instrument['volDecay'];\n /** @type {number} */\n const modDecay = modHold + instrument['modDecay'];\n /** @type {number} */\n const loopStart = instrument['loopStart'] / this.sampleRate;\n /** @type {number} */\n const loopEnd = instrument['loopEnd'] / this.sampleRate;\n /** @type {number} */\n const startTime = instrument['start'] / this.sampleRate;\n // TODO: ドラムパートのPanが変化した場合、その計算をしなければならない\n // http://cpansearch.perl.org/src/PJB/MIDI-SoundFont-1.08/doc/sfspec21.html#8.4.6\n /** @type {number} */\n const pan = instrument['pan'] !== 0 ? instrument['pan'] : this.panpot;\n\n const sample = this.buffer.subarray(\n 0,\n this.buffer.length + instrument['end']\n );\n /** @type {AudioBuffer} */\n const buffer = (this.audioBuffer = ctx.createBuffer(\n 1,\n sample.length,\n this.sampleRate\n ));\n /** @type {Float32Array} */\n const channelData = buffer.getChannelData(0);\n channelData.set(sample);\n\n // buffer source\n /** @type {AudioBufferSourceNode} */\n const bufferSource = this.bufferSource;\n bufferSource.buffer = buffer;\n bufferSource.loop = instrument['sampleModes'] || 0;\n bufferSource.loopStart = loopStart;\n bufferSource.loopEnd = loopEnd;\n this.updatePitchBend(this.pitchBend);\n\n // Output\n /** @type {GainNode} */\n const output = this.outputGainNode;\n\n // expression\n this.expressionGainNode.gain.value = this.expression / 127;\n\n // panpot\n /** @type {PannerNode} */\n const panner = this.panner;\n panner.panningModel = 'equalpower';\n panner.distanceModel = 'inverse';\n panner.positionX.setValueAtTime(Math.sin((pan * Math.PI) / 2), 0);\n panner.positionY.setValueAtTime(0, 0);\n panner.positionZ.setValueAtTime(Math.cos((pan * Math.PI) / 2), 0);\n\n // ---------------------------------------------------------------------------\n // Delay, Attack, Hold, Decay, Sustain\n // ---------------------------------------------------------------------------\n\n /** @type {number} */\n let volume =\n this.volume *\n (this.velocity / 127) *\n (1 - instrument['initialAttenuation'] / 1000);\n if (volume < 0) {\n volume = 0;\n }\n\n /** @type {AudioParam} volume envelope */\n const outputGain = output.gain;\n outputGain.setValueAtTime(0, now);\n outputGain.setValueAtTime(0, volDelay);\n outputGain.setTargetAtTime(volume, volDelay, instrument['volAttack']);\n outputGain.setValueAtTime(volume, volHold);\n outputGain.linearRampToValueAtTime(\n volume * (1 - instrument['volSustain']),\n volDecay\n );\n\n // modulation envelope\n /** @type {number} */\n const baseFreq = instrument['initialFilterFc'];\n /** @type {number} */\n const peekFreq =\n instrument['initialFilterFc'] + instrument['modEnvToFilterFc'];\n /** @type {number} */\n const sustainFreq =\n baseFreq + (peekFreq - baseFreq) * (1 - instrument['modSustain']);\n\n /** @type {BiquadFilterNode} */\n const modulator = this.modulator;\n modulator.Q.setValueAtTime(10 ** (instrument['initialFilterQ'] / 200), now);\n modulator.frequency.value = baseFreq;\n modulator.type = 'lowpass';\n modulator.frequency.setTargetAtTime(\n baseFreq / 127,\n this.ctx.currentTime,\n 0.5\n );\n modulator.frequency.setValueAtTime(baseFreq, now);\n modulator.frequency.setValueAtTime(baseFreq, modDelay);\n modulator.frequency.setTargetAtTime(\n peekFreq,\n modDelay,\n parseFloat(instrument['modAttack'])\n );\n modulator.frequency.setValueAtTime(peekFreq, modHold);\n modulator.frequency.exponentialRampToValueAtTime(sustainFreq, modDecay);\n\n // Vibrato\n /* * @type {GainNode} LFO Depth * /\n const lfoDepth = this.ctx.createGain();\n /* * @type {OscillatorNode} LFO Oscillator * /\n const lfo = this.ctx.createOscillator();\n // Set parameters for LFO\n lfo.type = 'sine';\n lfoDepth.gain.value = 1;\n lfo.frequency.value = this.instrument['freqVibLFO'];\n\n if (this.modulation) {\n // Effector (Vibrato) ON\n lfo.start(0);\n } else {\n // Effector (Vibrato) Off\n lfo.stop(0);\n }\n // OscillatorNode (LFO) -> GainNode (Depth) -> frequency (AudioParam)\n lfo.connect(lfoDepth);\n\n // connect\n bufferSource.connect(lfoDepth);\n lfoDepth.connect(modulator);\n modulator.connect(panner);\n panner.connect(this.expressionGainNode);\n */\n bufferSource.connect(modulator);\n modulator.connect(panner);\n panner.connect(this.expressionGainNode);\n\n if (!instrument['mute']) {\n this.connect();\n }\n\n this.expressionGainNode.connect(output);\n\n // fire\n bufferSource.start(0, startTime);\n }\n\n /**\n * @param {number} val\n * @return {number}\n */\n amountToFreq(val) {\n return 2 ** ((val - 6900) / 1200) * 440;\n }\n\n /** Note off */\n noteOff() {\n this.noteOffState = true;\n }\n\n /** @return {boolean} */\n isNoteOff() {\n return this.noteOffState;\n }\n\n /** @return {void} */\n release() {\n /**\n * @type {{\n * channel: number;\n * key: number;\n * sample: Uint8Array;\n * basePlaybackRate: number;\n * loopStart: number;\n * loopEnd: number;\n * volume: number;\n * panpot: number;\n * }}\n */\n const instrument = this.instrument;\n /** @type {AudioBufferSourceNode} */\n const bufferSource = this.bufferSource;\n /** @type {GainNode} */\n const output = this.outputGainNode;\n /** @type {number} */\n const now = this.ctx.currentTime;\n /** @type {number} */\n const release = instrument['releaseTime'] - 64;\n\n // ---------------------------------------------------------------------------\n // volume release time\n // ---------------------------------------------------------------------------\n /** @type {number} */\n const volEndTimeTmp = instrument['volRelease'] * output.gain.value;\n /** @type {number} */\n const volEndTime =\n now + volEndTimeTmp * (1 + release / (release < 0 ? 64 : 63));\n // now + instrument['volRelease'] * (1 - instrument['volSustain']);\n\n // ---------------------------------------------------------------------------\n // modulation release time\n // ---------------------------------------------------------------------------\n /** @type {BiquadFilterNode} */\n const modulator = this.modulator;\n /** @type {number} */\n const baseFreq = instrument['initialFilterFc'];\n /** @type {number} */\n const peekFreq =\n instrument['initialFilterFc'] + instrument['modEnvToFilterFc'];\n /** @type {number} */\n const modEndTime =\n now +\n instrument['modRelease'] *\n (baseFreq === peekFreq\n ? 1\n : (modulator.frequency.value - baseFreq) / (peekFreq - baseFreq));\n\n // const modEndTime =\n // now + instrument['modRelease'] * (1 - instrument['modSustain']);\n\n if (!this.audioBuffer) {\n return;\n }\n\n // ---------------------------------------------------------------------------\n // Release\n // ---------------------------------------------------------------------------\n\n switch (instrument['sampleModes']) {\n case 0:\n // ループしない\n bufferSource.loop = false;\n break;\n case 1:\n // ループさせる\n output.gain.cancelScheduledValues(0);\n output.gain.setValueAtTime(output.gain.value, now);\n output.gain.linearRampToValueAtTime(0, volEndTime);\n\n modulator.frequency.cancelScheduledValues(0);\n modulator.frequency.setValueAtTime(modulator.frequency.value, now);\n modulator.frequency.exponentialRampToValueAtTime(baseFreq, modEndTime);\n\n bufferSource.playbackRate.cancelScheduledValues(0);\n bufferSource.playbackRate.setValueAtTime(\n bufferSource.playbackRate.value,\n now\n );\n bufferSource.playbackRate.exponentialRampToValueAtTime(\n this.computedPlaybackRate,\n modEndTime\n );\n\n bufferSource.stop(volEndTime);\n break;\n case 2:\n // 未定義\n throw Error('[SynthesizerNote] Detect unused sampleModes');\n case 3:\n // ノートオフまでループさせる\n output.gain.cancelScheduledValues(0);\n output.gain.setValueAtTime(output.gain.value, now);\n output.gain.linearRampToValueAtTime(0, volEndTime);\n\n modulator.frequency.cancelScheduledValues(0);\n modulator.frequency.setValueAtTime(modulator.frequency.value, now);\n modulator.frequency.exponentialRampToValueAtTime(baseFreq, modEndTime);\n\n bufferSource.playbackRate.cancelScheduledValues(0);\n bufferSource.playbackRate.setValueAtTime(\n bufferSource.playbackRate.value,\n now\n );\n bufferSource.playbackRate.exponentialRampToValueAtTime(\n this.computedPlaybackRate,\n modEndTime\n );\n bufferSource.loop = false;\n bufferSource.buffer = null;\n break;\n default:\n throw Error(\n `[SynthesizerNote] ${instrument['sampleModes']} is undefined sampleModes.`\n );\n }\n }\n\n /** Connect AudioContext */\n connect() {\n this.reverb.connect(this.outputGainNode).connect(this.destination);\n }\n\n /** Disconnect AudioContext */\n disconnect() {\n this.outputGainNode.disconnect(0);\n }\n\n /** Caluclate playback rate */\n schedulePlaybackRate() {\n /** @type {AudioParam} */\n const playbackRate = this.bufferSource.playbackRate;\n /** @type {number} */\n const computed = this.computedPlaybackRate;\n /** @type {number} */\n const start = this.startTime;\n /** @type {Object} */\n const instrument = this.instrument;\n /** @type {number} */\n const modAttack = start + instrument['modAttack'];\n /** @type {number} */\n const modDecay = modAttack + instrument['modDecay'];\n /** @type {number} */\n const peekPitch =\n computed *\n 1.0594630943592953 ** // Math.pow(2, 1 / 12)\n (this.modEnvToPitch * this.instrument['scaleTuning']);\n\n playbackRate.cancelScheduledValues(0);\n playbackRate.setValueAtTime(computed, start);\n playbackRate.linearRampToValueAtTime(peekPitch, modAttack);\n playbackRate.linearRampToValueAtTime(\n computed + (peekPitch - computed) * (1 - instrument['modSustain']),\n modDecay\n );\n }\n\n /** @param {number} expression */\n updateExpression(expression) {\n this.expressionGainNode.gain.value = (this.expression = expression) / 127;\n }\n\n /** @param {number} pitchBend */\n updatePitchBend(pitchBend) {\n this.computedPlaybackRate =\n this.playbackRate *\n 1.0594630943592953 ** // Math.pow(2, 1 / 12)\n ((pitchBend / (pitchBend < 0 ? 8192 : 8191)) *\n this.pitchBendSensitivity *\n this.instrument['scaleTuning']);\n this.schedulePlaybackRate();\n }\n}\n","/**\n * @logue/reverb\n *\n * @description JavaScript Reverb effect class\n * @author Logue \n * @copyright 2019-2023 By Masashi Yoshikawa All rights reserved.\n * @license MIT\n * @version 1.3.5\n * @see {@link https://github.com/logue/Reverb.js}\n */\n\nconst INV_MAX = 1 / 2 ** 32;\nclass ARandom {\n float(norm = 1) {\n return this.int() * INV_MAX * norm;\n }\n probability(p) {\n return this.float() < p;\n }\n norm(norm = 1) {\n return (this.int() * INV_MAX - 0.5) * 2 * norm;\n }\n normMinMax(min, max) {\n const x = this.minmax(min, max);\n return this.float() < 0.5 ? x : -x;\n }\n minmax(min, max) {\n return this.float() * (max - min) + min;\n }\n minmaxInt(min, max) {\n min |= 0;\n const range = (max | 0) - min;\n return range ? min + (this.int() % range) : min;\n }\n minmaxUint(min, max) {\n min >>>= 0;\n const range = (max >>> 0) - min;\n return range ? min + (this.int() % range) : min;\n }\n}\n\nconst random = Math.random;\n/**\n * A `Math.random()` based {@link IRandom} implementation. Also @see\n * {@link SYSTEM}.\n */\nclass SystemRandom extends ARandom {\n int() {\n return (random() * 4294967296) /* 2**32 */ >>> 0;\n }\n float(norm = 1) {\n return random() * norm;\n }\n norm(norm = 1) {\n return (random() - 0.5) * 2 * norm;\n }\n}\n/**\n * Used as default PRNG throughout most other thi.ng projects, though usually is\n * configurable.\n */\nconst SYSTEM = new SystemRandom();\n\nconst defaults = {\n noise: \"white\",\n scale: 1,\n peaks: 2,\n randomAlgorithm: SYSTEM,\n decay: 2,\n delay: 0,\n reverse: false,\n time: 2,\n filterType: \"allpass\",\n filterFreq: 2200,\n filterQ: 1,\n mix: 0.5,\n once: false\n};\n\nconst Meta = {\n version: \"1.3.5\",\n date: \"2023-11-20T03:01:00.334Z\"\n};\n\nconst Noise = {\n /** Blue noise */\n blue: \"blue\",\n /** Brown noise (same as red noise) */\n brown: \"red\",\n /** Green noise */\n green: \"green\",\n /** Pink noise */\n pink: \"pink\",\n /** Red noise */\n red: \"red\",\n /** Violet noise */\n violet: \"violet\",\n /** White noise */\n white: \"white\"\n};\n\nconst DEFAULT_OPTS = {\n bins: 2,\n scale: 1,\n rnd: SYSTEM,\n};\n\nconst preseed = (n, scale, rnd) => {\n const state = new Array(n);\n for (let i = 0; i < n; i++) {\n state[i] = rnd.norm(scale);\n }\n return state;\n};\nconst sum = (src) => src.reduce((sum, x) => sum + x, 0);\nfunction* interleave(a, b) {\n const src = [a[Symbol.iterator](), b[Symbol.iterator]()];\n for (let i = 0; true; i ^= 1) {\n const next = src[i].next();\n if (next.done)\n return;\n yield next.value;\n }\n}\n\n/**\n * High-pass filtered noise. Opposite of {@link red}.\n *\n * @param opts -\n */\nfunction* blue(opts) {\n const { bins, scale, rnd } = {\n ...DEFAULT_OPTS,\n ...opts,\n };\n const state = preseed(bins, scale, rnd);\n state.forEach((x, i) => (state[i] = i & 1 ? x : -x));\n const invN = 1 / bins;\n let acc = sum(state);\n for (let i = 0, sign = -1; true; ++i >= bins && (i = 0)) {\n acc -= state[i];\n acc += state[i] = sign * rnd.norm(scale);\n sign ^= 0xfffffffe;\n yield sign * acc * invN;\n }\n}\n\n/**\n * Band-pass filtered noise (interleaved blue noise). Opposite of\n * {@link violet}.\n *\n * @param opts -\n */\nconst green = (opts) => interleave(blue(opts), blue(opts));\n\n/**\n * Returns number of 1 bits in `x`.\n *\n * @param x -\n */\nconst ctz32 = (x) => {\n let c = 32;\n x &= -x;\n x && c--;\n x & 0x0000ffff && (c -= 16);\n x & 0x00ff00ff && (c -= 8);\n x & 0x0f0f0f0f && (c -= 4);\n x & 0x33333333 && (c -= 2);\n x & 0x55555555 && (c -= 1);\n return c;\n};\n\n/**\n * Exponential decay (1/f) noise, based on Voss-McCarthy algorithm.\n *\n * @remarks\n * The number of internal states should be in the [4..32] range (default: 8).\n * Due to JS integer limitations, `n` > 32 are meaningless.\n *\n * References:\n *\n * - https://www.dsprelated.com/showarticle/908.php\n * - https://www.firstpr.com.au/dsp/pink-noise/#Voss-McCartney\n *\n * @param opts -\n */\nfunction* pink(opts) {\n const { bins, scale, rnd } = {\n ...DEFAULT_OPTS,\n bins: 8,\n ...opts,\n };\n const state = preseed(bins, scale, rnd);\n const invN = 1 / bins;\n let acc = sum(state);\n for (let i = 0; true; i = (i + 1) >>> 0) {\n const id = ctz32(i) % bins;\n acc -= state[id];\n acc += state[id] = rnd.norm(scale);\n yield acc * invN;\n }\n}\n\n/**\n * Low-pass filtered noise (same as brown noise). Opposite of {@link blue}.\n *\n * @param opts -\n */\nfunction* red(opts) {\n const { bins, scale, rnd } = {\n ...DEFAULT_OPTS,\n ...opts,\n };\n const state = preseed(bins, scale, rnd);\n const invN = 1 / bins;\n let acc = sum(state);\n for (let i = 0; true; ++i >= bins && (i = 0)) {\n acc -= state[i];\n acc += state[i] = rnd.norm(scale);\n yield acc * invN;\n }\n}\n\n/**\n * Band-stop filtered noise (interleaved red noise). Opposite of {@link green}.\n *\n * @param opts -\n */\nconst violet = (opts) => interleave(red(opts), red(opts));\n\n/**\n * Unfiltered noise w/ uniform distribution. Merely yields samples from\n * given PRNG.\n *\n * @param opts -\n */\nfunction* white(opts) {\n const { scale, rnd } = { ...DEFAULT_OPTS, ...opts };\n while (true) {\n yield rnd.norm(scale);\n }\n}\n\nconst implementsFunction = (x, fn) => x != null && typeof x[fn] === \"function\";\n\nconst ensureTransducer = (x) => implementsFunction(x, \"xform\") ? x.xform() : x;\n\nconst isIterable = (x) => x != null && typeof x[Symbol.iterator] === \"function\";\n\nclass Reduced {\n value;\n constructor(val) {\n this.value = val;\n }\n deref() {\n return this.value;\n }\n}\nconst reduced = (x) => new Reduced(x);\nconst isReduced = (x) => x instanceof Reduced;\nconst ensureReduced = (x) => x instanceof Reduced ? x : new Reduced(x);\nconst unreduced = (x) => (x instanceof Reduced ? x.deref() : x);\n\n/**\n * Convenience helper for building a full {@link Reducer} using the identity\n * function (i.e. `(x) => x`) as completion step (true for 90% of all\n * bundled transducers).\n *\n * @param init - init step of reducer\n * @param rfn - reduction step of reducer\n */\nconst reducer = (init, rfn) => [init, (acc) => acc, rfn];\n\nfunction push(xs) {\n return xs\n ? [...xs]\n : reducer(() => [], (acc, x) => (acc.push(x), acc));\n}\n\n/**\n * Takes a transducer and input iterable. Returns iterator of\n * transformed results.\n *\n * @param xform -\n * @param xs -\n */\nfunction* iterator(xform, xs) {\n const rfn = ensureTransducer(xform)(push());\n const complete = rfn[1];\n const reduce = rfn[2];\n for (let x of xs) {\n const y = reduce([], x);\n if (isReduced(y)) {\n yield* unreduced(complete(y.deref()));\n return;\n }\n if (y.length) {\n yield* y;\n }\n }\n yield* unreduced(complete([]));\n}\n\n/**\n * Reducer composition helper, internally used by various transducers\n * during initialization. Takes existing reducer `rfn` (a 3-tuple) and a\n * reducing function `fn`. Returns a new reducer tuple.\n *\n * @remarks\n * `rfn[2]` reduces values of type `B` into an accumulator of type `A`.\n * `fn` accepts values of type `C` and produces interim results of type\n * `B`, which are then (possibly) passed to the \"inner\" `rfn[2]`\n * function. Therefore the resulting reducer takes inputs of `C` and an\n * accumulator of type `A`.\n *\n * It is assumed that `fn` internally calls `rfn[2]` to pass its own\n * results for further processing by the nested reducer `rfn`.\n *\n * @example\n * ```ts\n * compR(rfn, fn)\n * // [rfn[0], rfn[1], fn]\n * ```\n *\n * @param rfn -\n * @param fn -\n */\nconst compR = (rfn, fn) => [rfn[0], rfn[1], fn];\n\nfunction take(n, src) {\n return isIterable(src)\n ? iterator(take(n), src)\n : (rfn) => {\n const r = rfn[2];\n let m = n;\n return compR(rfn, (acc, x) => --m > 0\n ? r(acc, x)\n : m === 0\n ? ensureReduced(r(acc, x))\n : reduced(acc));\n };\n}\n\nclass Reverb {\n /** Version strings */\n static version = Meta.version;\n /** Build date */\n static build = Meta.date;\n /** AudioContext */\n ctx;\n /** Wet Level (Reverberated node) */\n wetGainNode;\n /** Dry Level (Original sound node) */\n dryGainNode;\n /** Impulse response filter */\n filterNode;\n /** Convolution node for applying impulse response */\n convolverNode;\n /** Output gain node */\n outputNode;\n /** Option */\n options;\n /** Connected flag */\n isConnected;\n /** Noise Generator */\n noise = white;\n /**\n * Constructor\n *\n * @param ctx - Root AudioContext\n * @param options - Configure\n */\n constructor(ctx, options) {\n this.ctx = ctx;\n this.options = Object.assign(defaults, options);\n this.wetGainNode = this.ctx.createGain();\n this.dryGainNode = this.ctx.createGain();\n this.filterNode = this.ctx.createBiquadFilter();\n this.convolverNode = this.ctx.createConvolver();\n this.outputNode = this.ctx.createGain();\n this.isConnected = false;\n this.filterType(this.options.filterType);\n this.setNoise(this.options.noise);\n this.buildImpulse();\n this.mix(this.options.mix);\n }\n /**\n * Connect the node for the reverb effect to the original sound node.\n *\n * @param sourceNode - Input source node\n */\n connect(sourceNode) {\n if (this.isConnected && this.options.once) {\n this.isConnected = false;\n return this.outputNode;\n }\n this.convolverNode.connect(this.filterNode);\n this.filterNode.connect(this.wetGainNode);\n sourceNode.connect(this.convolverNode);\n sourceNode.connect(this.dryGainNode).connect(this.outputNode);\n sourceNode.connect(this.wetGainNode).connect(this.outputNode);\n this.isConnected = true;\n return this.outputNode;\n }\n /**\n * Disconnect the reverb node\n *\n * @param sourceNode - Input source node\n */\n disconnect(sourceNode) {\n if (this.isConnected) {\n this.convolverNode.disconnect(this.filterNode);\n this.filterNode.disconnect(this.wetGainNode);\n }\n this.isConnected = false;\n return sourceNode;\n }\n /**\n * Dry/Wet ratio\n *\n * @param mix - Ratio (0~1)\n */\n mix(mix) {\n if (!Reverb.inRange(mix, 0, 1)) {\n throw new RangeError(\"[Reverb.js] Dry/Wet ratio must be between 0 to 1.\");\n }\n this.options.mix = mix;\n this.dryGainNode.gain.value = 1 - this.options.mix;\n this.wetGainNode.gain.value = this.options.mix;\n }\n /**\n * Set Impulse Response time length (second)\n *\n * @param value - IR length\n */\n time(value) {\n if (!Reverb.inRange(value, 1, 50)) {\n throw new RangeError(\n \"[Reverb.js] Time length of inpulse response must be less than 50sec.\"\n );\n }\n this.options.time = value;\n this.buildImpulse();\n }\n /**\n * Impulse response decay rate.\n *\n * @param value - Decay value\n */\n decay(value) {\n if (!Reverb.inRange(value, 0, 100)) {\n throw new RangeError(\n \"[Reverb.js] Inpulse Response decay level must be less than 100.\"\n );\n }\n this.options.decay = value;\n this.buildImpulse();\n }\n /**\n * Delay before reverberation starts\n *\n * @param value - Time[ms]\n */\n delay(value) {\n if (!Reverb.inRange(value, 0, 100)) {\n throw new RangeError(\n \"[Reverb.js] Inpulse Response delay time must be less than 100.\"\n );\n }\n this.options.delay = value;\n this.buildImpulse();\n }\n /**\n * Reverse the impulse response.\n *\n * @param reverse - Reverse IR\n */\n reverse(reverse) {\n this.options.reverse = reverse;\n this.buildImpulse();\n }\n /**\n * Filter for impulse response\n *\n * @param type - Filiter Type\n */\n filterType(type = \"allpass\") {\n this.filterNode.type = this.options.filterType = type;\n }\n /**\n * Filter frequency applied to impulse response\n *\n * @param freq - Frequency\n */\n filterFreq(freq) {\n if (!Reverb.inRange(freq, 20, 2e4)) {\n throw new RangeError(\n \"[Reverb.js] Filter frequrncy must be between 20 and 20000.\"\n );\n }\n this.options.filterFreq = freq;\n this.filterNode.frequency.value = this.options.filterFreq;\n }\n /**\n * Filter quality.\n *\n * @param q - Quality\n */\n filterQ(q) {\n if (!Reverb.inRange(q, 0, 10)) {\n throw new RangeError(\n \"[Reverb.js] Filter quality value must be between 0 and 10.\"\n );\n }\n this.options.filterQ = q;\n this.filterNode.Q.value = this.options.filterQ;\n }\n /**\n * set IR source noise peaks\n *\n * @param p - Peaks\n */\n peaks(p) {\n this.options.peaks = p;\n this.buildImpulse();\n }\n /**\n * set IR source noise scale.\n *\n * @param s - Scale\n */\n scale(s) {\n this.options.scale = s;\n this.buildImpulse();\n }\n /**\n * set IR source noise generator.\n *\n * @param a - Algorithm\n */\n randomAlgorithm(a) {\n this.options.randomAlgorithm = a;\n this.buildImpulse();\n }\n /**\n * Inpulse Response Noise algorithm.\n *\n * @param type - IR noise algorithm type.\n */\n setNoise(type) {\n this.options.noise = type;\n switch (type) {\n case Noise.blue:\n this.noise = blue;\n break;\n case Noise.green:\n this.noise = green;\n break;\n case Noise.pink:\n this.noise = pink;\n break;\n case Noise.red:\n case Noise.brown:\n this.noise = red;\n break;\n case Noise.violet:\n this.noise = violet;\n break;\n default:\n this.noise = white;\n }\n this.buildImpulse();\n }\n /**\n * Set Random Algorythm\n *\n * @param algorithm - Algorythm\n */\n setRandomAlgorythm(algorithm) {\n this.options.randomAlgorithm = algorithm;\n this.buildImpulse();\n }\n /**\n * Return true if in range, otherwise false\n *\n * @param x - Target value\n * @param min - Minimum value\n * @param max - Maximum value\n */\n static inRange(x, min, max) {\n return (x - min) * (x - max) <= 0;\n }\n /** Utility function for building an impulse response from the module parameters. */\n buildImpulse() {\n const rate = this.ctx.sampleRate;\n const duration = Math.max(rate * this.options.time, 1);\n const delayDuration = rate * this.options.delay;\n const impulse = this.ctx.createBuffer(2, duration, rate);\n const impulseL = new Float32Array(duration);\n const impulseR = new Float32Array(duration);\n const noiseL = this.getNoise(duration);\n const noiseR = this.getNoise(duration);\n for (let i = 0; i < duration; i++) {\n let n = 0;\n if (i < delayDuration) {\n impulseL[i] = 0;\n impulseR[i] = 0;\n n = this.options.reverse ?? false ? duration - (i - delayDuration) : i - delayDuration;\n } else {\n n = this.options.reverse ?? false ? duration - i : i;\n }\n impulseL[i] = (noiseL[i] ?? 0) * (1 - n / duration) ** this.options.decay;\n impulseR[i] = (noiseR[i] ?? 0) * (1 - n / duration) ** this.options.decay;\n }\n impulse.getChannelData(0).set(impulseL);\n impulse.getChannelData(1).set(impulseR);\n this.convolverNode.buffer = impulse;\n }\n /**\n * Noise source\n *\n * @param duration - length of IR.\n */\n getNoise(duration) {\n return [\n ...take(\n duration,\n this.noise({\n bins: this.options.peaks,\n scale: this.options.scale,\n rnd: this.options.randomAlgorithm\n })\n )\n ];\n }\n}\n\nexport { Reverb as default };\n","/**\n * Riff Parser class\n *\n * @author imaya\n */\nexport class Riff {\n /**\n * @param {ArrayBuffer} input Input buffer.\n * @param {Object} [optParams] Option parameters.\n */\n constructor(input, optParams = {}) {\n /** @type {ArrayBuffer} */\n this.input = input;\n /** @type {number} */\n this.ip = optParams.index || 0;\n /** @type {number} */\n this.length = optParams.length || input.byteLength - this.ip;\n /** @type {RiffChunk[]} */\n this.chunkList = [];\n /** @type {number} */\n this.offset = this.ip;\n /** @type {boolean} */\n this.padding = optParams.padding !== void 0 ? optParams.padding : true;\n /** @type {boolean} */\n this.bigEndian =\n optParams.bigEndian !== void 0 ? optParams.bigEndian : false;\n }\n\n /** @returns {void} */\n parse() {\n /** @type {number} */\n const length = this.length + this.offset;\n\n this.chunkList = [];\n\n while (this.ip < length) {\n this.parseChunk();\n }\n }\n\n /** @returns {void} */\n parseChunk() {\n /** @type {ArrayBuffer} */\n const input = this.input;\n /** @type {number} */\n let ip = this.ip;\n /** @type {number} */\n let size;\n\n this.chunkList.push(\n new RiffChunk(\n String.fromCharCode(input[ip++], input[ip++], input[ip++], input[ip++]),\n (size = this.bigEndian\n ? ((input[ip++] << 24) |\n (input[ip++] << 16) |\n (input[ip++] << 8) |\n input[ip++]) >>>\n 0\n : (input[ip++] |\n (input[ip++] << 8) |\n (input[ip++] << 16) |\n (input[ip++] << 24)) >>>\n 0),\n ip\n )\n );\n\n ip += size;\n\n // padding\n if (this.padding && ((ip - this.offset) & 1) === 1) {\n ip++;\n }\n\n this.ip = ip;\n }\n\n /**\n * @param {number} index Chunk index.\n * @returns {RiffChunk | null}\n */\n getChunk(index) {\n /** @type {RiffChunk} */\n const chunk = this.chunkList[index];\n\n return chunk !== undefined ? chunk : null;\n }\n\n /** @returns {number} */\n getNumberOfChunks() {\n return this.chunkList.length;\n }\n}\n\n/**\n * Riff Chunk Structure\n *\n * @interface\n */\nexport class RiffChunk {\n /**\n * @param {string} type\n * @param {number} size\n * @param {number} offset\n */\n constructor(type, size, offset) {\n /** @type {string} */\n this.type = type;\n /** @type {number} */\n this.size = size;\n /** @type {number} */\n this.offset = offset;\n }\n}\n","import { Riff } from './riff.js';\n\n/**\n * SoundFont Parser Class\n *\n * @author imaya\n */\nexport default class Parser {\n /**\n * @param {Uint8Array} input\n * @param {Object} [optParams]\n */\n constructor(input, optParams = {}) {\n /** @type {Uint8Array} */\n this.input = input;\n /** @type {object} */\n this.parserOption = optParams.parserOption || {};\n /** @type {number} */\n this.sampleRate = optParams.sampleRate || 22050; // よくわからんが、OSで指定されているサンプルレートを入れないと音が切れ切れになる。\n\n /** @type {object[]} */\n this.presetHeader = [];\n /** @type {object[]} */\n this.presetZone = [];\n /** @type {object[]} */\n this.presetZoneModulator = [];\n /** @type {object[]} */\n this.presetZoneGenerator = [];\n /** @type {object[]} */\n this.instrument = [];\n /** @type {object[]} */\n this.instrumentZone = [];\n /** @type {object[]} */\n this.instrumentZoneModulator = [];\n /** @type {object[]} */\n this.instrumentZoneGenerator = [];\n /** @type {object[]} */\n this.sampleHeader = [];\n /** @type {string[]} */\n this.GeneratorEnumeratorTable = Object.keys(Parser.getGeneratorTable());\n }\n\n /** @return {Record} ジェネレータとデフォルト値 */\n static getGeneratorTable() {\n return Object.freeze({\n /** @type {number} サンプルヘッダの音声波形データ開始位置に加算されるオフセット(下位16bit) */\n startAddrsOffset: 0,\n /** @type {number} サンプルヘッダの音声波形データ終了位置に加算されるオフセット(下位16bit) */\n endAddrsOffset: 0,\n /** @type {number} サンプルヘッダの音声波形データループ開始位置に加算されるオフセット(下位16bit) */\n startloopAddrsOffset: 0,\n /** @type {number} サンプルヘッダの音声波形データループ開始位置に加算されるオフセット(下位16bit) */\n endloopAddrsOffset: 0,\n /** @type {number} サンプルヘッダの音声波形データ開始位置に加算されるオフセット(上位16bit) */\n startAddrsCoarseOffset: 0,\n /** @type {number} LFOによるピッチの揺れ幅 */\n modLfoToPitch: 0,\n /** @type {number} モジュレーションホイール用LFOからピッチに対しての影響量 */\n vibLfoToPitch: 0,\n /** @type {number} フィルタ・ピッチ用エンベロープからピッチに対しての影響量 */\n modEnvToPitch: 0,\n /** @type {number} フィルタのカットオフ周波数 */\n initialFilterFc: 13500,\n /** @type {number} フィルターのQ値(レゾナンス) */\n initialFilterQ: 0,\n /** @type {number} LFOによるフィルターカットオフ周波数の揺れ幅 */\n modLfoToFilterFc: 0,\n /** @type {number} フィルタ・ピッチ用エンベロープからフィルターカットオフに対しての影響量 */\n modEnvToFilterFc: 0,\n /** @type {number} サンプルヘッダの音声波形データ終了位置に加算されるオフセット(上位16bit) */\n endAddrsCoarseOffset: 0,\n /** @type {number} LFOによるボリュームの揺れ幅 */\n modLfoToVolume: 0,\n /** @type {undefined} 未使用1 */\n unused1: undefined, // 14\n /** @type {number} コーラスエフェクトのセンドレベル */\n chorusEffectsSend: 0,\n /** @type {number} リバーブエフェクトのセンドレベル */\n reverbEffectsSend: 0,\n /** @type {number} パンの位置 */\n pan: 0,\n /** @type {undefined} 未使用2 */\n unused2: undefined,\n /** @type {undefined} 未使用3 */\n unused3: undefined,\n /** @type {undefined} 未使用4 */\n unused4: undefined,\n /** @type {number} LFOの揺れが始まるまでの時間 */\n delayModLFO: -12000,\n /** @type {number} LFOの揺れの周期 */\n freqModLFO: 0,\n /** @type {number} ホイールの揺れが始まるまでの時間 */\n delayVibLFO: -12000,\n /** @type {number} ホイールの揺れの周期 */\n freqVibLFO: 0,\n /** @type {number} フィルタ・ピッチ用エンベロープのディレイ(アタックが始まるまでの時間) */\n delayModEnv: -12000,\n /** @type {number} フィルタ・ピッチ用エンベロープのアタック時間 */\n attackModEnv: -12000,\n /** @type {number} フィルタ・ピッチ用エンベロープのホールド時間(アタックが終わってからディケイが始まるまでの時間) */\n holdModEnv: -12000,\n /** @type {number} フィルタ・ピッチ用エンベロープのディケイ時間 */\n decayModEnv: -12000,\n /** @type {number} フィルタ・ピッチ用エンベロープのサステイン量 */\n sustainModEnv: 0,\n /** @type {number} フィルタ・ピッチ用エンベロープのリリース時間 */\n releaseModEnv: -12000,\n /** @type {number} キー(ノートNo)によるフィルタ・ピッチ用エンベロープのホールド時間への影響 */\n keynumToModEnvHold: 0,\n /** @type {number} キー(ノートNo)によるフィルタ・ピッチ用エンベロープのディケイ時間への影響 */\n keynumToModEnvDecay: 0,\n /** @type {number} アンプ用エンベロープのディレイ(アタックが始まるまでの時間) */\n delayVolEnv: -12000,\n /** @type {number} アンプ用エンベロープのアタック時間 */\n attackVolEnv: -12000,\n /** @type {number} アンプ用エンベロープのホールド時間(アタックが終わってからディケイが始まるまでの時間) */\n holdVolEnv: -12000,\n /** @type {number} アンプ用エンベロープのディケイ時間 */\n decayVolEnv: -12000,\n /** @type {number} アンプ用エンベロープのサステイン量 */\n sustainVolEnv: 0,\n /** @type {number} アンプ用エンベロープのリリース時間 */\n releaseVolEnv: -12000,\n /** @type {number} キー(ノートNo)によるアンプ用エンベロープのホールド時間への影響 */\n keynumToVolEnvHold: 0,\n /** @type {number} キー(ノートNo)によるアンプ用エンベロープのディケイ時間への影響 */\n keynumToVolEnvDecay: 0,\n /** @type {number} 割り当てるインストルメント(楽器) */\n instrument: null,\n /** @type {undefined} 予約済み1 */\n reserved1: undefined, // 42\n /** @type {number} マッピングするキー(ノートNo)の範囲 */\n keyRange: null,\n /** @type {number} マッピングするベロシティの範囲 */\n velRange: null,\n /** @type {number} サンプルヘッダの音声波形データループ開始位置に加算されるオフセット(上位16bit) */\n startloopAddrsCoarseOffset: 0,\n /** @type {number} どのキー(ノートNo)でも強制的に指定したキー(ノートNo)に変更する */\n keynum: null,\n /** @type {number} どのベロシティでも強制的に指定したベロシティに変更する */\n velocity: null,\n /** @type {number} 調整する音量 */\n initialAttenuation: 0,\n /** @type {undefined} 予約済み2 */\n reserved2: undefined, // 49\n /** @type {number} サンプルヘッダの音声波形データループ終了位置に加算されるオフセット(上位16bit) */\n endloopAddrsCoarseOffset: 0,\n /** @type {number} 半音単位での音程の調整 */\n coarseTune: 0,\n /** @type {number} cent単位での音程の調整 */\n fineTune: 0,\n /** @type {number} 割り当てるサンプル(音声波形) */\n sampleID: null,\n /** @type {number} サンプル(音声波形)をループさせるか等のフラグ */\n sampleModes: 0,\n /** @type {undefined} 予約済み3 */\n reserved3: undefined, // 55\n /** @type {number} キー(ノートNo)が+1されるごとに音程を何centあげるかの音階情報 */\n scaleTuning: 100,\n /** @type {number} 同時に音を鳴らさないようにするための排他ID(ハイハットのOpen、Close等に使用) */\n exclusiveClass: null,\n /** @type {number} サンプル(音声波形)の音程の上書き情報 */\n overridingRootKey: null,\n /** @type {undefined} 未使用5 */\n unuded5: undefined, // 59\n /** @type {undefined} 最後を示すオペレータ */\n endOper: undefined,\n });\n }\n\n /** @export */\n parse() {\n /** @type {Riff} */\n const parser = new Riff(this.input, this.parserOption);\n\n // parse RIFF chunk\n parser.parse();\n if (parser.chunkList.length !== 1) {\n throw new Error('wrong chunk length');\n }\n\n /** @type {import('./riff.js').RiffChunk | null} */\n const chunk = parser.getChunk(0);\n if (chunk === null) {\n throw new Error('chunk not found');\n }\n\n this.parseRiffChunk(chunk);\n this.input = null;\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseRiffChunk(chunk) {\n /** @type {ArrayBuffer} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n\n // check parse target\n if (chunk.type !== 'RIFF') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n // check signature\n /** @type {string} */\n const signature = String.fromCharCode(\n data[ip++],\n data[ip++],\n data[ip++],\n data[ip++]\n );\n if (signature !== 'sfbk') {\n throw new Error('invalid signature:' + signature);\n }\n\n // read structure\n /** @type {import('./riff.js').Riff} */\n const parser = new Riff(data, { index: ip, length: chunk.size - 4 });\n parser.parse();\n if (parser.getNumberOfChunks() !== 3) {\n throw new Error('invalid sfbk structure');\n }\n\n // INFO-list\n this.parseInfoList(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(0))\n );\n\n // sdta-list\n this.parseSdtaList(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(1))\n );\n\n // pdta-list\n this.parsePdtaList(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(2))\n );\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseInfoList(chunk) {\n /** @type {ArrayBuffer} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n\n // check parse target\n if (chunk.type !== 'LIST') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n // check signature\n /** @type {string} */\n const signature = String.fromCharCode(\n data[ip++],\n data[ip++],\n data[ip++],\n data[ip++]\n );\n if (signature !== 'INFO') {\n throw new Error('invalid signature:' + signature);\n }\n\n // read structure\n /** @type {import('./riff.js').Riff} */\n const parser = new Riff(data, { index: ip, length: chunk.size - 4 });\n parser.parse();\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseSdtaList(chunk) {\n /** @type {ArrayBuffer} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n\n // check parse target\n if (chunk.type !== 'LIST') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n // check signature\n /** @type {string} */\n const signature = String.fromCharCode(\n data[ip++],\n data[ip++],\n data[ip++],\n data[ip++]\n );\n if (signature !== 'sdta') {\n throw new Error('invalid signature:' + signature);\n }\n\n // read structure\n /** @type {import('./riff.js').Riff} */\n const parser = new Riff(data, { index: ip, length: chunk.size - 4 });\n parser.parse();\n if (parser.chunkList.length !== 1) {\n throw new Error('TODO');\n }\n this.samplingData =\n /** @type {{ type: string; size: number; offset: number }} */\n (parser.getChunk(0));\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parsePdtaList(chunk) {\n /** @type {Uint8Array} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n\n // check parse target\n if (chunk.type !== 'LIST') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n // check signature\n /** @type {string} */\n const signature = String.fromCharCode(\n data[ip++],\n data[ip++],\n data[ip++],\n data[ip++]\n );\n if (signature !== 'pdta') {\n throw new Error('invalid signature:' + signature);\n }\n\n // read structure\n /** @type {import('./riff.js').Riff} */\n const parser = new Riff(data, { index: ip, length: chunk.size - 4 });\n parser.parse();\n\n // check number of chunks\n if (parser.getNumberOfChunks() !== 9) {\n throw new Error('invalid pdta chunk');\n }\n\n this.parsePhdr(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(0))\n );\n this.parsePbag(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(1))\n );\n this.parsePmod(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(2))\n );\n this.parsePgen(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(3))\n );\n this.parseInst(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(4))\n );\n this.parseIbag(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(5))\n );\n this.parseImod(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(6))\n );\n this.parseIgen(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(7))\n );\n this.parseShdr(\n /** @type {import('./riff.js').RiffChunk} */ (parser.getChunk(8))\n );\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parsePhdr(chunk) {\n /** @type {Uint8Array} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n /** @type {Object[]} */\n const presetHeader = (this.presetHeader = []);\n /** @type {number} */\n const size = chunk.offset + chunk.size;\n\n // check parse target\n if (chunk.type !== 'phdr') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n while (ip < size) {\n presetHeader.push({\n presetName: String.fromCharCode.apply(\n null,\n data.subarray(ip, (ip += 20))\n ),\n preset: data[ip++] | (data[ip++] << 8),\n bank: data[ip++] | (data[ip++] << 8),\n presetBagIndex: data[ip++] | (data[ip++] << 8),\n library:\n (data[ip++] |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0,\n genre:\n (data[ip++] |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0,\n morphology:\n (data[ip++] |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0,\n });\n }\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parsePbag(chunk) {\n /** @type {ArrayBuffer} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n /** @type {Object[]} */\n const presetZone = (this.presetZone = []);\n /** @type {number} */\n const size = chunk.offset + chunk.size;\n\n // check parse target\n if (chunk.type !== 'pbag') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n while (ip < size) {\n presetZone.push({\n presetGeneratorIndex: data[ip++] | (data[ip++] << 8),\n presetModulatorIndex: data[ip++] | (data[ip++] << 8),\n });\n }\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parsePmod(chunk) {\n // check parse target\n if (chunk.type !== 'pmod') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n this.presetZoneModulator = this.parseModulator(chunk);\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parsePgen(chunk) {\n // check parse target\n if (chunk.type !== 'pgen') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n this.presetZoneGenerator = this.parseGenerator(chunk);\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseInst(chunk) {\n /** @type {Uint8Array} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n /** @type {Object[]} */\n const instrument = (this.instrument = []);\n /** @type {number} */\n const size = chunk.offset + chunk.size;\n\n // check parse target\n if (chunk.type !== 'inst') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n while (ip < size) {\n instrument.push({\n instrumentName: String.fromCharCode.apply(\n null,\n data.subarray(ip, (ip += 20))\n ),\n instrumentBagIndex: data[ip++] | (data[ip++] << 8),\n });\n }\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseIbag(chunk) {\n /** @type {ArrayBuffer} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n /** @type {Object[]} */\n const instrumentZone = (this.instrumentZone = []);\n /** @type {number} */\n const size = chunk.offset + chunk.size;\n\n // check parse target\n if (chunk.type !== 'ibag') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n while (ip < size) {\n instrumentZone.push({\n instrumentGeneratorIndex: data[ip++] | (data[ip++] << 8),\n instrumentModulatorIndex: data[ip++] | (data[ip++] << 8),\n });\n }\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseImod(chunk) {\n // check parse target\n if (chunk.type !== 'imod') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n this.instrumentZoneModulator = this.parseModulator(chunk);\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseIgen(chunk) {\n // check parse target\n if (chunk.type !== 'igen') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n this.instrumentZoneGenerator = this.parseGenerator(chunk);\n }\n\n /** @param {import('./riff.js').RiffChunk} chunk */\n parseShdr(chunk) {\n /** @type {Uint8Array} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n /** @type {Object[]} */\n const samples = (this.sample = []);\n /** @type {Object[]} */\n const sampleHeader = (this.sampleHeader = []);\n /** @type {number} */\n const size = chunk.offset + chunk.size;\n /** @type {string} */\n let sampleName;\n /** @type {number} */\n let start;\n /** @type {number} */\n let end;\n /** @type {number} */\n let startLoop;\n /** @type {number} */\n let endLoop;\n /** @type {number} */\n let sampleRate;\n /** @type {number} */\n let originalPitch;\n /** @type {number} */\n let pitchCorrection;\n /** @type {number} */\n let sampleLink;\n /** @type {number} */\n let sampleType;\n\n // check parse target\n if (chunk.type !== 'shdr') {\n throw new Error('invalid chunk type:' + chunk.type);\n }\n\n while (ip < size) {\n sampleName = String.fromCharCode.apply(\n null,\n data.subarray(ip, (ip += 20))\n );\n start =\n ((data[ip++] << 0) |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0;\n end =\n ((data[ip++] << 0) |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0;\n startLoop =\n ((data[ip++] << 0) |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0;\n endLoop =\n ((data[ip++] << 0) |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0;\n sampleRate =\n ((data[ip++] << 0) |\n (data[ip++] << 8) |\n (data[ip++] << 16) |\n (data[ip++] << 24)) >>>\n 0;\n originalPitch = data[ip++];\n pitchCorrection = (data[ip++] << 24) >> 24;\n sampleLink = data[ip++] | (data[ip++] << 8);\n sampleType = data[ip++] | (data[ip++] << 8);\n\n let sample = new Int16Array(\n new Uint8Array(\n data.subarray(\n this.samplingData.offset + start * 2,\n this.samplingData.offset + end * 2\n )\n ).buffer\n );\n\n startLoop -= start;\n endLoop -= start;\n\n if (sampleRate > 0) {\n const adjust = this.adjustSampleData(sample, sampleRate);\n sample = adjust.sample;\n sampleRate *= adjust.multiply;\n startLoop *= adjust.multiply;\n endLoop *= adjust.multiply;\n }\n\n samples.push(sample);\n\n sampleHeader.push({\n sampleName: sampleName,\n start: start,\n end: end,\n startLoop: startLoop,\n endLoop: endLoop,\n sampleRate: sampleRate,\n originalPitch: originalPitch,\n pitchCorrection: pitchCorrection,\n sampleLink: sampleLink,\n sampleType: sampleType,\n });\n }\n }\n\n /**\n * @param {Int16Array} sample\n * @param {number} sampleRate\n * @return {object}\n */\n adjustSampleData(sample, sampleRate) {\n /** @type {Int16Array} */\n let newSample;\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n /** @type {number} */\n let j;\n /** @type {number} */\n let multiply = 1;\n\n // buffer\n while (sampleRate < this.sampleRate) {\n // AudioContextのサンプルレートに変更\n newSample = new Int16Array(sample.length * 2);\n for (i = j = 0, il = sample.length; i < il; ++i) {\n newSample[j++] = sample[i];\n newSample[j++] = sample[i];\n }\n sample = newSample;\n multiply *= 2;\n sampleRate *= 2;\n }\n\n return {\n sample: sample,\n multiply: multiply,\n };\n }\n\n /**\n * @param {import('./riff.js').RiffChunk} chunk\n * @return {Object[]}\n */\n parseModulator(chunk) {\n /** @type {ArrayBuffer} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n /** @type {number} */\n const size = chunk.offset + chunk.size;\n /** @type {number} */\n let code;\n /** @type {string} */\n let key;\n /** @type {Object[]} */\n const output = [];\n\n while (ip < size) {\n // Src Oper\n // TODO\n ip += 2;\n\n // Dest Oper\n code = data[ip++] | (data[ip++] << 8);\n key = this.GeneratorEnumeratorTable[code];\n if (key === void 0) {\n // Amount\n output.push({\n type: key,\n value: {\n code: code,\n amount: data[ip] | (((data[ip + 1] << 8) << 16) >> 16),\n lo: data[ip++],\n hi: data[ip++],\n },\n });\n } else {\n // Amount\n switch (key) {\n case 'keyRange':\n /* FALLTHROUGH */\n case 'velRange':\n /* FALLTHROUGH */\n case 'keynum':\n /* FALLTHROUGH */\n case 'velocity':\n output.push({\n type: key,\n value: {\n amount: null,\n lo: data[ip++],\n hi: data[ip++],\n },\n });\n break;\n default:\n output.push({\n type: key,\n value: {\n amount: data[ip++] | (((data[ip++] << 8) << 16) >> 16),\n },\n });\n break;\n }\n }\n\n // AmtSrcOper\n // TODO\n ip += 2;\n\n // Trans Oper\n // TODO\n ip += 2;\n }\n\n return output;\n }\n\n /**\n * @param {import('./riff.js').RiffChunk} chunk\n * @return {Object[]}\n */\n parseGenerator(chunk) {\n /** @type {ArrayBuffer} */\n const data = this.input;\n /** @type {number} */\n let ip = chunk.offset;\n /** @type {number} */\n const size = chunk.offset + chunk.size;\n /** @type {number} */\n let code;\n /** @type {string} */\n let key;\n /** @type {Object[]} */\n const output = [];\n\n while (ip < size) {\n code = data[ip++] | (data[ip++] << 8);\n key = this.GeneratorEnumeratorTable[code];\n if (key === void 0) {\n output.push({\n type: key,\n value: {\n code: code,\n amount: data[ip] | (((data[ip + 1] << 8) << 16) >> 16),\n lo: data[ip++],\n hi: data[ip++],\n },\n });\n continue;\n }\n\n switch (key) {\n case 'keynum':\n /* FALLTHROUGH */\n case 'keyRange':\n /* FALLTHROUGH */\n case 'velRange':\n /* FALLTHROUGH */\n case 'velocity':\n output.push({\n type: key,\n value: {\n amount: null,\n lo: data[ip++],\n hi: data[ip++],\n },\n });\n break;\n default:\n output.push({\n type: key,\n value: {\n amount: data[ip++] | (((data[ip++] << 8) << 16) >> 16),\n },\n });\n break;\n }\n }\n\n return output;\n }\n\n /** @return {object[]} */\n createInstrument() {\n /** @type {Object[]} */\n const instrument = this.instrument;\n /** @type {Object[]} */\n const zone = this.instrumentZone;\n /** @type {Object[]} */\n const output = [];\n /** @type {number} */\n let bagIndex;\n /** @type {number} */\n let bagIndexEnd;\n /** @type {Object[]} */\n let zoneInfo;\n /** @type {{ generator: Object; generatorInfo: Object[] }} */\n let instrumentGenerator;\n /** @type {{ modulator: Object; modulatorInfo: Object[] }} */\n let instrumentModulator;\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n /** @type {number} */\n let j;\n /** @type {number} */\n let jl;\n\n // instrument -> instrument bag -> generator / modulator\n for (i = 0, il = instrument.length; i < il; ++i) {\n bagIndex = instrument[i].instrumentBagIndex;\n bagIndexEnd = instrument[i + 1]\n ? instrument[i + 1].instrumentBagIndex\n : zone.length;\n zoneInfo = [];\n\n // instrument bag\n for (j = bagIndex, jl = bagIndexEnd; j < jl; ++j) {\n instrumentGenerator = this.createInstrumentGenerator_(zone, j);\n instrumentModulator = this.createInstrumentModulator_(zone, j);\n\n zoneInfo.push({\n generator: instrumentGenerator.generator,\n generatorSequence: instrumentGenerator.generatorInfo,\n modulator: instrumentModulator.modulator,\n modulatorSequence: instrumentModulator.modulatorInfo,\n });\n }\n\n output.push({\n name: instrument[i].instrumentName,\n info: zoneInfo,\n });\n }\n\n return output;\n }\n\n /** @return {object[]} */\n createPreset() {\n /** @type {Object[]} */\n const preset = this.presetHeader;\n /** @type {Object[]} */\n const zone = this.presetZone;\n /** @type {Object[]} */\n const output = [];\n /** @type {number} */\n let bagIndex;\n /** @type {number} */\n let bagIndexEnd;\n /** @type {Object[]} */\n let zoneInfo;\n /** @type {number} */\n let instrument;\n /** @type {{ generator: Object; generatorInfo: Object[] }} */\n let presetGenerator;\n /** @type {{ modulator: Object; modulatorInfo: Object[] }} */\n let presetModulator;\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n /** @type {number} */\n let j;\n /** @type {number} */\n let jl;\n\n // preset -> preset bag -> generator / modulator\n for (i = 0, il = preset.length; i < il; ++i) {\n bagIndex = preset[i].presetBagIndex;\n bagIndexEnd = preset[i + 1] ? preset[i + 1].presetBagIndex : zone.length;\n zoneInfo = [];\n\n // preset bag\n for (j = bagIndex, jl = bagIndexEnd; j < jl; ++j) {\n presetGenerator = this.createPresetGenerator_(zone, j);\n presetModulator = this.createPresetModulator_(zone, j);\n\n zoneInfo.push({\n generator: presetGenerator.generator,\n generatorSequence: presetGenerator.generatorInfo,\n modulator: presetModulator.modulator,\n modulatorSequence: presetModulator.modulatorInfo,\n });\n\n instrument =\n presetGenerator.generator['instrument'] !== void 0\n ? presetGenerator.generator['instrument'].amount\n : presetModulator.modulator['instrument'] !== void 0\n ? presetModulator.modulator['instrument'].amount\n : null;\n }\n\n output.push({\n name: preset[i].presetName,\n info: zoneInfo,\n header: preset[i],\n instrument: instrument,\n });\n }\n\n return output;\n }\n\n /**\n *\n * @private\n * @param {Object[]} zone\n * @param {number} index\n * @returns {{ generator: Object; generatorInfo: Object[] }}\n */\n createInstrumentGenerator_(zone, index) {\n const modgen = this.createBagModGen_(\n zone,\n zone[index].instrumentGeneratorIndex,\n zone[index + 1]\n ? zone[index + 1].instrumentGeneratorIndex\n : this.instrumentZoneGenerator.length,\n this.instrumentZoneGenerator\n );\n\n return {\n generator: modgen.modgen,\n generatorInfo: modgen.modgenInfo,\n };\n }\n\n /**\n *\n * @private\n * @param {Object[]} zone\n * @param {number} index\n * @returns {{ modulator: Object; modulatorInfo: Object[] }}\n */\n createInstrumentModulator_(zone, index) {\n const modgen = this.createBagModGen_(\n zone,\n zone[index].presetModulatorIndex,\n zone[index + 1]\n ? zone[index + 1].instrumentModulatorIndex\n : this.instrumentZoneModulator.length,\n this.instrumentZoneModulator\n );\n\n return {\n modulator: modgen.modgen,\n modulatorInfo: modgen.modgenInfo,\n };\n }\n\n /**\n *\n * @private\n * @param {Object[]} zone\n * @param {number} index\n * @returns {{ generator: Object; generatorInfo: Object[] }}\n */\n createPresetGenerator_(zone, index) {\n const modgen = this.createBagModGen_(\n zone,\n zone[index].presetGeneratorIndex,\n zone[index + 1]\n ? zone[index + 1].presetGeneratorIndex\n : this.presetZoneGenerator.length,\n this.presetZoneGenerator\n );\n\n return {\n generator: modgen.modgen,\n generatorInfo: modgen.modgenInfo,\n };\n }\n\n /**\n *\n * @private\n * @param {Object[]} zone\n * @param {number} index\n * @returns {{ modulator: Object; modulatorInfo: Object[] }}\n */\n createPresetModulator_(zone, index) {\n /** @type {{ modgen: Object; modgenInfo: Object[] }} */\n const modgen = this.createBagModGen_(\n zone,\n zone[index].presetModulatorIndex,\n zone[index + 1]\n ? zone[index + 1].presetModulatorIndex\n : this.presetZoneModulator.length,\n this.presetZoneModulator\n );\n\n return {\n modulator: modgen.modgen,\n modulatorInfo: modgen.modgenInfo,\n };\n }\n\n /**\n *\n * @private\n * @param {Object[]} _zone\n * @param {number} indexStart\n * @param {number} indexEnd\n * @param {Array} zoneModGen\n * @returns {{ modgen: Object; modgenInfo: Object[] }}\n */\n createBagModGen_(_zone, indexStart, indexEnd, zoneModGen) {\n /** @type {Object[]} */\n const modgenInfo = [];\n /** @type {Object} */\n const modgen = {\n unknown: [],\n keyRange: {\n amount: null,\n hi: 127,\n lo: 0,\n },\n }; // TODO\n /** @type {Object} */\n let info;\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n\n for (i = indexStart, il = indexEnd; i < il; ++i) {\n info = zoneModGen[i];\n modgenInfo.push(info);\n\n if (info.type === 'unknown') {\n modgen.unknown.push(info.value);\n } else {\n modgen[info.type] = info.value;\n }\n }\n\n return {\n modgen: modgen,\n modgenInfo: modgenInfo,\n };\n }\n}\n","import SynthesizerNote from './sound_font_synth_note';\nimport Reverb from '@logue/reverb';\nimport Parser from './sf2';\n\n/**\n * Synthesizer Class\n *\n * @author imaya\n */\nexport default class Synthesizer {\n /** @param {Uint8Array} input */\n constructor(input) {\n /** @type {number} */\n let i;\n /** @type {Uint8Array} */\n this.input = input;\n /** @type {Parser} */\n this.parser = undefined;\n /** @type {number} */\n this.bank = 0;\n /** @type {Object} */\n this.bankSet = {};\n /** @type {number} */\n this.bufferSize = 2048;\n /** @type {AudioContext} */\n this.ctx = this.getAudioContext();\n /** @type {GainNode} */\n this.gainMaster = this.ctx.createGain();\n /** @type {AudioBufferSourceNode} */\n this.bufSrc = this.ctx.createBufferSource();\n /** @type {number[]} */\n this.channelInstrument = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n /** @type {number[]} */\n this.channelBank = [0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0];\n /** @type {number[]} */\n this.channelVolume = [\n 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,\n 100,\n ];\n /** @type {number[]} */\n this.channelPanpot = [\n 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n ];\n /** @type {number[]} */\n this.channelPitchBend = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n /** @type {number[]} */\n this.channelPitchBendSensitivity = [\n 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n ];\n /** @type {number[]} */\n this.channelExpression = [\n 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,\n 127,\n ];\n /** @type {number[]} */\n this.channelAttack = [\n 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n ];\n /** @type {number[]} */\n this.channelDecay = [\n 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n ];\n /** @type {number[]} */\n this.channelSustin = [\n 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n ];\n /** @type {number[]} */\n this.channelRelease = [\n 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n ];\n\n /** @type {boolean[]} */\n this.channelHold = [\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n ];\n /** @type {number[]} */\n this.channelHarmonicContent = [\n 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n ];\n /** @type {number[]} */\n this.channelCutOffFrequency = [\n 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n ];\n\n /** @type {'GM'|'GM2'|'XG'|'GS'} */\n this.mode = 'GM2';\n\n /** @type {string[][]} */\n this.programSet = [];\n\n /** @type {boolean[]} */\n this.channelMute = [\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n ];\n /** @type {SynthesizerNote[][]} */\n this.currentNoteOn = [\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n [],\n ];\n /** @type {number} @const */\n this.baseVolume = 1 / 0xffff;\n /** @type {number} */\n this.masterVolume = 16384;\n\n /** @type {boolean[]} */\n this.percussionPart = [\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n false,\n true,\n false,\n false,\n false,\n false,\n false,\n false,\n ];\n\n /** @type {number[]} */\n this.percussionVolume = [];\n while (i === 127) {\n this.percussionVolume[i] = 127;\n i++;\n }\n\n /** @type {string[][]} */\n this.programSet = [];\n\n /** @type {Reverb[]} リバーブエフェクト(チャンネル毎に用意する) */\n this.reverb = [];\n\n /** @type {number[]} モジュレーション(ビブラート) */\n this.modulation = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n\n /** @type {BiquadFilterNode[]} フィルタ */\n this.filter = [];\n\n for (i = 0; i < 16; ++i) {\n // @ts-ignore\n this.reverb[i] = new Reverb(this.ctx, { noise: 'violet' });\n // フィルタを定義\n this.filter[i] = this.ctx.createBiquadFilter();\n }\n\n /** 表示項目 */\n this.items = [];\n\n /** @type {IntersectionObserver} 交差していない */\n this.intersection = new IntersectionObserver(\n entries =>\n entries.forEach(entry => {\n // @ts-ignore\n entry.target.dataset.isIntersecting = entry.isIntersecting;\n }),\n {}\n );\n\n /** @type {NodeJS.Timeout} タイマーのスレッド */\n this.timer = undefined;\n /** @type {boolean} */\n this.drag = false;\n }\n\n /** @return {AudioContext} */\n getAudioContext() {\n /** @type {AudioContext} */\n const ctx = new AudioContext();\n\n // Defreeze AudioContext for iOS.\n const initAudioContext = () => {\n document.removeEventListener('touchstart', initAudioContext);\n /** @type {AudioBufferSourceNode} wake up AudioContext */\n const emptySource = ctx.createBufferSource();\n emptySource.start();\n emptySource.stop();\n };\n\n document.addEventListener('touchstart', initAudioContext);\n\n return ctx;\n }\n\n /**\n * System Reset\n *\n * @param {'GM'|'GM2'|'XG'|'GS'} mode 音源モード\n */\n init(mode = 'GM') {\n this.gainMaster.disconnect();\n\n this.refreshInstruments(this.input);\n\n this.mode = mode;\n\n for (let i = 0; i < 16; ++i) {\n this.setPercussionPart(i, i === 9);\n this.programChange(i, 0);\n this.volumeChange(i, 100);\n this.panpotChange(i, 64);\n this.pitchBend(i, 0x00, 0x40); // 8192\n this.pitchBendSensitivity(i, 2);\n this.hold(i, 0);\n this.expression(i, 127);\n this.bankSelectMsb(i, i === 9 ? 127 : 0);\n this.bankSelectLsb(i, i === 9 ? 127 : 0);\n this.attackTime(i, 64);\n this.decayTime(i, 64);\n this.sustinTime(i, 64);\n this.releaseTime(i, 64);\n this.harmonicContent(i, 64);\n this.cutOffFrequency(i, 64);\n this.reverbDepth(i, 40);\n this.modulationDepth(i, 0);\n\n this.updateBankSelect(i);\n this.updateProgramSelect(i);\n }\n\n this.setPercussionPart(9, true);\n\n for (let i = 0; i < 128; ++i) {\n this.percussionVolume[i] = 127;\n }\n\n this.setMasterVolume(8192);\n\n this.gainMaster.connect(this.ctx.destination);\n\n if (this.element) {\n /** @type {HTMLDivElement} */\n const modeElement = this.element.querySelector('.header .keys div');\n modeElement.innerText = mode + ' Mode';\n /** @type {NodeListOf} */\n const bankSelectElement = this.element.querySelectorAll(\n `.instrument .bank > select`\n );\n\n bankSelectElement.forEach(element => (element.disabled = mode === 'GM'));\n this.element.dataset.mode = mode;\n }\n }\n\n /** Close AudioContext */\n async close() {\n await this.ctx.close();\n }\n\n /** @param {Uint8Array} input */\n refreshInstruments(input) {\n this.input = input;\n this.parser = new Parser(input, {\n sampleRate: this.ctx.sampleRate,\n });\n this.bankSet = this.createAllInstruments();\n }\n\n /** @returns {Object[][]} */\n createAllInstruments() {\n /** @type {Parser} */\n const parser = this.parser;\n parser.parse();\n /** @type {Array} TODO */\n const presets = parser.createPreset();\n /** @type {Array} TODO */\n const instruments = parser.createInstrument();\n /** @type {Array} */\n const banks = [];\n /** @type {Record} */\n let bank;\n /** @type {number} */\n let bankNumber;\n /** @type {Object} */\n let instrument;\n /** @type {number} */\n let presetNumber;\n /** @type {string} */\n let presetName;\n\n const programSet = [];\n\n presets.forEach(preset => {\n presetNumber = preset.header.preset;\n bankNumber = preset.header.bank;\n presetName = preset.name.replace(/\\0*$/, '');\n\n if (typeof preset.instrument !== 'number') {\n return;\n }\n\n instrument = instruments[preset.instrument];\n if (instrument.name.replace(/\\0*$/, '') === 'EOI') {\n return;\n }\n\n // select bank\n banks[bankNumber] = banks[bankNumber] ?? [];\n bank = banks[bankNumber];\n bank[presetNumber] = {};\n bank[presetNumber].name = presetName;\n\n instrument.info.forEach(info =>\n this.createNoteInfo(parser, info, bank[presetNumber])\n );\n\n if (!programSet[bankNumber]) {\n programSet[bankNumber] = [];\n }\n programSet[bankNumber][presetNumber] = presetName;\n });\n\n this.programSet = programSet;\n\n return banks;\n }\n\n /**\n * @param {Parser} parser\n * @param {any} info\n * @param {any} preset\n */\n createNoteInfo(parser, info, preset) {\n /** @type {*} */\n const generator = info.generator;\n\n if (!generator.keyRange || !generator.sampleID) {\n return;\n }\n\n // デフォルト値\n // https://www.utsbox.com/?p=2390\n\n /** @type {number} 33: DelayVolEnv */\n const volDelay = this.getModGenAmount(generator, 'delayVolEnv');\n /** @type {number} 34: AttackVolEnv */\n const volAttack = this.getModGenAmount(generator, 'attackVolEnv');\n /** @type {number} 35: HoldVolEnv */\n const volHold = this.getModGenAmount(generator, 'holdVolEnv');\n /** @type {number} 36: DecayVolEnv */\n const volDecay = this.getModGenAmount(generator, 'decayVolEnv');\n /** @type {number} 37: SustainVolEnv */\n const volSustain = this.getModGenAmount(generator, 'sustainVolEnv');\n /** @type {number} 38: ReleaseVolEnv */\n const volRelease = this.getModGenAmount(generator, 'releaseVolEnv');\n /** @type {number} 25: DelayModEnv */\n const modDelay = this.getModGenAmount(generator, 'delayModEnv');\n /** @type {number} 26: AttackModEnv */\n const modAttack = this.getModGenAmount(generator, 'attackModEnv');\n /** @type {number} 27: HoldModEnv */\n const modHold = this.getModGenAmount(generator, 'holdModEnv');\n /** @type {number} 28: DecayModEnv */\n const modDecay = this.getModGenAmount(generator, 'decayModEnv');\n /** @type {number} 29: SustainModEnv */\n const modSustain = this.getModGenAmount(generator, 'sustainModEnv');\n /** @type {number} 30: ReleaseModEnv */\n const modRelease = this.getModGenAmount(generator, 'releaseModEnv');\n /** @type {number} 56: ScaleTuning */\n const scale = this.getModGenAmount(generator, 'scaleTuning') / 100;\n /** @type {number} */\n const tune =\n this.getModGenAmount(generator, 'coarseTune') +\n this.getModGenAmount(generator, 'fineTune') / 100;\n /** @type {number} */\n const sampleModes = this.getModGenAmount(generator, 'sampleModes');\n\n for (\n let i = generator.keyRange.lo, il = generator.keyRange.hi;\n i <= il;\n ++i\n ) {\n if (preset[i]) {\n continue;\n }\n /** @type {number} */\n const sampleId = this.getModGenAmount(generator, 'sampleID');\n /** @type {object} */\n const sampleHeader = parser.sampleHeader[sampleId];\n\n preset[i] = {\n sample: parser.sample[sampleId],\n sampleRate: sampleHeader.sampleRate,\n // 54\n sampleModes: sampleModes,\n basePlaybackRate:\n 1.0594630943592953 ** // Math.pow(2, 1 / 12)\n ((i -\n this.getModGenAmount(generator, 'overridingRootKey') +\n tune +\n sampleHeader.pitchCorrection / 100) *\n scale),\n modEnvToPitch: this.getModGenAmount(generator, 'modEnvToPitch') / 100,\n scaleTuning: scale,\n start:\n this.getModGenAmount(generator, 'startAddrsCoarseOffset') * 32768 +\n this.getModGenAmount(generator, 'startAddrsOffset'),\n end:\n this.getModGenAmount(generator, 'endAddrsCoarseOffset') * 32768 +\n this.getModGenAmount(generator, 'endAddrsOffset'),\n loopStart:\n // (sampleHeader.startLoop - sampleHeader.start) +\n sampleHeader.startLoop +\n this.getModGenAmount(generator, 'startloopAddrsCoarseOffset') *\n 32768 +\n this.getModGenAmount(generator, 'startloopAddrsOffset'),\n loopEnd:\n // (sampleHeader.endLoop - sampleHeader.start) +\n sampleHeader.endLoop +\n this.getModGenAmount(generator, 'endloopAddrsCoarseOffset') * 32768 +\n this.getModGenAmount(generator, 'endloopAddrsOffset'),\n volDelay: 2 ** (volDelay / 1200),\n volAttack: 2 ** (volAttack / 1200),\n volHold:\n 2 ** (volHold / 1200) *\n 2 **\n (((60 - i) *\n this.getModGenAmount(generator, 'keynumToVolEnvHold')) /\n 1200),\n volDecay:\n 2 ** (volDecay / 1200) *\n 2 **\n (((60 - i) *\n this.getModGenAmount(generator, 'keynumToVolEnvDecay')) /\n 1200),\n volSustain: volSustain / 1000,\n volRelease: 2 ** (volRelease / 1200),\n modDelay: 2 ** (modDelay / 1200),\n modAttack: 2 ** (modAttack / 1200),\n modHold:\n 2 ** (modHold / 1200) *\n 2 **\n (((60 - i) *\n this.getModGenAmount(generator, 'keynumToModEnvHold')) /\n 1200),\n modDecay:\n 2 ** (modDecay / 1200) *\n 2 **\n (((60 - i) *\n this.getModGenAmount(generator, 'keynumToModEnvDecay')) /\n 1200),\n modSustain: modSustain / 1000,\n modRelease: 2 ** (modRelease / 1200),\n initialFilterFc:\n 8.176 *\n Math.pow(\n 2,\n this.getModGenAmount(generator, 'initialFilterFc') / 1200\n ),\n modEnvToFilterFc:\n this.getModGenAmount(generator, 'modEnvToFilterFc') / 100,\n initialFilterQ: this.getModGenAmount(generator, 'initialFilterQ') / 10,\n reverbEffectSend:\n this.getModGenAmount(generator, 'reverbEffectSend') / 10,\n initialAttenuation:\n this.getModGenAmount(generator, 'initialAttenuation') / 10,\n freqVibLFO:\n 8.176 *\n Math.pow(2, this.getModGenAmount(generator, 'freqVibLFO') / 1200),\n pan: this.getModGenAmount(generator, 'pan') / 1200,\n };\n }\n }\n\n /**\n * @param {Object} generator\n * @param {string} enumeratorType\n * @return {number}\n */\n getModGenAmount(generator, enumeratorType) {\n return generator[enumeratorType]\n ? generator[enumeratorType].amount\n : Parser.getGeneratorTable()[enumeratorType];\n }\n\n /**\n * Start Tone Generator\n */\n start() {\n this.connect();\n this.bufSrc.start(0);\n this.setMasterVolume(16383);\n }\n\n /** @param {number} volume */\n setMasterVolume(volume) {\n this.masterVolume = volume;\n this.gainMaster.gain.value = this.baseVolume * (volume / 16384);\n }\n\n /** Connect root AudioContext */\n connect() {\n this.bufSrc.connect(this.gainMaster);\n }\n\n /** Disconnect root AudioContext */\n disconnect() {\n this.bufSrc.disconnect(this.gainMaster);\n this.bufSrc.buffer = null;\n }\n\n /** @return {HTMLDivElement} */\n drawSynth() {\n /** @type {Document} */\n const doc = window.document;\n /** @type {HTMLDivElement} */\n const wrapper = (this.element = doc.createElement('div'));\n wrapper.className = 'synthesizer';\n /** @type {HTMLDivElement} */\n const instElem = doc.createElement('div');\n instElem.className = 'instrument';\n /** @type {string[]} */\n this.items = [\n 'mute',\n 'bank',\n 'program',\n 'volume',\n 'expression',\n 'panpot',\n 'pitchBend',\n 'pitchBendSensitivity',\n 'reverbDepth',\n 'keys',\n ];\n /** @type {string} */\n const eventStart = 'ontouchstart' in window ? 'touchstart' : 'mousedown';\n /** @type {string} */\n const eventEnd = 'ontouchend' in window ? 'touchend' : 'mouseup';\n\n for (let channel = 0; channel < 16; channel++) {\n /** @type {HTMLDivElement} */\n const channelElem = doc.createElement('div');\n channelElem.className = 'channel';\n // ホールドを無効化する処理\n channelElem.addEventListener(eventStart, () => {\n this.hold(channel, 0);\n });\n for (const item in this.items) {\n if (!Object.hasOwn(this.items, item)) {\n continue;\n }\n /** @type {HTMLDivElement} */\n const itemElem = doc.createElement('div');\n itemElem.className = this.items[item];\n\n switch (this.items[item]) {\n case 'mute': {\n /** @type {HTMLDivElement | null} */\n const checkboxElement = doc.createElement('div');\n checkboxElement.className = 'form-check form-check-inline';\n /** @type {HTMLInputElement | null} */\n const checkbox = doc.createElement('input');\n checkbox.ariaLabel = `Ch.${channel + 1} Mute`;\n checkbox.setAttribute('type', 'checkbox');\n checkbox.className = 'form-check-input';\n checkbox.id = 'mute' + channel + 'ch';\n checkbox.value = channel.toString();\n checkbox.addEventListener(\n 'change',\n event => {\n // @ts-ignore\n this.mute(channel, event.target.checked);\n },\n false\n );\n checkboxElement.appendChild(checkbox);\n /** @type {HTMLLabelElement} */\n const labelElem = doc.createElement('label');\n\n labelElem.className = 'form-check-label';\n labelElem.textContent = (channel + 1).toString();\n labelElem.setAttribute('for', 'mute' + channel + 'ch');\n checkboxElement.appendChild(labelElem);\n itemElem.appendChild(checkboxElement);\n break;\n }\n case 'bank': {\n /** @type {HTMLSelectElement} Bank select */\n const bankSelect = doc.createElement('select');\n bankSelect.ariaLabel = `Ch.${channel + 1} Bank Select`;\n bankSelect.className = 'form-select form-select-sm bank-select';\n bankSelect.addEventListener(\n 'change',\n ((synth, ch) => event => {\n /** @type {HTMLSelectElement} */\n const program = channelElem.querySelector('.program select');\n // console.log(ch, event.target.value, program);\n // @ts-ignore\n synth.bankChange(ch, event.target.value);\n synth.programChange(ch, parseInt(program.value));\n })(this, channel),\n false\n );\n itemElem.appendChild(bankSelect);\n break;\n }\n case 'program': {\n /** @type {HTMLSelectElement} Program change */\n const select = doc.createElement('select');\n select.className = 'form-select form-select-sm';\n select.ariaLabel = `Ch.${channel + 1} Program Change`;\n select.addEventListener(\n 'change',\n ((synth, ch) => event => {\n // @ts-ignore\n synth.programChange(ch, event.target.value);\n })(this, channel),\n false\n );\n itemElem.appendChild(select);\n break;\n }\n case 'volume': {\n /** @type {HTMLElement} */\n const volumeElem = document.createElement('var');\n volumeElem.ariaLabel = `Ch.${channel + 1} Volume`;\n volumeElem.innerText = '100';\n itemElem.appendChild(volumeElem);\n break;\n }\n case 'expression': {\n /** @type {HTMLElement} */\n const expressionElem = document.createElement('var');\n expressionElem.ariaLabel = `Ch.${channel + 1} Expression`;\n expressionElem.innerText = '127';\n itemElem.appendChild(expressionElem);\n break;\n }\n case 'pitchBendSensitivity': {\n /** @type {HTMLElement} */\n const pitchSensElem = document.createElement('var');\n pitchSensElem.ariaLabel = `Ch.${\n channel + 1\n } Pitch Bend Sensitivity`;\n pitchSensElem.innerText = '2';\n itemElem.appendChild(pitchSensElem);\n break;\n }\n case 'reverbDepth': {\n /** @type {HTMLElement} */\n const reverbDepthElem = document.createElement('var');\n reverbDepthElem.ariaLabel = `Ch.${channel + 1} Reverb Depth`;\n reverbDepthElem.innerText = '40';\n itemElem.appendChild(reverbDepthElem);\n break;\n }\n case 'panpot': {\n /** @type {HTMLDivElement} */\n const panpotOuter = doc.createElement('div');\n panpotOuter.role = 'progressbar';\n panpotOuter.ariaLabel = `Ch.${channel + 1} Panpod`;\n panpotOuter.ariaValueMin = '0';\n panpotOuter.ariaValueNow = '64';\n panpotOuter.ariaValueMax = '127';\n panpotOuter.className = 'progress';\n const panpot = doc.createElement('div');\n // 緑色\n panpot.className = 'progress-bar';\n panpotOuter.appendChild(panpot);\n itemElem.appendChild(panpotOuter);\n break;\n }\n case 'pitchBend': {\n /** @type {HTMLDivElement} */\n const pitchOuter = doc.createElement('div');\n pitchOuter.className = 'progress';\n pitchOuter.role = 'progressbar';\n pitchOuter.ariaLabel = `Ch.${channel + 1} Pitch Bend`;\n pitchOuter.ariaValueMin = '-8192';\n pitchOuter.ariaValueNow = '0';\n pitchOuter.ariaValueMax = '8192';\n pitchOuter.className = 'progress';\n /** @type {HTMLDivElement} */\n const pitch = doc.createElement('div');\n // 黄色\n pitch.className = 'progress-bar progress-bar-animated';\n pitchOuter.appendChild(pitch);\n itemElem.appendChild(pitchOuter);\n break;\n }\n case 'keys': {\n // 鍵盤の描画\n for (let key = 0; key < 127; key++) {\n /** @type {HTMLDivElement} */\n const keyElem = doc.createElement('div');\n /** @type {number} */\n const n = key % 12;\n // 白鍵と黒鍵の色分け\n keyElem.className =\n 'key ' + ([1, 3, 6, 8, 10].includes(n) ? 'semitone' : 'tone');\n itemElem.appendChild(keyElem);\n\n // イベント割当\n keyElem.addEventListener(\n eventStart,\n ((synth, ch, k) => event => {\n event.preventDefault();\n synth.drag = true;\n synth.noteOn(ch, k, 127);\n })(this, channel, key)\n );\n keyElem.addEventListener(\n 'mouseover',\n ((synth, ch, k) => event => {\n event.preventDefault();\n if (synth.drag) {\n synth.noteOn(ch, k, 127);\n }\n })(this, channel, key)\n );\n keyElem.addEventListener(\n 'mouseout',\n ((synth, ch, k) => event => {\n event.preventDefault();\n synth.noteOff(ch, k);\n })(this, channel, key)\n );\n keyElem.addEventListener(\n eventEnd,\n ((synth, ch, k) => event => {\n event.preventDefault();\n synth.drag = false;\n synth.noteOff(ch, k);\n })(this, channel, key)\n );\n }\n break;\n }\n }\n channelElem.appendChild(itemElem);\n }\n instElem.appendChild(channelElem);\n this.intersection.observe(channelElem);\n }\n // ヘッダー行の描画\n const itemName = [\n 'Ch.',\n 'Bank',\n 'Program',\n 'Vol.',\n 'Exp.',\n 'Panpot',\n 'Pitch Bend',\n '',\n 'Rev.',\n '',\n ];\n /** @type {HTMLDivElement} */\n const headerElem = doc.createElement('div');\n headerElem.className = 'header';\n for (const item in this.items) {\n if (!Object.hasOwn(this.items, item)) {\n continue;\n }\n /** @type {HTMLDivElement} */\n const itemElem = doc.createElement('div');\n itemElem.className = this.items[item];\n itemElem.textContent = itemName[item];\n if (this.items[item] === 'keys') {\n // MIDI音源のLCDのテキスト領域エミュレーター\n itemElem.appendChild(document.createElement('code'));\n // GM / GS / XG表記\n itemElem.appendChild(document.createElement('div'));\n }\n headerElem.appendChild(itemElem);\n }\n instElem.prepend(headerElem);\n wrapper.appendChild(instElem);\n\n // ヘッダー行のリサイズ\n const ro = new ResizeObserver(_entries => {\n this.items.forEach(item => {\n /** @type {HTMLElement} */\n const headerItem = wrapper.querySelector(`.header .${item}`);\n /** @type {HTMLElement} */\n const channelItem = wrapper.querySelector(`.channel .${item}`);\n\n headerItem.style.width = channelItem.offsetWidth + 'px';\n });\n /** @type {HTMLElement} */\n const keysItem = wrapper.querySelector(`.header .keys`);\n\n keysItem.style.display =\n document.documentElement.clientWidth <= 680 ? 'none' : 'flex';\n });\n ro.observe(wrapper);\n\n return wrapper;\n }\n\n /**\n * シンセサイザーのDOMの更新\n *\n * @param {number} channel\n * @param {number} key\n * @param {number} velocity\n */\n updateSynthElement(channel, key, velocity) {\n if (!this.element) {\n return;\n }\n /** @type {NodeListOf} */\n const channelElems = this.element.querySelectorAll(\n `.instrument > .channel`\n );\n\n if (channelElems[channel].dataset.isIntersecting) {\n /** @type {HTMLDivElement} */\n const keyElem = channelElems[channel].querySelector(\n `.key:nth-child(${key + 1})`\n );\n if (velocity === 0) {\n if (keyElem.classList.contains('note-on')) {\n keyElem.classList.remove('note-on');\n }\n keyElem.style.opacity = '1';\n } else {\n keyElem.classList.add('note-on');\n // ベロシティに応じて透過度を調整\n keyElem.style.opacity = (velocity / 127).toFixed(2);\n }\n }\n }\n\n /**\n * バンクセレクタの選択ボックスの処理\n *\n * @param {number} channel\n */\n updateBankSelect(channel) {\n if (!this.element) {\n return;\n }\n /** @type {HTMLElement} */\n const bankElement = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.bank > select');\n\n while (bankElement.firstChild)\n bankElement.removeChild(bankElement.firstChild);\n\n for (const bankNo in this.programSet) {\n if (!Object.hasOwn(this.programSet, bankNo)) {\n continue;\n }\n const option = document.createElement('option');\n option.value = bankNo;\n option.textContent = ('000' + parseInt(bankNo)).slice(-3);\n if (parseInt(bankNo) === this.channelBank[channel]) {\n option.selected = true;\n }\n bankElement.appendChild(option);\n }\n }\n\n /**\n * プログラムチェンジの選択ボックスの処理\n *\n * @param {number} channel\n */\n updateProgramSelect(channel) {\n if (!this.element) {\n return;\n }\n const dom = this.element.querySelectorAll(`.instrument > .channel`)[\n channel\n ];\n\n /** @type {number} */\n const bankIndex = this.channelBank[channel];\n /** @type {HTMLSelectElement} */\n const bankElement = dom.querySelector('.bank > select');\n /** @type {HTMLSelectElement} */\n const programElement = dom.querySelector('.program > select');\n\n bankElement.value = this.channelBank[channel].toString();\n while (programElement.firstChild)\n programElement.removeChild(programElement.firstChild);\n\n for (const programNo in this.programSet[bankIndex]) {\n if (!Object.hasOwn(this.programSet[bankIndex], programNo)) {\n continue;\n }\n // TODO: 存在しないプログラムの場合、現状では空白になってしまう\n /** @type {HTMLOptionElement} */\n const option = document.createElement('option');\n option.value = programNo;\n option.textContent = `${('000' + (parseInt(programNo) + 1)).slice(-3)}:${\n this.programSet[bankIndex][programNo]\n }`;\n if (parseInt(programNo) === this.channelInstrument[channel]) {\n option.selected = true;\n }\n programElement.appendChild(option);\n }\n }\n\n /**\n * ノートオン\n *\n * @param {number} channel NoteOn するチャンネル.\n * @param {number} key NoteOn するキー.\n * @param {number} velocity 強さ.\n */\n noteOn(channel, key, velocity = 100) {\n /** @type {number} */\n const bankIndex = this.channelBank[channel];\n // バンクに楽器が存在しない場合は、原則的にバンク0の楽器を選択する。\n // ただし、SFX(Bank 64)は発音しない、\n // パーカッション(Bank127~128) の場合、0のStandard Kitの音を鳴らさなければならない)\n /** @type {Object} */\n const bank =\n typeof this.bankSet[bankIndex] === 'object'\n ? this.bankSet[bankIndex]\n : this.bankSet[0];\n\n /** @type {Object} */\n let instrument;\n\n if (typeof bank[this.channelInstrument[channel]] === 'object') {\n // 音色が存在する場合\n instrument = bank[this.channelInstrument[channel]];\n } else if (this.percussionPart[channel]) {\n // パーカッションバンクが選択されている場合で音色が存在しない場合Standard Kitを選択\n instrument = this.bankSet[this.mode === 'XG' ? 127 : 128][0];\n } else {\n // 通常の音色が選択されている状態で音色が存在しない場合バンク0を選択\n instrument = this.bankSet[0][this.channelInstrument[channel]];\n }\n\n if (instrument[key] === void 0) {\n // TODO\n console.warn(\n 'instrument not found: bank=%s instrument=%s channel=%s key=%s',\n bankIndex,\n this.channelInstrument[channel],\n channel,\n key\n );\n return;\n }\n /** @type {Object} */\n const instrumentKey = instrument[key];\n /** @type {number} */\n let panpot =\n this.channelPanpot[channel] === 0\n ? Math.floor(Math.random() * 127) // パンが0の場合ランダムとなる。\n : this.channelPanpot[channel] - 64;\n panpot /= panpot < 0 ? 64 : 63;\n\n // create note information\n instrumentKey['channel'] = channel;\n instrumentKey['key'] = key;\n instrumentKey['velocity'] = velocity;\n instrumentKey['panpot'] = panpot;\n instrumentKey['volume'] = this.channelVolume[channel] / 127;\n instrumentKey['pitchBend'] = this.channelPitchBend[channel] - 8192;\n instrumentKey['expression'] = this.channelExpression[channel];\n instrumentKey['pitchBendSensitivity'] = Math.round(\n this.channelPitchBendSensitivity[channel]\n );\n instrumentKey['mute'] = this.channelMute[channel];\n instrumentKey['releaseTime'] = this.channelRelease[channel];\n instrumentKey['cutOffFrequency'] = this.cutOffFrequency[channel];\n instrumentKey['harmonicContent'] = this.harmonicContent[channel];\n instrumentKey['reverb'] = this.reverb[channel];\n instrumentKey['modulation'] = this.modulation[channel];\n\n // percussion\n if (bankIndex >= 127) {\n // ドラムパートのハイハットクローズはここで定義するべきではない。\n if (key === 42 || key === 44) {\n // 42: Closed Hi-Hat\n // 44: Pedal Hi-Hat\n // 46: Open Hi-Hat\n this.noteOff(channel, 46);\n }\n if (key === 80) {\n // 80: Mute Triangle\n // 81: Open Triangle\n this.noteOff(channel, 81);\n }\n instrument['volume'] *= this.percussionVolume[key] / 127;\n }\n\n // note on\n /** @type {SynthesizerNote} */\n const note = new SynthesizerNote(this.ctx, this.gainMaster, instrumentKey);\n // TODO: 本来パンポットはここで指定する\n note.noteOn();\n this.currentNoteOn[channel].push(note);\n\n this.updateSynthElement(channel, key, velocity);\n }\n\n /**\n * ノートオフ\n *\n * @param {number} channel NoteOff するチャンネル.\n * @param {number} key NoteOff するキー.\n */\n noteOff(channel, key) {\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n /** @type {SynthesizerNote[]} */\n const currentNoteOn = this.currentNoteOn[channel];\n /** @type {SynthesizerNote} */\n let note;\n /** @type {boolean} */\n const hold = this.channelHold[channel];\n\n for (i = 0, il = currentNoteOn.length; i < il; ++i) {\n note = currentNoteOn[i];\n if (note.key === key) {\n note.noteOff();\n // hold している時は NoteOff にはするがリリースはしない\n if (!hold) {\n note.release();\n currentNoteOn.splice(i, 1);\n --i;\n --il;\n }\n }\n }\n this.updateSynthElement(channel, key, 0);\n }\n\n /**\n * ホールド(ダンパーペダル)\n *\n * @param {number} channel ホールドするチャンネル\n * @param {number} value 値\n */\n hold(channel, value) {\n /** @type {SynthesizerNote[]} */\n const currentNoteOn = this.currentNoteOn[channel];\n /** @type {boolean} 0以外はonである。 */\n const hold = (this.channelHold[channel] = value > 64);\n /** @type {SynthesizerNote} */\n let note;\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n\n if (!hold) {\n for (i = 0, il = currentNoteOn.length; i < il; ++i) {\n note = currentNoteOn[i];\n if (note.isNoteOff()) {\n note.release();\n currentNoteOn.splice(i, 1);\n --i;\n --il;\n }\n }\n }\n\n if (this.element) {\n /** @type {NodeListOf} */\n const channelElements = this.element.querySelectorAll(\n `.instrument > .channel`\n );\n\n if (!channelElements[channel]) {\n return;\n }\n if (this.channelHold[channel]) {\n channelElements[channel].classList.add('hold');\n } else if (channelElements[channel].classList.contains('hold')) {\n channelElements[channel].classList.remove('hold');\n }\n }\n }\n\n /**\n * バンクセレクトMSB(GS音源/GM Level2用)\n *\n * @param {number} channel チャンネルのバンクセレクトMSB\n * @param {number} value 値\n */\n bankSelectMsb(channel, value) {\n // 125より値が大きい場合、パーカッションとして処理\n this.percussionPart[channel] = value >= 125;\n // 念の為バンクを0にリセット\n this.channelBank[channel] = channel === 9 ? 128 : 0;\n\n if (this.mode === 'GM') {\n // GM音源モードのときはバンク・セレクトを無視\n return;\n } else if (this.mode === 'XG') {\n // XG音源は、MSB→LSBの優先順でバンクセレクトをする。\n if (value === 64) {\n // Bank Select MSB #64 (Voice Type: SFX)\n this.channelBank[channel] = 125;\n } else if (value === 126 || value === 127) {\n // Bank Select MSB #126 (Voice Type: Drum)\n // Bank Select MSB #127 (Voice Type: Drum)\n this.channelBank[channel] = value;\n } else if (value === 128) {\n this.channelBank[channel] = 127;\n }\n } else {\n // GS音源\n // ※チャンネル10のバンク・セレクト命令は無視する。\n this.channelBank[channel] = channel === 9 ? 128 : value;\n this.percussionPart[channel] = value === 128;\n }\n this.updateBankSelect(channel);\n }\n\n /**\n * バンクセレクトLSB(XG音源)\n *\n * @param {number} channel チャンネルのバンクセレクトLSB\n * @param {number} value 値\n */\n bankSelectLsb(channel, value) {\n // XG音源以外は処理しない\n if (this.mode !== 'XG') {\n return;\n }\n\n if (!this.percussionPart[channel]) {\n // ドラムパートではバンクセレクトLSB命令を無視する。\n this.channelBank[channel] = value;\n }\n\n this.updateBankSelect(channel);\n }\n\n /**\n * プログラムチェンジ\n *\n * @param {number} channel 音色を変更するチャンネル.\n * @param {number} instrument 音色番号.\n */\n programChange(channel, instrument) {\n this.channelInstrument[channel] = instrument;\n\n this.bankChange(channel, this.channelBank[channel]);\n if (this.element) {\n /** @type {HTMLSelectElement} */\n const select = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.program > select');\n\n select.value = instrument.toString();\n }\n }\n\n /**\n * バンクセレクト\n *\n * @param {number} channel 音色を変更するチャンネル.\n * @param {number} bank バンク・セレクト.\n */\n bankChange(channel, bank) {\n /** パーカッションバンク */\n const percussionBank = this.mode === 'XG' || this.mode === 'GM' ? 127 : 128;\n if (this.mode === 'GM') {\n // GMの場合バンクセレクトを無効化\n bank = 0;\n }\n if (channel === 9) {\n // GS、XGフラグが立っていない(拡張音源ではない)場合は、ch10はドラム固定、それ以外は0とする。\n bank = percussionBank;\n }\n if (this.bankSet[bank]) {\n this.channelBank[channel] = bank;\n } else {\n // 存在しない場合0を選択\n this.channelBank[channel] = this.percussionPart[channel]\n ? percussionBank\n : 0;\n }\n // }\n\n if (this.element) {\n /** @type {HTMLSelectElement} バンクセレクトの値 */\n const bankSelect = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.bank > select');\n bankSelect.value = bank.toString();\n }\n // TODO: 厳密にはMIDI音源はプログラムチェンジがあったときに、バンク・セレクトの値が反映されるのでこの実装は正しくない。\n this.updateProgramSelect(channel);\n }\n\n /**\n * ボリューム\n *\n * @param {number} channel 音量を変更するチャンネル.\n * @param {number} volume 音量(0-127).\n */\n volumeChange(channel, volume) {\n if (this.element) {\n /** @type {HTMLElement} */\n const volumeVariable = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.volume var');\n volumeVariable.innerText = volume.toString();\n }\n\n this.channelVolume[channel] = volume;\n }\n\n /**\n * エクスプレッション\n *\n * @param {number} channel 音量を変更するチャンネル.\n * @param {number} expression 音量(0-127).\n */\n expression(channel, expression) {\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n /** @type {SynthesizerNote[]} */\n const currentNoteOn = this.currentNoteOn[channel];\n\n for (i = 0, il = currentNoteOn.length; i < il; ++i) {\n currentNoteOn[i].updateExpression(expression);\n }\n\n if (this.element) {\n /** @type {HTMLElement} */\n const expressionVariabe = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.expression var');\n\n expressionVariabe.innerText = expression.toString();\n }\n\n this.channelExpression[channel] = expression;\n }\n\n /**\n * パンポット\n *\n * @param {number} channel Panpot を変更するチャンネル.\n * @param {number} panpot Panpot(0-127).\n */\n panpotChange(channel, panpot) {\n this.channelPanpot[channel] = panpot;\n if (this.element) {\n const dom = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.panpot');\n dom.ariaValueNow = panpot.toString();\n /** @type {HTMLDivElement} */\n const progressBar = dom.querySelector('.progress-bar');\n const percentage = (panpot / 127) * 100;\n progressBar.style.width = `${percentage}%`;\n progressBar.classList.remove('left', 'right');\n progressBar.title = panpot.toString();\n if (panpot === 64) {\n return;\n }\n dom.classList.add(panpot < 63 ? 'left' : 'right');\n }\n }\n\n /**\n * ピッチベンド\n *\n * @param {number} channel ピッチベンドを変更するチャンネル.\n * @param {number} lowerByte\n * @param {number} higherByte\n */\n pitchBend(channel, lowerByte, higherByte) {\n /** @type {number} */\n const bend = (lowerByte & 0x7f) | ((higherByte & 0x7f) << 7);\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n /** @type {import('./sound_font_synth_note').default[]} */\n const currentNoteOn = this.currentNoteOn[channel];\n /** @type {number} */\n const calculated = bend - 8192;\n\n for (i = 0, il = currentNoteOn.length; i < il; ++i) {\n currentNoteOn[i].updatePitchBend(calculated);\n }\n\n this.channelPitchBend[channel] = bend;\n\n if (this.element) {\n /** @type {HTMLDivElement} */\n const dom = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.pitchBend');\n dom.ariaValueNow = bend.toString();\n /** @type {HTMLDivElement} */\n const progressBar = dom.querySelector('.progress-bar');\n progressBar.style.width = `${Math.floor((bend / 16384) * 100)}%`;\n progressBar.title = calculated.toString();\n progressBar.classList.remove('high', 'low');\n if (calculated === 0) {\n return;\n }\n progressBar.classList.add(calculated < 0 ? 'low' : 'high');\n }\n }\n\n /**\n * ピッチベンド・センシビリティ\n *\n * @param {number} channel Pitch bend sensitivity を変更するチャンネル.\n * @param {number} sensitivity\n */\n pitchBendSensitivity(channel, sensitivity) {\n if (this.element) {\n /** @type {HTMLElement} */\n const pitchBendSensitivityVariable = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.pitchBendSensitivity > var');\n pitchBendSensitivityVariable.innerText = sensitivity.toString();\n }\n this.channelPitchBendSensitivity[channel] = sensitivity;\n }\n\n /**\n * アタックタイム\n *\n * @param {number} channel\n * @param {number} attackTime\n */\n attackTime(channel, attackTime) {\n this.channelAttack[channel] = attackTime;\n }\n\n /**\n * ディケイタイム\n *\n * @param {number} channel\n * @param {number} decayTime\n */\n decayTime(channel, decayTime) {\n this.channelDecay[channel] = decayTime;\n }\n\n /**\n * サスティンタイム\n *\n * @param {number} channel\n * @param {number} sustinTime\n */\n sustinTime(channel, sustinTime) {\n this.channelSustin[channel] = sustinTime;\n }\n\n /**\n * リリースタイム\n *\n * @param {number} channel\n * @param {number} releaseTime\n */\n releaseTime(channel, releaseTime) {\n this.channelRelease[channel] = releaseTime;\n }\n\n /**\n * ハーモニックコンテント(ブライトネス)\n *\n * @param {number} channel\n * @param {number} value\n */\n harmonicContent(channel, value) {\n this.channelHarmonicContent[channel] = value;\n }\n\n /**\n * カットオフフリクエンシー\n *\n * @param {number} channel\n * @param {number} value\n */\n cutOffFrequency(channel, value) {\n this.channelCutOffFrequency[channel] = value;\n }\n\n /**\n * リバーブエフェクト\n *\n * @param {number} channel\n * @param {number} depth\n */\n reverbDepth(channel, depth) {\n // リバーブ深度は、ドライ/ウェット比とする。\n this.reverb[channel].mix(depth / 127);\n\n if (this.element) {\n /** @type {HTMLElement} */\n const reverbVariable = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.reverbDepth var');\n reverbVariable.innerText = depth.toString();\n }\n }\n\n /**\n * モジュレーション(ビブラート)デプス\n *\n * @param {number} channel\n * @param {number} depth\n */\n modulationDepth(channel, depth) {\n if (this.element) {\n const dom = this.element\n .querySelectorAll(`.instrument > .channel`)\n [channel].querySelector('.pitchBend .progress-bar');\n\n // モデレーターが0でないときは、ピッチに斜め線を入れる\n if (depth !== 0) {\n dom.classList.add('progress-bar-striped');\n } else {\n dom.classList.remove('progress-bar-striped');\n }\n }\n this.modulation[channel] = depth;\n }\n\n /**\n * @param {number} channel Pitch bend sensitivity を取得するチャンネル.\n * @return {number}\n */\n getPitchBendSensitivity(channel) {\n return this.channelPitchBendSensitivity[channel];\n }\n\n /**\n * @param {number} key\n * @param {number} volume\n */\n drumInstrumentLevel(key, volume) {\n this.percussionVolume[key] = volume;\n }\n\n /**\n * オールノートオフ\n *\n * @param {number} channel NoteOff するチャンネル.\n */\n allNoteOff(channel) {\n /** @type {SynthesizerNote[]} */\n const currentNoteOn = this.currentNoteOn[channel];\n\n // ホールドを解除\n this.hold(channel, 0);\n\n // 再生中の音をすべて止める\n while (currentNoteOn.length > 0) {\n this.noteOff(channel, currentNoteOn[0].key);\n }\n }\n\n /**\n * オールサウンドオフ\n *\n * @param {number} channel 音を消すチャンネル.\n */\n allSoundOff(channel) {\n /** @type {SynthesizerNote[]} */\n const currentNoteOn = this.currentNoteOn[channel];\n /** @type {SynthesizerNote} */\n let note;\n\n while (currentNoteOn.length > 0) {\n note = currentNoteOn.shift();\n this.noteOff(channel, note.key);\n note.release();\n note.disconnect();\n }\n\n // ホールドを解除\n this.hold(channel, 0);\n }\n\n /**\n * リセットオールコントロール\n *\n * @param {number} channel リセットするチャンネル\n */\n resetAllControl(channel) {\n // 実装不十分では?\n this.allNoteOff(channel);\n this.expression(channel, 127);\n this.pitchBend(channel, 0x00, 0x40);\n }\n\n /**\n * ミュート\n *\n * @param {number} channel ミュートの設定を変更するチャンネル.\n * @param {boolean} mute ミュートにするなら true.\n */\n mute(channel, mute) {\n /** @type {SynthesizerNote[]} */\n const currentNoteOn = this.currentNoteOn[channel];\n /** @type {number} */\n let i;\n /** @type {number} */\n let il;\n\n this.channelMute[channel] = mute;\n\n if (mute) {\n for (i = 0, il = currentNoteOn.length; i < il; ++i) {\n currentNoteOn[i].disconnect();\n }\n } else {\n for (i = 0, il = currentNoteOn.length; i < il; ++i) {\n currentNoteOn[i].connect();\n }\n }\n }\n\n /**\n * パーカッションチャネルにする\n *\n * @param {number} channel パーカッションチャネルとしてセットするチャンネル\n * @param {boolean} sw パーカッションチャネルか通常かのスイッチ\n */\n setPercussionPart(channel, sw) {\n this.channelBank[channel] =\n this.mode === 'GS' || this.mode === 'GM2' ? 128 : 127;\n\n this.percussionPart[channel] = sw;\n this.updateBankSelect(channel);\n }\n\n /**\n * MIDI音源のメッセージ欄に送られるsysExを解析\n *\n * @param {number[]} message\n */\n processMidiMessage(message) {\n clearTimeout(this.timer);\n /** @type {HTMLElement} */\n const dom = this.element.querySelector('.header .keys code');\n dom.innerText = message.map(e => String.fromCharCode(e)).join('');\n\n // 10秒後に削除\n this.timer = setTimeout(() => {\n dom.innerText = '';\n }, 50000);\n }\n}\n","/**\n * @classdesc File Loader Class\n * @private\n * @author Logue \n */\nexport default class Loader {\n /** キャッシュの名前空間 */\n static CACHE_NAME = 'wml';\n /**\n * コンストラクタ\n *\n * @constructor\n * @param {string} url\n * @param {HTMLDivElement} placeholder\n * @param {boolean} cache\n * @param {Function} callback\n */\n constructor(url, placeholder, cache, callback) {\n this.url = url;\n this.cache = cache;\n this.callback = callback;\n\n /** @type {HTMLDivElement} */\n this.alert = document.createElement('div');\n this.alert.className = 'alert alert-warning';\n\n /** @type {HTMLParagraphElement} */\n this.message = document.createElement('p');\n this.message.innerText = 'Now Loading...';\n\n /** @type {HTMLDivElement} */\n this.progressOuter = document.createElement('div');\n this.progressOuter.className = 'progress';\n this.progressOuter.role = 'progressbar';\n this.progressOuter.ariaLabel = `Loading Progress`;\n this.progressOuter.ariaValueMin = '0';\n this.progressOuter.ariaValueNow = '0';\n this.progressOuter.ariaValueMax = '100';\n\n /** @type {HTMLDivElement} */\n this.progress = document.createElement('div');\n this.progress.className = 'progress-bar';\n\n this.progressOuter.appendChild(this.progress);\n this.alert.appendChild(this.message);\n this.alert.appendChild(this.progressOuter);\n\n placeholder.appendChild(this.alert);\n }\n\n /**\n * ダウンロード中のハンドラ\n * @param {number} current\n * @param {number} total\n * @private\n */\n onProgress(current, total) {\n const percentCompleted = Math.floor((current / total) * 100);\n this.progress.style.width = `${percentCompleted}%`;\n this.progress.innerText = `${percentCompleted}%`;\n }\n\n /**\n * ロード完了時のハンドラ\n *\n * @param {ArrayBuffer} buffer\n * @private\n */\n onComplete(buffer) {\n this.alert.className = 'alert alert-info';\n this.message.innerText = 'Initializing...';\n this.progress.className =\n 'progress-bar progress-bar-striped progress-bar-animated';\n this.progress.style.width = '100%';\n // コールバック実行\n this.callback(new Uint8Array(buffer));\n }\n\n /**\n * エラー時のハンドラ\n *\n * @param {Error | undefined} error エラー内容\n * @private\n */\n onError(error = undefined) {\n requestAnimationFrame(() => {\n this.alert.className = 'alert alert-danger';\n this.message.innerText =\n 'An error occurred while loading SoundFont. See the console log for details. In addition, it may be cured by deleting the cache of the browser.';\n this.progressOuter.style.display = 'none';\n });\n }\n\n /**\n * データ取得\n * @public\n */\n async fetch() {\n /** @type {Cache} */\n const cache = await window.caches.open(Loader.CACHE_NAME);\n /** @type {Response} */\n const cached = await cache.match(this.url);\n\n if (this.cache && cached) {\n // キャッシュが存在する場合、キャッシュの値を返す\n this.onComplete(await cached.arrayBuffer());\n return;\n }\n\n /** @type {void | Response} キャッシュがない場合Fetchで取得 */\n const response = await fetch(this.url, {\n method: 'GET',\n }).catch(e => this.onError(e));\n\n if (!response || (response && !response.ok)) {\n return;\n }\n\n /** @type {Response} キャッシュ用レスポンス */\n const cloned = response.clone();\n\n /** @type {number} ファイルの容量 */\n const contentLength = parseInt(response.headers.get('Content-Length'));\n\n /** @type {ReadableStreamDefaultReader} ファイルリーダー */\n const reader = cloned.body.getReader();\n\n /** @type {number} 読み込まれたチャンクの長さ */\n let receivedLength = 0;\n\n /** @type {Uint8Array[]} 受信したバイナリチャンクの配列(本文を構成します) */\n const chunks = [];\n\n // eslint-disable-next-line\n while (true) {\n // 最後のチャンクも場合、done は true。\n // value はチャンクバイトの Uint8Array\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n chunks.push(value);\n receivedLength += value.length;\n\n this.message.innerText = `Now Loading... (${receivedLength} of ${contentLength} byte)`;\n\n // Content lengthヘッダーが出力されている場合プログレスバーを表示\n this.onProgress(receivedLength, contentLength);\n }\n\n /** @type {Uint8Array} 全チャンク */\n const chunksAll = new Uint8Array(receivedLength);\n /** @type {number} 現在の読み込んだチャンク位置 */\n let position = 0;\n for (const chunk of chunks) {\n chunksAll.set(chunk, position);\n position += chunk.length;\n }\n\n // キャッシュへ保存\n await cache.put(this.url, response);\n // 完了時のイベントを実行\n this.onComplete(chunksAll);\n }\n}\n","import Synthesizer from './sound_font_synth';\nimport Loader from './loader';\n\n/**\n * WebMidiLink Class\n *\n * @author imaya\n */\nexport default class WebMidiLink {\n /** @param {object} option */\n constructor(option = {}) {\n /** @type {number[]} */\n this.NrpnMsb = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n /** @type {number[]} */\n this.NrpnLsb = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n /** @type {number[]} */\n this.RpnMsb = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n /** @type {number[]} */\n this.RpnLsb = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n /** @type {boolean} */\n this.ready = false;\n /** @type {Synthesizer} */\n this.synth = undefined;\n /** @type {Function} */\n this.messageHandler = this.onMessage.bind(this);\n /** @type {boolean} */\n this.rpnMode = true;\n /** @type {object} */\n this.option = {};\n /** @type {boolean} Display synthsizer Web UI */\n this.option.drawSynth = option.drawSynth !== 'false';\n /** @type {boolean} Use Cache API */\n this.option.cache = option.cache ?? true;\n /** @type {string} CORS */\n this.option.targetOrigin = option.targetOrigin ?? '*';\n /** @type {'dark'|'light'|'auto'|undefined} Color mode */\n this.option.colorMode = option.colorMode ?? 'auto';\n /** @type {string} SoundFont URL */\n this.url =\n option.url ??\n 'https://cdn.jsdelivr.net/npm/@logue/sf2synth@latest/dist/Yamaha XG Sound Set.sf2';\n\n /** @type {HTMLDivElement} */\n // @ts-ignore\n this.placeholder = option.placeholder\n ? document.getElementById(option.placeholder)\n : window.document.body;\n this.setColorMode(this.option.colorMode);\n /** @type {Window} */\n this.window = null;\n\n if (window.opener) {\n this.window = window.opener;\n } else if (window.parent !== window) {\n this.window = window.parent;\n } else {\n this.window = window;\n }\n }\n\n /**\n * Setup Soundfont by URL.\n *\n * @param {string?} url SoundFont URL\n * @public\n */\n async setup(url = undefined) {\n // DOMをクリア\n while (this.placeholder.firstChild) {\n this.placeholder.removeChild(this.placeholder.firstChild);\n }\n if (url) {\n // URLが明示的に指定されていた場合\n this.url = url;\n }\n\n /** 読み込み */\n const loader = new Loader(\n this.url,\n this.placeholder,\n this.option.cache,\n (/** @type {ArrayBuffer} */ buffer) => this.setupByBuffer(buffer)\n );\n await loader.fetch();\n }\n\n /**\n * Get SoundFont URL.\n *\n * @return {string}\n */\n getUrl() {\n return this.url;\n }\n\n /**\n * Setup SoundFont by ArrayBuffer.\n *\n * @param {ArrayBuffer} buffer\n */\n setupByBuffer(buffer) {\n // DOMをクリア\n while (this.placeholder.firstChild) {\n this.placeholder.removeChild(this.placeholder.firstChild);\n }\n\n if (!this.synth) {\n // 読み込まれていないときシンセサイザをセットアップ\n // @ts-ignore\n this.synth = new Synthesizer(buffer);\n // 待受開始\n this.synth.start();\n } else {\n // 別のSoundFontが読み込まれたときリロード\n // @ts-ignore\n this.synth.refreshInstruments(buffer);\n }\n if (this.option.drawSynth) {\n // キーボードなどを描画\n this.placeholder.appendChild(this.synth.drawSynth());\n } else {\n /** @type {HTMLDivElement} キーボードを描画しないときはReadyだけを表示する。 */\n const readyElem = document.createElement('div');\n readyElem.className = 'alert alert-success';\n readyElem.role = 'alert';\n readyElem.innerText = 'Ready.';\n this.placeholder.appendChild(readyElem);\n }\n // シンセサイザを初期化\n this.synth.init();\n\n this.onReady();\n }\n\n /**\n * Callback\n *\n * @protected\n */\n callback() {\n return;\n }\n\n /**\n * SoundFont Load Ready\n *\n * @protected\n */\n onReady() {\n // 一旦MIDI Link待受を解除\n // @ts-ignore\n window.removeEventListener('message', this.messageHandler);\n // コールバック実行\n this.callback();\n // MIDI Link待ち受け開始\n // @ts-ignore\n window.addEventListener('message', this.messageHandler, false);\n // ホスト側に準備完了通知を送信\n this.window.postMessage('link,ready', this.option.targetOrigin);\n }\n\n /**\n * WebMidiLink信号をパース\n *\n * @param {Event} ev\n * @private\n */\n onMessage(ev) {\n /** @type {Array} */\n // @ts-ignore\n const msg = typeof ev.data.split === 'function' ? ev.data.split(',') : [];\n /** @type {string} */\n // @ts-ignore\n const type = msg.length !== 0 ? msg.shift() : '';\n /** @type {string} */\n let command;\n\n switch (type) {\n case 'midi':\n this.processMidiMessage(msg.map(hex => parseInt(hex, 16)));\n break;\n case 'link':\n if (this.window === void 0) {\n return;\n }\n command = msg.shift();\n switch (command) {\n case 'reqpatch':\n // TODO: dummy data\n this.window.postMessage('link,patch', this.option.targetOrigin);\n break;\n case 'setpatch':\n case 'ready':\n this.window.postMessage('link,ready', this.option.targetOrigin);\n // TODO: NOP\n break;\n case 'progress':\n // ※この命令は、WebMidiLinkの仕様に含まれていません。\n this.window.postMessage('link,progress', this.option.targetOrigin);\n break;\n default:\n console.error('unknown link message:', command);\n break;\n }\n break;\n default:\n console.error('unknown message type');\n }\n }\n\n /**\n * MIDI準備完了時のコールバック処理を登録する\n *\n * @param {()=>{}} callback コールバック関数\n * @public\n */\n setLoadCallback(callback) {\n this.callback = callback;\n }\n\n /**\n * MIDI信号を解析し、シンセサイザーを操作する\n *\n * @param {number[]} message\n * @protected\n */\n processMidiMessage(message) {\n /** @type {number} */\n const channel = message[0] & 0x0f;\n /** @type {Synthesizer} */\n const synth = this.synth;\n\n // http://amei.or.jp/midistandardcommittee/MIDI1.0.pdf\n switch (message[0] & 0xf0) {\n case 0x80: // NoteOff: 8n kk vv\n // @ts-ignore\n synth.noteOff(channel, message[1], message[2]);\n break;\n case 0x90: // NoteOn: 9n kk vv\n if (message[2] > 0) {\n synth.noteOn(channel, message[1], message[2]);\n } else {\n // @ts-ignore\n synth.noteOff(channel, message[1], 0);\n }\n break;\n case 0xb0: {\n // Control Change: Bn cc dd\n /** @type {number} */\n const value = message[2];\n switch (message[1]) {\n case 0x00: // Bank Select MSB: Bn 00 dd\n synth.bankSelectMsb(channel, value);\n break;\n case 0x01: // Modulation Depth\n synth.modulationDepth(channel, value);\n break;\n case 0x05: // Portament Time\n break;\n case 0x06: // Data Entry(MSB): Bn 06 dd\n if (this.rpnMode) {\n // RPN\n switch (this.RpnMsb[channel]) {\n case 0:\n switch (this.RpnLsb[channel]) {\n case 0: // Pitch Bend Sensitivity\n synth.pitchBendSensitivity(channel, value);\n break;\n case 1:\n // console.log(\"fine\");\n break;\n case 2:\n // console.log(\"coarse\");\n break;\n default:\n // console.log(\"default\");\n break;\n }\n break;\n default:\n // console.log(\"default:\", this.RpnMsb[channel], this.RpnLsb[channel]);\n break;\n }\n } else {\n // NRPN\n switch (this.NrpnMsb[channel]) {\n case 26: // Drum Instrument Level\n synth.drumInstrumentLevel(this.NrpnLsb[channel], value);\n break;\n default:\n // console.log(\"default:\", this.RpnMsb[channel], this.RpnLsb[channel]);\n break;\n }\n }\n break;\n case 0x26: // Data Entry(LSB): Bn 26 dd\n if (this.rpnMode) {\n // RPN\n switch (this.RpnMsb[channel]) {\n case 0:\n switch (this.RpnLsb[channel]) {\n case 0: // Pitch Bend Sensitivity\n synth.pitchBendSensitivity(\n channel,\n synth.getPitchBendSensitivity(channel) + value / 100\n );\n break;\n case 1:\n // console.log(\"fine\");\n break;\n case 2:\n // console.log(\"coarse\");\n break;\n }\n break;\n }\n }\n\n // NRPN で LSB が必要なものは今のところない\n break;\n\n case 0x07: // Volume Change: Bn 07 dd\n synth.volumeChange(channel, value);\n break;\n case 0x0a: // Panpot Change: Bn 0A dd\n synth.panpotChange(channel, value);\n break;\n case 0x78: // All Sound Off: Bn 78 00]\n synth.allSoundOff(channel);\n break;\n case 0x79: // Reset All Control: Bn 79 00\n synth.resetAllControl(channel);\n break;\n case 0x20: // BankSelect LSB: Bn 00 dd\n synth.bankSelectLsb(channel, value);\n break;\n case 0x47: // Harmonic Content\n synth.harmonicContent(channel, value);\n break;\n case 0x60: //\n // console.log(60);\n break;\n case 0x61: //\n // console.log(61);\n break;\n case 0x62: // NRPN LSB\n this.rpnMode = false;\n this.NrpnLsb[channel] = value;\n break;\n case 0x63: // NRPN MSB\n this.rpnMode = false;\n this.NrpnMsb[channel] = value;\n break;\n case 0x64: // RPN LSB\n this.rpnMode = true;\n this.RpnLsb[channel] = value;\n break;\n case 0x65: // RPN MSB\n this.rpnMode = true;\n this.RpnMsb[channel] = value;\n break;\n case 0x40: // Hold\n synth.hold(channel, value);\n break;\n case 0x0b: // Expression\n synth.expression(channel, value);\n break;\n case 0x48: // DecayTyme\n synth.decayTime(channel, value);\n break;\n case 0x49: // ReleaseTime\n synth.releaseTime(channel, value);\n break;\n case 0x4a: // Attack time\n synth.attackTime(channel, value);\n break;\n case 0x4b: // Brightness\n synth.cutOffFrequency(channel, value);\n break;\n case 0x5b: // Effect1 Depth(Reverb Send Level)\n synth.reverbDepth(channel, value);\n break;\n default:\n // not supported\n break;\n }\n break;\n }\n case 0xc0: // Program Change: Cn pp\n synth.programChange(channel, message[1]);\n break;\n case 0xe0: // Pitch Bend\n synth.pitchBend(channel, message[1], message[2]);\n break;\n case 0xf0: {\n // delete checksum\n message.splice(1, 1);\n\n // System Exclusive Message\n // [1] F0\n // [2] https://www.amei.or.jp/report/report6.html\n // [3] \n // [4] \n // [5] \n // [6] \n // [7] \n // [8] \n // [9] \n // [10] \n // [11] [IGNORE]\n // [12] F7 EOX [IGNORE]\n // console.log(this.dumpMessage(message));\n\n /**\n * @type {number} System Exclusive Manufacture's ID Number\n * @see {@link https://electronicmusic.fandom.com/wiki/List_of_MIDI_Manufacturer_IDs}\n */\n const manufacturerId = message[1];\n /** @type {number} Device ID (GM extended=0x10 / ポケミク=0x79 / Any=0x7F) */\n const device = message[2];\n /** @type {number} Model ID: (GM=0x09 / GS=0x42 / XG=0x4C) */\n const model = message[3];\n\n if (manufacturerId === 0x7e || device === 0x09) {\n // Gneral MIDI\n // http://amei.or.jp/midistandardcommittee/Recommended_Practice/GM2_japanese.pdf\n // console.log('GM:', this.dumpMessage(message));\n // Non Realtime\n switch (model) {\n case 0x01:\n // GM System On\n synth.init('GM');\n console.info('\\x1b[34mGM System On\\x1b[0m');\n break;\n case 0x02:\n // GM System Off\n console.info('\\x1b[34mGM System Off\\x1b[0m');\n // Throuh\n break;\n case 0x03:\n // GM2 System On\n console.info('\\x1b[34mGM (v2) System On\\x1b[0m');\n synth.init('GM2');\n break;\n default:\n // @ts-ignore\n console.log('\\x1b[34mGM\\x1b[0m: ' + this.dumpMessage(message));\n }\n } else if (manufacturerId === 0x7f) {\n // Realtime\n if (model === 0x01) {\n // master volume: F0 7F 7F 04 01 [value] [value] F7\n synth.setMasterVolume(message[4] + (message[5] << 7));\n } else {\n // @ts-ignore\n console.log(\n '\\x1b[34mRealtime\\x1b[0m: ' + this.dumpMessage(message)\n );\n }\n } else if (manufacturerId === 0x7d) {\n // smfplayer / sf2synth固有命令は、プライベート/非営利用途用のManufacturer IDである0x7Dを使用する。\n // プログラム上意味はないが、GM互換であるため、deviceID:0x10、ModelID:0x00とする。\n // よって、F0 7D 10 00 [...] 7Fで定義\n\n if (message[4] === 0x01) {\n // カラーモード切替\n // F0 7D 10 00 01 [value]\n if (message[5] === 0x01) {\n // 明示的にライトモード\n this.setColorMode('light');\n } else if (message[5] === 0x02) {\n // 明示的にダークモード\n this.setColorMode('dark');\n } else {\n // OSの設定に合わせる\n this.setColorMode('auto');\n }\n }\n }\n\n if (model === 0x42) {\n // Roland GS\n // http://lib.roland.co.jp/support/jp/manuals/res/1809974/SC-88VL_j.pdf\n // deviceは10、modelIDは42固定。\n // F0 41 10 42 12 [addr] [part] [key] [value] [checksum] F7\n // (DeviceID = 10, ModelID = 42, CommandID = 12)\n\n // QuickTime音源や、WindowsMIDI音源は、GS互換音源なのでmanufacturerIdが41とは限らない\n\n /* * @param {number} GsAddress GSアドレス(未使用)\n const GsAddress = message[6];\n */\n /** @type {number} GSパート番号 */\n const GsPart = message[6] - 0x0f;\n /** @type {number} GSのキーパラメータ */\n const GsKey = message[7];\n /** @type {number} GSの値 */\n const GsValue = message[8];\n // TODO\n switch (GsKey) {\n case 0x00:\n // TEXT INSERT FOR SC (ASCI code)\n // http://kurizill.g1.xrea.com/memorandum/midi2.htm\n // F0 41 10 45 12 10 [page] 00 [...value] [checksum] F7\n // ex. F0 41 10 45 12 10 00 00 [48 65 6C 6C 6F] 21 F7 = Hello\n\n // device IDの値は0x45固定だがその判定処理は省略\n\n if (GsPart === 0x00) {\n // ページが0x00の場合、LCDに表示するメッセージとする\n // @ts-ignore\n const msg = message.splice(8);\n // Remove F7\n msg.pop();\n // Remove Checksum\n msg.pop();\n synth.processMidiMessage(msg);\n } else {\n // GS音源のLCDの16x16のビットマップ画像\n // @ts-ignore\n console.log(\n '\\x1b[31mGS Bitmap message\\x1b[0m:' +\n this.dumpMessage(message)\n );\n }\n break;\n case 0x04:\n // GS Master Volume:\n // F0 41 10 42 12 40 00 04 [value] [checksum] F7\n // console.log('GS Volume:', this.dumpMessage(message));\n synth.setMasterVolume(GsValue * 64);\n break;\n\n case 0x15: {\n // GS Dram part: F0 41 10 42 12 40 1[part no] [Map] [checksum] F7\n // Notice: [sum] is ignroe in this program.\n\n if (GsPart === 0) {\n // 10 Ch.\n synth.setPercussionPart(9, GsValue !== 0x00);\n } else if (GsPart >= 10) {\n // 1~9 Ch.\n synth.setPercussionPart(GsPart - 1, GsValue !== 0x00);\n } else {\n // 11~16 Ch.\n synth.setPercussionPart(GsPart, GsValue !== 0x00);\n }\n break;\n }\n case 0x19:\n // VOLUME ON/OFF (PART LEVEL)\n // F0 41 10 42 12 40 1[part no] 19 [value] [checksum] F7\n console.info(\n '\\x1b[31mGS Volume On/Off\\x1b[0m: ' + GsPart,\n GsValue\n );\n break;\n case 0x30:\n // Reverb Effect\n console.info(\n '\\x1b[31mGS Reverb\\x1b[0m: ' + this.dumpMessage(message)\n );\n break;\n case 0x38:\n // Chorus Effect\n console.info(\n '\\x1b[31mGS Chorus\\x1b[0m: ' + this.dumpMessage(message)\n );\n break;\n case 0x45:\n // Bitmap icon 16x16 ?\n console.info(\n '\\x1b[31mGS Bitmap\\x1b[0m: ' + this.dumpMessage(message)\n );\n break;\n case 0x7f:\n // GS Reset: F0 41 10 42 12 40 00 7F 00 [checksum] F7\n synth.init('GS');\n console.info('\\x1b[31mGS Reset\\x1b[0m');\n break;\n default:\n // @ts-ignore\n console.log('\\x1b[31mGS\\x1b[0m: ' + this.dumpMessage(message));\n }\n } else if (model === 0x4c) {\n // YAMAHA XG\n // F0 43 10 4C [...] F7\n // https://jp.yamaha.com/files/download/other_assets/9/321739/read_aoyama.pdf\n // https://jp.yamaha.com/files/download/other_assets/1/316861/MU100J1.pdf\n\n // カシオとKORGはXG互換音源を作っていたためmanufacturerIdが43とは限らない\n\n /** @type {number} Xg音源のキー */\n const XgKey = message[4];\n /** @type {number} Xg音源のパート */\n const XgPart = message[5];\n\n switch (XgKey) {\n case 0x00:\n // XG Reset:\n // F0 43 1n 4C 00 00 7E 00 F7\n if (message[6] === 0x7e) {\n synth.init('XG');\n console.info('\\x1b[32mXG Reset\\x1b[0m');\n }\n break;\n case 0x02:\n // Effect\n // https://jp.yamaha.com/files/download/other_assets/5/321745/efctparamlist.pdf\n // F0 43 10 4C 02 01 [type] [value] F7\n //\n // type\n // 02: Reverb\n // リバーブエフェクトのインパルス応答を選択する\n // 40: Variation\n // F0 43 10 4C 02 01 40 [type] 00 F7\n // インサーションエフェクトとして使用するモードと全チャンネルにかけるシステムエフェクトモード場合がある。\n // アンプシミュレーターやディストーション、フェイザー、ディレイなど飛び道具的なエフェクトはここに入っていた。\n // 41: バリエーションエフェクトの種類\n // [value]にエフェクトの種類\n // 5B: バリエーションエフェクトをかけるパート\n // F0 43 10 4C 02 01 5B [part] F7\n // [value]が0でインサーションエフェクト、1でシステムエフェクトモードに切り替える。\n // インサーションエフェクトが実装される前(MU100よりも前の機種)は、ディレイ・エフェクトで使う場合が多かった。\n console.log(\n '\\x1b[32mXG Effect\\x1b[0m: ' + this.dumpMessage(message)\n );\n break;\n case 0x03:\n // Insertion Effect\n // F0 43 10 4C 03 [type] [value] F7\n // MU100以降の機種で実装されている。最大2系統。1チャンネルのみ指定可能。\n console.log(\n '\\x1b[32mXG Insertion Effect\\x1b[0m: ' +\n this.dumpMessage(message)\n );\n break;\n case 0x04:\n // XG Master Volume:\n // F0 43 1n 4C 00 00 04 [value] F7\n synth.setMasterVolume(message[9] * 64);\n break;\n case 0x06: {\n // Text:\n // F0 43 1n 4C 06 00 00 [text] F7\n // ex. F0 43 1n 4C 06 00 00 48 65 6C 6C 6F 21 F7 = Hello\n // @ts-ignore\n const msg = message.splice(8);\n // Remove F7\n msg.pop();\n synth.processMidiMessage(msg);\n break;\n }\n case 0x07:\n // Bitmap Window\n // F0 43 10 4C 07 00 00 [bitmap] F7\n // 音源のアイコン描画領域に描画する16x16のビットマップ画像。\n // 7bitごとに左上から描画する。仕様がややこしいので処理しない\n console.log(\n '\\x1b[32mXG Bitmap\\x1b[0m: ' + this.dumpMessage(message)\n );\n break;\n case 0x08:\n // XG Dram Part:\n // F0 43 10 4C 08 [partNum] 07 [map] F7\n // 厳密には[map]は1以上の値が入り、3+1系統までしか使えない(MU2000の場合)が、本プログラムでは制限しない。\n synth.setPercussionPart(XgPart, message[8] !== 0x00);\n break;\n\n default:\n // @ts-ignore\n console.log('\\x1b[32mXG\\x1b[0m: ', this.dumpMessage(message));\n }\n }\n break;\n }\n default:\n // not supported\n synth.setPercussionPart(9, true);\n break;\n }\n }\n\n /**\n * Dump System Exclusive Message\n *\n * @private\n * @param {number[]} messages\n * @return {string}\n */\n dumpMessage(messages) {\n const ret = [];\n let i = 0;\n for (const msg of messages) {\n let str = '';\n switch (i) {\n case 0:\n // 青\n str = '\\x1b[35m';\n break;\n case 1:\n case 2:\n case 3:\n // 黄色\n str = '\\x1b[33m';\n break;\n default:\n // 末尾の場合は青、それ以外はシアン\n str = messages.length - 1 === i ? '\\x1b[35m' : '\\x1b[36m';\n break;\n }\n\n ret.push(str + msg.toString(16).toUpperCase().padStart(2, '0'));\n i++;\n }\n return ret.join(' ') + '\\x1b[0m';\n }\n\n /**\n * Change Color mode\n *\n * @param {'dark'|'light'|'auto'|undefined} mode Color Mode\n * @public\n */\n setColorMode(mode) {\n // Mode was given\n if (mode) {\n if (mode === 'auto') {\n mode = window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light';\n }\n // Update data-* attr on html\n document.documentElement.setAttribute('data-bs-theme', mode);\n }\n // No mode given (e.g. reset)\n else {\n document.documentElement.setAttribute('data-bs-theme', 'auto');\n // Remove data-* attr from html\n document.documentElement.removeAttribute('data-bs-theme');\n }\n }\n}\n","import WebMidiLink from './wml';\n\n/**\n * Web MIDI API Reciever Class.\n *\n * @author Logue \n */\nexport default class WebMidiApi extends WebMidiLink {\n /**\n * @inheritdoc\n */\n constructor(option = {}) {\n super(option);\n /** @type {WebMidi.MIDIAccess | undefined} */\n this.midi = undefined;\n }\n\n /**\n * @inheritdoc\n * @param {string} url\n */\n async setup(url) {\n this.midi = await window.navigator.requestMIDIAccess({ sysex: true });\n await super.setup(url);\n }\n\n /**\n * @inheritdoc\n */\n onReady() {\n // コールバック実行\n super.callback();\n // Web MIDI APIを待ち受け\n this.midi.inputs.forEach(\n (\n /** @type {{ onmidimessage: (msg: WebMidi.MIDIMessageEvent) => void; }} */ input\n ) =>\n (input.onmidimessage = msg =>\n super.processMidiMessage(Array.from(msg.data)))\n );\n }\n}\n","// This file is auto-generated by the build system.\nconst meta = {\n version: '0.6.2',\n date: '2023-11-29T01:17:37.499Z',\n};\nexport default meta;\n","import WebMidiLink from './wml';\nimport WebMidiApi from './web_midi_api';\nimport Parser from './sf2';\nimport Meta from './meta.js';\nimport './wml.scss';\n\nconst SoundFont = {\n version: Meta.version,\n build: Meta.date,\n WebMidiLink,\n WebMidiApi,\n Parser,\n};\n\nexport default SoundFont;\n","\n import qs from 'query-string';\n import SoundFont from '/src/index';\n\n /** sf2synth.js Option */\n let options = {\n ...{\n // URL to SoundFont File\n // url: 'https://cdn.jsdelivr.net/npm/@logue/sf2synth@latest/dist/Yamaha XG Sound Set.sf2',\n // Show Keyboard\n drawSynth: true,\n // Target dom id\n placeholder: 'placeholder',\n // Color Mode (auto, dark, light)\n colorMode: 'auto',\n },\n ...qs.parse(window.location.search),\n ...qs.parse(window.location.hash),\n };\n\n /** @type {typeof import(\"./src/wml\").WebMidiLink } WebMidiLink */\n const wml = new SoundFont.WebMidiLink(options);\n\n document.addEventListener(\n 'DOMContentLoaded',\n event => {\n /** @type {HTMLInputElement} File Input Form */\n const fileInput = document.getElementById('file');\n /** @type {HTMLDivElement} drag area */\n const dragArea = document.getElementById('drag');\n /** @type {HTMLTimeElement} Build Date */\n const build = document.getElementById('build');\n /** @type {HTMLInputElement} */\n const toggleDarkMode = document.getElementById('toggleDarkMode');\n /** @type {HTMLSelectElement} */\n // const selector = document.getElementById('selector');\n\n wml.setLoadCallback(() => {\n dragArea.classList.remove('bg-info');\n document.getElementById('soundfont').innerText = decodeURIComponent(\n wml.getUrl()\n ).match('.+/(.+?)([?#;].*)?$')[1];\n });\n\n // Apply build time\n build.dateTime = SoundFont.build;\n build.innerText = new Date(SoundFont.build).toLocaleString();\n\n wml.setup();\n\n // Keep an eye out for System Light/Dark Mode Changes\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n mediaQuery.addListener(() => {\n // Ignore change if there's an override set\n if (document.documentElement.getAttribute('data-bs-theme')) {\n return;\n }\n\n // Apply color mode.\n wml.setColorMode(options.colorMode);\n\n // Make sure the checkbox is up-to-date\n toggleDarkMode.checked = mediaQuery.matches;\n });\n\n /**\n * Load sound font\n *\n * @param {File} file\n */\n const handleSoundFont = file => {\n const reader = new FileReader();\n reader.readAsArrayBuffer(file);\n\n reader.onload = e => {\n document.getElementById('soundfont').innerText = file.name;\n const data = new Uint8Array(e.target.result);\n wml.setupByBuffer(data);\n };\n };\n\n // When select SoundFont file\n fileInput.addEventListener(\n 'change',\n event => {\n event.preventDefault();\n handleSoundFont(fileInput.files[0]);\n fileInput.value = '';\n },\n false\n );\n\n // When SoundFont Drag and Drop.\n dragArea.addEventListener(\n 'drop',\n event => {\n const dt = event.dataTransfer;\n if (dt.files.length) {\n event.preventDefault();\n event.stopPropagation();\n handleSoundFont(dt.files[0]);\n }\n dragArea.classList.remove('bg-info');\n },\n false\n );\n dragArea.addEventListener(\n 'dragover',\n event => {\n event.preventDefault();\n event.stopPropagation();\n dragArea.classList.add('bg-info');\n },\n false\n );\n dragArea.addEventListener(\n 'dragleave',\n event => {\n event.preventDefault();\n event.stopPropagation();\n dragArea.classList.remove('bg-info');\n },\n false\n );\n\n // Toggle Dark mode\n toggleDarkMode.addEventListener('change', e => {\n wml.setColorMode(e.target.checked ? 'dark' : 'light');\n });\n\n /*\n selector.addEventListener('change', () => {\n console.log(selector.value);\n wml.setup(\n `https://cdn.jsdelivr.net/npm/@logue/sf2synth@latest/dist/${selector.value}`\n );\n });\n */\n },\n false\n );\n\n window.addEventListener(\n 'hashchange',\n () => {\n const url = qs.parse(window.location.hash);\n if (url) {\n wml.setup(url);\n }\n },\n false\n );\n "],"names":["token","singleMatcher","multiMatcher","decodeComponents","components","split","left","right","decode","input","tokens","i","customDecodeURIComponent","replaceMap","match","result","entries","key","decodeUriComponent","encodedURI","splitOnFirst","string","separator","separatorIndex","includeKeys","object","predicate","descriptor","value","isNullOrUndefined","strictUriEncode","x","encodeFragmentIdentifier","encoderForArrayFormat","options","index","encode","keyValueSep","parserForArrayFormat","accumulator","isArray","isEncodedArray","newValue","item","arrayValue","validateArrayFormatSeparator","decodeComponent","keysSorter","a","b","removeHash","hashStart","getHash","url","hash","parseValue","extract","queryStart","parse","query","formatter","returnValue","parameter","parameter_","key2","value2","stringify","shouldFilter","objectCopy","keys","parseUrl","url_","stringifyUrl","queryFromUrl","queryString","urlObjectForFragmentEncode","pick","filter","fragmentIdentifier","exclude","exclusionFilter","SynthesizerNote","ctx","destination","instrument","now","volDelay","modDelay","volAttack","modAttack","volHold","modHold","volDecay","modDecay","loopStart","loopEnd","startTime","pan","sample","buffer","bufferSource","output","panner","volume","outputGain","baseFreq","peekFreq","sustainFreq","modulator","val","release","volEndTimeTmp","volEndTime","modEndTime","playbackRate","computed","start","peekPitch","expression","pitchBend","INV_MAX","ARandom","norm","p","min","max","range","random","SystemRandom","SYSTEM","defaults","Meta","Noise","DEFAULT_OPTS","preseed","n","scale","rnd","state","sum","src","interleave","next","blue","opts","bins","invN","acc","sign","green","ctz32","c","pink","id","red","violet","white","implementsFunction","fn","ensureTransducer","isIterable","Reduced","reduced","isReduced","ensureReduced","unreduced","reducer","init","rfn","push","xs","iterator","xform","complete","reduce","y","compR","take","r","m","Reverb","sourceNode","mix","reverse","type","freq","q","s","algorithm","rate","duration","delayDuration","impulse","impulseL","impulseR","noiseL","noiseR","Riff","optParams","length","ip","size","RiffChunk","chunk","offset","Parser","parser","data","signature","presetHeader","presetZone","instrumentZone","samples","sampleHeader","sampleName","end","startLoop","endLoop","sampleRate","originalPitch","pitchCorrection","sampleLink","sampleType","adjust","newSample","il","j","multiply","code","zone","bagIndex","bagIndexEnd","zoneInfo","instrumentGenerator","instrumentModulator","jl","preset","presetGenerator","presetModulator","modgen","_zone","indexStart","indexEnd","zoneModGen","modgenInfo","info","Synthesizer","entry","initAudioContext","emptySource","mode","modeElement","element","presets","instruments","banks","bank","bankNumber","presetNumber","presetName","programSet","generator","volSustain","volRelease","modSustain","modRelease","tune","sampleModes","sampleId","enumeratorType","doc","wrapper","instElem","eventStart","eventEnd","channel","channelElem","itemElem","checkboxElement","checkbox","event","labelElem","bankSelect","synth","ch","program","select","volumeElem","expressionElem","pitchSensElem","reverbDepthElem","panpotOuter","panpot","pitchOuter","pitch","keyElem","k","itemName","headerElem","_entries","headerItem","channelItem","keysItem","velocity","channelElems","bankElement","bankNo","option","dom","bankIndex","programElement","programNo","instrumentKey","note","currentNoteOn","hold","channelElements","percussionBank","volumeVariable","expressionVariabe","progressBar","percentage","lowerByte","higherByte","bend","calculated","sensitivity","pitchBendSensitivityVariable","attackTime","decayTime","sustinTime","releaseTime","depth","reverbVariable","mute","sw","message","e","Loader","placeholder","cache","callback","current","total","percentCompleted","error","cached","response","cloned","contentLength","reader","receivedLength","chunks","done","chunksAll","position","WebMidiLink","readyElem","ev","msg","command","hex","manufacturerId","device","model","GsPart","GsKey","GsValue","XgKey","XgPart","messages","ret","str","WebMidiApi","meta","SoundFont","qs","wml","fileInput","dragArea","build","toggleDarkMode","mediaQuery","handleSoundFont","file","dt"],"mappings":"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","x_google_ignoreList":[0,1,2,3,5]} \ No newline at end of file diff --git a/index.html b/index.html index b157c4d..dd4b1e3 100644 --- a/index.html +++ b/index.html @@ -22,7 +22,7 @@ gtag('js', new Date()); gtag('config', 'G-2Y2FW3QEG4'); - + diff --git a/wml.html b/wml.html deleted file mode 100644 index 97749e0..0000000 --- a/wml.html +++ /dev/null @@ -1,287 +0,0 @@ - - - - - - - - Web Midi Link - - - - - - - -
-
-
-

- SoundFont: - -

-
- - -   - - - - - -
-
-

- Logue - / - - Last Modified: - - -

-
-
- -
- - -
- drag and drop here *.sf2 file to change sound font. -
-
-
-
-
-
- - -