Jazz-Soft.net
We make it sound!
Home » Examples » Jazz-Plugin » Karaoke +

Karaoke +

This example requires Jazz-Plugin v.1.2 or later.

How it works

Besides playing the notes, MIDI event handler also updates the style of HTML elements.

During the initialization, we extract the words from the MIDI file, and attach created <SPAN>s to the MIDI file events that will be passed to the event handler at the playback time.

Page source

<!DOCTYPE HTML>
<html>
<head>

<title>Karaoke +</title>
<script src="JZZ.Midi.js"></script>
<script src="JZZ.MidiFile.js"></script>

<style type="text/css">
div#piano {
 position: relative;
 color: #808080;
 height: 102px;
}
div.ivory {
 position: absolute;
 left: 0px;
 top: 0px;
 border-left: 1px solid;
 width: 504px;
}
.ivory span {
 background-color: #fffff0;
 padding: 0px;
 margin: 0px;
 border: 1px solid;
 border-left: 0px;
 display: inline-block;
 width: 27px;
 height: 100px;
 vertical-align: top;
}
div.ebony {
 position: absolute;
 left: 0px;
 top: 0px;
 margin-left: 18px;
 width: 504px;
}
.ebony span {
 position: relative;
 z-index: 1;
 background-color: #111;
 padding: 0px;
 margin: 0px;
 border: 1px solid;
 display: inline-block;
 width: 15px;
 height: 70px;
 margin-right: 15px;
 vertical-align: top;
}
.ebony span.break {
 border: 0px;
 display: inline-block;
 width: 1px;
 margin-right: 17px;
 visibility:hidden;
}
.ivory span.on {
 background-color: #aaa;
}
.ebony span.on {
 background-color: #aaa;
}
.hidden {
 visibility: hidden;
 width: 0px;
 height: 0px;
 margin: 0px;
 padding: 0px;
 border-style: none;
 border-width: 0px;
 max-width: 0px;
 max-height: 0px;
}
button {
 width:6em;
}
#kar {
 background-color:#222;
 color:#fff;
 font-size:1.2em;
 font-weight:bold;
 padding:.5em;
 margin-bottom:.5em;
}
#kar h2 {
 color:#ff8;
 font-size:1.4em;
 font-weight:bold;
}
#kar .pink {
 color:#f8f;
}
</style>
</head>

<body>
<h1>Karaoke +</h1>

<object id="Jazz1" classid="CLSID:1ACE1618-1C7D-4561-AEE1-34842AA85E90" class="hidden">
  <object id="Jazz2" type="audio/x-jazz" class="hidden">
<p style="visibility:visible;">This page requires <a href=http://jazz-soft.net>Jazz-Plugin</a> ...</p>
  </object>
</object>

<div id=kar></div>

<div id=piano>
<div class=ebony>
<span id=49></span><span id=51></span><span class=break></span><span id=54></span><span id=56></span><span id=58></span><span class=break></span><span id=61></span><span id=63></span><span class=break></span><span id=66></span><span id=68></span><span id=70></span><span class=break></span><span id=73></span><span id=75></span>
</div>
<div class=ivory>
<span id=48></span><span id=50></span><span id=52></span><span id=53></span><span id=55></span><span id=57></span><span id=59></span><span id=60></span><span id=62></span><span id=64></span><span id=65></span><span id=67></span><span id=69></span><span id=71></span><span id=72></span><span id=74></span><span id=76></span>
</div>
</div>

<div id=selectmididiv class="hidden"><p>MIDI Out: <select id=selectmidi onchange='changemidi();'></select></p></div>
<p>
<button id=play onmousedown='play();' disabled>Play</button>
<button id=pause onmousedown='pause();' disabled>Pause</button>
<button id=stop onmousedown='stop();' disabled>Stop</button>
</p>

<script><!--
var Jazz = document.getElementById("Jazz1"); if(!Jazz || !Jazz.isJazz) Jazz = document.getElementById("Jazz2");
var player;
function onPlayerEvent(e){
 if(e.midi instanceof JZZ_.Midi){
  Jazz.MidiOutRaw(e.midi.array());
  var m=e.midi.data();
  if(m.charCodeAt(0)==0x90 && m.charCodeAt(2)){
   var k=document.getElementById(m.charCodeAt(1));
   k.className='on';
   window.setTimeout(function(){ k.className='';},100);
  }
 }
 if(e.user) e.user.className='pink';
 if(e.control=='play'){
  document.getElementById('play').disabled=true;
  document.getElementById('pause').disabled=false;
  document.getElementById('pause').innerHTML='Pause';
  document.getElementById('stop').disabled=false;
  document.getElementById('selectmidi').disabled=true;
 }
 else if(e.control=='stop'){
  for(var i=0;i<16;i++) Jazz.MidiOut(0xb0+i,123,0);
  document.getElementById('play').disabled=false;
  document.getElementById('pause').disabled=true;
  document.getElementById('pause').innerHTML='Pause';
  document.getElementById('stop').disabled=true;
  document.getElementById('selectmidi').disabled=false;
 }
 else if(e.control=='pause'){
  for(var i=0;i<16;i++) Jazz.MidiOut(0xb0+i,123,0);
  document.getElementById('pause').innerHTML='Resume';
 }
 else if(e.control=='resume'){
  document.getElementById('pause').innerHTML='Pause';
 }
}
function play(){
 for(var i in words) words[i].className='';
 player.play();
}
function stop(){ player.stop();}
function pause(){
 if(player.playing) player.pause();
 else player.resume();
}
function changemidi(){
 Jazz.MidiOutOpen(select.options[select.selectedIndex].value);
 Jazz.MidiOut(0xc0,11);
}
var key;
document.onmousedown=function(e){
  var e=window.event || e;
  var k;
  if (e.target) k = e.target;
  else if (e.srcElement) k = e.srcElement;
  var m=parseInt(k.id);
  if(k.id==m)
  { document.onmouseup(e);
    onPlayerEvent({midi:JZZ_.MIDI(0x90,m,0x7f)});
    key=k;
  }
  return true;
}
document.onmouseup=function(e){
  if(key)
  { var m=parseInt(key.id);
    { onPlayerEvent({midi:JZZ_.MIDI(0x90,m,0)});
      key=undefined;
    }
  }
}
window.onload=function(){
  if(Jazz.isJazz) Jazz.MidiOut(0x80,0,0);
}

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==';

var words=[];
var select=document.getElementById('selectmidi');
try{
 var list=Jazz.MidiOutList();
 for(var i in list){
  select[i]=new Option(list[i],list[i],i==0,i==0);
 }
 Jazz.MidiOutOpen(0);
 Jazz.MidiOut(0xc0,11);
 document.getElementById('selectmididiv').className='';
 var midifile=new JZZ_.MidiFile(JZZ_.MidiFile.fromBase64(b64));
 player=midifile.player();
 var kar=document.getElementById('kar');
 var p=document.createElement('p');
 for(var i=0;i<player.length;i++){ // extracting words
  if(player[i].status=='\xff\x01' && player[i].track==1){
   var str=player[i].data;
   if(str.substr(0,1)=='@'){
    var h=div=document.createElement('h2');
    h.innerHTML=str.substr(2);
    kar.appendChild(h);
    continue;
   }
   if(str.substr(0,1)=='\\' || str.substr(0,1)=='/'){
    p=document.createElement('p');
    kar.appendChild(p);
    str=str.substr(1);
   }
   var sp=document.createElement('span');
   sp.innerHTML=str; p.appendChild(sp);
   player[i].user=sp; // user data will be sent to the event handler along with MIDI event.
   words.push(sp);
  }
 }
 player.onEvent=onPlayerEvent;
 document.getElementById('play').disabled=false;
 document.getElementById('pause').disabled=true;
 document.getElementById('stop').disabled=true;
 document.getElementById('selectmidi').disabled=false;
}
catch(err){}
--></script>

</body>
</html>

See also