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

Harmonizer

MIDI In:   MIDI Out:   Sound:

-8 -5 -4 -3 >< +3 +4 +5 +8    Key:

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

How it works

This script adds another line to your melody when you play it on your MIDI instrument.

MIDI In connection opens/closes when the page gets in/out of focus, same as in previous example.

External MIDI Out is handled in similar way, while the default (software) MIDI Out stays open regardless of focus.

Page source

<!DOCTYPE html>
<html>
<head>
<title>Harmonizer</title>

<style type="text/css">
.hidden {
 visibility:hidden;
 width:0px;
 height:0px;
 margin:0px;
 padding:0px;
 border-style:none;
 border-width:0px;
 max-width:0px;
 max-height:0px;
}
</style>
</head>

<body>
<h1>Harmonizer</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>

<p>
MIDI In: <select id=midiIn onchange='changeIn();'><option value="">Not connected</option></select>
 
MIDI Out: <select id=midiOut onchange='changeOut();'><option value="">Not connected</option></select>
 
Sound: <select id=midiSnd onchange='changeSnd();'></select>
</p><p>
-8<input type=radio name=shift onClick='shift=0;'>
-5<input type=radio name=shift onClick='shift=1;'>
-4<input type=radio name=shift onClick='shift=2;'>
-3<input type=radio name=shift onClick='shift=3;'>
><input type=checkbox id=chkbox onclick='playSelf=chkbox.checked;' checked><
<input type=radio name=shift onClick='shift=4;' checked>+3
<input type=radio name=shift onClick='shift=5;'>+4
<input type=radio name=shift onClick='shift=6;'>+5
<input type=radio name=shift onClick='shift=7;'>+8
  
Key: <select id=midiKey onchange='changeKey();'>
<option value=0>C Major / A minor</option>
<option value=11>Db Major / Bb minor</option>
<option value=10>D Major / B minor</option>
<option value=9>Eb Major / C minor</option>
<option value=8>E Major / C# minor</option>
<option value=7>F Major / D minor</option>
<option value=6>Gb Major / Eb minor</option>
<option value=5>G Major / E minor</option>
<option value=4>Ab Major / F minor</option>
<option value=3>A Major / F# minor</option>
<option value=2>Bb Major / G minor</option>
<option value=1>B Major / G# minor</option>
</select>
</p>

<script><!--
var Jazz;
var active_element;
var current_in;
var current_out;
var default_out;
var current_snd=0;
var current_key=0;
var voice=0;
var shift=4;
var selIn;
var selOut;
var selSnd;
var selKey;
var chkbox;
var playSelf=1;
var gmidi=['Acoustic Grand Piano','Bright Acoustic Piano','Electric Grand Piano','Honky-tonk Piano','Electric Piano 1','Electric Piano 2','Harpsichord','Clavinet',
'Celesta','Glockenspiel','Music Box','Vibraphone','Marimba','Xylophone','Tubular Bells','Dulcimer',
'Drawbar Organ','Percussive Organ','Rock Organ','Church Organ','Reed Organ','Accordion','Harmonica','Tango Accordion',
'Acoustic Guitar nylon','Acoustic Guitar steel','Electric Guitar jazz','Electric Guitar clean','Electric Guitar muted','Overdriven Guitar','Distortion Guitar','Guitar Harmonics',
'Acoustic Bass','Electric Bass finger','Electric Bass pick','Fretless Bass','Slap Bass 1','Slap Bass 2','Synth Bass 1','Synth Bass 2',
'Violin','Viola','Cello','Contrabass','Tremolo Strings','Pizzicato Strings','Orchestral Harp','Timpani',
'String Ensemble 1','String Ensemble 2','Synth Strings 1','Synth Strings 2','Choir Aahs','Voice Oohs','Synth Choir','Orchestra Hit',
'Trumpet','Trombone','Tuba','Muted Trumpet','French Horn','Brass Section','Synth Brass 1','Synth Brass 2',
'Soprano Sax','Alto Sax','Tenor Sax','Baritone Sax','Oboe','English Horn','Bassoon','Clarinet',
'Piccolo','Flute','Recorder','Pan Flute','Blown Bottle','Shakuhachi','Whistle','Ocarina',
'Lead 1 square','Lead 2 sawtooth','Lead 3 calliope','Lead 4 chiff','Lead 5 charang','Lead 6 voice','Lead 7 fifths','Lead 8 bass + lead',
'Pad 1 new age','Pad 2 warm','Pad 3 polysynth','Pad 4 choir','Pad 5 bowed','Pad 6 metallic','Pad 7 halo','Pad 8 sweep',
'FX 1 rain','FX 2 soundtrack','FX 3 crystal','FX 4 atmosphere','FX 5 brightness','FX 6 goblins','FX 7 echoes','FX 8 sci-fi',
'Sitar','Banjo','Shamisen','Koto','Kalimba','Bagpipe','Fiddle','Shanai',
'Tinkle Bell','Agogo','Steel Drums','Woodblock','Taiko Drum','Melodic Tom','Synth Drum','Reverse Cymbal',
'Guitar Fret Noise','Breath Noise','Seashore','Bird Tweet','Telephone Ring','Helicopter','Applause','Gunshot'];

//// Callback function
function midiProc(t,a,b,c){
 if(current_out=='') return;
 if(a>0xaf){
  Jazz.MidiOut(a,b,c);
 } else {
  if(playSelf) Jazz.MidiOut(a,b,c);
  Jazz.MidiOut(a,transpose(b),c);
 }
}
function transpose(x){
 x=parseInt(x);
 switch(shift){
  case 0: return x-12;
  case 1: return x-[7,7,7,7,7,6,7,7,7,7,7,7][(x+current_key)%12];
  case 2: return x-[5,5,5,5,5,5,5,5,5,5,5,6][(x+current_key)%12];
  case 3: return x-[3,4,3,4,4,3,4,3,4,4,3,4][(x+current_key)%12];
  case 4: return x+[4,3,3,4,3,4,3,4,3,3,4,3][(x+current_key)%12];
  case 5: return x+[5,5,5,5,5,6,5,5,5,5,5,5][(x+current_key)%12];
  case 6: return x+[7,7,7,7,7,7,7,7,7,7,7,6][(x+current_key)%12];
  case 7: return x+12;
 }
}
function changeIn(){
 try{
  if(selIn.selectedIndex){
   current_in=Jazz.MidiInOpen(selIn.options[selIn.selectedIndex].value,midiProc);
  } else {
   Jazz.MidiInClose(); current_in='';
  }
  for(var i=0;i<selIn.length;i++){
   if(selIn[i].value==current_in) selIn[i].selected=1;
  }
 }
 catch(err){}
}
function changeOut(){
 try{
  if(selOut.selectedIndex){
   current_out=Jazz.MidiOutOpen(selOut.options[selOut.selectedIndex].value);
   if(current_out!=''){ Jazz.MidiOut(0xc0,current_snd,0);}
  } else {
   Jazz.MidiOutClose(); current_out='';
  }
  for(var i=0;i<selOut.length;i++){
   if(selOut[i].value==current_out) selOut[i].selected=1;
  }
 }
 catch(err){}
}
function changeSnd(){
 current_snd=selSnd.options[selSnd.selectedIndex].value;
 if(current_out!=''){ Jazz.MidiOut(0xc0,current_snd,0);}
}
function changeKey(){
 current_key=parseInt(selKey.options[selKey.selectedIndex].value);
}
//// Connect/disconnect
function connectMidi(){
 try{
  var str;
  if(current_out!=default_out){
   str=Jazz.MidiOutOpen(current_out);
   if(str!=''){ Jazz.MidiOut(0xc0,current_snd,0);}
   for(var i=0;i<selOut.length;i++){
    if(selOut[i].value==str) selOut[i].selected=1;
   }
  }
  str=Jazz.MidiInOpen(current_in,midiProc);
  for(var i=0;i<selIn.length;i++){
   if(selIn[i].value==str) selIn[i].selected=1;
  }
 }
 catch(err){}
}
function disconnectMidi(){
 try{
  if(current_out!=default_out){ Jazz.MidiOutClose(); selOut[0].selected=1;}
  Jazz.MidiInClose(); selIn[0].selected=1;
 }
 catch(err){}
}
function onFocusIE(){
 active_element=document.activeElement;
 connectMidi();
}
function onBlurIE(){
 if(active_element!=document.activeElement){ active_element=document.activeElement; return;}
 disconnectMidi();
}

//// Initialize
Jazz=document.getElementById("Jazz1"); if(!Jazz || !Jazz.isJazz) Jazz = document.getElementById("Jazz2");
selIn=document.getElementById("midiIn");
selOut=document.getElementById("midiOut");
selSnd=document.getElementById("midiSnd");
selKey=document.getElementById("midiKey");
chkbox=document.getElementById("chkbox");
for(var i in gmidi){
 selSnd[i]=new Option(gmidi[i],i,!i,!i);
}
try{
 current_out=Jazz.MidiOutOpen(0);
 default_out=current_out;
 var list=Jazz.MidiOutList();
 for(var i in list){
  selOut[selOut.options.length]=new Option(list[i],list[i],list[i]==current_out,list[i]==current_out);
 }
 current_in=Jazz.MidiInOpen(0,midiProc);
 var list=Jazz.MidiInList();
 for(var i in list){
  selIn[selIn.options.length]=new Option(list[i],list[i],list[i]==current_in,list[i]==current_in);
 }
}
catch(err){}

if(navigator.appName=='Microsoft Internet Explorer'){ document.onfocusin=onFocusIE; document.onfocusout=onBlurIE;}
else{ window.onfocus=connectMidi; window.onblur=disconnectMidi;}
--></script>

</body>
</html>

See also