snd-1.js 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. // abc2svg - ABC to SVG translator
  2. // @source: https://chiselapp.com/user/moinejf/repository/abc2svg
  3. // Copyright (C) 2014-2023 Jean-Francois Moine - LGPL3+
  4. //snd-1.js-file to include in html pages with abc2svg-1.js for playing
  5. function 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)
  6. return conf.sfu
  7. conf.sfu=v},set_speed:function(v){if(v==undefined)
  8. return conf.speed
  9. conf.new_speed=v},set_vol:function(v){if(v==undefined)
  10. return conf.gain;conf.gain=v
  11. if(current&&current.set_vol)
  12. current.set_vol(v)},play:play,stop:vf}
  13. function vf(){}
  14. function play(istart,i_iend,a_e){init.istart=istart;init.i_iend=i_iend;init.a_e=a_e
  15. if(midi5)
  16. midi5.get_outputs(play2)
  17. else
  18. play2()}
  19. function play2(out){var o
  20. if(!out)
  21. out=[]
  22. o=audio5.get_outputs()
  23. if(o)
  24. Array.prototype.push.apply(out,o)
  25. if(out.length==0){if(conf.onend)
  26. conf.onend()
  27. return}
  28. if(out.length==1){o=0}else{o=-1
  29. var pr="Use"
  30. for(var i=0;i<out.length;i++)
  31. pr+="\n "+i+": "+out[i]
  32. var res=window.prompt(pr,'0')
  33. if(res){o=Number(res)
  34. if(isNaN(o)||o<0||o>=out.length)
  35. o=-1}
  36. if(!res||o<0){if(conf.onend)
  37. conf.onend()
  38. return}}
  39. current=out[o]=='sf2'?audio5:midi5;abcplay.play=current.play;abcplay.stop=current.stop
  40. if(current.set_output)
  41. current.set_output(out[o]);abcplay.play(init.istart,init.i_iend,init.a_e)}
  42. conf.gain=0.7;conf.speed=1;(function(){var v
  43. try{if(!localStorage)
  44. return}catch(e){return}
  45. if(!conf.sfu){v=localStorage.getItem("sfu")
  46. if(v)
  47. conf.sfu=v}
  48. v=localStorage.getItem("volume")
  49. if(v)
  50. conf.gain=Number(v)})()
  51. if(typeof Midi5=="function")
  52. midi5=Midi5(conf)
  53. if(typeof Audio5=="function")
  54. audio5=Audio5(conf);return abcplay}
  55. if(typeof module=='object'&&typeof exports=='object')
  56. exports.AbcPlay=AbcPlay
  57. if(!abc2svg)
  58. var abc2svg={}
  59. function 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,s=first,rst=s,rst_fac,rsk=[],b_tim,b_typ
  60. function get_beat(){var s=first.p_v.meter
  61. if(!s.a_meter[0])
  62. return C.BLEN/4
  63. if(!s.a_meter[0].bot)
  64. return(s.a_meter[1]&&s.a_meter[1].top=='|')?C.BLEN/2:C.BLEN/4
  65. if(s.a_meter[0].bot=="8"&&s.a_meter[0].top%3==0)
  66. return C.BLEN/8*3
  67. return C.BLEN/s.a_meter[0].bot|0}
  68. function def_beats(){var i,s2,s3,tim,last_d,beat=get_beat(),d=first.p_v.meter.wmeasure,nb=d/beat|0,v=voice_tb.length,p_v={id:"_beats",v:v,sym:{type:C.BLOCK,v:v,subtype:"midiprog",chn:9,instr:16384,ts_prev:first}},s={type:C.NOTE,v:v,p_v:p_v,dur:beat,nhd:0,notes:[{midi:37}]}
  69. for(s2=first;s2;s2=s2.ts_next){if(s2.bar_type&&s2.time){nb=(2*d-s2.time)/beat|0
  70. last_d=beat-s2.time
  71. break}}
  72. s2=p_v.sym
  73. for(s3=first;s3&&!s3.time;s3=s3.ts_next){if(s3.type==C.TEMPO){s3=Object.create(s3)
  74. s3.v=v
  75. s3.p_v=p_v
  76. s3.prev=s3.ts_prev=s2
  77. s2.next=s2.ts_next=s3
  78. s2=s3
  79. play_fac=set_tempo(s2)
  80. break}}
  81. voice_tb[v]=p_v
  82. p_v.sym.p_v=p_v
  83. tim=abc_time=-d
  84. first.time=s2.time=tim
  85. if(s3)
  86. p_v.sym.time=tim
  87. for(i=0;i<nb;i++){s3=Object.create(s)
  88. s3.time=tim
  89. s3.prev=s2
  90. s2.next=s3
  91. s3.ts_prev=s2
  92. s2.ts_next=s3
  93. s2=s3
  94. if(last_d&&i==nb-1){s3.dur=s3.dur_orig=s3.notes[0].dur=last_d}
  95. tim+=beat}
  96. s2.ts_next=first.ts_next
  97. s2.ts_next.ts_prev=s2
  98. first.ts_next=p_v.sym}
  99. function build_parts(first){var i,j,c,n,v,s=first,p=s.parts,st=[],r=""
  100. for(i=0;i<p.length;i++){c=p[i]
  101. switch(c){case'.':continue
  102. case'(':st.push(r.length)
  103. continue
  104. case')':j=st.pop()
  105. if(j==undefined)
  106. j=r.length
  107. continue}
  108. if(c>='A'&&c<='Z'){j=r.length
  109. r+=c
  110. continue}
  111. n=Number(c)
  112. if(isNaN(n))
  113. break
  114. v=r.slice(j)
  115. if(r.length+v.length*n>128)
  116. continue
  117. while(--n>0)
  118. r+=v}
  119. s.parts=r
  120. s.p_s=[]
  121. while(1){if(!s.ts_next){s.part1=first
  122. break}
  123. s=s.ts_next
  124. if(s.part){s.part1=first
  125. v=s.part.text[0]
  126. for(i=0;i<first.parts.length;i++){if(first.parts[i]==v)
  127. first.p_s[i]=s}}}}
  128. function gen_grace(s){var g,i,n,t,d,s2,next=s.next
  129. if(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
  130. if(!(d&(d-1)))
  131. d=next.dur/2
  132. else
  133. d=next.dur/3
  134. if(s.p_v.key.k_bagpipe)
  135. d/=2
  136. next.time+=d
  137. next.dur-=d}
  138. n=0
  139. for(g=s.extra;g;g=g.next)
  140. n++
  141. d/=n*play_fac
  142. t=p_time
  143. for(g=s.extra;g;g=g.next){g.ptim=t
  144. g.pdur=d
  145. t+=d}}
  146. function set_tempo(s){var i,d=0,n=s.tempo_notes.length
  147. for(i=0;i<n;i++)
  148. d+=s.tempo_notes[i]
  149. return d*s.tempo/60}
  150. function set_variant(s){var d,n=s.text.match(/[1-8]-[2-9]|[1-9,.]|[^\s]+$/g)
  151. while(1){d=n.shift()
  152. if(!d)
  153. break
  154. if(d[1]=='-')
  155. for(i=d[0];i<=d[2];i++)
  156. rsk[i]=s
  157. else if(d>='1'&&d<='9')
  158. rsk[Number(d)]=s
  159. else if(d!=',')
  160. rsk.push(s)}}
  161. if(cfmt.chord)
  162. abc2svg.chord(first,voice_tb,cfmt)
  163. if(cfmt.playbeats)
  164. def_beats()
  165. if(s.parts)
  166. build_parts(s)
  167. rst_fac=play_fac
  168. while(s){if(s.noplay){s=s.ts_next
  169. continue}
  170. dt=s.time-abc_time
  171. if(dt!=0){p_time+=dt/play_fac
  172. abc_time=s.time}
  173. s.ptim=p_time
  174. if(s.part){rst=s
  175. rst_fac=play_fac}
  176. switch(s.type){case C.BAR:if(s.time!=b_tim){b_tim=s.time
  177. b_typ=0}
  178. if(s.text&&rsk.length>1&&s.text[0]!='1'){if(b_typ&1)
  179. break
  180. b_typ|=1
  181. set_variant(s)
  182. play_fac=rst_fac
  183. rst=rsk[0]}
  184. if(s.bar_type[0]==':'){if(b_typ&2)
  185. break
  186. b_typ|=2
  187. s.rep_p=rst
  188. if(rst==rsk[0])
  189. s.rep_v=rsk}
  190. if(s.text){if(s.text[0]=='1'){if(b_typ&1)
  191. break
  192. b_typ|=1
  193. s.rep_s=rsk=[rst]
  194. if(rst.bar_type&&rst.bar_type.slice(-1)!=':')
  195. rst.bar_type+=':'
  196. set_variant(s)
  197. rst_fac=play_fac}}else if(s.bar_type.slice(-1)==':'){if(b_typ&4)
  198. break
  199. b_typ|=4
  200. rst=s
  201. rst_fac=play_fac}else if(s.rbstop==2){if(b_typ&8)
  202. break
  203. b_typ|=8
  204. rst=s
  205. rst_fac=play_fac}
  206. break
  207. case C.GRACE:if(s.time==0&&abc_time==0){dt=0
  208. if(s.sappo)
  209. dt=C.BLEN/16
  210. else if(!s.next||s.next.type!=C.NOTE)
  211. dt=d/2
  212. abc_time-=dt}
  213. gen_grace(s)
  214. break
  215. case C.REST:case C.NOTE:d=s.dur
  216. if(s.next&&s.next.type==C.GRACE){dt=0
  217. if(s.next.sappo)
  218. dt=C.BLEN/16
  219. else if(!s.next.next||s.next.next.type!=C.NOTE)
  220. dt=d/2
  221. s.next.time-=dt
  222. d-=dt}
  223. d/=play_fac
  224. s.pdur=d
  225. v=s.v
  226. break
  227. case C.TEMPO:if(s.tempo)
  228. play_fac=set_tempo(s)
  229. break}
  230. s=s.ts_next}}}}
  231. abc2svg.play_next=function(po){function do_tie(not_s,d){var i,s=not_s.s,C=abc2svg.C,v=s.v,end_time=s.time+s.dur,repv=po.repv
  232. while(1){s=s.ts_next
  233. if(!s||s.time>end_time)
  234. break
  235. if(s.type==C.BAR){if(s.rep_p){if(!po.repn){s=s.rep_p
  236. end_time=s.time}}
  237. if(s.rep_s){if(!s.rep_s[repv])
  238. break
  239. s=s.rep_s[repv++]
  240. end_time=s.time}
  241. while(s.ts_next&&!s.ts_next.dur)
  242. s=s.ts_next
  243. continue}
  244. if(s.time<end_time||!s.ti2)
  245. continue
  246. i=s.notes.length
  247. while(--i>=0){note=s.notes[i]
  248. if(note.tie_s==not_s){d+=s.pdur/po.conf.speed
  249. return note.tie_e?do_tie(note,d):d}}}
  250. return d}
  251. function set_ctrl(po,s2,t){var i,p_v=s2.p_v,s={subtype:"midictl",p_v:p_v,v:s2.v}
  252. for(i in p_v.midictl){s.ctrl=Number(i)
  253. s.val=p_v.midictl[i]
  254. po.midi_ctrl(po,s,t)}
  255. for(s=p_v.sym;s!=s2;s=s.next){if(s.subtype=="midictl")
  256. po.midi_ctrl(po,s,t)
  257. else if(s.subtype=='midiprog')
  258. po.midi_prog(po,s)}
  259. i=po.v_c[s2.v]
  260. if(i==undefined)
  261. po.v_c[s2.v]=i=s2.v<9?s2.v:s2.v+1
  262. if(po.c_i[i]==undefined)
  263. po.c_i[i]=0
  264. po.p_v[s2.v]=true}
  265. function play_cont(po){var d,i,st,m,note,g,s2,t,maxt,now,C=abc2svg.C,s=po.s_cur
  266. function var_end(s){var i,s2,s3,a=s.rep_v||s.rep_s
  267. ti=0
  268. for(i=1;i<a.length;i++){s2=a[i]
  269. if(s2.time>ti){ti=s2.time
  270. s3=s2}}
  271. for(s=s3;s!=po.s_end;s=s.ts_next){if(s.time==ti)
  272. continue
  273. if(s.rbstop==2)
  274. break}
  275. po.repv=1
  276. return s}
  277. if(po.stop){if(po.onend)
  278. po.onend(po.repv)
  279. return}
  280. while(s.noplay){s=s.ts_next
  281. if(!s||s==po.s_end){if(po.onend)
  282. po.onend(po.repv)
  283. return}}
  284. t=po.stim+s.ptim/po.conf.speed
  285. now=po.get_time(po)
  286. if(po.conf.new_speed){po.stim=now-(now-po.stim)*po.conf.speed/po.conf.new_speed
  287. po.conf.speed=po.conf.new_speed
  288. po.conf.new_speed=0
  289. t=po.stim+s.ptim/po.conf.speed}
  290. maxt=t+po.tgen
  291. po.timouts=[]
  292. while(1){if(!po.p_v[s.v])
  293. set_ctrl(po,s,t)
  294. switch(s.type){case C.BAR:s2=null
  295. if(s.rep_p){po.repv++
  296. if(!po.repn&&(!s.rep_v||po.repv<=s.rep_v.length)){s2=s.rep_p
  297. po.repn=true}else{if(s.rep_v)
  298. s2=var_end(s)
  299. po.repn=false}}
  300. if(s.rep_s){s2=s.rep_s[po.repv]
  301. if(s2){po.repn=false
  302. if(s2==s)
  303. s2=null}else{s2=var_end(s)
  304. if(s2==po.s_end)
  305. break}}
  306. if(s.bar_type.slice(-1)==':'&&s.bar_type[0]!=':')
  307. po.repv=1
  308. if(s2){po.stim+=(s.ptim-s2.ptim)/po.conf.speed
  309. s=s2
  310. while(s&&!s.dur)
  311. s=s.ts_next
  312. if(!s)
  313. break
  314. t=po.stim+s.ptim/po.conf.speed
  315. break}
  316. if(!s.part1){while(s.ts_next&&!s.ts_next.seqst){s=s.ts_next
  317. if(s.part1)
  318. break}
  319. if(!s.part1)
  320. break}
  321. default:if(s.part1&&po.i_p!=undefined){s2=s.part1.p_s[++po.i_p]
  322. if(s2){po.stim+=(s.ptim-s2.ptim)/po.conf.speed
  323. s=s2
  324. t=po.stim+s.ptim/po.conf.speed}else{s=po.s_end}
  325. po.repv=1}
  326. break}
  327. if(s&&s!=po.s_end){switch(s.type){case C.BAR:break
  328. case C.BLOCK:if(s.subtype=="midictl")
  329. po.midi_ctrl(po,s,t)
  330. else if(s.subtype=='midiprog')
  331. po.midi_prog(po,s)
  332. break
  333. case C.GRACE:for(g=s.extra;g;g=g.next){d=g.pdur/po.conf.speed
  334. for(m=0;m<=g.nhd;m++){note=g.notes[m]
  335. if(!note.noplay)
  336. po.note_run(po,g,note.midi,t+g.ptim-s.ptim,d)}}
  337. break
  338. case C.NOTE:case C.REST:d=s.pdur/po.conf.speed
  339. if(s.type==C.NOTE){for(m=0;m<=s.nhd;m++){note=s.notes[m]
  340. if(note.tie_s||note.noplay)
  341. continue
  342. po.note_run(po,s,note.midi,t,note.tie_e?do_tie(note,d):d)}}
  343. if(po.onnote&&s.istart){i=s.istart
  344. st=(t-now)*1000
  345. po.timouts.push(setTimeout(po.onnote,st,i,true))
  346. if(d>2)
  347. d-=.1
  348. setTimeout(po.onnote,st+d*1000,i,false)}
  349. break}}
  350. while(1){if(!s||s==po.s_end||!s.ts_next){if(po.onend)
  351. setTimeout(po.onend,(t-now+d)*1000,po.repv)
  352. po.s_cur=s
  353. return}
  354. s=s.ts_next
  355. if(!s.noplay)
  356. break}
  357. t=po.stim+s.ptim/po.conf.speed
  358. if(t>maxt)
  359. break}
  360. po.s_cur=s
  361. po.timouts.push(setTimeout(play_cont,(t-now)*1000
  362. -300,po))}
  363. function get_part(po){var s,i,s_p
  364. for(s=po.s_cur;s;s=s.ts_prev){if(s.parts){po.i_p=-1
  365. return}
  366. s_p=s.part1
  367. if(!s_p||!s_p.p_s)
  368. continue
  369. for(i=0;i<s_p.p_s.length;i++){if(s_p.p_s[i]==s){po.i_p=i
  370. return}}}}
  371. get_part(po)
  372. po.stim=po.get_time(po)+.3
  373. -po.s_cur.ptim*po.conf.speed
  374. po.p_v=[]
  375. if(!po.repv)
  376. po.repv=1
  377. play_cont(po)}
  378. if(typeof module=='object'&&typeof exports=='object')
  379. exports.ToAudio=ToAudio
  380. var abcsf2=[]
  381. function Audio5(i_conf){var po,conf=i_conf,empty=function(){},errmsg,ac,gain,model,parser,presets,instr=[],params=[],rates=[],w_instr=0
  382. var b64d=[]
  383. function init_b64d(){var b64l='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',l=b64l.length
  384. for(var i=0;i<l;i++)
  385. b64d[b64l[i]]=i
  386. b64d['=']=0}
  387. function b64dcod(s){var i,t,dl,a,l=s.length,j=0
  388. dl=l*3/4
  389. if(s[l-1]=='='){if(s[l-2]=='=')
  390. dl--
  391. dl--
  392. l-=4}
  393. a=new Uint8Array(dl)
  394. for(i=0;i<l;i+=4){t=(b64d[s[i]]<<18)+
  395. (b64d[s[i+1]]<<12)+
  396. (b64d[s[i+2]]<<6)+
  397. b64d[s[i+3]]
  398. a[j++]=(t>>16)&0xff
  399. a[j++]=(t>>8)&0xff
  400. a[j++]=t&0xff}
  401. if(l!=s.length){t=(b64d[s[i]]<<18)+
  402. (b64d[s[i+1]]<<12)+
  403. (b64d[s[i+2]]<<6)+
  404. b64d[s[i+3]]
  405. a[j++]=(t>>16)&0xff
  406. if(j<dl)
  407. a[j++]=(t>>8)&0xff}
  408. return a}
  409. function sample_cp(b,s){var i,n,a=b.getChannelData(0)
  410. for(i=0;i<s.length;i++)
  411. a[i]=s[i]/196608}
  412. function sf2_create(instr,sf2par,sf2pre){function get_instr(i){var instrument=sf2par.instrument,zone=sf2par.instrumentZone,j=instrument[i].instrumentBagIndex,jl=instrument[i+1]?instrument[i+1].instrumentBagIndex:zone.length,info=[]
  413. while(j<jl){instrumentGenerator=sf2par.createInstrumentGenerator_(zone,j)
  414. info.push({generator:instrumentGenerator.generator,})
  415. j++}
  416. return{info:info}}
  417. var i,j,k,sid,gen,parm,gparm,sample,infos,sampleRate,scale,b=instr>>7,p=instr%128,pr=sf2pre
  418. rates[instr]=[]
  419. for(i=0;i<pr.length;i++){gen=pr[i].header
  420. if(gen.preset==p&&gen.bank==b)
  421. break}
  422. pr=pr[i]
  423. if(!pr){errmsg('unknown instrument '+b+':'+p)
  424. return}
  425. pr=pr.info
  426. for(k=0;k<pr.length;k++){if(!pr[k].generator.instrument)
  427. continue
  428. gparm=null
  429. infos=get_instr(pr[k].generator.instrument.amount).info
  430. for(i=0;i<infos.length;i++){gen=infos[i].generator
  431. if(!gparm){parm=gparm={attack:.001,hold:.001,decay:.001,sustain:0}}else{parm=Object.create(gparm)
  432. if(!gen.sampleID)
  433. gparm=parm}
  434. if(gen.attackVolEnv)
  435. parm.attack=Math.pow(2,gen.attackVolEnv.amount/1200)
  436. if(gen.holdVolEnv)
  437. parm.hold=Math.pow(2,gen.holdVolEnv.amount/1200)
  438. if(gen.decayVolEnv)
  439. parm.decay=Math.pow(2,gen.decayVolEnv.amount/1200)/3
  440. if(gen.sustainVolEnv)
  441. parm.sustain=gen.sustainVolEnv.amount/1000
  442. if(gen.sampleModes&&gen.sampleModes.amount&1)
  443. parm.sm=1
  444. if(!gen.sampleID)
  445. continue
  446. sid=gen.sampleID.amount
  447. sampleRate=sf2par.sampleHeader[sid].sampleRate
  448. sample=sf2par.sample[sid]
  449. parm.buffer=ac.createBuffer(1,sample.length,sampleRate)
  450. parm.hold+=parm.attack
  451. parm.decay+=parm.hold
  452. if(parm.sustain>=.4)
  453. parm.sustain=0.01
  454. else
  455. parm.sustain=1-parm.sustain/.4
  456. sample_cp(parm.buffer,sample)
  457. if(parm.sm){parm.loopStart=sf2par.sampleHeader[sid].startLoop/sampleRate
  458. parm.loopEnd=sf2par.sampleHeader[sid].endLoop/sampleRate}
  459. scale=(gen.scaleTuning?gen.scaleTuning.amount:100)/100,tune=(gen.coarseTune?gen.coarseTune.amount:0)+
  460. (gen.fineTune?gen.fineTune.amount:0)/100+
  461. sf2par.sampleHeader[sid].pitchCorrection/100-
  462. (gen.overridingRootKey?gen.overridingRootKey.amount:sf2par.sampleHeader[sid].originalPitch)
  463. for(j=gen.keyRange.lo;j<=gen.keyRange.hi;j++){rates[instr][j]=Math.pow(Math.pow(2,1/12),(j+tune)*scale)
  464. params[instr][j]=parm}}}}
  465. function load_instr(instr){w_instr++
  466. abc2svg.loadjs(conf.sfu+'/'+instr+'.js',function(){var sf2par=new sf2.Parser(b64dcod(abcsf2[instr]))
  467. sf2par.parse()
  468. var sf2pre=sf2par.getPresets()
  469. sf2_create(instr,sf2par,sf2pre)
  470. if(--w_instr==0)
  471. play_start()},function(){errmsg('could not find the instrument '+
  472. ((instr/128)|0).toString()+'-'+
  473. (instr%128).toString())
  474. if(--w_instr==0)
  475. play_start()})}
  476. function def_instr(s,f,sf2par,sf2pre){var i,bk=[],nv=-1,vb=0
  477. s=s.p_v.sym
  478. while(s.ts_prev)
  479. s=s.ts_prev
  480. for(;s;s=s.ts_next){if(s.v>nv){nv=s.v
  481. bk[nv]=0
  482. if(s.p_v.midictl){if(s.p_v.midictl[0])
  483. bk[s.v]=(bk[s.v]&~0x1fc000)
  484. +(s.p_v.midictl[0]<<14)
  485. if(s.p_v.midictl[32])
  486. bk[s.v]=(bk[s.v]&~0x3f80)
  487. +(s.p_v.midictl[32]<<7)}}
  488. switch(s.subtype){case"midiprog":break
  489. case"midictl":if(s.ctrl!=0&&s.ctrl!=32)
  490. continue
  491. if(bk[s.v]==undefined)
  492. bk[s.v]=0
  493. if(s.ctrl==0)
  494. bk[s.v]=(bk[s.v]&~0x1fc000)
  495. +(s.val<<14)
  496. else
  497. bk[s.v]=(bk[s.v]&~0x3f80)
  498. +(s.val<<7)
  499. default:continue}
  500. vb|=1<<s.v
  501. i=s.instr
  502. if(i==undefined){if(s.chn!=9)
  503. continue
  504. i=bk[s.v]?0:128*128}
  505. if(bk[s.v])
  506. i+=bk[s.v]
  507. if(!params[i]){params[i]=[]
  508. f(i,sf2par,sf2pre)}}
  509. nv=(2<<nv)-1
  510. if(nv!=vb&&!params[0]){params[0]=[]
  511. f(0,sf2par,sf2pre)}}
  512. function load_res(s){if(abc2svg.sf2||conf.sfu.slice(-4)==".sf2"||conf.sfu.slice(-3)==".js"){if(abc2svg.sf2){if(!parser){parser=new sf2.Parser(b64dcod(abc2svg.sf2))
  513. parser.parse()
  514. presets=parser.getPresets()}}else if(!parser){w_instr++
  515. if(conf.sfu.slice(-3)==".js"){abc2svg.loadjs(conf.sfu,function(){load_res(s)
  516. if(--w_instr==0)
  517. play_start()},function(){errmsg('could not load the sound file '
  518. +conf.sfu)
  519. if(--w_instr==0)
  520. play_start()})
  521. return}
  522. var r=new XMLHttpRequest()
  523. r.open('GET',conf.sfu,true)
  524. r.responseType="arraybuffer"
  525. r.onload=function(){if(r.status===200){parser=new sf2.Parser(new Uint8Array(r.response))
  526. parser.parse()
  527. presets=parser.getPresets()
  528. load_res(s)
  529. if(--w_instr==0)
  530. play_start()}else{errmsg('could not load the sound file '
  531. +conf.sfu)
  532. if(--w_instr==0)
  533. play_start()}}
  534. r.onerror=function(){errmsg('could not load the sound file '
  535. +conf.sfu)
  536. if(--w_instr==0)
  537. play_start()}
  538. r.send()
  539. return}
  540. def_instr(s,sf2_create,parser,presets)}else{def_instr(s,load_instr)}}
  541. function get_time(po){return po.ac.currentTime}
  542. function midi_ctrl(po,s,t){switch(s.ctrl){case 0:if(po.v_b[s.v]==undefined)
  543. po.v_b[s.v]=0
  544. po.v_b[s.v]=(po.v_b[s.v]&~0x1fc000)
  545. +(s.val<<14)
  546. break
  547. case 7:s.p_v.vol=s.val/127
  548. break
  549. case 32:if(po.v_b[s.v]==undefined)
  550. po.v_b[s.v]=0
  551. po.v_b[s.v]=(po.v_b[s.v]&~0x3f80)
  552. +(s.val<<7)
  553. break}}
  554. function midi_prog(po,s){var i=s.instr
  555. po.v_c[s.v]=s.chn
  556. if(i==undefined){if(s.chn!=9)
  557. return
  558. i=po.v_b[s.v]?0:128*128}
  559. if(po.v_b[s.v])
  560. i+=po.v_b[s.v]
  561. po.c_i[s.chn]=i}
  562. function note_run(po,s,key,t,d){var g,st,c=po.v_c[s.v],instr=po.c_i[c],k=key|0,parm=params[instr][k],o=po.ac.createBufferSource(),v=s.p_v.vol==undefined?1:s.p_v.vol
  563. if(!v||!parm)
  564. return
  565. o.buffer=parm.buffer
  566. if(parm.loopStart){o.loop=true
  567. o.loopStart=parm.loopStart
  568. o.loopEnd=parm.loopEnd}
  569. if(o.detune){var dt=(key*100)%100
  570. if(dt)
  571. o.detune.value=dt}
  572. o.playbackRate.value=po.rates[instr][k]
  573. g=po.ac.createGain()
  574. if(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)
  575. g.gain.linearRampToValueAtTime(v,t+parm.attack)}
  576. g.gain.setValueAtTime(v,t+parm.hold)}
  577. g.gain.exponentialRampToValueAtTime(parm.sustain*v,t+parm.decay)
  578. o.connect(g)
  579. g.connect(po.gain)
  580. o.start(t)
  581. o.stop(t+d)}
  582. function play_start(){if(po.stop){po.onend(repv)
  583. return}
  584. gain.connect(ac.destination)
  585. abc2svg.play_next(po)}
  586. init_b64d()
  587. if(!conf.sfu)
  588. conf.sfu="Scc1t2"
  589. if(navigator.userAgentData&&navigator.userAgentData.getHighEntropyValues)
  590. navigator.userAgentData.getHighEntropyValues(['model']).then(function(ua){model=ua.model})
  591. else
  592. model=navigator.userAgent
  593. return{get_outputs:function(){return(window.AudioContext||window.webkitAudioContext)?['sf2']:null},play:function(i_start,i_end,i_lvl){errmsg=conf.errmsg||alert
  594. function play_unlock(){var buf=ac.createBuffer(1,1,22050),src=ac.createBufferSource()
  595. src.buffer=buf
  596. src.connect(ac.destination)
  597. src.start(0)}
  598. if(!gain){ac=conf.ac
  599. if(!ac){conf.ac=ac=new(window.AudioContext||window.webkitAudioContext)
  600. if(/iPad|iPhone|iPod/.test(model))
  601. play_unlock()}
  602. gain=ac.createGain()
  603. gain.gain.value=conf.gain}
  604. while(i_start.noplay)
  605. i_start=i_start.ts_next
  606. 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,midi_prog:midi_prog,note_run:note_run,timouts:[],v_c:[],c_i:[],v_b:[],ac:ac,gain:gain,rates:rates}
  607. w_instr++
  608. load_res(i_start)
  609. if(--w_instr==0)
  610. play_start()},stop:function(){po.stop=true
  611. po.timouts.forEach(function(id){clearTimeout(id)})
  612. abc2svg.play_next(po)
  613. if(gain){gain.disconnect()
  614. gain=null}},set_vol:function(v){if(gain)
  615. gain.gain.value=v}}}
  616. (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(sf2){"use strict";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)
  617. throw new Error('wrong chunk length');chunk=parser.getChunk(0);if(chunk===null)
  618. throw 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')
  619. throw new Error('invalid chunk type:'+chunk.type);signature=String.fromCharCode(data[ip++],data[ip++],data[ip++],data[ip++]);if(signature!=='sfbk')
  620. throw new Error('invalid signature:'+signature);parser=new sf2.Riff.Parser(data,{'index':ip,'length':chunk.size-4});parser.parse();if(parser.getNumberOfChunks()!==3)
  621. throw 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')
  622. throw new Error('invalid chunk type:'+chunk.type);signature=String.fromCharCode(data[ip++],data[ip++],data[ip++],data[ip++]);if(signature!=='INFO')
  623. throw 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')
  624. throw new Error('invalid chunk type:'+chunk.type);signature=String.fromCharCode(data[ip++],data[ip++],data[ip++],data[ip++]);if(signature!=='sdta')
  625. throw new Error('invalid signature:'+signature);parser=new sf2.Riff.Parser(data,{'index':ip,'length':chunk.size-4});parser.parse();if(parser.chunkList.length!==1)
  626. throw 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')
  627. throw new Error('invalid chunk type:'+chunk.type);signature=String.fromCharCode(data[ip++],data[ip++],data[ip++],data[ip++]);if(signature!=='pdta')
  628. throw new Error('invalid signature:'+signature);parser=new sf2.Riff.Parser(data,{'index':ip,'length':chunk.size-4});parser.parse();if(parser.getNumberOfChunks()!==9)
  629. throw 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')
  630. throw 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')
  631. throw 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')
  632. throw new Error('invalid chunk type:'+chunk.type);this.presetZoneModulator=this.parseModulator(chunk)};sf2.Parser.prototype.parsePgen=function(chunk){if(chunk.type!=='pgen')
  633. throw 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')
  634. throw 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')
  635. throw 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')
  636. throw new Error('invalid chunk type:'+chunk.type);this.instrumentZoneModulator=this.parseModulator(chunk)};sf2.Parser.prototype.parseIgen=function(chunk){if(chunk.type!=='igen')
  637. throw 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')
  638. throw 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}
  639. samples.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]}
  640. sample=newSample;multiply*=2;sampleRate*=2}
  641. return{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}}
  642. ip+=2;ip+=2}
  643. return 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}
  644. switch(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}}
  645. return output};sf2.Parser.prototype.getPresets=function(){var preset=this.presetHeader,zone=this.presetZone,output=[],bagIndex,bagIndexEnd,zoneInfo,presetGenerator,presetModulator,i,il,j,jl
  646. for(i=0,il=preset.length;i<il;++i){j=preset[i].presetBagIndex
  647. jl=preset[i+1]?preset[i+1].presetBagIndex:zone.length
  648. zoneInfo=[];for(;j<jl;++j){presetGenerator=this.createPresetGenerator_(zone,j);presetModulator=this.createPresetModulator_(zone,j);zoneInfo.push({generator:presetGenerator.generator,modulator:presetModulator.modulator,})}
  649. output.push({info:zoneInfo,header:preset[i],})}
  650. return 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.createPresetGenerator_=function(zone,index){var modgen=this.createBagModGen_(zone,zone[index].presetGeneratorIndex,zone[index+1]?zone[index+1].presetGeneratorIndex:this.presetZoneGenerator.length,this.presetZoneGenerator);return{generator:modgen.modgen,}};sf2.Parser.prototype.createPresetModulator_=function(zone,index){var modgen=this.createBagModGen_(zone,zone[index].presetModulatorIndex,zone[index+1]?zone[index+1].presetModulatorIndex:this.presetZoneModulator.length,this.presetZoneModulator);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')
  651. modgen.unknown.push(info.value);else
  652. modgen[info.type]=info.value}
  653. return{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)
  654. this.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)
  655. ip++;this.ip=ip};sf2.Riff.Parser.prototype.getChunk=function(index){var chunk=this.chunkList[index];if(chunk===undefined)
  656. return 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
  657. function get_time(po){return window.performance.now()/1000}
  658. function note_run(po,s,k,t,d){var j,a=(k*100)%100,c=po.v_c[s.v],i=po.c_i[c]
  659. k|=0
  660. t*=1000
  661. d*=1000
  662. if(a&&Midi5.ma.sysexEnabled){po.op.send(new Uint8Array([0xf0,0x7f,0x7f,0x08,0x02,i&0x7f,0x01,k,k,a/.78125,0,0xf7]),t)}
  663. po.op.send(new Uint8Array([0x90+c,k,127]),t)
  664. po.op.send(new Uint8Array([0x80+c,k,0]),t+d-20)}
  665. function midi_ctrl(po,s,t){po.op.send(new Uint8Array([0xb0+po.v_c[s.v],s.ctrl,s.val]),t*1000)}
  666. function midi_prog(po,s){var i,c=s.chn
  667. po.v_c[s.v]=c
  668. if(po.c_i[c]==undefined){po.op.send(new Uint8Array([0xb0+c,121,0]))
  669. if(0){if(s.p_v.midictl){for(i in s.p_v.midictl)
  670. po.op.send(new Uint8Array([0xb0+c,i,s.p_v.midictl[i]]))}}}
  671. i=s.instr
  672. if(i!=undefined){po.c_i[c]=i
  673. po.op.send(new Uint8Array([0xc0+c,i&0x7f]))}}
  674. function send_outputs(access){var o,os,out=[]
  675. Midi5.ma=access
  676. if(access&&access.outputs.size>0){os=access.outputs.values()
  677. while(1){o=os.next()
  678. if(!o||o.done)
  679. break
  680. out.push(o.value.name)}}
  681. rf(out)}
  682. return{get_outputs:function(f){if(!navigator.requestMIDIAccess){f()
  683. return}
  684. rf=f
  685. navigator.requestMIDIAccess({sysex:true}).then(send_outputs,function(msg){navigator.requestMIDIAccess().then(send_outputs,function(msg){rf()})})},set_output:function(name){if(!Midi5.ma)
  686. return
  687. var o,os=Midi5.ma.outputs.values()
  688. while(1){o=os.next()
  689. if(!o||o.done)
  690. break
  691. if(o.value.name==name){op=o.value
  692. break}}},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,midi_prog:midi_prog,note_run:note_run,timouts:[],op:op,v_c:[],c_i:[]}
  693. if(0){op.send(new Uint8Array([0xf0,0x7f,0x7f,0x08,0x02,0x00,0x01,0x69,0x69,0x00,0,0xf7]),t)}
  694. abc2svg.play_next(po)},stop:function(){po.stop=true
  695. po.timouts.forEach(function(id){clearTimeout(id)})
  696. abc2svg.play_next(po)
  697. if(op&&op.clear)
  698. op.clear()}}}
  699. function follow(abc,user,playconf){var keep_types={note:true,rest:true}
  700. user.anno_stop=function(type,start,stop,x,y,w,h){if(!keep_types[type])
  701. return
  702. 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')}
  703. playconf.onnote=function(i,on){var b,i,e,elts,x=0,y=0
  704. if(abc2svg.mu)
  705. elts=abc2svg.mu.d.getElementsByClassName('_'+i+'_')
  706. else
  707. elts=document.getElementsByClassName('_'+i+'_')
  708. if(!elts||!elts.length)
  709. return
  710. e=elts[0]
  711. e.style.fillOpacity=on?0.4:0
  712. if(on&&!window.no_scroll){b=e.getBoundingClientRect()
  713. if(b.top<0||b.bottom>window.innerHeight*.8)
  714. y=b.top-window.innerHeight*.3
  715. if(b.left<0||b.right>window.innerWidth*.8)
  716. x=b.left-window.innerWidth*.3
  717. if(x||y)
  718. window.scrollBy({top:y,left:x,behavior:(x<0||y)?'instant':'smooth'})}}}
  719. (function(){var sty=document.createElement("style")
  720. sty.innerHTML=".abcr {fill: #d00000; fill-opacity: 0; z-index: 15}"
  721. document.head.appendChild(sty)})()
  722. abc2svg.ch_names={'':["C-E G C+","E-C G C+","G-C E G "],m:["C-e G C+","e-C G C+","G-C e G "],'7':["C-b-E G ","E-C G b ","G-E b C+","b-E G C+"],m7:["C-b-e G ","e-C G b ","G-e b C+","b-e G C+"],m7b5:["C-b-e g ","e-C g b ","g-e b C+","b-e g C+"],M7:["C-B-E G ","E-C G B ","G-E B C+","B-E G C+"],'6':["C-A-E G ","E-C A B ","A-E B C+","B-E A C+"],m6:["C-A-e G ","e-C A B ","A-e B C+","B-e A C+"],aug:["C-E a C+","E-C a C+","a-C E a "],aug7:["C-b-E a ","E-C a b ","a-E b C+","b-E a C+"],dim:["C-E g C+","E-C g C+","g-C E g "],dim7:["C-e g A ","e-C g A ","g-e A C+","A-C e G "],'9':["C-b-E G D+","E-C G b D+","G-E b C+D+","b-E G C+D+","D-G-C E b "],m9:["C-b-e G D+","e-C G b D+","G-e b C+D+","b-e G C+D+","D-G-C e b "],maj9:["C-B-E G D+","E-C G B D+","G-E B C+D+","B-E G C+D+","D-G-C E B "],M9:["C-B-E G D+","E-C G B D+","G-C E B D+","B-E G C+D+","D-G-C E B "],'11':["C-b-E G D+F+","E-C G b D+F+","G-E b C+D+F+","b-E G C+D+F+","D-G-C E b F+","F-D-G-C E b D+"],dim9:["C-A-e g d+","e-C g A d+","g-C e A d+","A-C e g d+","D-g-C e A "],sus4:["C-F G C+","F-C G C+","G-C F G "],sus9:["C-D G C+","D-C G C+","G-C D G "],'7sus4':["C-b-F G ","F-C G b ","G-F b C+","b-C F G "],'7sus9':["C-b-D G ","D-C G b ","G-D b C+","b-C D G "],'5':["C-G C+","G-G C+"]}
  723. abc2svg.midlet="CdDeEFgGaAbB"
  724. abc2svg.letmid={C:0,d:1,D:2,e:3,E:4,F:5,g:6,G:7,a:8,A:9,b:10,B:11}
  725. abc2svg.chord=function(first,voice_tb,cfmt){var chnm,i,k,vch,s,gchon,C=abc2svg.C,trans=48+(cfmt.chord.trans?cfmt.chord.trans*12:0)
  726. function chcr(b,ch){var i,v,r=[]
  727. b=abc2svg.midlet[b]
  728. i=ch.length
  729. while(--i>0){if(ch[i][0]==b)
  730. break}
  731. ch=ch[i]
  732. for(i=0;i<ch.length;i+=2){v=abc2svg.letmid[ch[i]]
  733. switch(ch[i+1]){case'+':v+=12;break
  734. case'-':v-=12;break}
  735. r.push(v)}
  736. return r}
  737. function filter(a_cs){var i,cs,t
  738. for(i=0;i<a_cs.length;i++){cs=a_cs[i]
  739. if(cs.type!='g')
  740. continue
  741. t=cs.otext
  742. if(t.slice(-1)==')')
  743. t=t.replace(/\(.*/,'')
  744. return t.replace(/\(|\)|\[|\]/g,'')}}
  745. function gench(sb){var r,ch,b,m,n,not,a=filter(sb.a_gch),s={v:vch.v,p_v:vch,type:C.NOTE,time:sb.time,notes:[]}
  746. if(!a)
  747. return
  748. a=a.match(/([A-GN])([#♯b♭]?)([^/]*)\/?(.*)/)
  749. if(!a)
  750. return
  751. r=abc2svg.letmid[a[1]]
  752. if(r==undefined){if(a[1]!="N")
  753. return
  754. s.type=C.REST
  755. ch=[0]
  756. r=0}else{switch(a[2]){case"#":case"♯":r++;break
  757. case"b":case"♭":r--;break}
  758. if(!a[3]){ch=chnm[""]}else{ch=abc2svg.ch_alias[a[3]]
  759. if(ch==undefined)
  760. ch=a[3]
  761. ch=chnm[ch]
  762. if(!ch)
  763. ch=a[3][0]=='m'?chnm.m:chnm[""]}
  764. if(a[4]){b=a[4][0].toUpperCase()
  765. b=abc2svg.letmid[b]
  766. if(b!=undefined){switch(a[4][1]){case"#":case"♯":b++;if(b>=12)b=0;break
  767. case"b":case"♭":b--;if(b<0)b=11;break}}}}
  768. if(b==undefined)
  769. b=0
  770. ch=chcr(b,ch)
  771. n=ch.length
  772. r+=trans
  773. if(sb.p_v.tr_snd)
  774. r+=sb.p_v.tr_snd
  775. for(m=0;m<n;m++){not={midi:r+ch[m]}
  776. s.notes.push(not)}
  777. s.nhd=n-1
  778. s.prev=vch.last_sym
  779. vch.last_sym.next=s
  780. s.ts_next=sb.ts_next
  781. sb.ts_next=s
  782. s.ts_prev=sb
  783. if(s.ts_next)
  784. s.ts_next.ts_prev=s
  785. vch.last_sym=s}
  786. if(cfmt.chord.names){chnm=Object.create(abc2svg.ch_names)
  787. for(k in cfmt.chord.names){vch=""
  788. for(i=0;i<cfmt.chord.names[k].length;i++){s=cfmt.chord.names[k][i]
  789. vch+=abc2svg.midlet[s%12]
  790. vch+=i==0?"-":(s>=12?"+":" ")}
  791. chnm[k]=[vch]}}else{chnm=abc2svg.ch_names}
  792. k=0
  793. for(i=0;i<voice_tb.length;i++){if(k<voice_tb[i].chn)
  794. k=voice_tb[i].chn}
  795. if(k==8)
  796. k++
  797. vch={v:voice_tb.length,id:"_chord",time:0,sym:{type:C.BLOCK,subtype:"midiprog",chn:k+1,instr:cfmt.chord.prog||0,time:0,ts_prev:first,ts_next:first.ts_next},vol:cfmt.chord.vol||.6}
  798. vch.sym.p_v=vch
  799. vch.sym.v=vch.v
  800. vch.last_sym=vch.sym
  801. voice_tb.push(vch)
  802. first.ts_next=vch.sym
  803. gchon=cfmt.chord.gchon
  804. s=first
  805. while(1){if(!s.ts_next){if(gchon)
  806. vch.last_sym.dur=s.time-vch.last_sym.time
  807. break}
  808. s=s.ts_next
  809. if(!s.a_gch){if(s.subtype=="midigch"){if(gchon&&!s.on)
  810. vch.last_sym.dur=s.time-vch.last_sym.time
  811. gchon=s.on}
  812. continue}
  813. if(!gchon)
  814. continue
  815. for(i=0;i<s.a_gch.length;i++){gch=s.a_gch[i]
  816. if(gch.type!='g')
  817. continue
  818. vch.last_sym.dur=s.time-vch.last_sym.time
  819. gench(s)
  820. break}}}