1// abc2svg - ABC to SVG translator 2// @source: https://chiselapp.com/user/moinejf/repository/abc2svg 3// Copyright (C) 2014-2020 Jean-Francois Moine - LGPL3+ 4//snd-1.js-file to include in html pages with abc2svg-1.js for playing 5// 6// changes from Anika Henke <anika@selfthinker.org>: 7// changed default conf.sfu to point to CDN due to licensing issues 8function AbcPlay(i_conf){var conf=i_conf,init={},audio=ToAudio(),audio5,midi5,current,abcplay={clear:audio.clear,add:audio.add,set_sfu:function(v){if(v==undefined) 9return conf.sfu 10conf.sfu=v},set_speed:function(v){if(v==undefined) 11return conf.speed 12conf.new_speed=v},set_vol:function(v){if(v==undefined) 13return conf.gain;conf.gain=v 14if(current&¤t.set_vol) 15current.set_vol(v)},play:play,stop:vf} 16function vf(){} 17function play(istart,i_iend,a_e){init.istart=istart;init.i_iend=i_iend;init.a_e=a_e 18if(midi5) 19midi5.get_outputs(play2) 20else 21play2()} 22function play2(out){var o 23if(!out) 24out=[] 25o=audio5.get_outputs() 26if(o) 27Array.prototype.push.apply(out,o) 28if(out.length==0){if(conf.onend) 29conf.onend() 30return} 31if(out.length==1){o=0}else{o=-1 32var pr="Use" 33for(var i=0;i<out.length;i++) 34pr+="\n "+i+": "+out[i] 35var res=window.prompt(pr,'0') 36if(res){o=Number(res) 37if(isNaN(o)||o<0||o>=out.length) 38o=-1} 39if(!res||o<0){if(conf.onend) 40conf.onend() 41return}} 42current=out[o]=='sf2'?audio5:midi5;abcplay.play=current.play;abcplay.stop=current.stop 43if(current.set_output) 44current.set_output(out[o]);if(abc2svg.pwait){if(typeof abc2svg.pwait=="boolean"){abc2svg.pwait=function(){abcplay.play(init.istart,init.i_iend,init.a_e)}} 45return} 46abcplay.play(init.istart,init.i_iend,init.a_e)} 47conf.gain=0.7;conf.speed=1;(function get_param(){try{if(!localStorage) 48return}catch(e){return} 49var v=localStorage.getItem("sfu") 50if(v) 51conf.sfu=v;v=localStorage.getItem("volume") 52if(v) 53conf.gain=Number(v)})() 54if(typeof Midi5=="function") 55midi5=Midi5(conf) 56if(typeof Audio5=="function") 57audio5=Audio5(conf);return abcplay} 58if(typeof module=='object'&&typeof exports=='object') 59exports.AbcPlay=AbcPlay 60if(!abc2svg) 61var abc2svg={} 62function ToAudio(){return{add:function(first,voice_tb,cfmt){var toaud=this,C=abc2svg.C,p_time=0,abc_time=0,play_fac=C.BLEN/4*120/60,i,n,dt,d,v,c,s=first,rst=s,rst_fac,rsk,b_tim,b_typ,instr=[],chn=[] 63function build_parts(first){var i,j,c,n,v,s=first,p=s.parts,st=[],r="" 64for(i=0;i<p.length;i++){c=p[i] 65switch(c){case'.':continue 66case'(':st.push(r.length) 67continue 68case')':j=st.pop() 69if(j==undefined) 70j=r.length 71continue} 72if(c>='A'&&c<='Z'){j=r.length 73r+=c 74continue} 75n=Number(c) 76if(isNaN(n)) 77break 78v=r.slice(j) 79if(r.length+v.length*n>128) 80continue 81while(--n>0) 82r+=v} 83s.parts=r 84s.p_s=[] 85while(1){if(!s.ts_next){s.part=first 86break} 87s=s.ts_next 88if(s.type==C.PART){s.part=first 89v=s.text[0] 90for(i=0;i<first.parts.length;i++){if(first.parts[i]==v) 91first.p_s[i]=s}}}} 92function midi_start(){var v,p_v,c,i,ii 93for(v=0;v<voice_tb.length;v++){p_v=voice_tb[v] 94ii=p_v.instr||0 95c=p_v.chn 96if(c==undefined) 97c=p_v.v<9?p_v.v:p_v.v+1 98else if(c==9) 99ii=(ii&~0x7f)|16384 100if(p_v.midictl){for(i in p_v.midictl){switch(Number(i)){case 0:ii=(ii&0x3fff)|(p_v.midictl[i]<<14) 101break 102case 32:ii=(ii&0x1fc07f)|(p_v.midictl[i]<<7) 103break}}} 104if((ii&~0x7f)==16384) 105c=9 106chn[v]=c 107instr[c]=ii}} 108function do_block(s){var v=s.v,c=chn[v] 109switch(s.subtype){case"midichn":chn[v]=s.chn 110break 111case"midictl":switch(s.ctrl){case 0:instr[c]=(instr[c]&0x3fff)|(s.val<<14) 112break 113case 32:instr[c]=(instr[c]&0x1fc07f)|(s.val<<7) 114break} 115if((instr[c]&~0x7f)==16384){instr[9]=instr[c] 116chn[v]=c=9} 117s.chn=c 118break 119case"midiprog":instr[c]=(instr[c]&~0x7f)|s.instr 120s.chn=c 121break}} 122function gen_grace(s){var g,i,n,t,d,s2,next=s.next 123if(s.sappo){d=C.BLEN/16}else if((!next||next.type!=C.NOTE)&&s.prev&&s.prev.type==C.NOTE){d=s.prev.dur/2}else{d=next.dur/12 124if(!(d&(d-1))) 125d=next.dur/2 126else 127d=next.dur/3 128next.time+=d 129next.dur-=d} 130n=0 131for(g=s.extra;g;g=g.next) 132n++ 133d/=n*play_fac 134t=p_time 135for(g=s.extra;g;g=g.next){g.ptim=t 136g.pdur=d 137g.chn=chn[s.v] 138g.instr=instr[g.chn] 139t+=d}} 140function set_tempo(s){var i,d=0,n=s.tempo_notes.length 141for(i=0;i<n;i++) 142d+=s.tempo_notes[i] 143return d*s.tempo/60} 144function set_variant(rsk,n,s){var d 145n=n.match(/[1-8]-[2-9]|[1-9,.]|[^\s]+$/g) 146while(1){d=n.shift() 147if(!d) 148break 149if(d[1]=='-') 150for(i=d[0];i<=d[2];i++) 151rsk[i]=s 152else if(d>='1'&&d<='9') 153rsk[Number(d)]=s 154else if(d!=',') 155rsk.push(s)}} 156if(cfmt.chord){if(!abc2svg.chord){abc2svg.pwait=true 157abc2svg.loadjs("chord-1.js",function(){toaud.add(first,voice_tb,cfmt)},function(){cfmt.chord=null 158toaud.add(first,voice_tb,cfmt)}) 159return} 160abc2svg.chord(first,voice_tb,cfmt)} 161if(s.parts) 162build_parts(s) 163midi_start() 164rst_fac=play_fac 165while(s){if(s.noplay){s=s.ts_next 166continue} 167dt=s.time-abc_time 168if(dt!=0){p_time+=dt/play_fac 169abc_time=s.time} 170s.ptim=p_time 171switch(s.type){case C.BAR:if(s.time!=b_tim){b_tim=s.time 172b_typ=0} 173if(s.text&&rsk&&s.text[0]!='1'){if(b_typ&1) 174break 175b_typ|=1 176set_variant(rsk,s.text,s) 177play_fac=rst_fac 178rst=rsk[0]} 179if(s.bar_type[0]==':'){if(b_typ&2) 180break 181b_typ|=2 182s.rep_p=rst 183if(rsk&&rst==rsk[0]) 184s.rep_v=rsk} 185if(s.text){if(s.text[0]=='1'){if(b_typ&1) 186break 187b_typ|=1 188s.rep_s=rsk=[rst] 189if(rst.bar_type&&rst.bar_type.slice(-1)!=':') 190rst.bar_type+=':' 191set_variant(rsk,s.text,s) 192rst_fac=play_fac}}else if(s.rbstop){if(s.bar_type.slice(-1)==':'){if(b_typ&4) 193break 194b_typ|=4}else{if(b_typ&8) 195break 196b_typ|=8} 197rst=s 198rst_fac=play_fac} 199break 200case C.BLOCK:do_block(s) 201break 202case C.GRACE:if(s.time==0&&abc_time==0){dt=0 203if(s.sappo) 204dt=C.BLEN/16 205else if(!s.next||s.next.type!=C.NOTE) 206dt=d/2 207abc_time-=dt} 208gen_grace(s) 209break 210case C.REST:case C.NOTE:d=s.dur 211if(s.next&&s.next.type==C.GRACE){dt=0 212if(s.next.sappo) 213dt=C.BLEN/16 214else if(!s.next.next||s.next.next.type!=C.NOTE) 215dt=d/2 216s.next.time-=dt 217d-=dt} 218d/=play_fac 219s.pdur=d 220v=s.v 221c=chn[v] 222s.chn=c 223s.instr=instr[c] 224break 225case C.PART:rst=s 226rst_fac=play_fac 227break 228case C.TEMPO:if(s.tempo) 229play_fac=set_tempo(s) 230break} 231s=s.ts_next} 232if(abc2svg.pwait){i=abc2svg.pwait 233delete abc2svg.pwait 234if(typeof i=="function") 235i()}}}} 236abc2svg.play_next=function(po){function do_tie(s,midi,d){var i,note,C=abc2svg.C,v=s.v,end_time=s.time+s.dur 237while(1){s=s.ts_next 238if(!s) 239return d 240switch(s.type){case C.BAR:if(s.rep_p){if(!po.repn){s=s.rep_p 241end_time=s.time}} 242if(s.rep_s){if(!s.rep_s[po.repv+1]) 243return d 244s=s.rep_s[po.repv+1] 245end_time=s.time} 246while(s.ts_next&&!s.ts_next.dur) 247s=s.ts_next} 248if(s.time>end_time) 249return d 250if(s.type==C.NOTE&&s.v==v) 251break} 252i=s.notes.length 253while(--i>=0){note=s.notes[i] 254if(note.midi==midi){note.ti2=true 255d+=s.pdur/po.conf.speed 256return note.tie_ty?do_tie(s,midi,d):d}} 257return d} 258function set_ctrl(po,s2,t){var i,p_v=s2.p_v,tim=s2.time,s={subtype:"midictl",p_v:p_v,v:p_v.v,chn:p_v.chn} 259for(i in p_v.midictl){s.ctrl=Number(i) 260s.val=p_v.midictl[i] 261po.midi_ctrl(po,s,t)} 262for(s=p_v.sym;s&&s.time<=tim;s=s.next){if(s.subtype=="midictl") 263po.midi_ctrl(po,s,t)} 264po.p_v[s2.v]=true} 265function play_cont(po){var d,i,st,m,note,g,s2,t,maxt,C=abc2svg.C,s=po.s_cur 266if(po.stop){if(po.onend) 267po.onend(po.repv) 268return} 269while(s.noplay){s=s.ts_next 270if(!s||s==po.s_end){if(po.onend) 271po.onend(po.repv) 272return}} 273t=po.stim+s.ptim/po.conf.speed 274if(po.conf.new_speed){d=po.get_time(po) 275po.stim=d-(d-po.stim)*po.conf.speed/po.conf.new_speed 276po.conf.speed=po.conf.new_speed 277po.conf.new_speed=0 278t=po.stim+s.ptim/po.conf.speed} 279maxt=t+po.tgen 280po.timouts=[] 281while(1){if(!po.p_v[s.v]) 282set_ctrl(po,s,t) 283switch(s.type){case C.BAR:if(s.rep_p){po.repv++ 284if(!po.repn&&(!s.rep_v||po.repv<s.rep_v.length)){po.stim+=(s.ptim-s.rep_p.ptim)/po.conf.speed 285s=s.rep_p 286while(s.ts_next&&!s.ts_next.dur) 287s=s.ts_next 288t=po.stim+s.ptim/po.conf.speed 289po.repn=true 290break} 291po.repn=false} 292if(s.rep_s){s2=s.rep_s[po.repv] 293if(s2){po.stim+=(s.ptim-s2.ptim)/po.conf.speed 294s=s2 295t=po.stim+s.ptim/po.conf.speed 296po.repn=false}else{s=po.s_end 297break}} 298if(s.bar_type.slice(-1)==':') 299po.repv=1 300while(s.ts_next&&!s.ts_next.seqst) 301s=s.ts_next 302if(!s.part) 303break 304case C.PART:if(s.part&&po.i_p!=undefined){s2=s.part.p_s[++po.i_p] 305if(s2){po.stim+=(s.ptim-s2.ptim)/po.conf.speed 306s=s2 307t=po.stim+s.ptim/po.conf.speed}else{s=po.s_end}} 308break 309case C.BLOCK:if(s.subtype=="midictl") 310po.midi_ctrl(po,s,t) 311break 312case C.GRACE:for(g=s.extra;g;g=g.next){d=g.pdur/po.conf.speed 313for(m=0;m<=g.nhd;m++){note=g.notes[m] 314po.note_run(po,g,note.midi,t+g.ptim-s.ptim,d)}} 315break 316case C.NOTE:d=s.pdur/po.conf.speed 317for(m=0;m<=s.nhd;m++){note=s.notes[m] 318if(note.ti2) 319continue 320po.note_run(po,s,note.midi,t,note.tie_ty?do_tie(s,note.midi,d):d)} 321case C.REST:d=s.pdur/po.conf.speed 322if(po.onnote&&s.istart){i=s.istart 323st=(t-po.get_time(po))*1000 324po.timouts.push(setTimeout(po.onnote,st,i,true)) 325setTimeout(po.onnote,st+d*1000,i,false)} 326break} 327while(1){if(s==po.s_end||!s.ts_next){if(po.onend) 328setTimeout(po.onend,(t-po.get_time(po)+d)*1000,po.repv) 329po.s_cur=s 330return} 331s=s.ts_next 332if(!s.noplay) 333break} 334t=po.stim+s.ptim/po.conf.speed 335if(t>maxt) 336break} 337po.s_cur=s 338po.timouts.push(setTimeout(play_cont,(t-po.get_time(po))*1000 339-300,po))} 340function get_part(po){var s,i,s_p 341for(s=po.s_cur;s;s=s.ts_prev){if(s.parts){po.i_p=-1 342return} 343s_p=s.part 344if(!s_p||!s_p.p_s) 345continue 346for(i=0;i<s_p.p_s.length;i++){if(s_p.p_s[i]==s){po.i_p=i 347return}}}} 348get_part(po) 349po.stim=po.get_time(po)+.3 350-po.s_cur.ptim*po.conf.speed 351po.p_v=[] 352if(!po.repv) 353po.repv=1 354play_cont(po)} 355if(typeof module=='object'&&typeof exports=='object') 356exports.ToAudio=ToAudio 357var abcsf2=[] 358function Audio5(i_conf){var po,conf=i_conf,empty=function(){},errmsg,ac,gain,instr=[],params=[],rates=[],w_instr=0 359var b64d=[] 360function init_b64d(){var b64l='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',l=b64l.length 361for(var i=0;i<l;i++) 362b64d[b64l[i]]=i 363b64d['=']=0} 364function b64dcod(s){var i,t,dl,a,l=s.length,j=0 365dl=l*3/4 366if(s[l-1]=='='){if(s[l-2]=='=') 367dl-- 368dl-- 369l-=4} 370a=new Uint8Array(dl) 371for(i=0;i<l;i+=4){t=(b64d[s[i]]<<18)+ 372(b64d[s[i+1]]<<12)+ 373(b64d[s[i+2]]<<6)+ 374b64d[s[i+3]] 375a[j++]=(t>>16)&0xff 376a[j++]=(t>>8)&0xff 377a[j++]=t&0xff} 378if(l!=s.length){t=(b64d[s[i]]<<18)+ 379(b64d[s[i+1]]<<12)+ 380(b64d[s[i+2]]<<6)+ 381b64d[s[i+3]] 382a[j++]=(t>>16)&0xff 383if(j<dl) 384a[j++]=(t>>8)&0xff} 385return a} 386function sample_cp(b,s){var i,n,a=b.getChannelData(0) 387for(i=0;i<s.length;i++) 388a[i]=s[i]/196608} 389function sf2_create(sf2_bin,instr){var i,sid,gen,parm,sampleRate,sample,infos,parser=new sf2.Parser(sf2_bin) 390parser.parse() 391infos=parser.getInstruments()[0].info 392rates[instr]=[] 393for(i=0;i<infos.length;i++){gen=infos[i].generator 394if(!gen.sampleID) 395continue 396sid=gen.sampleID.amount 397sampleRate=parser.sampleHeader[sid].sampleRate 398sample=parser.sample[sid] 399parm={attack:Math.pow(2,(gen.attackVolEnv?gen.attackVolEnv.amount:-12000)/1200),hold:Math.pow(2,(gen.holdVolEnv?gen.holdVolEnv.amount:-12000)/1200),decay:Math.pow(2,(gen.decayVolEnv?gen.decayVolEnv.amount:-12000)/1200)/3,sustain:gen.sustainVolEnv?(gen.sustainVolEnv.amount/1000):0,buffer:ac.createBuffer(1,sample.length,sampleRate)} 400parm.hold+=parm.attack 401parm.decay+=parm.hold 402if(parm.sustain>=.4) 403parm.sustain=0.01 404else 405parm.sustain=1-parm.sustain/.4 406sample_cp(parm.buffer,sample) 407if(gen.sampleModes&&(gen.sampleModes.amount&1)){parm.loopStart=parser.sampleHeader[sid].startLoop/sampleRate 408parm.loopEnd=parser.sampleHeader[sid].endLoop/sampleRate} 409var scale=(gen.scaleTuning?gen.scaleTuning.amount:100)/100,tune=(gen.coarseTune?gen.coarseTune.amount:0)+ 410(gen.fineTune?gen.fineTune.amount:0)/100+ 411parser.sampleHeader[sid].pitchCorrection/100- 412(gen.overridingRootKey?gen.overridingRootKey.amount:parser.sampleHeader[sid].originalPitch) 413for(j=gen.keyRange.lo;j<=gen.keyRange.hi;j++){rates[instr][j]=Math.pow(Math.pow(2,1/12),(j+tune)*scale) 414params[instr][j]=parm}}} 415function load_instr(instr){w_instr++ 416conf.instr_load(instr,function(sf2_bin){sf2_create(sf2_bin,instr) 417if(--w_instr==0) 418play_start()},function(){errmsg('could not find the instrument '+ 419((instr/128)|0).toString()+'-'+ 420(instr%128).toString()) 421if(--w_instr==0) 422play_start()})} 423function load_res(s){var i 424while(s){i=s.instr 425if(i!=undefined&&!params[i]){params[i]=[] 426load_instr(i)} 427s=s.ts_next}} 428function get_time(po){return po.ac.currentTime} 429function midi_ctrl(po,s,t){if(s.ctrl==7) 430s.p_v.vol=s.val/127} 431function note_run(po,s,key,t,d){var g,st,instr=s.instr,k=key|0 432parm=po.params[instr][k],o=po.ac.createBufferSource(),v=s.p_v.vol==undefined?1:s.p_v.vol 433if(!v||!parm) 434return 435o.buffer=parm.buffer 436if(parm.loopStart){o.loop=true 437o.loopStart=parm.loopStart 438o.loopEnd=parm.loopEnd} 439if(o.detune){var dt=(key*100)%100 440if(dt) 441o.detune.value=dt} 442o.playbackRate.value=po.rates[instr][k] 443g=po.ac.createGain() 444if(parm.hold<0.002){g.gain.setValueAtTime(v,t)}else{if(parm.attack<0.002){g.gain.setValueAtTime(v,t)}else{g.gain.setValueAtTime(0,t) 445g.gain.linearRampToValueAtTime(v,t+parm.attack)} 446g.gain.setValueAtTime(v,t+parm.hold)} 447g.gain.exponentialRampToValueAtTime(parm.sustain*v,t+parm.decay) 448o.connect(g) 449g.connect(po.gain) 450o.start(t) 451o.stop(t+d)} 452function play_start(){if(po.stop){po.onend(repv) 453return} 454gain.connect(ac.destination) 455abc2svg.play_next(po)} 456init_b64d() 457if(!conf.sfu) 458conf.sfu="https://cdn.jsdelivr.net/npm/abc2svg@1.20.16/Scc1t2" 459if(!conf.instr_load){conf.instr_load=function(instr,done,fail){abc2svg.loadjs(conf.sfu+'/'+instr+'.js',function(){done(b64dcod(abcsf2[instr]))},fail)}} 460return{get_outputs:function(){return(window.AudioContext||window.webkitAudioContext)?['sf2']:null},play:function(i_start,i_end,i_lvl){errmsg=conf.errmsg||alert 461function play_unlock(){var buf=ac.createBuffer(1,1,22050),src=ac.createBufferSource() 462src.buffer=buf 463src.connect(ac.destination) 464src.noteOn(0)} 465if(!gain){ac=conf.ac 466if(!ac){conf.ac=ac=new(window.AudioContext||window.webkitAudioContext) 467if(/iPad|iPhone|iPod/.test(navigator.userAgent)) 468play_unlock()} 469gain=ac.createGain() 470gain.gain.value=conf.gain} 471while(i_start.noplay) 472i_start=i_start.ts_next 473po={conf:conf,onend:conf.onend||empty,onnote:conf.onnote||empty,s_end:i_end,s_cur:i_start,repv:i_lvl||0,tgen:2,get_time:get_time,midi_ctrl:midi_ctrl,note_run:note_run,ac:ac,gain:gain,params:params,rates:rates} 474w_instr++ 475load_res(i_start) 476if(--w_instr==0) 477play_start()},stop:function(){po.stop=true 478po.timouts.forEach(function(id){clearTimeout(id)}) 479abc2svg.play_next(po) 480if(gain){gain.disconnect() 481gain=null}},set_vol:function(v){if(gain) 482gain.gain.value=v}}} 483(function(root,factory){if(typeof exports==="object"){root.sf2=exports;factory(exports)}else if(typeof define==="function"&&define.amd){define(["exports"],function(exports){root.sf2=exports;return(root.sf2,factory(exports))})}else{root.sf2={};factory(root.sf2)}}(this,function(exports){"use strict";var sf2=exports;sf2.Parser=function(input,options){options=options||{};this.input=input;this.parserOptions=options.parserOptions};sf2.Parser.prototype.parse=function(){var parser=new sf2.Riff.Parser(this.input,this.parserOptions),chunk;parser.parse();if(parser.chunkList.length!==1) 484throw new Error('wrong chunk length');chunk=parser.getChunk(0);if(chunk===null) 485throw new Error('chunk not found');this.parseRiffChunk(chunk);this.input=null};sf2.Parser.prototype.parseRiffChunk=function(chunk){var parser,data=this.input,ip=chunk.offset,signature;if(chunk.type!=='RIFF') 486throw new Error('invalid chunk type:'+chunk.type);signature=String.fromCharCode(data[ip++],data[ip++],data[ip++],data[ip++]);if(signature!=='sfbk') 487throw new Error('invalid signature:'+signature);parser=new sf2.Riff.Parser(data,{'index':ip,'length':chunk.size-4});parser.parse();if(parser.getNumberOfChunks()!==3) 488throw new Error('invalid sfbk structure');this.parseInfoList(parser.getChunk(0));this.parseSdtaList(parser.getChunk(1));this.parsePdtaList(parser.getChunk(2))};sf2.Parser.prototype.parseInfoList=function(chunk){var parser,data=this.input,ip=chunk.offset,signature;if(chunk.type!=='LIST') 489throw new Error('invalid chunk type:'+chunk.type);signature=String.fromCharCode(data[ip++],data[ip++],data[ip++],data[ip++]);if(signature!=='INFO') 490throw new Error('invalid signature:'+signature);parser=new sf2.Riff.Parser(data,{'index':ip,'length':chunk.size-4});parser.parse()};sf2.Parser.prototype.parseSdtaList=function(chunk){var parser,data=this.input,ip=chunk.offset,signature;if(chunk.type!=='LIST') 491throw new Error('invalid chunk type:'+chunk.type);signature=String.fromCharCode(data[ip++],data[ip++],data[ip++],data[ip++]);if(signature!=='sdta') 492throw new Error('invalid signature:'+signature);parser=new sf2.Riff.Parser(data,{'index':ip,'length':chunk.size-4});parser.parse();if(parser.chunkList.length!==1) 493throw new Error('TODO');this.samplingData=parser.getChunk(0)};sf2.Parser.prototype.parsePdtaList=function(chunk){var parser,data=this.input,ip=chunk.offset,signature;if(chunk.type!=='LIST') 494throw new Error('invalid chunk type:'+chunk.type);signature=String.fromCharCode(data[ip++],data[ip++],data[ip++],data[ip++]);if(signature!=='pdta') 495throw new Error('invalid signature:'+signature);parser=new sf2.Riff.Parser(data,{'index':ip,'length':chunk.size-4});parser.parse();if(parser.getNumberOfChunks()!==9) 496throw new Error('invalid pdta chunk');this.parsePhdr((parser.getChunk(0)));this.parsePbag((parser.getChunk(1)));this.parsePmod((parser.getChunk(2)));this.parsePgen((parser.getChunk(3)));this.parseInst((parser.getChunk(4)));this.parseIbag((parser.getChunk(5)));this.parseImod((parser.getChunk(6)));this.parseIgen((parser.getChunk(7)));this.parseShdr((parser.getChunk(8)))};sf2.Parser.prototype.parsePhdr=function(chunk){var data=this.input,ip=chunk.offset,presetHeader=this.presetHeader=[],size=chunk.offset+chunk.size;if(chunk.type!=='phdr') 497throw new Error('invalid chunk type:'+chunk.type);while(ip<size){presetHeader.push({presetName:String.fromCharCode.apply(null,data.subarray(ip,ip+=20)),preset:data[ip++]|(data[ip++]<<8),bank:data[ip++]|(data[ip++]<<8),presetBagIndex:data[ip++]|(data[ip++]<<8),library:(data[ip++]|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24))>>>0,genre:(data[ip++]|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24))>>>0,morphology:(data[ip++]|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24))>>>0})}};sf2.Parser.prototype.parsePbag=function(chunk){var data=this.input,ip=chunk.offset,presetZone=this.presetZone=[],size=chunk.offset+chunk.size;if(chunk.type!=='pbag') 498throw new Error('invalid chunk type:'+chunk.type);while(ip<size){presetZone.push({presetGeneratorIndex:data[ip++]|(data[ip++]<<8),presetModulatorIndex:data[ip++]|(data[ip++]<<8)})}};sf2.Parser.prototype.parsePmod=function(chunk){if(chunk.type!=='pmod') 499throw new Error('invalid chunk type:'+chunk.type);this.presetZoneModulator=this.parseModulator(chunk)};sf2.Parser.prototype.parsePgen=function(chunk){if(chunk.type!=='pgen') 500throw new Error('invalid chunk type:'+chunk.type);this.presetZoneGenerator=this.parseGenerator(chunk)};sf2.Parser.prototype.parseInst=function(chunk){var data=this.input,ip=chunk.offset,instrument=this.instrument=[],size=chunk.offset+chunk.size;if(chunk.type!=='inst') 501throw new Error('invalid chunk type:'+chunk.type);while(ip<size){instrument.push({instrumentName:String.fromCharCode.apply(null,data.subarray(ip,ip+=20)),instrumentBagIndex:data[ip++]|(data[ip++]<<8)})}};sf2.Parser.prototype.parseIbag=function(chunk){var data=this.input,ip=chunk.offset,instrumentZone=this.instrumentZone=[],size=chunk.offset+chunk.size;if(chunk.type!=='ibag') 502throw new Error('invalid chunk type:'+chunk.type);while(ip<size){instrumentZone.push({instrumentGeneratorIndex:data[ip++]|(data[ip++]<<8),instrumentModulatorIndex:data[ip++]|(data[ip++]<<8)})}};sf2.Parser.prototype.parseImod=function(chunk){if(chunk.type!=='imod') 503throw new Error('invalid chunk type:'+chunk.type);this.instrumentZoneModulator=this.parseModulator(chunk)};sf2.Parser.prototype.parseIgen=function(chunk){if(chunk.type!=='igen') 504throw new Error('invalid chunk type:'+chunk.type);this.instrumentZoneGenerator=this.parseGenerator(chunk)};sf2.Parser.prototype.parseShdr=function(chunk){var data=this.input,ip=chunk.offset,samples=this.sample=[],sampleHeader=this.sampleHeader=[],size=chunk.offset+chunk.size,sampleName,start,end,startLoop,endLoop,sampleRate,originalPitch,pitchCorrection,sampleLink,sampleType;if(chunk.type!=='shdr') 505throw new Error('invalid chunk type:'+chunk.type);while(ip<size){sampleName=String.fromCharCode.apply(null,data.subarray(ip,ip+=20));start=(data[ip++]<<0)|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24);end=(data[ip++]<<0)|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24);startLoop=(data[ip++]<<0)|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24);endLoop=(data[ip++]<<0)|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24);sampleRate=(data[ip++]<<0)|(data[ip++]<<8)|(data[ip++]<<16)|(data[ip++]<<24);originalPitch=data[ip++];pitchCorrection=(data[ip++]<<24)>>24;sampleLink=data[ip++]|(data[ip++]<<8);sampleType=data[ip++]|(data[ip++]<<8);var sample=new Int16Array(new Uint8Array(data.subarray(this.samplingData.offset+start*2,this.samplingData.offset+end*2)).buffer);startLoop-=start;endLoop-=start;if(sampleRate>0){var adjust=this.adjustSampleData(sample,sampleRate);sample=adjust.sample;sampleRate*=adjust.multiply;startLoop*=adjust.multiply;endLoop*=adjust.multiply} 506samples.push(sample);sampleHeader.push({sampleName:sampleName,startLoop:startLoop,endLoop:endLoop,sampleRate:sampleRate,originalPitch:originalPitch,pitchCorrection:pitchCorrection,sampleLink:sampleLink,sampleType:sampleType})}};sf2.Parser.prototype.adjustSampleData=function(sample,sampleRate){var newSample,i,il,j,multiply=1;while(sampleRate<22050){newSample=new Int16Array(sample.length*2);for(i=j=0,il=sample.length;i<il;++i){newSample[j++]=sample[i];newSample[j++]=sample[i]} 507sample=newSample;multiply*=2;sampleRate*=2} 508return{sample:sample,multiply:multiply}};sf2.Parser.prototype.parseModulator=function(chunk){var data=this.input,ip=chunk.offset,size=chunk.offset+chunk.size,code,key,output=[];while(ip<size){ip+=2;code=data[ip++]|(data[ip++]<<8);key=sf2.Parser.GeneratorEnumeratorTable[code];if(key===undefined){output.push({type:key,value:{code:code,amount:data[ip]|(data[ip+1]<<8)<<16>>16,lo:data[ip++],hi:data[ip++]}})}else{switch(key){case'keyRange':case'velRange':case'keynum':case'velocity':output.push({type:key,value:{lo:data[ip++],hi:data[ip++]}});break;default:output.push({type:key,value:{amount:data[ip++]|(data[ip++]<<8)<<16>>16}});break}} 509ip+=2;ip+=2} 510return output};sf2.Parser.prototype.parseGenerator=function(chunk){var data=this.input,ip=chunk.offset,size=chunk.offset+chunk.size,code,key,output=[];while(ip<size){code=data[ip++]|(data[ip++]<<8);key=sf2.Parser.GeneratorEnumeratorTable[code];if(key===undefined){output.push({type:key,value:{code:code,amount:data[ip]|(data[ip+1]<<8)<<16>>16,lo:data[ip++],hi:data[ip++]}});continue} 511switch(key){case'keynum':case'keyRange':case'velRange':case'velocity':output.push({type:key,value:{lo:data[ip++],hi:data[ip++]}});break;default:output.push({type:key,value:{amount:data[ip++]|(data[ip++]<<8)<<16>>16}});break}} 512return output};sf2.Parser.prototype.getInstruments=function(){var instrument=this.instrument,zone=this.instrumentZone,output=[],bagIndex,bagIndexEnd,zoneInfo,instrumentGenerator,instrumentModulator,i,il,j,jl;for(i=0,il=instrument.length;i<il;++i){bagIndex=instrument[i].instrumentBagIndex;bagIndexEnd=instrument[i+1]?instrument[i+1].instrumentBagIndex:zone.length;zoneInfo=[];for(j=bagIndex,jl=bagIndexEnd;j<jl;++j){instrumentGenerator=this.createInstrumentGenerator_(zone,j);instrumentModulator=this.createInstrumentModulator_(zone,j);zoneInfo.push({generator:instrumentGenerator.generator,modulator:instrumentModulator.modulator,})} 513output.push({name:instrument[i].instrumentName,info:zoneInfo})} 514return output};sf2.Parser.prototype.createInstrumentGenerator_=function(zone,index){var modgen=this.createBagModGen_(zone,zone[index].instrumentGeneratorIndex,zone[index+1]?zone[index+1].instrumentGeneratorIndex:this.instrumentZoneGenerator.length,this.instrumentZoneGenerator);return{generator:modgen.modgen,}};sf2.Parser.prototype.createInstrumentModulator_=function(zone,index){var modgen=this.createBagModGen_(zone,zone[index].presetModulatorIndex,zone[index+1]?zone[index+1].instrumentModulatorIndex:this.instrumentZoneModulator.length,this.instrumentZoneModulator);return{modulator:modgen.modgen}};sf2.Parser.prototype.createBagModGen_=function(zone,indexStart,indexEnd,zoneModGen){var modgen={unknown:[],'keyRange':{hi:127,lo:0}};var info,i,il;for(i=indexStart,il=indexEnd;i<il;++i){info=zoneModGen[i];if(info.type==='unknown') 515modgen.unknown.push(info.value);else 516modgen[info.type]=info.value} 517return{modgen:modgen}};sf2.Parser.GeneratorEnumeratorTable=['startAddrsOffset','endAddrsOffset','startloopAddrsOffset','endloopAddrsOffset','startAddrsCoarseOffset','modLfoToPitch','vibLfoToPitch','modEnvToPitch','initialFilterFc','initialFilterQ','modLfoToFilterFc','modEnvToFilterFc','endAddrsCoarseOffset','modLfoToVolume',undefined,'chorusEffectsSend','reverbEffectsSend','pan',undefined,undefined,undefined,'delayModLFO','freqModLFO','delayVibLFO','freqVibLFO','delayModEnv','attackModEnv','holdModEnv','decayModEnv','sustainModEnv','releaseModEnv','keynumToModEnvHold','keynumToModEnvDecay','delayVolEnv','attackVolEnv','holdVolEnv','decayVolEnv','sustainVolEnv','releaseVolEnv','keynumToVolEnvHold','keynumToVolEnvDecay','instrument',undefined,'keyRange','velRange','startloopAddrsCoarseOffset','keynum','velocity','initialAttenuation',undefined,'endloopAddrsCoarseOffset','coarseTune','fineTune','sampleID','sampleModes',undefined,'scaleTuning','exclusiveClass','overridingRootKey'];sf2.Riff={};sf2.Riff.Parser=function(input,options){options=options||{};this.input=input;this.ip=options.index||0;this.length=options.length||input.length-this.ip;this.offset=this.ip;this.padding=options.padding!==undefined?options.padding:true;this.bigEndian=options.bigEndian!==undefined?options.bigEndian:false};sf2.Riff.Chunk=function(type,size,offset){this.type=type;this.size=size;this.offset=offset};sf2.Riff.Parser.prototype.parse=function(){var length=this.length+this.offset;this.chunkList=[];while(this.ip<length) 518this.parseChunk()};sf2.Riff.Parser.prototype.parseChunk=function(){var input=this.input,ip=this.ip,size;this.chunkList.push(new sf2.Riff.Chunk(String.fromCharCode(input[ip++],input[ip++],input[ip++],input[ip++]),(size=this.bigEndian?((input[ip++]<<24)|(input[ip++]<<16)|(input[ip++]<<8)|(input[ip++])):((input[ip++])|(input[ip++]<<8)|(input[ip++]<<16)|(input[ip++]<<24))),ip));ip+=size;if((this.padding&&(ip-this.offset)&1)===1) 519ip++;this.ip=ip};sf2.Riff.Parser.prototype.getChunk=function(index){var chunk=this.chunkList[index];if(chunk===undefined) 520return null;return chunk};sf2.Riff.Parser.prototype.getNumberOfChunks=function(){return this.chunkList.length};return sf2}));function Midi5(i_conf){var po,conf=i_conf,empty=function(){},rf,op 521function get_time(po){return window.performance.now()/1000} 522function note_run(po,s,k,t,d){var j,a=(k*100)%100,i=s.instr,c=s.chn 523k|=0 524t*=1000 525d*=1000 526if(i!=po.c_i[c]){if(po.c_i[c]==undefined){po.op.send(new Uint8Array([0xb0+c,121,0])) 527if(s.p_v.midictl){for(j in s.p_v.midictl) 528po.op.send(new Uint8Array([0xb0+c,j,s.p_v.midictl[j]]))}} 529po.c_i[c]=i 530po.op.send(new Uint8Array([0xc0+c,i&0x7f]))} 531if(a&&Midi5.ma.sysexEnabled){po.op.send(new Uint8Array([0xf0,0x7f,0x7f,0x08,0x02,i&0x7f,0x01,k,k,a/.78125,0,0xf7]),t)} 532po.op.send(new Uint8Array([0x90+c,k,127]),t) 533po.op.send(new Uint8Array([0x80+c,k,0]),t+d-20)} 534function midi_ctrl(po,s,t){po.op.send(new Uint8Array([0xb0+s.chn,s.ctrl,s.val]),t*1000)} 535function send_outputs(access){var o,os,out=[] 536Midi5.ma=access 537if(access&&access.outputs.size>0){os=access.outputs.values() 538while(1){o=os.next() 539if(!o||o.done) 540break 541out.push(o.value.name)}} 542rf(out)} 543return{get_outputs:function(f){if(!navigator.requestMIDIAccess){f() 544return} 545rf=f 546navigator.requestMIDIAccess({sysex:true}).then(send_outputs,function(msg){navigator.requestMIDIAccess().then(send_outputs,function(msg){rf()})})},set_output:function(name){var o,os 547if(!Midi5.ma) 548return 549os=Midi5.ma.outputs.values() 550while(1){o=os.next() 551if(!o||o.done) 552break 553if(o.value.name==name){op=o.value 554break}}},play:function(i_start,i_end,i_lvl){po={conf:conf,onend:conf.onend||empty,onnote:conf.onnote||empty,s_end:i_end,s_cur:i_start,repv:i_lvl||0,tgen:2,get_time:get_time,midi_ctrl:midi_ctrl,note_run:note_run,op:op,c_i:[]} 555if(0){op.send(new Uint8Array([0xf0,0x7f,0x7f,0x08,0x02,0x00,0x01,0x69,0x69,0x00,0,0xf7]),t)} 556abc2svg.play_next(po)},stop:function(){po.stop=true 557po.timouts.forEach(function(id){clearTimeout(id)}) 558abc2svg.play_next(po) 559if(op&&op.clear) 560op.clear()}}} 561function follow(abc,user,playconf){var ref=[],keep_types={note:true,rest:true} 562user.anno_stop=function(type,start,stop,x,y,w,h){if(!keep_types[type]) 563return 564ref[start]=stop;abc.out_svg('<rect class="abcr _'+start+'_" x="');abc.out_sxsy(x,'" y="',y);abc.out_svg('" width="'+w.toFixed(2)+'" height="'+abc.sh(h).toFixed(2)+'"/>\n')} 565playconf.onnote=function(i,on){var b,x,y,elts=document.getElementsByClassName('_'+i+'_') 566if(elts&&elts[0]){elts[0].style.fillOpacity=on?0.4:0 567if(on&&!window.no_scroll){b=elts[0].getBoundingClientRect() 568if(b.top<0) 569y=window.scrollY+b.top- 570window.innerHeight/2 571else if(b.bottom>window.innerHeight) 572y=window.scrollY+b.bottom+ 573window.innerHeight/2 574if(b.left<0) 575x=window.scrollX+b.left- 576window.innerWidth/2 577else if(b.right>window.innerWidth) 578x=window.scrollX+b.right+ 579window.innerWidth/2 580if(x!=undefined||y!=undefined) 581window.scrollTo(x||0,y||0)}}} 582var sty=document.createElement("style");sty.innerHTML=".abcr {fill: #d00000; fill-opacity: 0; z-index: 15}";document.head.appendChild(sty)} 583