{"id":52747,"date":"2021-07-18T03:01:34","date_gmt":"2021-07-17T17:01:34","guid":{"rendered":"http:\/\/www.rjmprogramming.com.au\/ITblog\/?p=52747"},"modified":"2021-07-17T18:59:18","modified_gmt":"2021-07-17T08:59:18","slug":"html5-web-audio-mudcube-piano-integration-chord-composing-tutorial","status":"publish","type":"post","link":"https:\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-mudcube-piano-integration-chord-composing-tutorial\/","title":{"rendered":"HTML5 Web Audio Mudcube Piano Integration Chord Composing Tutorial"},"content":{"rendered":"<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"HTML5 Web Audio Mudcube Piano Integration Chord Composing Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/piano_composing_chords.jpg\" title=\"HTML5 Web Audio Mudcube Piano Integration Chord Composing Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">HTML5 Web Audio Mudcube Piano Integration Chord Composing Tutorial<\/p><\/div>\n<p>Yesterday&#8217;s <a target=_blank  href='\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-piano-keyboard-tutorial\/'>HTML5 Web Audio Piano Keyboard Tutorial<\/a> had us integrating keyboard functionality for non-mobile users of our piano playing web application, and today, building on the previous <a title='HTML5 Web Audio Mudcube Piano Integration Composing Tutorial' href='#html5wampict'>HTML5 Web Audio Mudcube Piano Integration Composing Tutorial<\/a>, we involve those similar keyboard functionality principles into the music composing functionality parts of <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html----------GETME\">today&#8217;s changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html----------GETME\">MyScale.html<\/a>&#8216;s <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html\" title=\"Click picture\">live run<\/a> link.<\/p>\n<p>You may recall with this web application how we developed an &#8220;inhouse language&#8221; not as good as sheet music, but able to convey the meaning of simple musical compositions.  Of course, it was only a start, and we expected days like today to arrive whereby we extend its scope to make room for <font color=blue>musical chord writing<\/font> &#8230;<\/p>\n<p><code><br \/>\nslowby4,51<font color=blue>;c<\/font>,-0.5,53,-0.5,51,-0.5,46,-0.5,51,-3.0,51,-0.5,53,-0.5,51,-0.5,53,-0.5,56,-0.5,53,-0.5,51,-0.5,53,-0.5,51,-0.5,46,-0.5,49,-3.0,61,-1.0,60,-0.5,56,-0.5,53,-1.0,51,-0.5,53,-0.5,51,-0.5,46,-0.5,51,-3.0,51,-0.5,53,-0.5,51,-0.5,53,-0.5,56,-0.5,53,-0.5,51,-0.5,53,-0.5,51,-0.5,46,-0.5,49,-3.0<br \/>\n<\/code><\/p>\n<p> &#8230; establishing an octave chord on the first note of the inhouse composition above, and involving <font color=purple>this changed code<\/font> below &#8230;<\/p>\n<p><code><br \/>\n    function abscissacheck(whatsm) {<br \/>\n            \/\/ slowby4,51,-0.5,53,-0.5,51,-0.5,46,-0.5,51,-3.0,51,-0.5,53,-0.5,51,-0.5,53,-0.5,56,-0.5,53,-0.5,51,-0.5,53,-0.5,51,-0.5,46,-0.5,49,-3.0,61,-1.0,60,-0.5,56,-0.5,53,-1.0,51,-0.5,53,-0.5,51,-0.5,46,-0.5,51,-3.0,51,-0.5,53,-0.5,51,-0.5,53,-0.5,56,-0.5,53,-0.5,51,-0.5,53,-0.5,51,-0.5,46,-0.5,49,-3.0<br \/>\n            var iout=\"\", zdelim=\"\", jou=0, jout=\"\", kout=\"\", newchordnote=0, xz=\"\";<br \/>\n            var xmididata=whatsm.split(',');<br \/>\n            var atend=eval(-2 + xmididata.length);<br \/>\n            var usual=true;<br \/>\n            var ioffs=0;<br \/>\n            <font color=purple>var xzsuff='';<br \/>\n            var xzpref='';<br \/>\n            var subhuhs=[];<br \/>\n            var isubj=0;<br \/>\n            var jusubj=0;<br \/>\n            var numc='';<\/font><br \/>\n            showr=false;<br \/>\n            if (xmididata[0].substring(0,1) &gt;= 'A') {<br \/>\n              ioffs=1;<br \/>\n              kout=xmididata[0] + \",\";<br \/>\n            }<br \/>\n            for (var iu=atend; iu&gt;=ioffs; iu-=2) {<br \/>\n              jout=iout;<br \/>\n              if (jout != \"\") { zdelim=\",\"; }<br \/>\n              usual=true;<br \/>\n              if ((\"\" + xmididata[iu]).indexOf('.') != -1) {   \/\/ an abscissa chord scenario<br \/>\n                 for (jou=0; jou&lt;xmididata[iu].split('.')[1].length; jou+=3) {<br \/>\n                  <font color=purple>if (xmididata[iu].indexOf(';') != -1) {<br \/>\n                  xzsuff=';' + xmididata[iu].split(';')[1].split('.')[0];<br \/>\n                  xmididata[iu]=xmididata[iu].replace(xzsuff,'');<br \/>\n                  subhuhs=xzsuff.substring(1).split(' ');<br \/>\n                  if (eval('' + subhuhs.length) == 1) {  subhuhs=xzsuff.substring(1).split(',');  }<br \/>\n                  if (eval('' + subhuhs.length) == 1) {  subhuhs=xzsuff.substring(1).split('.');  }<br \/>\n                  for (isubj=0; isubj&lt;subhuhs.length; isubj++) {<br \/>\n                  numc='';<br \/>\n                  for (jsubj = ('A').charCodeAt(0); jsubj &lt;= ('Z').charCodeAt(0); jsubj++) {<br \/>\n                    while (subhuhs[isubj].indexOf(String.fromCharCode(jsubj)) != -1) {<br \/>\n                      if (('' + numc) == '') { numc=0;  }<br \/>\n                      subhuhs[isubj]=subhuhs[isubj].replace(String.fromCharCode(jsubj), '' + eval(10 + eval(jsubj - ('A').charCodeAt(0)))); \/\/numc+=eval(10 + eval(jsubj - ('A').charAt(0)));<br \/>\n                    }<br \/>\n                  }<br \/>\n                  for (jsubj = ('a').charCodeAt(0); jsubj &lt;= ('z').charCodeAt(0); jsubj++) {<br \/>\n                    while (subhuhs[isubj].indexOf(String.fromCharCode(jsubj)) != -1) {<br \/>\n                      if (('' + numc) == '') { numc=0;  }<br \/>\n                      subhuhs[isubj]=subhuhs[isubj].replace(String.fromCharCode(jsubj), '' + eval(10 + eval(jsubj - ('a').charCodeAt(0)))); \/\/numc+=eval(10 + eval(jsubj - ('A').charAt(0)));<br \/>\n                    }<br \/>\n                  }<br \/>\n                  if (('' + numc) != '') {  numc='' + subhuhs[isubj];  subhuhs[isubj]='' + numc; }<br \/>\n                  xzpref+='' + eval(eval('' + subhuhs[isubj]) + eval('' + xmididata[iu])) + ',-0.01,';<br \/>\n                  console.log('xzpref=' + xzpref);<br \/>\n                  }<br \/>\n                  xzsuff='';<br \/>\n                  }<\/font><br \/>\n                  xz=xmididata[iu].split('.')[1].substring(jou, eval(3 + jou))<br \/>\n                  if (xz.substring(0,1) == \"0\") {<br \/>\n                  newchordnote=eval('' + xz.substring(1));<br \/>\n                  if (usual) { iout=xmididata[iu].split('.')[0] + \",\" + xmididata[eval(1 + eval('' + iu))] + zdelim + jout; zdelim=\",\";  jout=iout;  }<br \/>\n                  usual=false;<br \/>\n                  } else {<br \/>\n                  newchordnote=eval('' + xz);<br \/>\n                  if (usual) { iout=xmididata[iu].split('.')[0] + \",\" + xmididata[eval(1 + eval('' + iu))] + zdelim + jout; zdelim=\",\";  jout=iout; }<br \/>\n                  usual=false;<br \/>\n                  }<br \/>\n                  showr=true;<br \/>\n                  iout=<font color=purple>xzpref + <\/font>newchordnote<font color=purple> + xzsuff<\/font> + \",\" + \"-0.1\" + zdelim + jout;<br \/>\n                  jout=iout;<br \/>\n                  <font color=purple>xzsuff='';<br \/>\n                  xzpref='';<\/font><br \/>\n                  zdelim=\",\";<br \/>\n                  \/\/alert('' + newchordnote);<br \/>\n                }<br \/>\n                if (usual) { iout=xmididata[iu].split('.')[0] + \",\" + xmididata[eval(1 + eval('' + iu))] + zdelim + jout; }<br \/>\n              } else {<br \/>\n                  <font color=purple>if (xmididata[iu].indexOf(';') != -1) {<br \/>\n                  xzsuff=';' + xmididata[iu].split(';')[1].split('.')[0];<br \/>\n                  xmididata[iu]=xmididata[iu].replace(xzsuff,'');<br \/>\n                  subhuhs=xzsuff.substring(1).split(' ');<br \/>\n                  if (eval('' + subhuhs.length) == 1) {  subhuhs=xzsuff.substring(1).split(',');  }<br \/>\n                  if (eval('' + subhuhs.length) == 1) {  subhuhs=xzsuff.substring(1).split('.');  }<br \/>\n                  for (isubj=0; isubj&lt;subhuhs.length; isubj++) {<br \/>\n                  numc='';<br \/>\n                  for (jsubj = ('A').charCodeAt(0); jsubj &lt;= ('Z').charCodeAt(0); jsubj++) {<br \/>\n                    while (subhuhs[isubj].indexOf(String.fromCharCode(jsubj)) != -1) {<br \/>\n                      if (('' + numc) == '') { numc=0;  }<br \/>\n                      subhuhs[isubj]=subhuhs[isubj].replace(String.fromCharCode(jsubj), '' + eval(10 + eval(jsubj - ('A').charCodeAt(0)))); \/\/numc+=eval(10 + eval(jsubj - ('A').charAt(0)));<br \/>\n                    }<br \/>\n                  }<br \/>\n                  for (jsubj = ('a').charCodeAt(0); jsubj &lt;= ('z').charCodeAt(0); jsubj++) {<br \/>\n                    while (subhuhs[isubj].indexOf(String.fromCharCode(jsubj)) != -1) {<br \/>\n                      if (('' + numc) == '') { numc=0;  }<br \/>\n                      subhuhs[isubj]=subhuhs[isubj].replace(String.fromCharCode(jsubj), '' + eval(10 + eval(jsubj - ('a').charCodeAt(0)))); \/\/numc+=eval(10 + eval(jsubj - ('A').charAt(0)));<br \/>\n                    }<br \/>\n                  }<br \/>\n                  if (('' + numc) != '') {  numc='' + subhuhs[isubj];  subhuhs[isubj]='' + numc; }<br \/>\n                  xzpref+='' + eval(eval('' + subhuhs[isubj]) + eval('' + xmididata[iu])) + ',-0.01,';<br \/>\n                  console.log('xzpref=' + xzpref);<br \/>\n                  }<br \/>\n                  xzsuff='';<br \/>\n                  }<\/font><br \/>\n                iout=<font color=purple>xzpref + <\/font>xmididata[iu]<font color=purple> + xzsuff<\/font> + \",\" + xmididata[eval(1 + eval('' + iu))] + zdelim + jout;<br \/>\n                  <font color=purple>xzsuff='';<br \/>\n                  xzpref='';<\/font><br \/>\n              }<br \/>\n            }<br \/>\n            jout=iout;<br \/>\n            if (kout != \"\") { iout=kout + jout; }<br \/>\n            showr=false;<br \/>\n            if (showr) { alert(iout.slice(-100)); }<br \/>\n            return iout;<br \/>\n    }<br \/>\n<\/code><\/p>\n<p>Just remember that a (delimiter of) semicolon (ie. \ud83d\ude09 is the delimiter for non base note chord definition on top of the base note number, the number of semitones above on a chromatic scale, expressed in base36 (ie, 0-9,a-z) notation, and delimited within the semicolon section by comma or space or dot.<\/p>\n<p><!--p>You can also see this play out at WordPress 4.1.1's <a target=_blank  href='\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-mudcube-piano-integration-chord-composing-tutorial\/'>HTML5 Web Audio Mudcube Piano Integration Chord Composing Tutorial<\/a>.<\/p-->\n<hr>\n<p id='html5wampict'>Previous relevant <a target=_blank title='HTML5 Web Audio Mudcube Piano Integration Composing Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-mudcube-piano-integration-composing-tutorial\/'>HTML5 Web Audio Mudcube Piano Integration Composing Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"HTML5 Web Audio Mudcube Piano Integration Composing Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/composing_near_to_chords.jpg\" title=\"HTML5 Web Audio Mudcube Piano Integration Composing Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">HTML5 Web Audio Mudcube Piano Integration Composing Tutorial<\/p><\/div>\n<p>As promised in yesterday&#8217;s <a title='HTML5 Web Audio Mudcube Piano Integration Keyboard Tutorial' href='#html5wampikt'>HTML5 Web Audio Mudcube Piano Integration Keyboard Tutorial<\/a> as we left it with &#8230;<\/p>\n<blockquote cite='\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-mudcube-piano-integration-keyboard-tutorial\/'><p>\nNext stop &#8220;Work out a Protocol to Compose Chords&#8221;, maybe, into the future &#8230;\n<\/p><\/blockquote>\n<p> &#8230; we&#8217;re <i>back to the future<\/i> <font size=1>(tee hee)<\/font> today.  And in the spirit of <a target=_blank title='?' href='https:\/\/www.youtube.com\/watch?v=PablFo3yaa4'>&#8220;I never promised you a Rose Garden&#8221;<\/a> we had to settle for &#8220;near to music chords&#8221; with today&#8217;s endeavours.  But look at it this way &#8230; you may have dodged a rose thorn bullet here!?<\/p>\n<p>It is a personal favourite programming choice of ours to look for cute &#8220;delimitation&#8221; solutions, an example being <a target=_blank title='PHP Geo Map Google Chart Offset Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/php-geo-map-google-chart-offset-tutorial\/'>PHP Geo Map Google Chart Offset Tutorial<\/a>.  And one of our favourites is to add complexity by turning what used to be an <i>integer<\/i> data &#8220;type&#8221; into a <i>float<\/i> (ie. real number with decimal (fractional) parts called the &#8220;mantissa&#8221;) data &#8220;type&#8221; (eg. starting with 60 as Middle C, and turning that into 60.048 for Middle C and an Octave C lower, or 60.048072 for Middle C and an Octave C lower and higher).  Extra joy comes if that resultant &#8220;number&#8221; (covering both of those data types in scope) when &#8220;rounded&#8221; would result in the original &#8220;integer&#8221; number anyway.  Today we have such joy (because the highest note number of our piano is only 108 &#8230; much less than 499 even) as we allow the user to, within their textarea &#8220;composing pallette&#8221; <b>now<\/b> say that a &#8230;<\/p>\n<blockquote><p>\nnormal number is a note <b>(and mantissa sets of 3 characters (zero left padded) play notes close behind, like chords)<\/b>\n<\/p><\/blockquote>\n<p>In order to make this happen we intervene where a composition takes Javascript variable form and encase that into a Javascript function return value &#8220;mapping&#8221; <b>as per<\/b> &#8230;<\/p>\n<p><code><br \/>\n    <b>function abscissacheck(whatsm) {<br \/>\n            \/\/ slowby4,51,-0.5,53,-0.5,51,-0.5,46,-0.5,51,-3.0,51,-0.5,53,-0.5,51,-0.5,53,-0.5,56,-0.5,53,-0.5,51,-0.5,53,-0.5,51,-0.5,46,-0.5,49,-3.0,61,-1.0,60,-0.5,56,-0.5,53,-1.0,51,-0.5,53,-0.5,51,-0.5,46,-0.5,51,-3.0,51,-0.5,53,-0.5,51,-0.5,53,-0.5,56,-0.5,53,-0.5,51,-0.5,53,-0.5,51,-0.5,46,-0.5,49,-3.0<br \/>\n            var iout=\"\", zdelim=\"\", jou=0, jout=\"\", kout=\"\", newchordnote=0, xz=\"\";<br \/>\n            var xmididata=whatsm.split(',');<br \/>\n            var atend=eval(-2 + xmididata.length);<br \/>\n            var usual=true;<br \/>\n            var ioffs=0;<br \/>\n            showr=false;<br \/>\n            if (xmididata[0].substring(0,1) &gt;= 'A') {<br \/>\n              ioffs=1;<br \/>\n              kout=xmididata[0] + \",\";<br \/>\n            }<br \/>\n            for (var iu=atend; iu&gt;=ioffs; iu-=2) {<br \/>\n              jout=iout;<br \/>\n              if (jout != \"\") { zdelim=\",\"; }<br \/>\n              usual=true;<br \/>\n              if ((\"\" + xmididata[iu]).indexOf('.') != -1) {   \/\/ a mantissa chord scenario<br \/>\n                 for (jou=0; jou&lt;xmididata[iu].split('.')[1].length; jou+=3) {<br \/>\n                  xz=xmididata[iu].split('.')[1].substring(jou, eval(3 + jou))<br \/>\n                  if (xz.substring(0,1) == \"0\") {<br \/>\n                  newchordnote=eval('' + xz.substring(1));<br \/>\n                  if (usual) { iout=xmididata[iu].split('.')[0] + \",\" + xmididata[eval(1 + eval('' + iu))] + zdelim + jout; zdelim=\",\";  jout=iout;  }<br \/>\n                  usual=false;<br \/>\n                  } else {<br \/>\n                  newchordnote=eval('' + xz);<br \/>\n                  if (usual) { iout=xmididata[iu].split('.')[0] + \",\" + xmididata[eval(1 + eval('' + iu))] + zdelim + jout; zdelim=\",\";  jout=iout; }<br \/>\n                  usual=false;<br \/>\n                  }<br \/>\n                  showr=true;<br \/>\n                  iout=newchordnote + \",\" + \"-0.1\" + zdelim + jout;<br \/>\n                  jout=iout;<br \/>\n                  zdelim=\",\";<br \/>\n                  \/\/alert('' + newchordnote);<br \/>\n                }<br \/>\n                if (usual) { iout=xmididata[iu].split('.')[0] + \",\" + xmididata[eval(1 + eval('' + iu))] + zdelim + jout; }<br \/>\n              } else {<br \/>\n                iout=xmididata[iu] + \",\" + xmididata[eval(1 + eval('' + iu))] + zdelim + jout;<br \/>\n              }<br \/>\n            }<br \/>\n            jout=iout;<br \/>\n            if (kout != \"\") { iout=kout + jout; }<br \/>\n            showr=false;<br \/>\n            if (showr) { alert(iout.slice(-100)); }<br \/>\n            return iout;<br \/>\n    }<\/b><br \/>\n<br \/> <br \/>\n    function insong(sheetmusic) { \/\/ assumes comma separators<br \/>\n      if (sheetmusic != \"\") {<br \/>\n            \/\/ add a suffix of + if two hands are playing together<br \/>\n            \/\/ normal word is a speed descriptor<br \/>\n            \/\/ normal number is a note (and mantissa sets of 3 characters (zero left padded) play notes close behind, like chords)<br \/>\n            \/\/ -1 is crotchet, -2 is minum, -0.5 is quaver, -0.25 is semi-quaver etcetera<br \/>\n\t\t\t\/\/ 0 (alone) is for a rest of the duration above<br \/>\n            \/\/ 0127 is normal loudness, etcetera<br \/>\n            var done=\"\", offset=0.0, offset2=0.0, planbit=\"\", isrest=false, delaydelim='', notedelim='', curnote=-1, curvelocity=127, curdelay=-1, jk, ijk, prevvelocity=-1, prefix=\"\", curval=1, kji=0, allhhh, bitshhbefore, notes, curnotes=\"\", delays, curdelays=\"\";<br \/>\n            var plan=\"\t   MIDI.loadPlugin({ \\n\";<br \/>\n            \/\/ etcetera etcetera etcetera<br \/>\n<br \/> <br \/>\n            var mididata=<b>abscissacheck(<\/b>sheetmusic<b>)<\/b>.split(',');<br \/>\n            \/\/ etcetera etcetera etcetera<br \/>\n      }<br \/>\n            \/\/ etcetera etcetera etcetera<br \/>\n    }<br \/>\n<\/code><\/p>\n<p> &#8230; for transcribed music or brand new compositions like (the new three octave version of <a target=_blank title='Google search of Merry Christmas Mr Lawrence' href='https:\/\/www.google.com\/search?client=firefox-b&#038;biw=1155&#038;bih=609&#038;ei=t3YsXMffI4SZ8gWwyIDQBw&#038;q=Merry+Christmas+Mr+Lawrence&#038;oq=Merry+Christmas+Mr+Lawrence&#038;gs_l=psy-ab.3..35i39j0j0i20i263j0j0i20i263j0l5.3015752.3028508..3028925...0.0..0.428.7575.2-14j10j2......0....1..gws-wiz.......0i71j0i67j0i131.kxfPMBL-rNM'>Merry Christmas, Mr Lawrence<\/a> theme) &#8230;<\/p>\n<div style='width:100%;overflow:scroll;'><iframe style='width:100%;height:800px;' src='http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html?instrument=acoustic_grand_piano&#038;myselpos=Left&#038;mode=0&#038;x=x&#038;speed=0.15&#038;playthis=twooctave_merry_christmas_mr_lawrence'><\/iframe><\/div>\n<p>So feel free to try <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html---------GETME\" title=\"MyScale.html\">the changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html---------GETME\" title=\"MyScale.html\">MyScale.html<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html\"title=\"Click picture\">live run<\/a> link (supervising <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.php--GETME\" title=\"MyScale.php\">the changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.php--GETME\" title=\"MyScale.php\">MyScale.php<\/a>).<\/p>\n<p><i><b>Did you know?<\/b><\/i><\/p>\n<p>Looking for a real app that works with composing and sheet music?   We&#8217;ve tried and would highly recommend the brilliant <a target=_blank title='Sibelius' href='https:\/\/www.avid.com\/sibelius'>Sibelius<\/a>.<\/p>\n<hr>\n<p id='html5wampikt'>Previous relevant <a target=_blank title='HTML5 Web Audio Mudcube Piano Integration Keyboard Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-mudcube-piano-integration-keyboard-tutorial\/'>HTML5 Web Audio Mudcube Piano Integration Keyboard Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"HTML5 Web Audio Mudcube Piano Integration Mobile Keyboard Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/piano_keyboard.jpg\" title=\"HTML5 Web Audio Mudcube Piano Integration Mobile Keyboard Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">HTML5 Web Audio Mudcube Piano Integration Keyboard Tutorial<\/p><\/div>\n<p>The web application of <a title='HTML5 Web Audio Mudcube Piano Integration Mobile Debug Tutorial' href='#html5wampimdt'>HTML5 Web Audio Mudcube Piano Integration Mobile Debug Tutorial<\/a> makes minimal use of the keyboard, though it can be used for &#8220;composing&#8221; your own musical works into a textarea element.  <a target=_blank title='?' href='https:\/\/www.youtube.com\/watch?v=Pil50G4AfxM'>&#8220;While you see a chance, take it&#8221;<\/a> &#8230; and so this could be an &#8220;onions of the fourth dimension&#8221; moment for this web application &#8230;<\/p>\n<ul>\n<li>for non-mobile platforms (where the keyboard is that independent th<strike>a<\/strike>ing, whereas on mobile, it interferes with web application workflows) &#8230; because it facilitates &#8230;<\/li>\n<li>the chance to play multiple notes (almost) at the same time &#8230; as per a musical chord<\/li>\n<\/ul>\n<p> &#8230; for all practical purposes, an important thing you&#8217;d want to be able to do with a piano playing web application (sadly only for non-mobile platforms).<\/p>\n<p>And so, we&#8217;re using characters from the <a target=_blank title='Ascii table' href='http:\/\/www.asciitable.com\/'>Ascii table<\/a> &#8230;<\/p>\n<ul>\n<li>the numbers 1 through to 7 &#8230; and &#8230;<\/li>\n<li>the letters A through to W uppercase &#8230; and &#8230;<\/li>\n<li>the letters a through to w lowercase &#8230; for the piano ivory (white) keys &#8230;<\/li>\n<li>ahead of corresponding key above for an associated sharp click the Ctrl or Control key &#8230; for the piano ebony (black) keys<\/li>\n<\/ul>\n<p> &#8230; to cover the needs for a keyboard method of reaching all 87 piano keys of interest on our (online digital) piano, <font color=blue>as per<\/font> &#8230;<\/p>\n<p><code><br \/>\n    <font color=blue>var kqueue=[], ikqueue=-1;<br \/>\n    var eioisaltKey=false;<br \/>\n    var eioisctrlKey=false;<br \/>\n    var okn='';<\/font><br \/>\n<br \/>\n  <font color=blue>function keyb(eiois) {<br \/>\n    if (eiois.ctrlKey) {<br \/>\n       eioisctrlKey=true;<br \/>\n    } else if (eiois.altKey) {<br \/>\n       eioisaltKey=true;<br \/>\n    } else if ( eiois.keyCode == 17 ) {<br \/>\n       eioisctrlKey=true;<br \/>\n    } else if ( (eiois.which || eiois.keyCode) == 8 ) {<br \/>\n       if (okn.length &gt; 0) {<br \/>\n       okn=okn.substring(0, eval(-1 + okn.length));<br \/>\n       } else {<br \/>\n       okn='';<br \/>\n       }<br \/>\n       if (eioisctrlKey) {<br \/>\n       eioisctrlKey=false;<br \/>\n       } else if (eioisaltKey) {<br \/>\n       eioisaltKey=false;<br \/>\n       }<br \/>\n    } else if (eioisctrlKey) {<br \/>\n       if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= 'A' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= 'G') {<br \/>\n         kqueue.push(\"document.getElementById('N\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       } else if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= 'a' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= 'g') {<br \/>\n         kqueue.push(\"document.getElementById('o\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       } else if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= 'H' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= 'N') {<br \/>\n         kqueue.push(\"document.getElementById('N\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       } else if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= 'h' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= 'n') {<br \/>\n         kqueue.push(\"document.getElementById('o\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       } else if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= 'O' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= 'U') {<br \/>\n         kqueue.push(\"document.getElementById('N\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       } else if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= 'o' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= 'u') {<br \/>\n         kqueue.push(\"document.getElementById('o\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       } else if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= '1' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= '7') {<br \/>\n         kqueue.push(\"document.getElementById('N\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       } else if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= 'V' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= 'X') {<br \/>\n         kqueue.push(\"document.getElementById('N\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       }<br \/>\n       okn+=String.fromCharCode(eiois.which || eiois.keyCode) + '#';<br \/>\n       if (eioisctrlKey) {<br \/>\n       eioisctrlKey=false;<br \/>\n       } else if (eioisaltKey) {<br \/>\n       eioisaltKey=false;<br \/>\n       }<br \/>\n    } else {<br \/>\n       if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= 'A' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= 'G') {<br \/>\n         kqueue.push(\"document.getElementById('P\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       } else if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= 'a' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= 'g') {<br \/>\n         kqueue.push(\"document.getElementById('q\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       } else if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= 'H' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= 'N') {<br \/>\n         kqueue.push(\"document.getElementById('P\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       } else if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= 'h' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= 'n') {<br \/>\n         kqueue.push(\"document.getElementById('q\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       } else if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= 'O' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= 'U') {<br \/>\n         kqueue.push(\"document.getElementById('P\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       } else if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= 'o' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= 'u') {<br \/>\n         kqueue.push(\"document.getElementById('q\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       } else if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= '1' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= '7') {<br \/>\n         kqueue.push(\"document.getElementById('P\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       } else if (String.fromCharCode(eiois.which || eiois.keyCode) &gt;= 'V' && String.fromCharCode(eiois.which || eiois.keyCode) &lt;= 'X') {<br \/>\n         kqueue.push(\"document.getElementById('P\" + String.fromCharCode(eiois.which || eiois.keyCode) + \"').click();\");<br \/>\n       }<br \/>\n       okn+=String.fromCharCode(eiois.which || eiois.keyCode);<br \/>\n       if (eioisctrlKey) {<br \/>\n       eioisctrlKey=false;<br \/>\n       } else if (eioisaltKey) {<br \/>\n       eioisaltKey=false;<br \/>\n       }<br \/>\n    }<br \/>\n    if (ikqueue == -1 && kqueue.length &gt; 0) {<br \/>\n      ikqueue=0;<br \/>\n      setTimeout(keychecking, 20);<br \/>\n    }<br \/>\n  }<\/font><br \/>\n<br \/> <br \/>\n  <font color=blue>function keychecking() {<br \/>\n    var iok=-1, cok='';<br \/>\n    if (kqueue.length &gt; 0) {<br \/>\n     for (var jkl=0; jkl&lt;kqueue.length; jkl++) {<br \/>\n       if (iok == -1 && kqueue[jkl] != '') {<br \/>\n         iok=jkl;<br \/>\n       }<br \/>\n     }<br \/>\n     if (iok != -1) {<br \/>\n       cok=kqueue[iok];<br \/>\n       kqueue[iok]='';<br \/>\n       eval(cok);<br \/>\n       setTimeout(keychecking, 20);<br \/>\n     } else {<br \/>\n       kqueue=[];<br \/>\n       ikqueue=0;<br \/>\n       setTimeout(keychecking, 20);<br \/>\n     }<br \/>\n    } else {<br \/>\n     setTimeout(keychecking, 20);<br \/>\n    }<br \/>\n  }<\/font><br \/>\n<br \/> <br \/>\n\tsetTimeout(andthenmode, 2000);<br \/>\n&lt;\/script&gt;<br \/>\n&lt;\/head&gt;<br \/>\n&lt;body style='background-color: yellow;'<font color=blue> onkeydown='prekeyb(event);' onkeypress='keyb(event);'<\/font>&gt;<br \/>\n<\/code><\/p>\n<p>Try <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html--------GETME\" title=\"MyScale.html\">the changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html--------GETME\" title=\"MyScale.html\">MyScale.html<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html\"title=\"Click picture\">live run<\/a> link.<\/p>\n<p>Next stop &#8220;Work out a Protocol to Compose Chords&#8221;, maybe, into the future &#8230; <font size=2>an<\/font>d b<font size=4>ey<\/font><font size=6>ond<\/font>.<\/p>\n<hr>\n<p id='html5wampimdt'>Previous relevant <a target=_blank title='HTML5 Web Audio Mudcube Piano Integration Mobile Debug Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-mudcube-piano-integration-mobile-debug-tutorial\/'>HTML5 Web Audio Mudcube Piano Integration Mobile Debug Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"HTML5 Web Audio Mudcube Piano Integration Mobile Debug Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/mudcube_mobile_debug.gif\" title=\"HTML5 Web Audio Mudcube Piano Integration Mobile Debug Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">HTML5 Web Audio Mudcube Piano Integration Mobile Debug Tutorial<\/p><\/div>\n<p>Yesterday&#8217;s <a title='HTML5 Web Audio Mudcube Piano Integration Tutorial' href='#html5wampit'>HTML5 Web Audio Mudcube Piano Integration Tutorial<\/a> was tested on non-mobile platforms, but with mobile (iOS) work we sometimes reach different parts of the Javascript client code, the reason being that the non-mobile platforms do not require that &#8220;button touch event&#8221; intervention, and they can just go ahead and load any Web Audio functionality parts during the webpage onload period, and use it or not, at leisure.   We noticed yesterday, &#8220;no go&#8221; for an iPad, which almost certainly means &#8220;no go&#8221; for iPhone as well.  What to do?  Similar to <a target=_blank title='HTML5 Web Audio Piano Mobile Safari Web Inspector Debug Tutorial' href='#html5wapmswidt'>HTML5 Web Audio Piano Mobile Safari Web Inspector Debug Tutorial<\/a> as per &#8230;<\/p>\n<blockquote cite='\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-piano-mobile-safari-web-inspector-debug-tutorial\/'>\n<p>Did you notice the use of &#8230; <a target=_blank title='?' href='https:\/\/www.youtube.com\/watch?v=uhiCFdWeQfA'>anyone, anyone<\/a>? &#8230; yes, <a target=_blank title='?' href='http:\/\/mentalfloss.com\/article\/53131\/ada-lovelace-first-computer-programmer'>Augusta Ada King<\/a> &#8230; <a target=_blank title='HTML DOM console.log information' href='https:\/\/www.w3schools.com\/jsref\/met_console_log.asp'>console.log([message])<\/a> calls all over the place.   Could it be that &#8220;alert&#8221; calls would be too disruptive?  That&#8217;s right.  Do you remember, perhaps, in science at school, how we learnt that looking at a photon was difficult because we would be interfering in how that photon would be in nature, and so we can not conclude anything categorically because of our interference.  Well, &#8220;timing issues&#8221; are a bit the same, but console.log([message]) calls will not interfere and yet pass on information to  &#8230; <a target=_blank title='?' href='https:\/\/www.youtube.com\/watch?v=uhiCFdWeQfA'>anyone, anyone<\/a>? &#8230; yes, <a target=_blank title='?' href='https:\/\/en.wikipedia.org\/wiki\/Grace_Hopper'>Grace Brewster Murray Hopper<\/a> &#8230; a web inspector.  Like Safari&#8217;s we think, given we&#8217;re working with &#8230;<\/p>\n<p><\/p>\n<ul>\n<li>an iPhone to test on<\/li>\n<li>a MacBook Pro to facilitate the testing &#8230; connected via &#8230;<\/li>\n<li>(the ubiquitous Apple white) lead &#8230; hardware wise &#8230; and &#8230;<\/li>\n<li>the Safari web browser (on both devices, running our <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/piano.htm\">&#8220;piano web application&#8221;<\/a> on the iPhone Safari web browser) &#8230; software wise &#8230; and within that browser&#8217;s &#8230;<\/li>\n<li>Developer menu can get us to (the iPhone incarnation of the) Web Inspector &#8230; within which the &#8230;<\/li>\n<li>Console tab can show us errors and warnings and information (which we can augment ourselves via our console.log[message]) Javascript DOM calls in the HTML\/Javascript\/CSS code of our &#8220;piano web application&#8221; and its &#8220;web audio interfacing&#8221; friend<\/li>\n<\/ul>\n<p><\/p>\n<p> &#8230; but if you&#8217;ve not done this in the past <font color=red>&#8230; yes we have thanks &#8230;<\/font>\n<\/p><\/blockquote>\n<p> &#8230; except, today, &#8220;an iPhone <font color=red>and iPad<\/font> to test on&#8221;.   We found a few problems that the fixes for, allowed the Web Audio option for the piano web application to start working on the iPad and iPhone, for the &#8220;composing&#8221; parts as well.<\/p>\n<p>And you can see us doing a bit of this with today&#8217;s <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/mudcube_mobile_debug.gif\" title=\"Tutorial picture\">animated GIF presentation<\/a>.<\/p>\n<p>Again, here are today&#8217;s mobile platform debugging changes &#8230;<\/p>\n<ul>\n<li><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html------GETME\" title=\"MyScale.html\">the changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html------GETME\" title=\"MyScale.html\">MyScale.html<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html\"title=\"Click picture\">live run<\/a> link as the parent webpage to the child iframe &#8230;<\/li>\n<li><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html----------GETME\" title=\"web_audio.htm\">the changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html----------GETME\" title=\"web_audio.htm\">web_audio.htm<\/a> inhouse interfacer to Web Audio API<\/li>\n<\/ul>\n<hr>\n<p id='html5wampit'>Previous relevant <a target=_blank title='HTML5 Web Audio Mudcube Piano Integration Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-mudcube-piano-integration-tutorial\/'>HTML5 Web Audio Mudcube Piano Integration Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"HTML5 Web Audio Mudcube Piano Integration Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale_web_audio.jpg\" title=\"HTML5 Web Audio Mudcube Piano Integration Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">HTML5 Web Audio Mudcube Piano Integration Tutorial<\/p><\/div>\n<p>The integrations of the recent <a title='HTML5 Web Audio Piano Mobile Safari Web Inspector Debug Tutorial' href='#html5wapmswidt'>HTML5 Web Audio Piano Mobile Safari Web Inspector Debug Tutorial<\/a> have a lot in common with today&#8217;s &#8230;<\/p>\n<ul>\n<li>audio applicability &#8230; in conjunction with &#8230;<\/li>\n<li>piano<\/li>\n<\/ul>\n<p> &#8230; basis.  But this integration to an older &#8220;piano application&#8221; incarnation, that used MIDI interfacing, has additional &#8220;composing&#8221; functionality we&#8217;re keen to &#8220;lassoo&#8221; into the integrations, because the integration of Web Audio will mean we can compose music on mobile platforms (we hope by tomorrow), if that&#8217;s your preference.  On this front, do you remember us working out the haunting and beautiful theme to the music to Merry Christmas, Mr Lawrence when we presented <a target=_blank href='https:\/\/www.rjmprogramming.com.au\/ITblog\/htmljavascriptphp-compose-music-makeover-tutorial\/' title='HTML\/Javascript\/PHP Compose Music Makeover Tutorial'>HTML\/Javascript\/PHP Compose Music Makeover Tutorial<\/a> &#8230; as per &#8230;<\/p>\n<blockquote cite='https:\/\/www.rjmprogramming.com.au\/ITblog\/htmljavascriptphp-compose-music-makeover-tutorial\/'>\n<p>What was some of the inspiration?  Right near the end of ABC Radio 702&#8217;s <a target=_blank title='ABC Radio 702 Thu 27 Dec 2018, 6:00am' href='https:\/\/www.abc.net.au\/radio\/sydney\/programs\/breakfast\/breakfast\/10645018'>Thu 27 Dec 2018, 6:00am Sydney, Australia<\/a> podcast you can hear what was to me a captivating piano solo played by <a target=_blank title='Google search for Ryuichi Sakamoto' href='https:\/\/www.google.com\/search?client=firefox-b&#038;biw=1155&#038;bih=609&#038;ei=jYIsXOWNNsit8QXh8ZToAg&#038;q=Ryuichi+Sakamoto&#038;oq=Ryuichi+Sakamoto&#038;gs_l=psy-ab.3..0i71l8.93312.93312..93585...0.0..0.0.0.......0....1j2..gws-wiz.nvAiL4H3BRI'>Ryuichi Sakamoto<\/a> below &#8230;<\/p>\n<p>\n<iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/BPAMTIou8vM\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><br \/>\n<\/p>\n<p> &#8230; written for the movie <a target=_blank title='Google search for Merry Christmas Mr Lawrence' href='https:\/\/www.google.com\/search?client=firefox-b&#038;biw=1155&#038;bih=609&#038;ei=t3YsXMffI4SZ8gWwyIDQBw&#038;q=Merry+Christmas+Mr+Lawrence&#038;oq=Merry+Christmas+Mr+Lawrence&#038;gs_l=psy-ab.3..35i39j0j0i20i263j0j0i20i263j0l5.3015752.3028508..3028925...0.0..0.428.7575.2-14j10j2......0....1..gws-wiz.......0i71j0i67j0i131.kxfPMBL-rNM'>Merry Christmas, Mr Lawrence<\/a>.\n<\/p><\/blockquote>\n<p>?   Well, we&#8217;ve used that tune to test run our integration, where it wasn&#8217;t just the case of plugging in the same logic of the integration of <a title='HTML5 Web Audio Piano Mobile Safari Web Inspector Debug Tutorial' href='#html5wapmswidt'>HTML5 Web Audio Piano Mobile Safari Web Inspector Debug Tutorial<\/a>, alas.   The MIDI plugin of the mudcube incarnation does some clever client &#8220;sleeping&#8221; to do its th<strike>a<\/strike>ing, so we have to work out quite a bit of setTimeout (timer) rearranging to simulate those &#8220;smarts&#8221;.<\/p>\n<p>Here are the changes &#8230;<\/p>\n<ul>\n<li><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html-----GETME\" title=\"MyScale.html\">the changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html-----GETME\" title=\"MyScale.html\">MyScale.html<\/a>  (supervising <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.php-GETME\" title=\"MyScale.php\">the changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.php-GETME\" title=\"MyScale.php\">MyScale.php<\/a>) <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html\"title=\"Click picture\">live run<\/a> link as the parent webpage to the child iframe &#8230;<\/li>\n<li><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html---------GETME\" title=\"web_audio.htm\">the changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html---------GETME\" title=\"web_audio.htm\">web_audio.htm<\/a> inhouse interfacer to Web Audio API<\/li>\n<\/ul>\n<p> &#8230; for transcribed music or brand new compositions like &#8230;<\/p>\n<div style='width:100%;overflow:scroll;'><iframe style='width:100%;height:800px;' src='http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/MIDI.js-master\/examples\/MyScale.html?instrument=acoustic_grand_piano&#038;myselpos=Left&#038;mode=0&#038;x=x&#038;speed=0.15&#038;playthis=merry_christmas_mr_lawrence'><\/iframe><\/div>\n<p> &#8230; with which we hope you might now be able to work music compositions (at least on non-mobile for today), via the Web Audio API that came in with HTML5.<\/p>\n<hr>\n<p id='html5wapmswidt'>Previous relevant <a target=_blank title='HTML5 Web Audio Piano Mobile Safari Web Inspector Debug Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-piano-mobile-safari-web-inspector-debug-tutorial\/'>HTML5 Web Audio Piano Mobile Safari Web Inspector Debug Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPhone\/iphone_macbook_lead_safari_web_inspector_debug.pdf\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"HTML5 Web Audio Piano Mobile Safari Web Inspector Debug Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPhone\/iphone_macbook_lead_safari_web_inspector_debug.jpg\" title=\"HTML5 Web Audio Piano Mobile Safari Web Inspector Debug Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">HTML5 Web Audio Piano Mobile Safari Web Inspector Debug Tutorial<\/p><\/div>\n<p>There were problems peculiar to mobile platforms involved in the work of yesterday&#8217;s <a title='HTML5 Web Audio Piano Mobile Tutorial' href='#html5wapmt'>HTML5 Web Audio Piano Mobile Tutorial<\/a>.  But just how did we arrive at a solution?  We can tell you now a placement of Javascript &#8220;alert&#8221; popup windows is inadequate for such an involved issue that cannot be simulated on our usual MacBook Pro laptop &#8220;home base&#8221; computer.  So what to do?<\/p>\n<p>There&#8217;s a big clue in the difference reports of yesterday &#8230;<\/p>\n<ul>\n<li><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/piano.html----GETME\" title=\"piano.htm\">piano.htm difference report<\/a><\/li>\n<li><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html--------GETME\" title=\"web_audio.htm\">web_audio.htm difference report<\/a><\/li>\n<\/ul>\n<p>Did you notice the use of &#8230; <a target=_blank title='?' href='https:\/\/www.youtube.com\/watch?v=uhiCFdWeQfA'>anyone, anyone<\/a>? &#8230; yes, <a target=_blank title='?' href='http:\/\/mentalfloss.com\/article\/53131\/ada-lovelace-first-computer-programmer'>Augusta Ada King<\/a> &#8230; <a target=_blank title='HTML DOM console.log information' href='https:\/\/www.w3schools.com\/jsref\/met_console_log.asp'>console.log([message])<\/a> calls all over the place.   Could it be that &#8220;alert&#8221; calls would be too disruptive?  That&#8217;s right.  Do you remember, perhaps, in science at school, how we learnt that looking at a photon was difficult because we would be interfering in how that photon would be in nature, and so we can not conclude anything categorically because of our interference.  Well, &#8220;timing issues&#8221; are a bit the same, but console.log([message]) calls will not interfere and yet pass on information to  &#8230; <a target=_blank title='?' href='https:\/\/www.youtube.com\/watch?v=uhiCFdWeQfA'>anyone, anyone<\/a>? &#8230; yes, <a target=_blank title='?' href='https:\/\/en.wikipedia.org\/wiki\/Grace_Hopper'>Grace Brewster Murray Hopper<\/a> &#8230; a web inspector.  Like Safari&#8217;s we think, given we&#8217;re working with &#8230;<\/p>\n<ul>\n<li>an iPhone to test on<\/li>\n<li>a MacBook Pro to facilitate the testing &#8230; connected via &#8230;<\/li>\n<li>(the ubiquitous Apple white) lead &#8230; hardware wise &#8230; and &#8230;<\/li>\n<li>the Safari web browser (on both devices, running our <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/piano.htm\">&#8220;piano web application&#8221;<\/a> on the iPhone Safari web browser) &#8230; software wise &#8230; and within that browser&#8217;s &#8230;<\/li>\n<li>Developer menu can get us to (the iPhone incarnation of the) Web Inspector &#8230; within which the &#8230;<\/li>\n<li>Console tab can show us errors and warnings and information (which we can augment ourselves via our console.log[message]) Javascript DOM calls in the HTML\/Javascript\/CSS code of our &#8220;piano web application&#8221; and its &#8220;web audio interfacing&#8221; friend<\/li>\n<\/ul>\n<p> &#8230; but if you&#8217;ve not done this in the past, there is a fair bit to do to get up and running doing this.  In setting this up, we were stuck for a while with connections but blank console tab screens.  Why?  Well, you need both iPhone and MacBook Pro to have any outstanding operating system updates attended to.  Then, given that, we&#8217;d recommend following the excellent advice of <a target=_blank title='Useful link, thanks' href='https:\/\/www.lifewire.com\/activate-the-debug-console-in-safari-445798'>How to Activate the iPhone Debug Console<\/a>, thanks &#8230;<\/p>\n<p>On the iPhone (setting up wise) &#8230;<\/p>\n<blockquote cite='https:\/\/www.lifewire.com\/activate-the-debug-console-in-safari-445798'>\n<ol>\n<li>Tap the Settings icon on the iPhone Home screen.<\/li>\n<li>Scroll down until you reach Safari and tap on it to open the screen that contains everything related to the Safari web browser on your iPhone, iPad, or iPod touch.<\/li>\n<li>Scroll to the bottom of the screen and tap Advanced menu.<\/li>\n<li>Toggle the slider next to Web Inspector to the On position.<\/li>\n<\/ol>\n<\/blockquote>\n<p>On the MacBook Pro (setting up wise) &#8230;<\/p>\n<blockquote cite='https:\/\/www.lifewire.com\/activate-the-debug-console-in-safari-445798'>\n<ol>\n<li>Click Safari in the menu bar and choose Preferences.<\/li>\n<li>Click the Advanced tab<\/li>\n<li>Select the box next to Show Develop menu in menu bar.<\/li>\n<li>Exit the settings window.<\/li>\n<li>Click Develop in the Safari menu bar and select Show Web Inspector.<\/li>\n<\/ol>\n<\/blockquote>\n<p> &#8230; and we&#8217;ve got for you some screenshots of our &#8220;goings on&#8221; sorting out our &#8220;piano web application&#8221; problems on mobile (at least iOS) platforms with today&#8217;s <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPhone\/iphone_macbook_lead_safari_web_inspector_debug.pdf\">PDF &#8220;stream of consciousness&#8221; presentation<\/a>.   We hope it helps you out, or gets you down the road of digging into an issue you have with an HTML web application on an iOS device.<\/p>\n<hr>\n<p id='html5wapmt'>Previous relevant <a target=_blank title='HTML5 Web Audio Piano Mobile Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-piano-mobile-tutorial\/'>HTML5 Web Audio Piano Mobile Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/piano.htm\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"HTML5 Web Audio Piano Mobile Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio_piano_iphone.jpg\" title=\"HTML5 Web Audio Piano Mobile Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">HTML5 Web Audio Piano Mobile Tutorial<\/p><\/div>\n<p>You guessed it!  The software integrations of yesterday&#8217;s <a title='HTML5 Web Audio Piano Tutorial' href='#html5wapt'>HTML5 Web Audio Piano Tutorial<\/a> had issues with the mobile platforms.  Do fish swim?  Do axolotl have two L&#8217;s and two O&#8217;s?  Yes, yes and yes.<\/p>\n<p>With our iPad and iPhone testing (and we&#8217;ll go more into that tomorrow) we found timing issues as to when exactly to call that window onload <i>init<\/i> function.  Which beggars the question, being that <i>window<\/i> and <i>document<\/i> are two different objects of a webpage <a target=_blank title=\"is window onload the same as document body onload?\" href=\"https:\/\/www.google.com\/search?q=is+window+onload+the+same+as+document+body+onload&#038;rlz=1C5CHFA_enAU832AU832&#038;oq=is+window+onload+the+same+as+document+body+onload&#038;aqs=chrome..69i57j33.11984j0j4&#038;sourceid=chrome&#038;ie=UTF-8\">&#8220;is window onload the same as document body onload?&#8221;<\/a>  We&#8217;d always <a target=_blank title='?' href='https:\/\/www.quotes.net\/mquote\/915087'>assume<\/a>d so, and trying &#8220;not to be in that bubble of our own existence&#8221;, did read at least the first link of that previous <a target=_blank title='Google' href='http:\/\/www.google.com'>Google search<\/a> to feel appeased.  It seems so &#8230; but we digress.<\/p>\n<p>Why is this timing important?  As we&#8217;ve said many times, <a target=_blank title='Apple' href='http:\/\/apple.com'>Apple<\/a>&#8216;s iOS (mobile operating system) and audio are super sensitive to trying to eradicate &#8220;sounds on (webpage) load&#8221;, we take it, and want to only allow for audio easily via a &#8220;touch&#8221; event off a button (made by a human <font size=1>&#8230; and, we hope, all axolotls<\/font>), that&#8217;s why.  Get the timing wrong, and we weren&#8217;t, on mobile platforms, creating the buttons needed to touch in order to make the 87 different notes on our piano.<\/p>\n<p>This work is accessible via <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/piano.html----GETME\" title=\"piano.htm\">the changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/piano.html----GETME\" title=\"piano.htm\">piano.htm<\/a>&#8216;s <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/piano.htm\" title=\"Click picture\">piano web application<\/a> calling on <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html--------GETME\" title=\"web_audio.htm\">the changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html--------GETME\" title=\"web_audio.htm\">web_audio.htm<\/a> (Web Audio API interfacer) in an iframe.<\/p>\n<hr>\n<p id='html5wapt'>Previous relevant <a target=_blank title='HTML5 Web Audio Piano Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-piano-tutorial\/'>HTML5 Web Audio Piano Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/piano.htm\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"HTML5 Web Audio Piano Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio_piano.jpg\" title=\"HTML5 Web Audio Piano Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">HTML5 Web Audio Piano Tutorial<\/p><\/div>\n<p>We find software integration interesting yet challenging, and the integration of &#8230;<\/p>\n<ul>\n<li><a title='HTML5 Web Audio Mobile Tutorial' href='#html5wamt'>HTML5 Web Audio Mobile Tutorial<\/a>&#8216;s inhouse Web Audio API interfacer &#8230; to the piano playing web application of &#8230;<\/li>\n<li><a title='Piano Playing Web Application Mobile Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/piano-playing-web-application-mobile-tutorial\/'>Piano Playing Web Application Mobile Tutorial<\/a><\/li>\n<\/ul>\n<p> &#8230; in these early days, before we give up on the mobile platform issue compromises we have so far, is no exception.<\/p>\n<p>In broad brush terms we &#8230;<\/p>\n<ul>\n<li>call from <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/piano.html---GETME\" title=\"piano.htm\">the changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/piano.html---GETME\" title=\"piano.htm\">piano.htm<\/a>&#8216;s <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/piano.htm\" title=\"Click picture\">piano web application<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html-------GETME\" title=\"web_audio.htm\">the changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html-------GETME\" title=\"web_audio.htm\">web_audio.htm<\/a> (Web Audio API interfacer) in an iframe as per (the HTML) &#8230;<br \/>\n<code><br \/>\n&lt;iframe class=ask title='versus Audio Web' frameborder=0 scrolling='no' style='overflow:hidden;background-color:orange;display:inline-block;width:500px;height:28px;max-height:28px;' width=500 height=28 src='web_audio.htm?vscaseyrule=y'&gt;&lt;\/iframe&gt;<br \/>\n<\/code><br \/>\n &#8230; and so in &#8230;\n<\/li>\n<li>web_audio.htm (it) creates up above all else in the top left corner of its webpage, on detecting this call above &#8230;<br \/>\n<code><br \/>\n&lt;script type='text\/javascript'&gt;<br \/>\nif ((location.search.split('vscaseyrule=')[1] ? (' ' + decodeURIComponent(location.search.split('vscaseyrule=')[1]).split('&')[0]) : '') != '') { \/\/navigator.userAgent.match(\/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile\/i)) {<br \/>\n  var hish='&lt;div class=parent id=dchoose style=\"font-size:26px;position:absolute;top:0px;left:0px;z-index:2001;display:inline-block;background-color:transparent;\"&gt;&lt;input class=child placeholder=\"CaseyRule\" title=\"versus Audio Web\" style=\"position:absolute;top:0px;left:0px;z-index:2001;display:inline-block;background-color:transparent;\" name=dlhuhb id=dlhuhb onchange=\"' + \"actedupon=true; this.visibility='visible'; parent.document.getElementById('conduit').value=' '; parent.document.getElementById('cmdconduit').value=' '; document.getElementById('dchoose').innerHTML='Web Audio'; \" + '\" onclick=\"actedupon=true; parent.document.getElementById(\"' + \"conduit\" + '\").value=String.fromCharCode(32); parent.document.getElementById(\"' + \"cmdconduit\" + '\").value=String.fromCharCode(32);  setTimeout(init,1500);\" onblur=\"actedupon=true; parent.document.getElementById(\"' + \"conduit\" + '\").value=String.fromCharCode(32); parent.document.getElementById(\"' + \"cmdconduit\" + '\").value=String.fromCharCode(32); this.value=' + \"'Web Audio';\"  + ' setTimeout(init,1800);\" ontouchstart=\" parent.document.getElementById(\"' + \"conduit\" + '\").value=String.fromCharCode(32); parent.document.getElementById(\"' + \"cmdconduit\" + '\").value=String.fromCharCode(32); setTimeout(init,500);\" list=\"modes\" name=\"modes\"&gt;&lt;datalist id=\"modes\"&gt;&lt;option value=\"CaseyRule\"&gt;&lt;option value=\"Audio Web\"&gt;&lt;\/datalist&gt;&lt;\/div&gt;';<br \/>\n  if (1 == 1 || navigator.userAgent.match(\/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile\/i)) {<br \/>\n    hish='&lt;div class=parent id=dchoose style=\"font-size:26px;position:absolute;top:0px;left:0px;z-index:2001;display:inline-block;background-color:transparent;\"&gt;CaseyRule versus &lt;button style=display:inline-block;background-color:red; id=dlhuhb onmousedown=\"' + \"actedupon=true; parent.document.getElementById('conduit').value=' '; parent.document.getElementById('cmdconduit').value=' ';  this.innerHTML=''; setTimeout(init,500);\" + '\" ontouchstart=\"' + \"actedupon=true; parent.document.getElementById('conduit').value=' '; parent.document.getElementById('cmdconduit').value=' ';  setTimeout(init,200);\" + '\"&gt;Web Audio&lt;\/button&gt;&lt;\/div&gt;';<br \/>\n  }<br \/>\n  document.write(hish);<br \/>\n}<br \/>\n&lt;\/script&gt;<br \/>\n<\/code><br \/>\n &#8230; a default piano &#8220;CaseyRule&#8221; mode of use piece of text, followed by a HTML button element &#8220;Web Audio&#8221; to switch to that &#8230; and back at &#8230;\n<\/li>\n<li>piano.htm detects a &#8220;Web Audio&#8221; mode of use when that &#8230;<br \/>\n<code><br \/>\n  if (document.getElementById('conduit').value != '') {<br \/>\n  document.getElementById('cmdconduit').value+=\"parent.document.getElementById('iaudio\" + caboffrank + \"').src='\" + what + \"'; \";<br \/>\n  document.getElementById('conduit').value+=what.replace('\/','').replace('.','') + ' ';<br \/>\n  } else {<br \/>\n  document.getElementById('iaudio' + caboffrank).src=what;<br \/>\n  }<br \/>\n<\/code><br \/>\n &#8230; document.getElementById(&#8216;conduit&#8217;).value is not &#8221; because it is storing button press information for &#8230;\n<\/li>\n<li>web_audio.htm to play the audio off that button press via &#8230;<br \/>\n<code><br \/>\nfunction pianonoteplay(bo) {<br \/>\n  var ioth='' + eval('' + bo.title);<br \/>\n  var prefix=\"\";<br \/>\n  if (!nostop) { stopit(); } else { lastbo=null; }<br \/>\n  if (whichs == \"\") { whichs=\"\" + ioth;  }<br \/>\n  whichs=\"\" + eval(ioffs[eval(-1 + eval('' + ioth))] + eval(ioth));<br \/>\n  if (sourcep_valid()) { \/\/if (typeof sourcep !== 'undefined') {<br \/>\n   sourcep[eval(-1 + eval(whichs))]=true;<br \/>\n  } else {<br \/>\n   eval(\"source\" + whichs + \"p=true;\");<br \/>\n  }<br \/>\n  var sendb=(\"(\" + document.getElementById('startingin').value + \",\" + document.getElementById('startingat').value + \");\").replace(\"(,)\", \"(0)\").replace(\"(,\", \"(0,\").replace(\",)\", \",0)\");<br \/>\n  var suffix=(\"(\" + document.getElementById('startingin').value + \",\" + document.getElementById('startingat').value + \")\").replace(\"(,)\", \"\").replace(\"(0,0)\", \"\").replace(\"(0,)\", \"\").replace(\"(,0)\", \"\").replace(\"(,\", \",\").replace(\",)\", \"\").trim();<br \/>\n  if (source_valid()) { \/\/if (typeof source !== 'undefined') {<br \/>\n   if (fors.replace('0','') != '' && fors.indexOf('-') == -1) {<br \/>\n   source[eval(-1 + eval(whichs))].start(eval('0' + document.getElementById('startingin').value), eval('0' + document.getElementById('startingat').value), eval('' + dura(document.getElementById('duration').value,lastbo).split(';')[0].split(':')[eval(-1 + dura(document.getElementById('duration').value,lastbo).split(';')[0].split(':').length)].split('.')[0].split(' ')[0]));<br \/>\n   } else if (document.getElementById('duration').value.replace('0','') != '') {<br \/>\n   source[eval(-1 + eval(whichs))].start(eval('0' + document.getElementById('startingin').value), eval('0' + document.getElementById('startingat').value), eval('' + dura(document.getElementById('duration').value,lastbo).split(';')[0].split(':')[eval(-1 + dura(document.getElementById('duration').value,lastbo).split(';')[0].split(':').length)].split('.')[0].split(' ')[0]));<br \/>\n   } else {<br \/>\n   source[eval(-1 + eval(whichs))].start(eval('0' + document.getElementById('startingin').value), eval('0' + document.getElementById('startingat').value));<br \/>\n   }<br \/>\n  } else {<br \/>\n   eval(\"source\" + whichs + \".start\" + dura(sendb,lastbo));<br \/>\n  }<br \/>\n  nostop=false;<br \/>\n  document.getElementById('startingat').value='';<br \/>\n  document.getElementById('startingin').value='';<br \/>\n  document.getElementById('loop1').checked=false;<br \/>\n  document.getElementById('loop2').checked=false;<br \/>\n  checknext();<br \/>\n  ioffs[eval(-1 + eval(ioth))]+=four;<br \/>\n  ioffset=ioffs[eval(-1 + eval(ioth))];<br \/>\n  if (sourcep_valid()) { \/\/if (typeof sourcep !== 'undefined') {<br \/>\n   sourcep[eval(-1 + eval(ioffset + eval(ioth)))]=false;<br \/>\n  } else {<br \/>\n   eval(\"source\" + eval(ioffset + eval(ioth)) + \"p=false;\");<br \/>\n  }<br \/>\n  if (source_valid()) { \/\/if (typeof source !== 'undefined') {<br \/>\n   source[eval(-1 + eval(ioffset + eval(ioth)))] = context.createBufferSource();<br \/>\n   source[eval(-1 + eval(ioffset + eval(ioth)))].buffer = sb[eval(-1 + eval(ioth))];<br \/>\n   source[eval(-1 + eval(ioffset + eval(ioth)))].connect(context.destination);<br \/>\n  } else {<br \/>\n   eval(\"source\" + eval(ioffset + eval(ioth)) + \" = context.createBufferSource(); source\" + eval(ioffset + eval(ioth)) + \".buffer = sb[\" + eval(-1 + eval(ioth)) + \"];  source\" + eval(ioffset + eval(ioth)) + \".connect(context.destination); \");<br \/>\n  }<br \/>\n}<br \/>\n<\/code>\n<\/li>\n<\/ul>\n<p> &#8230; for starters.<\/p>\n<p>Expecting a sound tonality difference between the methods?  No, a computer creates the sound the same way via the same sound frequency, and if the response time is reasonable we couldn&#8217;t hear big rhythm changes that you might expect with the parent\/child &#8220;chatter&#8221; required for all this.<\/p>\n<p>Feel free to try your piano playing scales and arpeggios and chords with today&#8217;s more integrated <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/piano.htm\" title=\"Click picture\">live run<\/a> link.<\/p>\n<hr>\n<p id='html5wamt'>Previous relevant <a target=_blank title='HTML5 Web Audio Mobile Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-mobile-tutorial\/'>HTML5 Web Audio Mobile Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.htm\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"HTML5 Web Audio Mobile Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio_mobile.jpg\" title=\"HTML5 Web Audio Mobile Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">HTML5 Web Audio Mobile Tutorial<\/p><\/div>\n<p>There is another two pronged improvement approach again today building on <a title='HTML5 Web Audio Overlay Tutorial' href='#html5waot'>HTML5 Web Audio Overlay Tutorial<\/a>&#8216;s two pronged approach to the previous two pronged approach &#8230; which makes for a great fork for spaghetti <font size=1>but we digress<\/font> &#8230; the prongs today being &#8230;<\/p>\n<ul>\n<li>first, and like yesterday, allow for clientside HTML to do what serverside PHP usually does for us &#8230; handle large amounts of data as PHP can do using its $_POST[] approach &#8230; we&#8217;re still calling &#8220;Overlay Iframe Remembering&#8221; &#8230; and add to &#8230;\n<ol>\n<li>child iframe src= mode of use &#8230; but also with, new to today &#8230;<\/li>\n<li>child <a target=_blank title='HTML iframe element information from w3schools' href='http:\/\/www.w3schools.com\/tags\/tag_iframe.asp'>iframe<\/a> srcdoc= mode of use<\/li>\n<\/ol>\n<p> &#8230; because <font size=1>(am not absolutely sure why as yet but)<\/font> it solves the problem with &#8230;<br \/>\n &#8230; non-mobile\/Safari\/fill in &#8220;Audio Content&#8221; form\/including a Duration\/click &#8220;Web Audio Run&#8221; button &#8230;<br \/>\n &#8230; didn&#8217;t automatically start any audio, though other non-mobile web browsers do &#8230;<br \/>\n &#8230; and as you may imagine this needs some delimitation explanations that <b>show below<\/b> &#8230;<br \/>\n<code><br \/>\nfunction takealook(fo) {<br \/>\n  var noneed=true;<br \/>\n  var htmlis='';<br \/>\n  var nsuffix='';<br \/>\n  if (document.getElementById('url1').value.length &gt; 500) { noneed=false; }<br \/>\n  if (document.getElementById('url2').value.length &gt; 500) { noneed=false; }<br \/>\n  if (document.getElementById('url3').value.length &gt; 500) { noneed=false; }<br \/>\n  if (document.getElementById('url4').value.length &gt; 500) { noneed=false; }<br \/>\n  if (document.getElementById('durationget').value.length &gt; 0) { nsuffix='&notoka=secret'; noneed=false; } else { isrc=' src='; }<br \/>\n  if (source_valid()) {<br \/>\n    if (noneed) { return true; }<br \/>\n    if (isrc == ' srcdoc=') {<br \/>\n    if (navigator.userAgent.match(\/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile\/i)) {<br \/>\n    document.getElementById('huhb').style.display='inline-block';<br \/>\n    document.getElementById('diframe').innerHTML=\"&lt;iframe id=myi style='opacity:1.0;position:absolute;top:0px;left:0px;z-index:-\" + eval(1 + eval('0' + zi)) + \";width:100%;height:100vh;' srcdoc=&gt;&lt;\/iframe&gt;\";<br \/>\n    } else {<br \/>\n    document.getElementById('diframe').innerHTML=\"&lt;iframe id=myi style='opacity:1.0;position:absolute;top:0px;left:0px;z-index:-\" + eval(1 + eval('0' + zi)) + \";width:100%;height:100vh;' srcdoc=&gt;&lt;\/iframe&gt;\";<br \/>\n    }<br \/>\n    if (documentURL.indexOf('#') == -1) { document.getElementById('divbody').style.opacity='1.0'; }<br \/>\n    <b>document.getElementById('myi').srcdoc='&lt;!doctype html&gt;&lt;html&gt;&lt;head&gt;' + document.head.innerHTML.replace(\/document\\.URL\/g,\"'\" + documentURL.split('#')[0].split('?')[0] + \"?zi=\" + eval(1 + eval('0' + zi)) + nsuffix + \"&notoka=\" + encodeURIComponent(notoka.trim()) + \"'\").replace(\/\\'0\\.2\\'\/g,\"'1.0'\") + '&lt;\/head&gt;&lt;body&gt;' + document.body.innerHTML.replace(\/document\\.URL\/g,\"'\" + documentURL.split('#')[0].split('?')[0] + \"?zi=\" + eval(1 + eval('0' + zi)) + nsuffix + \"&notoka=\" + encodeURIComponent(notoka.trim()) + \"'\").replace(\/\\'0\\.2\\'\/g,\"'1.0'\") + '&lt;\/body&gt;&lt;\/html&gt;';<\/b><br \/>\n    } else {<br \/>\n    if (documentURL.indexOf('#') == -1) { document.getElementById('divbody').style.opacity='0.2'; }<br \/>\n    document.getElementById('diframe').innerHTML=\"&lt;iframe style='position:absolute;top:0px;left:0px;z-index:\" + eval(1 + eval('0' + zi)) + \";width:100%;height:100vh;' src='\" + documentURL.split('#')[0].split('?')[0] + \"?zi=\" + eval(1 + eval('0' + zi)) + nsuffix + \"'&gt;&lt;\/iframe&gt;\";<br \/>\n    }<br \/>\n  } else {<br \/>\n    if (notoka.trim().toLowerCase() == 'secret') { noneed=false; }<br \/>\n    if (noneed) { return true; }<br \/>\n    if (isrc == ' srcdoc=') {<br \/>\n    if (navigator.userAgent.match(\/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile\/i)) {<br \/>\n    document.getElementById('huhb').style.display='inline-block';<br \/>\n    document.getElementById('diframe').innerHTML=\"&lt;iframe id=myi style='opacity:1.0;position:absolute;top:0px;left:0px;z-index:-\" + eval(1 + eval('0' + zi)) + \";width:100%;height:100vh;' srcdoc=&gt;&lt;\/iframe&gt;\";<br \/>\n    } else {<br \/>\n    document.getElementById('diframe').innerHTML=\"&lt;iframe id=myi style='opacity:1.0;position:absolute;top:0px;left:0px;z-index:-\" + eval(1 + eval('0' + zi)) + \";width:100%;height:100vh;' srcdoc=&gt;&lt;\/iframe&gt;\";<br \/>\n    }<br \/>\n    if (documentURL.indexOf('#') == -1) { document.getElementById('divbody').style.opacity='1.0'; }<br \/>\n    <b>document.getElementById('myi').srcdoc='&lt;!doctype html&gt;&lt;html&gt;&lt;head&gt;' + document.head.innerHTML.replace(\/document\\.URL\/g,\"'\" + documentURL.split('#')[0].split('?')[0] + \"?zi=\" + eval(1 + eval('0' + zi)) + \"&notoka=\" + encodeURIComponent(notoka.trim()) + \"'\").replace(\/\\'0\\.2\\'\/g,\"'1.0'\") + '&lt;\/head&gt;&lt;body&gt;' + document.body.innerHTML.replace(\/document\\.URL\/g,\"'\" + documentURL.split('#')[0].split('?')[0] + \"?zi=\" + eval(1 + eval('0' + zi)) + \"&notoka=\" + encodeURIComponent(notoka.trim()) + \"'\").replace(\/\\'0\\.2\\'\/g,\"'1.0'\") + '&lt;\/body&gt;&lt;\/html&gt;';<\/b><br \/>\n    } else {<br \/>\n    if (documentURL.indexOf('#') == -1) { document.getElementById('divbody').style.opacity='0.2'; }<br \/>\n    document.getElementById('diframe').innerHTML=\"&lt;iframe style='position:absolute;top:0px;left:0px;z-index:\" + eval(1 + eval('0' + zi)) + \";width:100%;height:100vh;' src='\" + documentURL.split('#')[0].split('?')[0] + \"?zi=\" + eval(1 + eval('0' + zi)) + \"&notoka=\" + encodeURIComponent(notoka.trim()) + \"'&gt;&lt;\/iframe&gt;\";<br \/>\n    }<br \/>\n  }<br \/>\n  return false;<br \/>\n}<br \/>\n<\/code><br \/>\n &#8230; adding another option to &#8220;Overlay Iframe Remembering&#8221; types of solutions, we figure &#8230; cute in the sense that all this is clientside HTML\/Javascript\/CSS<\/li>\n<p> &#8230; as per <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html-----GETME\" title=\"web_audio.htm\">these interim changes<\/a><\/p>\n<li>mobile platform considerations (in our tests of iOS iPad and iPhone) &#8230;\n<ol>\n<li>allowing for a button press &#8220;touch&#8221; event (&#8220;touchstart&#8221; for us, but read somewhere that they liked &#8220;touchend&#8221;) to trigger the AudioContext setup<\/li>\n<li>taking away the &#8220;capture&#8221; property of our browser buttons so that the mobile platform user can browse for an existant media file or capture that media<\/li>\n<li>we try to allow video media to be played in that video element should the user choose a video media file as their audio media choice which tends to be the way for the &#8220;capture&#8221; property of a mobile user input type=file browser button<\/li>\n<\/ol>\n<p> &#8230; as per <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html------GETME\" title=\"web_audio.htm\">these changes<\/a>\n<\/li>\n<\/ul>\n<p>Did you get from the code snippets how this &#8220;Overlay Iframe Remembering&#8221; works by storing the large amounts of data in an overlayed &#8220;layer&#8221; of webpage, both webpage layers &#8220;clientside&#8221; by nature and available datawise to each other in a parent\/child (layer1WebpageParent\/layer2OverlayedIframeWebpageChild) arrangement, that iframe being populated via a src= scenario getting the &#8220;overlay&#8221; to populate itself or help that &#8220;overlay&#8221; along <font size=1>(perhaps it&#8217;s that period after lunch digesting the caviar?!)<\/font> by supplying its content via srcdoc= usage?  Again, perhaps it is easier to see it in action at <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.htm\" title=\"Click picture\">this live run<\/a> link.<\/p>\n<hr>\n<p id='html5waot'>Previous relevant <a target=_blank title='HTML5 Web Audio Overlay Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-overlay-tutorial\/'>HTML5 Web Audio Overlay Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.htm\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"HTML5 Web Audio Overlay Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio_overlay.jpg\" title=\"HTML5 Web Audio Overlay Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">HTML5 Web Audio Overlay Tutorial<\/p><\/div>\n<p>Again, in building on yesterday&#8217;s <a title='HTML5 Web Audio Duration Tutorial' href='#html5wadt'>HTML5 Web Audio Duration Tutorial<\/a> two pronged approach, we have another one today, those approaches involving &#8230;<\/p>\n<ul>\n<li>first allow for clientside HTML to do what serverside PHP usually does for us &#8230; handle large amounts of data as PHP can do using its $_POST[] approach &#8230; we&#8217;re going to call &#8220;Overlay Iframe Remembering&#8221; &#8230; whereby the\n<ol>\n<li>navigational form gets a new <i> id=waform onsubmit=&#8217;return takealook(this);&#8217;<\/i> &#8230;<br \/>\n<code><br \/>\nfunction takealook(fo) {<br \/>\n  var noneed=true;<br \/>\n  var nsuffix='';<br \/>\n  if (document.getElementById('url1').value.length &gt; 500) { noneed=false; }<br \/>\n  if (document.getElementById('url2').value.length &gt; 500) { noneed=false; }<br \/>\n  if (document.getElementById('url3').value.length &gt; 500) { noneed=false; }<br \/>\n  if (document.getElementById('url4').value.length &gt; 500) { noneed=false; }<br \/>\n  if (document.getElementById('durationget').value.length &gt; 0) { nsuffix='&notoka=secret'; noneed=false; }<br \/>\n  if (source_valid()) {<br \/>\n    if (noneed) { return true; }<br \/>\n    document.getElementById('divbody').style.<font color=red>opacity<\/font>='0.2';<br \/>\n    document.getElementById('diframe').innerHTML=\"&lt;iframe style='<font color=blue>position:absolute;top:0px;left:0px;<\/font><font color=orange>z-index<\/font>:\" + eval(1 + eval('0' + zi)) + \";width:100%;height:100vh;' src='\" + document.URL.split('#')[0].split('?')[0] + \"?zi=\" + eval(1 + eval('0' + zi)) + nsuffix + \"'&gt;&lt;\/iframe&gt;\";<br \/>\n  } else {<br \/>\n    if (notoka.trim().toLowerCase() == 'secret') { noneed=false; }<br \/>\n    if (noneed) { return true; }<br \/>\n    document.getElementById('divbody').style.<font color=red>opacity<\/font>='0.2';<br \/>\n    document.getElementById('diframe').innerHTML=\"&lt;iframe style='<font color=blue>position:absolute;top:0px;left:0px;<\/font><font color=orange>z-index<\/font>:\" + eval(1 + eval('0' + zi)) + \";width:100%;height:100vh;' src='\" + document.URL.split('#')[0].split('?')[0] + \"?zi=\" + eval(1 + eval('0' + zi)) + \"&notoka=\" + encodeURIComponent(notoka.trim()) + \"'&gt;&lt;\/iframe&gt;\";<br \/>\n  }<br \/>\n  return false;<br \/>\n}<br \/>\n<\/code><br \/>\n &#8230; where if <i>noneed<\/i> ends up as <i>false<\/i> we perform some overlay f<font color=red>av<\/font>o<font color=blue>ur<\/font>i<font color=orange>te<\/font>s &#8230; building on &#8230;\n<\/li>\n<li>textbox HTML design changes from &#8230;<br \/>\n<code><br \/>\n&lt;input style='display:inline-block;background-color:#f0f0f0;' type=text name=url2 title='Audio URL 2' value='.\/one_to_fiftynine.m4a'&gt;&lt;\/input&gt;<br \/>\n<\/code><br \/>\n &#8230; to &#8230;<br \/>\n<code><br \/>\n&lt;input data-id=url2 onblur=\"document.getElementById(this.getAttribute('data-id')).value=this.value;\" style='display:inline-block;background-color:#f0f0f0;' type=text name=url2 title='Audio URL 2' value='.\/one_to_fiftynine.m4a'&gt;&lt;\/input&gt;<br \/>\n&lt;div id=dform style='display:none;'&gt;&lt;\/div&gt;<br \/>\n&lt;div id=diframe&gt;&lt;\/div&gt;<br \/>\n<\/code><br \/>\n &#8230; that makes the document.body onload logic below be useful for the context of that onsubmit form logic above &#8230;\n<\/li>\n<li>\n<code><br \/>\n   document.getElementById('dform').innerHTML=document.getElementById('waform').innerHTML.replace(\/\\ data\\-id=\/g, ' id=').replace(\/\\ onblur=\/g, ' data-onblur=');<br \/>\n<\/code>\n<\/li>\n<\/ol>\n<p> &#8230; as per <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html---GETME\" title=\"web_audio.htm\">these interim changes<\/a> &#8230; then in the context of those large amounts of data possibly coming from &#8230;\n<\/li>\n<li>like with the recent <a target=_blank title='Video via Canvas File API Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/video-via-canvas-file-api-tutorial\/'>Video via Canvas File API Tutorial<\/a> &#8230;<br \/>\n<blockquote cite='https:\/\/www.rjmprogramming.com.au\/ITblog\/video-via-canvas-file-api-tutorial\/'>\n<p> &#8230; we see for web applications, two primary source &#8220;partitions&#8221;, those being &#8230;<\/p>\n<p><\/p>\n<ul>\n<li>around the &#8220;net&#8221; (in the <i>server<\/i> wooooooorrrrrlllllld, in the public areas of the Internet, which are not in &#8220;the dark web&#8221;, that is) via an absolute URL (to the same domain or beyond) and\/or relative URL (in relation to the URL &#8220;home&#8221; place on the web server of the same domain as where you launched it &#8230; which we catered for yesterday, though quietly we&#8217;d have allowed absolute URLs too, it&#8217;s just that cross-domain restrictions make us shy about publicizing that) &#8230; versus &#8230;<\/li>\n<li>on the <i>client<\/i> computer (or device)<\/li>\n<\/ul>\n<p><\/p>\n<p> &#8230; and, yes, for all those who guessed we&#8217;d try to cater for image and\/or video data coming from this <i>client<\/i> source, you are correct &#8230;<\/p>\n<\/blockquote>\n<p> &#8230; media file browsing, via the wonderful <a target=_blank title='Great link' href='http:\/\/www.html5rocks.com\/en\/tutorials\/file\/dndfiles\/'>File API<\/a>, additional functionality as per <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html----GETME\" title=\"web_audio.htm\">these changes<\/a> to  <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html----GETME\" title=\"web_audio.htm\">web_audio.htm<\/a>\n<\/li>\n<\/ul>\n<p>Did you get from the code snippets how this &#8220;Overlay Iframe Remembering&#8221; works by storing the large amounts of data in an overlayed &#8220;layer&#8221; of webpage, both webpage layers &#8220;clientside&#8221; by nature and available datawise to each other in a parent\/child (layer1WebpageParent\/layer2OverlayedIframeWebpageChild) arrangement?  Perhaps it is easier to see it in action at <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.htm\" title=\"Click picture\">this live run<\/a> link.<\/p>\n<hr>\n<p id='html5wadt'>Previous relevant <a target=_blank title='HTML5 Web Audio Duration Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-duration-tutorial\/'>HTML5 Web Audio Duration Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"HTML5 Web Audio Duration Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio_more.jpg\" title=\"HTML5 Web Audio Duration Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">HTML5 Web Audio Duration Tutorial<\/p><\/div>\n<p>In building on yesterday&#8217;s <a title='HTML5 Web Audio Primer Tutorial' href='#html5wapt'>HTML5 Web Audio Primer Tutorial<\/a> we adopted a two pronged approach, that being &#8230;<\/p>\n<ul>\n<li>first allow for the reduction of use of Javascript <a target=_blank href='http:\/\/www.w3schools.com\/jsref\/jsref_eval.asp' title='Javascript eval'>eval<\/a> involving statements that assign values (ie. eval statement contains an &#8220;=&#8221; sign) (but will continue on with it helping out with some mathematics) &#8230; in favour of using arrays instead &#8230;<br \/>\n<code><br \/>\nvar source=[];<br \/>\nvar sourcep=[];<br \/>\nvar notoka=location.search.split('notoka=')[1] ? (\" \" + decodeURIComponent(location.search.split('notoka=')[1]).split('&')[0]) : \"\";<br \/>\nif (notoka == \"\") {<br \/>\n  for (var iii=1; iii&lt;=4; iii++) {<br \/>\n    source.push(null);<br \/>\n    sourcep.push(false);<br \/>\n  }<br \/>\n}<br \/>\n<br \/>\nfor (var ii=5; ii&lt;500; ii++) {<br \/>\nif (source_valid()) { \/\/if (typeof source !== 'undefined') {<br \/>\n source.push(null);<br \/>\n if (sourcep_valid()) { \/\/if (typeof sourcep !== 'undefined') {<br \/>\n  sourcep.push(false);<br \/>\n }<br \/>\n } else {<br \/>\n eval(\"var source\" + ii + \" = null;\"); \/\/context.createBufferSource();<br \/>\n }<br \/>\n}<br \/>\n<br \/>\nfunction source_valid() {<br \/>\n if (typeof source !== 'undefined') {<br \/>\n   if (source.length &gt;= 4) { return true; }<br \/>\n }<br \/>\n return false;<br \/>\n}<br \/>\n<br \/>\nfunction sourcep_valid() {<br \/>\n if (typeof sourcep !== 'undefined') {<br \/>\n   if (sourcep.length &gt;= 4) { return true; }<br \/>\n }<br \/>\n return false;<br \/>\n}<br \/>\n<\/code><br \/>\n &#8230; as per <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html-GETME\" title=\"web_audio.html\">these interim changes<\/a> &#8230; then go on to &#8230;<\/li>\n<li>other changes as per &#8230;\n<ol>\n<li>add duration as a very useful third parameter &#8230;<br \/>\n<blockquote><p>\nSeconds &#8230; optionally follow by ; sets of ButtonNumber1to4:StartingAt=[0]:StartingIn=[0]:Loop=[false]:Duration=[0]\n<\/p><\/blockquote>\n<p> &#8230; to <a target=_blank href='https:\/\/www.html5rocks.com\/en\/tutorials\/webaudio\/intro\/' title='Getting Started with Web Audio API'>Web Audio class &#8220;start&#8221; method<\/a> &#8230; the use of which is the final piece in a puzzle that allows us to &#8230;<\/li>\n<li>schedule an execution run of button presses to play Audio ahead of time &#8230; because with a duration we can piggy back the audios (so be able to synchronize our efforts better) &#8230; and we also &#8230;<\/li>\n<li>open the Audio content up to the &#8220;server&#8221; woooorrrrlllld (via the &#8220;reveal&#8221; friendly HTML <a target=_blank title='HTML details tag information from w3schools' href='https:\/\/www.w3schools.com\/tags\/tag_details.asp'>details<\/a>\/summary element combination) by allowing the user to specify their own 4 audio URLs (and one synchronized video one) along with 4 button labels presented in an HTML form method=GET to renavigate with this user supplied content back to the body onload scenario<\/li>\n<\/ol>\n<p> &#8230; to arrive at this <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html--GETME\" title=\"web_audio.html\">finally changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html--GETME\" title=\"web_audio.html\">web_audio.html<\/a>\n<\/li>\n<\/ul>\n<p> &#8230; that we welcome you to try at this <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html\" title=\"Click picture\"l>live run<\/a> link.<\/p>\n<hr>\n<p id='html5wapt'>Previous relevant <a target=_blank title='HTML5 Web Audio Primer Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-primer-tutorial\/'>HTML5 Web Audio Primer Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"HTML5 Web Audio Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.jpg\" title=\"HTML5 Web Audio Primer Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">HTML5 Web Audio Primer Tutorial<\/p><\/div>\n<p>As an audio\/video synchronization alternative to the techniques used in <a target=_blank title='Mac OS X Text to English Speech Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/mac-os-x-text-to-english-speech-primer-tutorial\/'>Mac OS X Text to English Speech Primer Tutorial<\/a>, today, we involve the great Web Audio API functionality introduced with HTML5 and &#8220;starring&#8221; in HTML5 Rocks&#8217;s <a target=_blank href='https:\/\/www.html5rocks.com\/en\/tutorials\/webaudio\/intro\/' title='Getting Started with Web Audio API'>Getting Started with Web Audio API<\/a> great advice on this subject.<\/p>\n<p>We start down this long road, we suspect, being able to &#8230;<\/p>\n<ul>\n<li>set up the audio playing of four separate audio sources (some featuring in <a title='Spliced Audio Number Genericization Tutorial' href='#sangt'>Spliced Audio Number Genericization Tutorial<\/a>) &#8230; where &#8230;<\/li>\n<li>one, with its default configuration, synchronizes with an apt video media play<\/li>\n<li>allow looping<\/li>\n<li>allow for &#8220;start at&#8221; seconds<\/li>\n<li>allow for &#8220;start in&#8221; seconds<\/li>\n<\/ul>\n<p> &#8230; on a first draft HTML and Javascript and CSS <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html_GETME\" title=\"web_audio.html\">web_audio.html<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/web_audio.html\" title=\"Click picture\">live run<\/a> link.<\/p>\n<p>We hope you hang around on our road trip with this topic.<\/p>\n<hr>\n<p id='sangt'>Previous relevant <a target=_blank title='Spliced Audio Number Genericization Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/spliced-audio-number-genericization-tutorial\/'>Spliced Audio Number Genericization Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/audio_1_59.htm?showform=on\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Spliced Audio Number Genericization Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/audio_numbers_genericization.jpg\" title=\"Spliced Audio Number Genericization Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">Spliced Audio Number Genericization Tutorial<\/p><\/div>\n<p>If you&#8217;ve completed a successful &#8220;proof of concept&#8221; stage to a project, it can be tempting at this early stage, even before applying it to the specific intended <i>software integration target<\/i>, to consider ways to &#8220;genericize&#8221; that application, and so it is for us, here, with yesterday&#8217;s <a title='Spliced Audio Number Announcements Tutorial' href='#sanat'>Spliced Audio Number Announcements Tutorial<\/a>, as shown below, that we feel this could come along to be applied for other purposes.  We have no doubt the exercise of doing this serves at least three good purposes &#8230;<\/p>\n<ol>\n<li>slow it down a bit before rushing to &#8220;software integrate&#8221;, as patience can be good here<\/li>\n<li>learn more about what&#8217;s possible, and what isn&#8217;t, to do with the scope of your planning and thinking<\/li>\n<li>other application may, too, benefit from this &#8220;early days&#8221; &#8220;genericization&#8221; of a potential plugin component piece of HTML and Javascript code<\/li>\n<\/ol>\n<p>In this early stage of &#8220;genericization&#8221; thoughts, we think that with our project we want to keep intact these ideas &#8230;<\/p>\n<ul>\n<li>there&#8217;ll be up to 3 &#8220;columns&#8221; of ideas to piece together an audio message from its constituent parts, like with those Sydney train platform announcements we&#8217;ve talked about before<\/li>\n<li>there&#8217;ll be 3 soundfiles mapped to most of the usage regarding these 3 &#8220;columns&#8221;<\/li>\n<li>there&#8217;ll be the possibility for silence to be an option in each &#8220;column&#8221;<\/li>\n<li>there&#8217;ll be the mechanism by which the user can define their own &#8220;Title&#8221; and &#8220;Subtitle&#8221; and 3 &#8220;column&#8221; headings themselves<\/li>\n<li>there&#8217;ll be 2 leftmost &#8220;columns&#8221; that define counting numbers whose ranges can be defined by the user, where, for now, the timing of sounds goes that sounds start at [number].4 seconds and plays for 1.5 seconds<\/li>\n<li>there&#8217;ll be minimum and maximum special case entries available for user definition in the leftmost &#8220;column&#8221; that calls on the fourth soundfile, where, for now, the timing of sounds goes that sounds start at 0 seconds and 2 seconds respectively and plays for 2 seconds<\/li>\n<li>there&#8217;ll be a minimum special case entry available for user definition in the middle &#8220;column&#8221; that calls on a sound from the third soundfile, where, for now, the timing of sounds goes that sounds start at 3.1 seconds and plays for 1.8 seconds<\/li>\n<li>there&#8217;ll be 1 rightmost &#8220;column&#8221; that can have three entries defined<\/li>\n<\/ul>\n<p>And that is as far as we go with &#8220;genericizations&#8221;, at this stage, with our project.<\/p>\n<p>In our experience, what Javascript function is a big friend of &#8220;genericization&#8221;?  We&#8217;d say Javascript <a target=_blank href='http:\/\/www.w3schools.com\/jsref\/jsref_eval.asp' title='Javascript eval'>eval<\/a> function is our favourite here.<\/p>\n<p>It&#8217;s funny to think that our HTML and Javascript and CSS <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/audio_1_59.html-GETME' title='audio_1_59.htm'>audio_1_59.htm<\/a>, vastly changed from yesterday as per <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/audio_1_59.html-GETME' title='audio_1_59.htm'>this link<\/a>, functions exactly the same in its default form, and you can continue to enjoy its accompanying <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/audio_1_59.htm' title='Click picture'>default live run<\/a> link, but it can, through the use of complex URLs (only, just at this early stage) be made to look quite different, with the same code, as you can see with this <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/audio_1_59.htm?showform=on' title='Click picture'>complex live run<\/a>.<\/p>\n<p>So, in summary, this leaves us with many more &#8220;live run&#8221; options, those being &#8230;<\/p>\n<ul>\n<li><a target=_blank title='Default live run' href='http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/audio_1_59.htm'>Default live run<\/a><\/li>\n<li><a target=_blank title='Default live run with form' href='http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/audio_1_59.htm?showform=on'>Default live run with form<\/a><\/li>\n<li><a target=_blank title='Different run scenario Counting Numbers to 100' href='http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/audio_1_59.htm?notAudio_Numbers=Counting+Numbers+to+100&#038;notHear_this____=Hear+your+number&#038;notHour=tens&#038;notMinute=digits&#038;notContext=&#038;soundpath=&#038;notmidnight=&#038;noth1=1&#038;noth11=9&#038;notmidday=&#038;noto_clock=0&#038;notm1=1&#038;notm59=9&#038;not=&#038;notam=&#038;notpm=&#038;notsoundfile1=one_to_fiftynine.m4a&#038;notsoundfile2=past_quarterto.m4a&#038;notsoundfile3=am_pm.m4a&#038;notsoundfile4=midnight_midday.m4a'>Different run scenario Counting Numbers to 100<\/a><\/li>\n<li><a target=_blank title='Different run scenario Hearts versus Counting Numbers to 100 with form' href='http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/audio_1_59.htm?notAudio_Numbers=Counting+Numbers+to+100&#038;notHear_this____=Hear+your+number&#038;notHour=tens&#038;notMinute=digits&#038;notContext=&#038;soundpath=&#038;notmidnight=&#038;noth1=1&#038;noth11=9&#038;notmidday=&#038;noto_clock=0&#038;notm1=1&#038;notm59=9&#038;not=&#038;notam=&#038;notpm=&#038;notsoundfile1=one_to_fiftynine.m4a&#038;notsoundfile2=past_quarterto.m4a&#038;notsoundfile3=am_pm.m4a&#038;notsoundfile4=midnight_midday.m4a&#038;showform=on'>Different run scenario Counting Numbers to 100 with form<\/a><\/li>\n<\/ul>\n<hr>\n<p id='sanat'>Previous relevant <a target=_blank title='Spliced Audio Number Announcements Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/spliced-audio-number-announcements-tutorial\/'>Spliced Audio Number Announcements Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/audio_1_59.html\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Spliced Audio Number Announcements Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/audio_numbers.jpg\" title=\"Spliced Audio Number Announcements Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">Spliced Audio Number Announcements Tutorial<\/p><\/div>\n<p>We&#8217;ve got a &#8220;proof of concept&#8221; tutorial for you today, because we&#8217;ve got an idea for something, as we said some time back at <a target=_blank title='Splicing Audio Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/splicing-audio-primer-tutorial\/'>Splicing Audio Primer Tutorial<\/a> &#8230; <\/p>\n<blockquote cite='https:\/\/www.rjmprogramming.com.au\/ITblog\/splicing-audio-primer-tutorial\/'><p>\nThe first was a simulation of those Sydney train public announcements where the timbre of the voice differs a bit between when they say &#8220;Platform&#8221; and the &#8220;6&#8221; (or whatever platform it is) that follows.  This is pretty obviously computer audio &#8220;bits&#8221; strung together &#8230; and wanted to get somewhere towards that capability.\n<\/p><\/blockquote>\n<p> &#8230; that will probably be <a target=_blank title=\"Blimmin' onbvious\" href='https:\/\/books.google.com.au\/books?id=h0mcBQAAQBAJ&#038;pg=PA76&#038;lpg=PA76&#038;dq=blimmin+obvious&#038;source=bl&#038;ots=_JyMS7qV49&#038;sig=zKzvLL-NYxPgBpSlBN9wkyoM5Nw&#038;hl=en&#038;sa=X&#038;ved=0ahUKEwiYmce8wpXPAhWDn5QKHc4pBSYQ6AEIOzAG#v=onepage&#038;q=blimmin%20obvious&#038;f=false'><i>blimmin&#8217; obvious<\/i><\/a> to you should you be a regular recent reader at this blog.<\/p>\n<p>Do you remember what we, here, see as a characteristic of &#8220;proof of concept&#8221; at <a target=_blank title='WordPress Is Mentioned By Navigation Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/wordpress-is-mentioned-by-code-download-navigation-tutorial\/'>WordPress Is Mentioned By Navigation Primer Tutorial<\/a> &#8230;<\/p>\n<blockquote cite='https:\/\/www.rjmprogramming.com.au\/ITblog\/wordpress-is-mentioned-by-code-download-navigation-tutorial\/'><p>\nTo us, a \u201cproof of concept\u201d is not much use if it is as involved as what it is trying to prove\n<\/p><\/blockquote>\n<p> &#8230; and do you remember how we observed at <a target=_blank title='Windows 10 Cortana Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/windows-10-cortana-primer-tutorial\/'>Windows 10 Cortana Primer Tutorial<\/a> &#8230;<\/p>\n<blockquote cite='https:\/\/www.rjmprogramming.com.au\/ITblog\/windows-10-cortana-primer-tutorial\/'><p>\n&#8230; because you can work Cortana without the voice recognition part, if you like, or if you have the urge to run for the nearest cupboard before being caught talking into a computer (microphone)\n<\/p><\/blockquote>\n<p>?  Well, today, we&#8217;d like you to be patient about the lack of audio quality with our home made audio (see excuse 2 above) bit we are mainly interested in &#8220;proof of concept&#8221; issues (see excuse 1 above).<\/p>\n<p>So what &#8220;ingredients&#8221; went into this &#8220;Audio Numbers&#8221; web application?  As we did in <a target=_blank href='https:\/\/www.rjmprogramming.com.au\/ITblog\/apple-ios-siri-audio-commentary-tutorial\/' title='Apple iOS Siri Audio Commentary Tutorial'>Apple iOS Siri Audio Commentary Tutorial<\/a> &#8230;<\/p>\n<blockquote cite='https:\/\/www.rjmprogramming.com.au\/ITblog\/apple-ios-siri-audio-commentary-tutorial\/'><p>\nHTML <a target=_blank title='HTML audio element information from w3schools' href='http:\/\/www.w3schools.com\/tags\/tag_audio.asp'>audio<\/a> elements that allow for an audio commentary of the 9 &#8220;subimages&#8221; &#8230; the content for which is derived on a Mac OS X by <a target=_blank title='QuickTime Player' href='https:\/\/support.apple.com\/downloads\/quicktime'>QuickTime Player<\/a>&#8216;s Audio Recording functionality, which we last talked about at this blog with <a target=_blank title='QuickTime Player Video Flickr Share Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/quicktime-player-video-flickr-share-primer-tutorial\/'>QuickTime Player Video Flickr Share Primer Tutorial<\/a>\n<\/p><\/blockquote>\n<p> &#8230; we do again today.  On doing this we realized the recordings were not loud enough, so started down the road of R&#038;D on this and got to the very useful <a target=_blank title='Very useful link, thanks' href='http:\/\/increase-audio-volume.blogspot.com.au\/2011\/03\/how-to-increase-audio-volume-video-avi.html?xl'>Increase Audio Volume<\/a> website tool that helped a little, and this manifests itself if\/when you run our <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/audio_1_59.html\" title='Click picture'>live run<\/a> today, that if you pick &#8220;minute&#8221; numbers less than or equal to &#8220;30&#8221; they are a better better in volume than others, with the &#8220;Trial Version&#8221; of this software helping you out with &#8220;half file&#8221; enhancements.  &#8220;Proof of concept&#8221;, remember?  And so the aspects you&#8217;d change for your own purposes, are &#8230;<\/p>\n<ol>\n<li>the content (and more than likely, names) of audio files mentioned below &#8230;<\/li>\n<li>arrays of audio files &#8230;<br \/>\n<code><br \/>\nvar audiomedia=[\"one_to_fiftynine.m4a\",\"past_quarterto.m4a\",\"am_pm.m4a\"];<br \/>\nvar midmedia=[\"midnight_midday.m4a\"];<br \/>\n<\/code><br \/>\n&#8230; and it should be noted here, that a separate file for each unique sound, could be a good alternative design, and would stop failures to do with the slow loading speed of the home web server causing audio misfiring &#8230; and would mean, below, that &#8220;astart&#8221; is always &#8220;0&#8221; and &#8220;delay&#8221; should be set to the audio object&#8217;s <i>duration<\/i> parameter\n<\/li>\n<li>var<font size=1>iables<\/font> <b>&#8220;astart&#8221;<\/b> and <b>&#8220;delay&#8221;<\/b> as per example &#8230;<br \/>\n<code><br \/>\n      } else if (thingis.toLowerCase().indexOf('clock') != -1) {<br \/>\n        oaudio.src=audiomedia[i];<br \/>\n        <b>astart=eval(\"3.1\");<br \/>\n        delay=1.8;<\/b><br \/>\n<\/code><br \/>\n&#8230; where &#8220;astart&#8221; reflects a start of play value and &#8220;delay&#8221; represents a length of play scenario in seconds, as we got going in the past when we presented <a title='Spliced Audio\/Video Overlay Position Tutorial' href='#savopt'>Spliced Audio\/Video Overlay Position Tutorial<\/a> as shown below, where you can read more about the HTML5 <a target=_blank title='HTML5 Audio objects information from w3schools' href='http:\/\/www.w3schools.com\/jsref\/dom_obj_audio.asp'>Audio objects<\/a> we used with this &#8220;proof of concept&#8221; project\n<\/li>\n<\/ol>\n<p>Please note with the recording of &#8220;one_to_fiftynine.m4a&#8221;, that records numbers from 1 to 59, via QuickTime Player, we relied on the recording timer, to time our number recording with a second of duration to make the HTML and Javascript coding a lot easier!<\/p>\n<p>So, as you can see, this is &#8220;proof of concept&#8221; preparation, and of you want to try it yourself, perhaps you&#8217;d like to start with a skeleton of today&#8217;s HTML and Javascript <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/audio_1_59.html_GETME\" title='audio_1_59.html'>audio_1_59.html<\/a> as a starting point?!<\/p>\n<hr>\n<p id='savopt'>Previous relevant <a target=_blank title='Spliced Audio\/Video Overlay Position Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/Spliced Audio\/Video Overlay Position Tutorial\/'>Spliced Audio\/Video Overlay Position Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.htm\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Spliced Audio\/Video Overlay Position Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audiovideo_position.jpg\" title=\"Spliced Audio\/Video Overlay Position Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">Spliced Audio\/Video Overlay Position Tutorial<\/p><\/div>\n<p>Today we&#8217;ve written a third draft of an HTML and Javascript web application that splices up to nine bits of audio or video or image input together, building on the previous <a title='Spliced Audio\/Video\/Image Overlay Tutorial' href='#saviot'>Spliced Audio\/Video\/Image Overlay Tutorial<\/a> as shown below, here, and that can take any of the forms &#8230;<\/p>\n<ul>\n<li>audio file &#8230; and less user friendly is &#8230;<\/li>\n<li>text that gets turned into speech via <a target=_blank title='Google Translate' href='http:\/\/translate.google.com'>Google Translate<\/a> (and user induced Text to Speech functionality), but needs your button presses<\/li>\n<li>video<\/li>\n<li>image &#8230; and background image for webpage<\/li>\n<\/ul>\n<p> &#8230; for either of the modes of use, that being &#8230;<\/p>\n<ul>\n<li>discrete &#8230; or &#8220;Optional&#8221;<\/li>\n<li>synchronized &#8230; or &#8220;Overlay&#8221;<\/li>\n<\/ul>\n<p> &#8230; all like yesterday, but this time we allow you to &#8220;seek&#8221; or position yourself within the audio and\/or video media.  We still all &#8220;fit&#8221; this into GET parameter usage.  Are you thinking we are a tad lazy with this approach?  Well, perhaps a little, but it also means you can do this job just using clientside HTML and Javascript, without having to involve any serverside code like PHP, and in this day and age, people are much keener on this &#8220;just clientside&#8221; or &#8220;just client looking, plus, perhaps, Javascript serverside code&#8221; (ala <a target=_blank title='Node.js installation download webpage' href='https:\/\/nodejs.org\/en\/download\/'>Node.js<\/a>) or perhaps &#8220;Javascript clientside client code, plus Ajax methodologies&#8221;.  In any case, it does simplify design to not have to involve a serverside language like PHP &#8230; but please don&#8217;t think we do not encourage you to learn a serverside language like PHP.<\/p>\n<p>While we are at it here, we continue to think about the mobile device unfriendliness with our current web application, it being, these days, that the setting of the <i>autoplay<\/i> property for a media object is frowned upon regarding these mobile devices &#8230; for reasons of &#8220;runaway&#8221; unknown charge issues as you can read at this <a target=_blank title='Useful link' href='http:\/\/stackoverflow.com\/questions\/12496144\/can-you-autoplay-html5-videos-on-the-ipad'>useful link<\/a> &#8230; thanks &#8230; and where they quote from Apple &#8230; <\/p>\n<blockquote cite=\"http:\/\/stackoverflow.com\/questions\/12496144\/can-you-autoplay-html5-videos-on-the-ipad\"><p>\n    &#8220;Apple has made the decision to disable the automatic playing of video on iOS devices, through both script and attribute implementations.<br \/>\n<b><\/b><br \/>\n    In Safari, on iOS (for all devices, including iPad), where the user may be on a cellular network and be charged per data unit, preload and auto-play are disabled. No data is loaded until the user initiates it.&#8221; &#8211; Apple documentation.\n<\/p><\/blockquote>\n<p>A link we&#8217;d like to thank regarding the new &#8220;seek&#8221; or media positioning functionality is <a target=_blank title='Useful link' href='http:\/\/stackoverflow.com\/questions\/9563887\/setting-html5-audio-position'>this one<\/a> &#8230; thanks.<\/p>\n<p><p>Also, today, for that sense of symmetry, we start to create the Audio objects from now on using &#8230;<\/p>\n<p><code><br \/>\ndocument.createElement(\"AUDIO\");<br \/>\n<\/code><\/p>\n<p> &#8230; as this acts the same as <i>new Audio()<\/i> to the best of our testing.<\/p>\n<p>For your own testing purposes, if you know of some media URLs to try, please feel free to try the &#8220;overlay&#8221; of media ideas inherent in today&#8217;s <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.html---GETME\">splice_audio.htm<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.htm\">live run<\/a>.  For today&#8217;s <i>cake<\/i> &#8220;prepared before the program&#8221; we&#8217;ve again channelled the <a target=_blank title='GoToMeeting Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/gotomeeting-primer-tutorial\/'>GoToMeeting Primer Tutorial<\/a> which had separate audio (albeit very short &#8230; sorry &#8230; but you get the gist) and video &#8230; well, below, you can click on the image to hear the presentation with audio and video synchronized, but only seconds 23 through to 47 of the video should play, and the presentation ending with the image below &#8230;<\/p>\n<p><a id='aaiff' title='Click to see the audio and video played together synchronously' onclick=\"  document.getElementById('aiff').style.display='block';  document.getElementById('aiff').src='http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.htm?audio1=..%2FGoToMeeting%2FGoToMeeting.m4v+%2323.47&#038;audio2=+..%2FGoToMeeting%2FGoToMeeting.m4a&#038;audio3=..%2FGoToMeeting%2FGoToMeeting-80aof.jpg++&#038;audio4=&#038;audio5=&#038;audio6=&#038;audio7=&#038;audio8=&#038;audio9=&#038;background=&#038;hide=offoff'; this.style.display='none'; \"><img title='Click to see the audio and video played together synchronously' id='iiif' src='http:\/\/www.rjmprogramming.com.au\/Mac\/GoToMeeting\/GoToMeeting-80aof.jpg'><\/img><\/a><iframe style='display:none; width:100%; height:500px;' id='aiff' src='http:\/\/www.rjmprogramming.com.au\/Mac\/GoToMeeting\/GoToMeeting-80aof.jpg' title='GoToMeeting Primer Tutorial presentation'><\/iframe><\/p>\n<p>We think, though, that we will be back regarding this interesting topic, and hope we can improve mobile device functionality.<\/p>\n<hr>\n<p id='saviot'>Previous relevant <a target=_blank title='Spliced Audio\/Video\/Image Overlay Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/spliced-audiovideoimage-overlay-tutorial\/'>Spliced Audio\/Video\/Image Overlay Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.htm\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Spliced Audio\/Video\/Image Overlay Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audiovideo.jpg\" title=\"Spliced Audio\/Video\/Image Overlay Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">Spliced Audio\/Video\/Image Overlay Tutorial<\/p><\/div>\n<p>Today we&#8217;ve written a second draft of an HTML and Javascript web application that splices up to nine bits of audio or video or image input together, building on the previous <a title='Splicing Audio Primer Tutorial' href='#sapt'>Splicing Audio Primer Tutorial<\/a> as shown below, here, and that can take any of the forms &#8230;<\/p>\n<ul>\n<li>audio file &#8230; and less user friendly is &#8230;<\/li>\n<li>text that gets turned into speech via <a target=_blank title='Google Translate' href='http:\/\/translate.google.com'>Google Translate<\/a> (and user induced Text to Speech functionality), but needs your button presses<\/li>\n<li>video<\/li>\n<li>image &#8230; and background image for webpage<\/li>\n<\/ul>\n<p> &#8230; for either of the modes of use, that being &#8230;<\/p>\n<ul>\n<li>discrete &#8230; or &#8220;Optional&#8221;<\/li>\n<li>synchronized &#8230; or &#8220;Overlay&#8221;<\/li>\n<\/ul>\n<p>The major new change here, apart from the ability to play two media files at once in our synchronized (or &#8220;overlayed&#8221;) way, is the additional functionality for Video, and we proceeded thinking there&#8217;d be an Javascript DOM <a target=_blank title='OOP information from Wikipedia ... thanks' href='http:\/\/en.wikipedia.org\/wiki\/Object-oriented_programming'>OOP<\/a>y method like &#8230; <i>var xv = new Video();<\/i> &#8230; to allow for this, but found out from this useful link &#8230; thanks &#8230; that an <a target=_blank title='Video object information from w3schools' href='http:\/\/www.w3schools.com\/jsref\/dom_obj_video.asp'>alternative approach for Video<\/a> object creation, on the fly, is &#8230;<\/p>\n<p><code><br \/>\nvar xv = document.createElement(\"VIDEO\");<br \/>\n<\/code><\/p>\n<p> &#8230; curiously.  And it took us a while to tweak to the idea that to have a &#8220;display home&#8221; for the video on the webpage we needed to &#8230;<\/p>\n<p><code><br \/>\ndocument.body.appendChild(xv);<br \/>\n<\/code><\/p>\n<p> &#8230; which means you need to take care of any HTML form data already filled in, that isn&#8217;t that form&#8217;s default, when you effectively &#8220;refresh&#8221; the webpage like this.  Essentially though, media on the fly is a modern approach possible fairly easily with just clientside code.  Cute, huh?!<\/p>\n<p>Of course, what we still miss here, is the upload from a local place onto the web server, here at RJM Programming, capability, which we may consider in future, and that some of those other <a target=_blank title='Synchronization blog postings here' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/synchronize'>synchronization of media<\/a> themed blog postings of the past, which you may want to read more, for this type of approach.<\/p>\n<p>In the meantime, if you know of some media URLs to try, please feel free to try the &#8220;overlay&#8221; of media ideas inherent in today&#8217;s <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.html--GETME\">splice_audio.htm<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.htm\">live run<\/a>.  We&#8217;ve thought of this one.  Do you remember how the <a target=_blank title='GoToMeeting Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/gotomeeting-primer-tutorial\/'>GoToMeeting Primer Tutorial<\/a> had separate audio (albeit very short &#8230; sorry &#8230; but you get the gist) and video &#8230; well, below, you can click on the image to hear the presentation with audio and video synchronized, and the presentation ending with the image below &#8230;<\/p>\n<p><a id='aaif' title='Click to see the audio and video played together synchronously' onclick=\"  document.getElementById('aif').style.display='block';  document.getElementById('aif').src='http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.htm?audio1=..%2FGoToMeeting%2FGoToMeeting.m4v+&#038;audio2=+..%2FGoToMeeting%2FGoToMeeting.m4a&#038;audio3=..%2FGoToMeeting%2FGoToMeeting-80aof.jpg++&#038;audio4=&#038;audio5=&#038;audio6=&#038;audio7=&#038;audio8=&#038;audio9=&#038;background=&#038;hide=offoff'; this.style.display='none'; \"><img title='Click to see the audio and video played together synchronously' id='iiif' src='http:\/\/www.rjmprogramming.com.au\/Mac\/GoToMeeting\/GoToMeeting-80aof.jpg'><\/img><\/a><iframe style='display:none; width:100%; height:500px;' id='aif' src='http:\/\/www.rjmprogramming.com.au\/Mac\/GoToMeeting\/GoToMeeting-80aof.jpg' title='GoToMeeting Primer Tutorial presentation'><\/iframe><\/p>\n<p>We think, though, that we will be back regarding this interesting topic.<\/p>\n<hr>\n<p id='sapt'>Previous relevant <a target=_blank title='Splicing Audio Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/splicing-audio-primer-tutorial\/'>Splicing Audio Primer Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.html\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Spliced Audio Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.jpg\" title=\"Spliced Audio Primer Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">Splicing Audio Primer Tutorial<\/p><\/div>\n<p>Today we&#8217;ve written a first draft of an HTML and Javascript web application that splices up to nine bits of audio input together that can take either of the forms &#8230;<\/p>\n<ul>\n<li>audio file &#8230; and less user friendly is &#8230;<\/li>\n<li>text that gets turned into speech via <a target=_blank title='Google Translate' href='http:\/\/translate.google.com'>Google Translate<\/a> (and user induced Text to Speech functionality), but needs your button presses<\/li>\n<\/ul>\n<p>Do you remember, perhaps, when we did a series of blog posts regarding the YouTube API, that finished, so far, with <a target=_blank title='YouTube API Iframe Synchronicity Resizing Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/youtube-api-iframe-synchronicity-resizing-tutorial\/'>YouTube API Iframe Synchronicity Resizing Tutorial<\/a>?  Well, a lot of what we do today is doing similar sorts of functionalities but just for <a target=_blank title='Javascript Audio object via DOM information from w3schools' href='http:\/\/www.w3schools.com\/tags\/ref_av_dom.asp'><i>Audio<\/i><\/a> objects in HTML5.  For help on this we&#8217;d like to thank this <a target=_blank title='Great link' href='http:\/\/stackoverflow.com\/questions\/10868249\/html5-audio-player-duration-showing-nan'>great link<\/a>.  So rather than have HTML <a target=_blank href='http:\/\/www.w3schools.com\/html\/html5_audio.asp' title='HTML audio tag information from w3schools'><i>audio<\/i><\/a> elements in our HTML, as we first shaped to do, we&#8217;ve taken the great advice from this link, and gone all Javascript DOM <a target=_blank title='OOP information from Wikipedia ... thanks' href='http:\/\/en.wikipedia.org\/wiki\/Object-oriented_programming'>OOP<\/a>y on the task, to splice audio media together.<\/p>\n<p>There were three thought patterns going on here for me.<\/p>\n<ul>\n<li>The first was a simulation of those Sydney train public announcements where the timbre of the voice differs a bit between when they say &#8220;Platform&#8221; and the &#8220;6&#8221; (or whatever platform it is) that follows.  This is pretty obviously computer audio &#8220;bits&#8221; strung together &#8230; and wanted to get somewhere towards that capability.<\/li>\n<li>The second one relates to presentation ideas following up on that &#8220;onmouseover&#8221; Siri audio enhanced presentation we did at <a target=_blank title='Apple iOS Siri Audio Commentary Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/apple-ios-siri-audio-commentary-tutorial\/'>Apple iOS Siri Audio Commentary Tutorial<\/a>.  Well, we think we can do something related to that here, and we&#8217;ve prepared this <strike>cake<\/strike> audio presentation here, for us, in advance &#8230; <font size=1>really, there&#8217;s no need for thanks<\/font>.<\/li>\n<li>The third concerns our eternal media file synchronization quests here at this blog that you may find of interest we hope, <a target=_blank title='Synchronization blog postings here' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/synchronize'>here<\/a>.<\/p>\n<\/ul>\n<p>Also of interest over time has been the <a target=_blank title='Google Translate' href='http:\/\/translate.google.com'>Google Translate<\/a> Text to Speech functionality that <a target=_blank title='Discussion here' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/text-to-speech'>used to be very open<\/a>, and we now only use around here in an interactive &#8220;user clicks&#8221; way &#8230; but we still use it, because it is very useful, so, thanks.  But trying to get this method working for &#8220;Platform&#8221; and &#8220;6&#8221; without a yawning gap in between ruins the spontaneity and fun somehow, but there&#8217;s nothing stopping you making your own audio files yourself as we did in that Siri tutorial called <a target=_blank title='Apple iOS Siri Audio Commentary Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/apple-ios-siri-audio-commentary-tutorial\/'>Apple iOS Siri Audio Commentary Tutorial<\/a> and take the HTML and Javascript code you could call <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.html_GETME\" title='splice_audio.html'>splice_audio.html<\/a> from today, and go and make your own web application? Now, is there? Huh?<\/p>\n<p>Try a <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.html\" title='Click picture'>live run<\/a> or perhaps some more Siri cakes?!<\/p>\n<ul>\n<li><a target=_blank title='Audio with Background then Form for another, perhaps' href='http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.html?audio1=slide1.m4a&#038;audio2=slide2.m4a&#038;audio3=slide3.m4a&#038;audio4=slide4.m4a&#038;audio5=slide5.m4a&#038;audio6=slide6.m4a&#038;audio7=slide7.m4a&#038;audio8=slide8.m4a&#038;audio9=slide9.m4a&#038;background=siri_setup.jpg&#038;hide=onoff'>Audio with Background then Form for another, perhaps<\/a><\/li>\n<li><a target=_blank title='Audio with Background and Form showing the whole time' href='http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.html?audio1=slide1.m4a&#038;audio2=slide2.m4a&#038;audio3=slide3.m4a&#038;audio4=slide4.m4a&#038;audio5=slide5.m4a&#038;audio6=slide6.m4a&#038;audio7=slide7.m4a&#038;audio8=slide8.m4a&#038;audio9=slide9.m4a&#038;background=siri_setup.jpg&#038;hide=offoff'>Audio with Background and Form showing the whole time<\/a><\/li>\n<li><a target=_blank title='Audio with no Background then Form for another, perhaps' href='http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.html?audio1=slide1.m4a&#038;audio2=slide2.m4a&#038;audio3=slide3.m4a&#038;audio4=slide4.m4a&#038;audio5=slide5.m4a&#038;audio6=slide6.m4a&#038;audio7=slide7.m4a&#038;audio8=slide8.m4a&#038;audio9=slide9.m4a&#038;background=&#038;hide=onoff'>Audio with no Background then Form for another, perhaps<\/a><\/li>\n<li><a target=_blank title='Just Audio' href='http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/splice_audio.html?audio1=slide1.m4a&#038;audio2=slide2.m4a&#038;audio3=slide3.m4a&#038;audio4=slide4.m4a&#038;audio5=slide5.m4a&#038;audio6=slide6.m4a&#038;audio7=slide7.m4a&#038;audio8=slide8.m4a&#038;audio9=slide9.m4a&#038;background=&#038;hide=onon'>Just Audio<\/a><\/li>\n<\/ul>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d24451' onclick='var dv=document.getElementById(\"d24451\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/audio\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d24451' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d24545' onclick='var dv=document.getElementById(\"d24545\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/video\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d24545' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d45376' onclick='var dv=document.getElementById(\"d45376\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/compose\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d45376' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d52747' onclick='var dv=document.getElementById(\"d52747\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/delimiter\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d52747' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Yesterday&#8217;s HTML5 Web Audio Piano Keyboard Tutorial had us integrating keyboard functionality for non-mobile users of our piano playing web application, and today, building on the previous HTML5 Web Audio Mudcube Piano Integration Composing Tutorial, we involve those similar keyboard &hellip; <a href=\"https:\/\/www.rjmprogramming.com.au\/ITblog\/html5-web-audio-mudcube-piano-integration-chord-composing-tutorial\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,14,37],"tags":[113,1534,2989,2147,354,452,532,576,652,673,760,822,849,875,894,997,1234,1670,1258,1319,1369,2980],"class_list":["post-52747","post","type-post","status-publish","format-standard","hentry","category-elearning","category-event-driven-programming","category-tutorials","tag-audio","tag-compose","tag-composition","tag-delimiter","tag-dom","tag-form","tag-google-translate","tag-html","tag-javascript","tag-keyboard","tag-media","tag-music-2","tag-object","tag-oop","tag-overlay","tag-programming","tag-synchronization","tag-synchronize","tag-text-to-speech","tag-tutorial","tag-video","tag-web-audio"],"_links":{"self":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/52747"}],"collection":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/comments?post=52747"}],"version-history":[{"count":4,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/52747\/revisions"}],"predecessor-version":[{"id":52751,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/52747\/revisions\/52751"}],"wp:attachment":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/media?parent=52747"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/categories?post=52747"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/tags?post=52747"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}