Jazz-Soft.net

We make it sound!

Home » Examples » Jazz-Plugin » Read MIDI File

Read MIDI File

NOTE: another example explains how to play it.

from file:

from URL:

from string:

 

Files accepted: SMF (*.mid, *.kar), RMID (*.rmi)

How it works

In this example, we are reading binary string from file, URL or base64-encoded string, and passing it to JZZ.MidiFile constructor.

Some older/freakier browsers may not support HTML5 File API required to open local files.

Due to the "same origin" security restriction, you must use URLs from your own domain, or write a proxy.

Page source

<!DOCTYPE html>
<html>
<head>
<title>Read MIDI File</title>
<script src="JZZ.Midi.js"></script>
<script src="JZZ.MidiFile.js"></script>

<style type="text/css">
button {
 width:6em;
}
#midi {
 font-family:Courier New, monospace;
 background-color:#eef;
 border:none;
 padding:0.2em;
}
#midi div {
 border:double;
 margin:0.2em;
}
#midi div div {
 border:none;
}
#midi div div.hdr {
 font-weight:bold;
 border:none;
}
#midi span.clk {
 width:6em;
 padding:0 0.5em;
 text-align:right;
 display:inline-block;
 background-color:#ddd;
}
#midi .wait {
 padding:.2em;
 font-size:1.5em;
 font-weight:bold;
 color:#888;
}
#midi .err {
 padding:.5em;
 font-size:1.2em;
 font-weight:bold;
 color:#d00;
}
</style>
</head>

<body>
<h1>Read MIDI File</h1>

<h2>from file:</h2>
<p><input type=file id=file size=80 onchange='fromFile();'></p>

<h2>from URL:</h2>
<form onsubmit='fromUrl(); return false;'>
<p><input type=text id=url size=80><input type=submit value=Submit...></p>
</form>

<h2>from string: <button onclick='fromString();'>Read...</button></h2>

<p>
<div id=fname>&nbsp;</div>
</p>
<p>
<div id=midi>Files accepted: SMF (*.mid, *.kar), RMID (*.rmi)</div>
</p>

<script><!--
function fromFile(){
 plzWait(); fName(document.getElementById('file').value);
 if(window.FileReader){
  var reader=new FileReader();
  var f=document.getElementById('file').files[0];
  reader.onload=function(e){ readMidiFile(e.target.result);};
  reader.readAsBinaryString(f);
 }
 else err('File API is not supported in this browser!');
}
function fromUrl(){
 var url=document.getElementById('url').value;
 plzWait(); fName(url);
 try{
  var req=new XMLHttpRequest();
  req.open("GET",url,true);
  if(req.overrideMimeType){
   req.overrideMimeType("text/plain; charset=x-user-defined");
  }
  req.onreadystatechange=function(ev){
   if(req.readyState===4){
    if(req.status===200){
     var s='';
     if(typeof req.responseBody=='unknown'){ // MSIE
      var a=new VBArray(req.responseBody).toArray();
      for(var i=0;i<a.length;i++) s+=String.fromCharCode(a[i]);
     }
     else {
      var r=req.responseText;
      for(var i=0;i<r.length;i++) s+=String.fromCharCode(r.charCodeAt(i)&0xff);
     }
     readMidiFile(s);
    }
    else err(req.status+": "+req.statusText);
   }
  };
  req.send(null);
 }
 catch(e){ err(e);}
}
function fromString(){
 plzWait(); fName('Base64 string');
 readMidiFile(JZZ_.MidiFile.fromBase64(b64));
}
function readMidiFile(s){
 try{
  var mf=new JZZ_.MidiFile(s);
  displayMidiFile(mf);
 }
 catch(e){ err(e);}
}
function displayMidiFile(mf){
 document.getElementById('midi').innerHTML='';
 var chunk;
 var div;
 chunk=document.createElement('div');
 chunk.innerHTML='<div class=hdr>MThd</div>';
 div=document.createElement('div');
 div.innerHTML='type: '+mf.type+(mf.ppqn?(', ppqn: '+mf.ppqn):(' smpte: '+mf.fps+'x'+mf.ppf));
 chunk.appendChild(div);
 document.getElementById('midi').appendChild(chunk);
 for(var i=0;i<mf.length;i++){
  chunk=document.createElement('div');
  chunk.innerHTML='<div class=hdr>'+mf[i].type+'</div>';
  if(mf[i].data){
   div=document.createElement('div');
   arr=[]; s=mf[i].data;
   for(var j=0;j<s.length;j++){
    var c=s.charCodeAt(j)<32?'-':s.charAt(j);
    if(c=='&') c='&amp;'; if(c=='<') c='&lt;'; if(c=='>') c='&gt;';
    var n=(s.charCodeAt(j)<16?'0':'')+s.charCodeAt(j).toString(16);
    if(j && !(j%32)) arr.push('<br>'); else if(j && !(j%8)) arr.push('&nbsp;');
    arr.push('<span title="'+c+'">'+n+'</span>');
   }
   div.innerHTML=arr.join(' ');
   chunk.appendChild(div);
  }
  if(mf[i] instanceof JZZ_.MidiFile.MTrk){
   for(var j=0;j<mf[i].length;j++){
    var evt=mf[i][j];
    var s=evt.toString().replace(/&/g,'&amp;').replace(/>/g,'&gt;').replace(/</g,'&lt;');
    div=document.createElement('div');
    div.innerHTML="<span class=clk>"+evt.time+"</span> <span>"+s+"</span>";
    chunk.appendChild(div);
   }
  }
  document.getElementById('midi').appendChild(chunk);
 }
}
function err(e){ document.getElementById('midi').innerHTML='<span class=err>'+e+'</span>';}
function plzWait(){ document.getElementById('midi').innerHTML='<span class=wait>One moment please...</span>';}
function fName(s){ document.getElementById('fname').innerHTML='<tt>'+s+'</tt>';}
var b64='\
TVRoZAAAAAYAAQADAGRNVHJrAAAAGgD/AwtMaXR0bGUgTGFtYgD/UQMKLCsA/y8ATVRyawAAAPEA/wMF\
V29yZHMA/wEYQFRNYXJ5IEhhZCBBIExpdHRsZSBMYW1iZP8BA1xNYTL/AQNyeSAy/wEEaGFkIDL/AQJh\
IDL/AQNsaXQy/wEEdGxlIDL/AQVsYW1iLGT/AQQvTGl0Mv8BBHRsZSAy/wEFbGFtYixk/wEEL0xpdDL/\
AQR0bGUgMv8BBWxhbWIsZP8BAy9NYTL/AQNyeSAy/wEEaGFkIDL/AQJhIDL/AQNsaXQy/wEEdGxlIDL/\
AQVsYW1iLGT/AQYvQmxhaC0y/wEFYmxhaC0y/wEFYmxhaC0y/wEFYmxhaC0y/wEFYmxhaCEA/y8ATVRy\
awAAALkA/wMFTXVzaWMAwAtkkEB/MkAAAD5/Mj4AADx/MjwAAD5/Mj4AAEB/MkAAAEB/MkAAAEB/WkAA\
Cj5/Mj4AAD5/Mj4AAD5/Wj4ACkB/MkAAAEN/MkMAAEN/WkMACkB/MkAAAD5/Mj4AADx/MjwAAD5/Mj4A\
AEB/MkAAAEB/MkAAAEB/WkAACj5/Mj4AAD5/Mj4AAEB/MkAAAD5/Mj4AADx/ZEBkAENkAEh/WjwAAEAA\
AEMAAEgACv8vAA==';
--></script>

</body>
</html>

Using proxy

Proxy is a little server-side script that allows reading files from other domain as if they were at your own domain.

It can be as simple as this:

<?php
$url=$_REQUEST['url'];
if($fp=fopen($url,"r")) while($str=fread($fp,1024)) echo $str;
?>

Make sure (or ask your hosting provider) that allow_url_fopen = On in your php settings.

All you have to do now, is to change

  req.open("GET",url,true);

to

  req.open("GET",'proxy.php?url='+url,true);

in your JavaScript.

See also