piano.php


Quell Code


 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>


<style>
#alles{
    margin:0;
  text-align:center;
  font-size:20px;
  font-family:Arial;
transform:scale(0.6);
margin-left:-10%;
}
h1{
text-align:center;
}
  
  
  
  
 
 
 
 @charset "UTF-8";
* {
  padding: 0;
  margin: 0;
}

.pressed {
          transform: rotateX(-10deg);
}

.pressed-black {
  -webkit-transform: rotateX(-10deg) translateZ(-150px) !important;
          transform: rotateX(-10deg) translateZ(-150px) !important;
  margin-top: -20px !important;
}

.piano {
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-perspective: 1500;
          perspective: 1500;
  position:relative;
  width: 100%;
  height: 10px;
  top:110px;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;

  -webkit-transform: translateZ(10px) rotateY(0deg) rotateX(-50deg);
          transform: translateZ(10px) rotateY(0deg) rotateX(-50deg);
}

.white-key-group {
  z-index: 1;
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  width: 60px;
  height: 70px;
  position: absolute;
  -webkit-transform-origin: 0% 0% -400px;
          transform-origin: 0% 0% -400px;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  -webkit-transition: .2s;
  transition: .2s;
}
.white-key-group .size-lr {
  width: 400px;
  height: 70px;
}
.white-key-group .size-t {
  width: 60px;
  height: 400px;
}
.white-key-group .tec {
  position: absolute;
  top: 0;
  left: 0;
  -webkit-transform-origin: 0% 0%;
          transform-origin: 0% 0%;
  border: 1px solid #ccc;
}
.white-key-group .y90-left {
  -webkit-transform: rotateY(90deg);
          transform: rotateY(90deg);
  background: #999;
  background-image: -webkit-gradient(linear, left top, right bottom, from(#fff), to(#999));
  background-image: linear-gradient(to bottom right, #fff, #999);
}
.white-key-group .y90-right {
  -webkit-transform: rotateY(90deg);
          transform: rotateY(90deg);
  left: 0px;
  background: #999;
  background-image: -webkit-gradient(linear, left top, right bottom, from(#fff), to(#999));
  background-image: linear-gradient(to bottom right, #fff, #999);
}
.white-key-group .x90-top {
  -webkit-transform: rotateX(-90deg);
          transform: rotateX(-90deg);
  background: #fff;
  background-image: -webkit-gradient(linear, left top, right bottom, from(#eee), to(#fff));
  background-image: linear-gradient(to bottom right, #eee, #fff);
}
.white-key-group .x90-front {
  -webkit-transform: rotateX(0deg);
          transform: rotateX(0deg);
  width: 60px;
  height: 70px;
  background: #eee;
  background-image: -webkit-gradient(linear, top bottom, from(#fff), to(#eee));
  background-image: linear-gradient(to top bottom, #fff, #eee);
  position: relative;
}
.white-key-group .x90-front2 {
  -webkit-transform: rotateY(0deg);
          transform: rotateY(0deg);
  margin-left: 60px;
  width: 60px;
  height: 70px;
  background: #eee;
  background-image: -webkit-gradient(linear, left top, right bottom, from(#999), to(#eee));
  background-image: linear-gradient(to bottom right, #999, #eee);
}

.black-key-group {
  margin-top: -42px;
  -webkit-transform: translateZ(-150px);
          transform: translateZ(-150px);
  z-index: 100;
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  width: 10px;
  height: 10px;
  position: absolute;
  -webkit-transform-origin: 0% 0% -250px;
          transform-origin: 0% 0% -250px;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  -webkit-transition: .2s;
  transition: .2s;
}
.black-key-group .size-lr {
  width: 250px;
  height: 40px;
}
.black-key-group .size-t {
  width: 30px;
  height: 250px;
}
.black-key-group .tec {
  position: absolute;
  top: 0;
  left: 0;
  -webkit-transform-origin: 0% 0%;
          transform-origin: 0% 0%;
  border: 1px solid #222;
}
.black-key-group .y90-left {
  -webkit-transform: rotateY(90deg);
          transform: rotateY(90deg);
  background: #222;
  background-image: -webkit-gradient(linear, left top, right bottom, from(#111), to(#222));
  background-image: linear-gradient(to bottom right, #111, #222);
}
.black-key-group .y90-right {
  -webkit-transform: rotateY(90deg);
          transform: rotateY(90deg);
  left: 30px;
  background: #222;
  background-image: -webkit-gradient(linear, left top, right bottom, from(#111), to(#222));
  background-image: linear-gradient(to bottom right, #111, #222);
}
.black-key-group .x90-top {
  -webkit-transform: rotateX(-90deg);
          transform: rotateX(-90deg);
  background: #111;
  background-image: -webkit-gradient(linear, left top, right bottom, from(#333), to(#111));
  background-image: linear-gradient(to bottom right, #333, #111);
}
.black-key-group .x90-front {
  -webkit-transform: rotateX(0deg);
          transform: rotateX(0deg);
  width: 30px;
  height: 40px;
  background: #333;
  background-image: -webkit-gradient(linear, top bottom, from(#111), to(#333));
  background-image: linear-gradient(to top bottom, #111, #333);
  position: relative;
}
.black-key-group .x90-front2 {
  -webkit-transform: rotateY(0deg);
          transform: rotateY(0deg);
  margin-left: 30px;
  width: 30px;
  height: 40px;
  background: #333;
  background-image: -webkit-gradient(linear, left top, right bottom, from(#222), to(#333));
  background-image: linear-gradient(to bottom right, #222, #333);
}
.black-key-group .f-notes {
  color: #eee;
  top: 5%;
}
.black-key-group .f-keymap {
  color: #eee;
  bottom: 5%;
}


.scene {
  position: absolute;
  width: 1200px;
  height: 0px;
  top:600px;
  left: -5%;
  right: 0;
  bottom: 0;
  margin: auto;
}

.menu1 {
  position:absolute;
  background:red;
  top: 20px;
  width:120%;
  height: 100vh;
  background: #191426;
  text-align: center;
  color: #C1B8B7;
  font-size: 14px;
  line-height: 70px;
}
.menu1 .options {
  border-left: 1px solid #2f2647;
  float: right;
  height: 70px;
  line-height: 70px;
}
 
 
 
.menu1 label {
  margin: 0 15px;
  vertical-align: middle;
  padding-top: 3px;
  line-height: 20px;
}

 
 

.animate {
  -webkit-animation-name: expand;
          animation-name: expand;
  -webkit-animation-duration: 10s;
          animation-duration: 10s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
  -webkit-animation-direction: alternate;
          animation-direction: alternate;
}

@-webkit-keyframes expand {
  0% {
    -webkit-transform: rotateY(-30deg) rotateX(-40deg);
            transform: rotateY(-30deg) rotateX(-40deg);
  }
  100% {
    -webkit-transform: rotateY(20deg) rotateX(-35deg);
            transform: rotateY(20deg) rotateX(-35deg);
  }
}

@keyframes expand {
  0% {
    -webkit-transform: rotateY(-30deg) rotateX(-40deg);
            transform: rotateY(-30deg) rotateX(-40deg);
  }
  100% {
    -webkit-transform: rotateY(20deg) rotateX(-35deg);
            transform: rotateY(20deg) rotateX(-35deg);
  }
}
/* 
 * CUSTOM DROP 
 * https://codepen.io/Thibaut/pen/Jasci
 */
.dropdown {
  display: inline-block;
  position: relative;
  overflow: hidden;
  vertical-align: middle;
  height: 28px;
  width: 150px;
  background: #f2f2f2;
  line-height: 20px;
  border: 1px solid;
  border-color: white #f7f7f7 whitesmoke;
  border-radius: 3px;
  background-image: -webkit-gradient(linear, left top, left bottom, from(transparent), to(rgba(0, 0, 0, 0.06)));
  background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.06));
  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.08);
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.08);
}

.dropdown:before, .dropdown:after {
  content: '';
  position: absolute;
  z-index: 2;
  top: 9px;
  right: 10px;
  width: 0;
  height: 0;
  border: 4px dashed;
  border-color: #888888 transparent;
  pointer-events: none;
}

.dropdown:before {
  border-bottom-style: solid;
  border-top: none;
}

.dropdown:after {
  margin-top: 7px;
  border-top-style: solid;
  border-bottom: none;
}

.dropdown-select {
  position: relative;
  width: 130%;
  margin: 0;
  padding: 6px 8px 6px 10px;
  height: 28px;
  line-height: 14px;
  font-size: 16px;
  color: #62717a;
  text-shadow: 0 1px white;
  background: #f2f2f2;
  /* Fallback for IE 8 */
  background: rgba(0, 0, 0, 0) !important;
  /* "transparent" doesn't work with Opera */
  border: 0;
  border-radius: 0;
  -webkit-appearance: none;
}

.dropdown-select:focus {
  z-index: 3;
  width: 100%;
  color: #394349;
  outline: 2px solid #49aff2;
  outline: 2px solid -webkit-focus-ring-color;
  outline-offset: -2px;
}

.dropdown-select > option {
  margin: 3px;
  padding: 6px 8px;
  text-shadow: none;
  background: #f2f2f2;
  border-radius: 3px;
  cursor: pointer;
}

/* Fix for IE 8 putting the arrows behind the select element. */
.lt-ie9 .dropdown {
  z-index: 1;
}

.lt-ie9 .dropdown-select {
  z-index: -1;
}

.lt-ie9 .dropdown-select:focus {
  z-index: 3;
}

/* Dirty fix for Firefox adding padding where it shouldn't. */
@-moz-document url-prefix() {
  .dropdown-select {
    padding-left: 6px;
  }
}
/* 
 * CUSTOM CHECKBOX  
 * https://codepen.io/CreativeJuiz/pen/BiHzp 
 */
/* Base for label styling */
[type="checkbox"]:not(:checked),
[type="checkbox"]:checked {
  position: absolute;
  left: -9999px;
}

[type="checkbox"]:not(:checked) + label,
[type="checkbox"]:checked + label {
  position: relative;
  padding-left: 25px;
  cursor: pointer;
}

/* checkbox aspect */
[type="checkbox"]:not(:checked) + label:before,
[type="checkbox"]:checked + label:before {
  content: '';
  position: absolute;
  left: 0;
  top: 2px;
  width: 17px;
  height: 17px;
  border: 1px solid #aaa;
  background: #f8f8f8;
  border-radius: 3px;
  -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3);
          box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3);
}

/* checked mark aspect */
[type="checkbox"]:not(:checked) + label:after,
[type="checkbox"]:checked + label:after {
  content: '?';
  position: absolute;
  top: 0;
  left: -2px;
  font-size: 35px;
  color: #47AFC4;
  -webkit-transition: all .2s;
  transition: all .2s;
}

/* checked mark aspect changes */
[type="checkbox"]:not(:checked) + label:after {
  opacity: 0;
  -webkit-transform: scale(0);
          transform: scale(0);
}

[type="checkbox"]:checked + label:after {
  opacity: 1;
  -webkit-transform: scale(1);
          transform: scale(1);
}

/* disabled checkbox */
[type="checkbox"]:disabled:not(:checked) + label:before,
[type="checkbox"]:disabled:checked + label:before {
  -webkit-box-shadow: none;
          box-shadow: none;
  border-color: #bbb;
  background-color: #ddd;
}

[type="checkbox"]:disabled:checked + label:after {
  color: #999;
}

[type="checkbox"]:disabled + label {
  color: #aaa;
}

/* accessibility */
[type="checkbox"]:checked:focus + label:before,
[type="checkbox"]:not(:checked):focus + label:before {
  border: 1px dotted blue;
}

  
 </style>

</head>

<h1 >
 Spiele mit Piano
</h1>
<div id="alles">
 <div class="menu1">
  
 <input id="volume" type="range" min="0" max="1" step="0.1" value="0.1"/>+
 
      
     
            
            
 <label for="instrument">Instruments</label>
                <div class="dropdown">
 <select id='instrument' class="dropdown-select">
  <option value="1">Church Organ</option>
   <option value="2">Cloud Song</option>
    <option value="3">Tom Crazy</option>
 <option value="4">Phone</option>
                    </select>
                </div>
 <span> <input type="checkbox" value='vibrato' id="vibrato">
 <label for="vibrato">Vibrato</label>
                </span>
  </div>
    

 
        <div class="scene">
 <div class="piano animate" id="piano">   
            </div>
        </div>
     </div>

   <script>
     
     ;(function( win, doc, $ ){

    'use strict';

	var __KEYSPRESSED = [], 
		__PLAYINGNOTES = [], 
		__STOPPEDNOTES = [],
		__INSTRUMENT = 1, 
		__VOLUME = 0.1, 
		__VIBRATO = false, 
		__OCTAVE = 3,
		audio_context, 
		oscillator;

	function Piano( octave, target ) {
		this.octave = octave;
		this.notes = ['c', 'd', 'e', 'f', 'g', 'a', 'b'];
		this.susNotes = ['c', 'd', 'f', 'g', 'a'];
		this.mapNotes = ['c', 'd', 'e', 'f', 'g', 'a', 'b','c#', 'd#', 'f#', 'g#', 'a#', 'c', 'd', 'e', 'c#', 'd#', 'f#', 'g#'];
		this.keymap = ['a', 's', 'd', 'f', 'g','h', 'j','w',  'e',  'r',   't', 'y',  'k', 'l', 'ç',  'u', 'i',   'o',  'p'];
		this.target = target;
		this.init();
	}

	Piano.prototype = {
		init: function() {
			this.$target = $( this.target );
			this.createKeys();
			this.bindEvents();
			this.changeOctave();
		},
		createKeys: function() {
			var key,whiteW=60, blackW = ( whiteW / 2 ), o = this.octave, wWidth=0, bWidth=blackW + (blackW/2);
			for( var k=0; k<o; k+=1 ) {

				for( var i=0, l=this.notes.length; i<l; i+=1 ) {
					key = this.createKey();
					key.find( '.f-notes' ).html( this.notes[ i ].toUpperCase() );
					key.addClass( 'white-key-group' );
					key.addClass( 'key' );
					key.addClass( 'tom-' + this.notes[ i ] );
					key.attr('data-note', this.notes[ i ].toUpperCase() + ( k + 3 ) );
					key.css('left', wWidth + 'px' );
					this.$target.append( key );
					wWidth += whiteW;

					if( i !== 2 && i !== 6 ) {
						key = this.createKey();
						key.find( '.f-notes' ).html( this.notes[ i ].toUpperCase() + '#' );
						key.addClass( 'black-key-group' );
						key.addClass( 'key' );
						key.addClass( 'tom-s' + this.notes[ i ] );
						key.attr('data-note', this.notes[ i ].toUpperCase()  + '#' + ( k + 3 ) );
						key.css('left', bWidth + 'px' );
						this.$target.append( key );
					}
					bWidth += whiteW;
				}
			}
		},
		changeOctave: function( octave ) {
			var self = this;

			self.$target.find( '.f-keymap' ).html( '' );
			var i=0, j=0, oc = octave || __OCTAVE; 
			this.mapNotes.forEach( function( e ) { 
				if( i===12 ) {
					oc++ ; i=0; 
				} 
				self.$target.find( 'div[data-note='+ e.toUpperCase() + oc + ']').find('.f-keymap').html( self.keymap[ j ].toUpperCase() ); 
				i++; 
				j++; 
			});
		},
		createKey: function() {
			return 	$('<div><div class="tec y90-left size-lr"></div><div class="tec y90-right size-lr"></div><div class="tec x90-top keyTop size-t"></div><div class="tec x90-front"><span class="f-keymap"></span><span class="f-notes"></span></div> </div> ');
		},
		bindEvents: function() {
			var $keys = $( '.key' );
			$keys.on( 'mouseenter', function( e ) {
				var $el = $( e.currentTarget ), freqs, freq;
				if( $el.hasClass('white-key-group') ) {
					$el.addClass( 'pressed' );
				} else {
					$el.addClass( 'pressed-black ' );
				}
				$el.addClass( 'active' );
				freq = mplay.getFrequency( $el.attr( 'data-note' ) );
				freqs = mplay.getInstrument( freq, __INSTRUMENT, __VIBRATO );
				mplay.play( freqs );
			});
			$keys.on( 'mouseout', function( e ) {
				var $el = $( e.currentTarget );
				if( $el.hasClass('white-key-group') ) {
					$el.removeClass( 'pressed' );
				} else {
					$el.removeClass( 'pressed-black ' );
				}
				$el.removeClass( 'active' );
				mplay.stop();
			});
		}
	};

	$( doc ).ready(function() {
		var $oct1 = $( '#oct1' ),$oct2 = $( '#oct2' );
		var _changeOctave = function( oct ) {
			if( oct ) {				
				$oct1.addClass( 'b-active' );
				$oct2.removeClass( 'b-active' );
			} else {				
				$oct1.removeClass( 'b-active' );
				$oct2.addClass( 'b-active' );
			}
		};
		
		try {
			var Tmp = win.AudioContext || win.webkitAudioContext;
			audio_context = new Tmp();
		} catch (e) {
			alert('No web audio oscillator support in this browser');
		}

		$( doc ).keydown(function( e ) {
			e.preventDefault();
			
			if( __KEYSPRESSED.indexOf( e.which ) === -1 ) {
				__KEYSPRESSED.push( e.which );
			}
			if( e.which === 49 ) {
				__OCTAVE = 3;
				piano.changeOctave();
				_changeOctave( true );
				
			}
			if( e.which === 50 ) {
				__OCTAVE = 4;
				piano.changeOctave();
				_changeOctave( false );
			}
		});
		$( doc ).keyup(function( e ) {
			e.preventDefault();
			var io = __KEYSPRESSED.indexOf( e.which );
			if( io !== -1 ) {
				__KEYSPRESSED.splice( io, 1 );
				__STOPPEDNOTES.push( e.which );
			}
		});
		$( '#vibrato').on( 'change', function( e ) {
			__VIBRATO = $( e.currentTarget ).is(':checked') ? true : false;
		});
		$( '#animate').on( 'change', function( e ) {
			if( $( e.currentTarget ).is(':checked') ) {
				win.piano.$target.addClass( 'animate' );
			} else {
				win.piano.$target.removeClass( 'animate' );
			}
		});
		$( '#instrument').on( 'change', function( e ) {
			__INSTRUMENT = +e.currentTarget.selectedIndex + 1;
		});
		$( '#volume').on( 'change', function( e ) {
			__VOLUME = +e.currentTarget.value;
		});

		$( '#notes' ).on( 'change', function( e ) {
			if( $( e.currentTarget ).is(':checked') ) {
				win.piano.$target.find( '.f-notes' ).addClass( 'info-active' );
			} else {
				win.piano.$target.find( '.f-notes' ).removeClass( 'info-active' );
			}
		});
		$( '#keymap' ).on( 'change', function( e ) {
			if( $( e.currentTarget ).is(':checked') ) {
				win.piano.$target.find( '.f-keymap' ).addClass( 'info-active' );
			} else {
				win.piano.$target.find( '.f-keymap' ).removeClass( 'info-active' );
			}
		});
		$( '.box' ).on( 'click', function( e ) {
			if( $( e.currentTarget ).attr( 'id' ) === 'oct1' ) {
				__OCTAVE = 3;
				piano.changeOctave();
				_changeOctave( true );
			} else {
				__OCTAVE = 4;
				piano.changeOctave();
				_changeOctave( false );
			}
		});

		win.piano = new Piano(3, '#piano');
		setInterval( mplay.render, 0 );
	});


	var mplay = {};
	var fq = [];
	mplay.play = function ( freqs, key ) {
		var oscs = [], o, i, g;
		freqs.forEach( function( freq ) {
			g = createGain();
			g.gain.value = __VOLUME;
			o = audio_context.createOscillator();
			o.frequency.value = freq;
			o.connect( g );
			g.connect( audio_context.destination );
			_play( 0 );
			oscs.push( o );
		});
		fq[ key ] = oscs;

		function createGain() {
			var out;
			if( audio_context.createGain ) {
				out = audio_context.createGain();
			} else if ( audio_context.createGainNode ) {
				out = audio_context.createGainNode();
			}
			return out;
		}
		function _play( arg ) {
			if( o.noteOn ) {
				o.noteOn( arg );
			} else if ( o.start ) {
				o.start( arg );
			}
		}
	};

	mplay.stop = function ( key ) {
		fq[ key ].forEach( function( o ) {
			_stop( 0, o );
		});
		function _stop( arg, o ) {
			if( o.noteOff ) {
				o.noteOff( arg );
			} else if ( o.stop ) {
				o.stop( arg );
			}
		}

	};

	mplay.getKeyMap = function( map ) {
		switch( map ) {
			case 65:
				return 'C' + __OCTAVE;
			case 83:
				return 'D' + __OCTAVE;
			case 68:
				return 'E' + __OCTAVE;
			case 70:
				return 'F' + __OCTAVE;
			case 71:
				return 'G' + __OCTAVE;
			case 72:
				return 'A' + __OCTAVE;
			case 74:
				return 'B' + __OCTAVE;
			case 87:
				return 'C#' + __OCTAVE;
			case 69:
				return 'D#' + __OCTAVE;
			case 82:
				return 'F#' + __OCTAVE;
			case 84:
				return 'G#' + __OCTAVE;
			case 89:
				return 'A#' + __OCTAVE;
			case 75:
				return 'C' + ( __OCTAVE + 1 );
			case 76:
				return 'D' + ( __OCTAVE + 1 );
			case 186:
				return 'E' + ( __OCTAVE + 1 );
			case 220:
				return 'F' + ( __OCTAVE + 1 );
			case 85:
				return 'C#' + ( __OCTAVE + 1 );
			case 73:
				return 'D#' + ( __OCTAVE + 1 );
			case 79:
				return 'F#' + ( __OCTAVE + 1 );
			case 80:
				return 'G#' + ( __OCTAVE + 1 );
			case 65:
				return 'A#' + ( __OCTAVE + 1 );
			default:
				return false;
		}
	};

	mplay.render = function() {
		var freq, keyMap, $el;
		__KEYSPRESSED.forEach( function( key ) {
			if( __PLAYINGNOTES.indexOf( key ) === -1 ) {
				keyMap = mplay.getKeyMap( key );
				if( keyMap ) {
					freq = mplay.getFrequency( keyMap );
					mplay.play( mplay.getInstrument( freq, __INSTRUMENT, __VIBRATO ), key );
					__PLAYINGNOTES.push( key );
					$el = $('div[data-note=' + keyMap + ']');

					if( $el.hasClass('white-key-group') ) {
						$el.addClass( 'pressed' );
					} else {
						$el.addClass( 'pressed-black ' );
					}
					$el.addClass( 'active' );
				}
			}
		});
		__STOPPEDNOTES.forEach( function( key ) {
			keyMap = mplay.getKeyMap( key );
			if( keyMap ) {
				mplay.stop( key );
				__STOPPEDNOTES.splice( __STOPPEDNOTES.indexOf( key ), 1 );
				__PLAYINGNOTES.splice( __PLAYINGNOTES.indexOf( key ), 1 );
				$el = $('div[data-note=' + keyMap + ']');
				if( $el.hasClass('white-key-group') ) {
					$el.removeClass( 'pressed' );
				} else {
					$el.removeClass( 'pressed-black ' );
				}
				$el.removeClass( 'active' );
			}
		});
	};

	// From Retrojs
	// https://github.com/eshiota/retro-audio-js
	mplay.getFrequency= function (note) {
		var notes = ["A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"], octave, keyNumber;

		if (note.length === 3) {
			octave = note.charAt(2);
		} else {
			octave = note.charAt(1);
		}
		octave = +octave + 1;

		keyNumber = notes.indexOf(note.slice(0, -1));

		if (keyNumber < 3) {
			keyNumber = keyNumber + 12 + ((octave - 1) * 12) + 1;
		} else {
			keyNumber = keyNumber + ((octave - 1) * 12) + 1;
		}

		// Return frequency of note
		return Math.floor(440 * Math.pow(2, (keyNumber - 49) / 12));
	};
	mplay.getInstrument = function( freq, instrument, vibrato ) {
		var freqs = [];

		switch( instrument ) {
			case 1:
				freqs.push( freq );
				freqs.push( freq * 2 );
				freqs.push( freq * 4 );
				freqs.push( freq * 8.5);
				freqs.push( freq * 19 );
				freqs.push( freq / 2 );
				break;
			case 2:
				freqs.push( freq );
				freqs.push( freq * (freq / ( freq -1 ) ) );
				freqs.push( freq * (freq / ( freq -5 ) ) );
				freqs.push( freq * (freq * ( freq -22 ) ) );
				freqs.push( freq * 4 );				
				freqs.push( freq / 2 );
				freqs.push( freq / 3 );
				break;
			case 3:
				freqs.push( freq );
				freqs.push( freq * (freq * ( freq -122 ) ) );
				freqs.push( freq * (freq * ( freq -22 ) ) );
				freqs.push( freq * (freq * ( freq -2 ) ) );
				freqs.push( freq * 23 );
				freqs.push( freq * 1.221 );
				freqs.push( freq / 2 );
				freqs.push( freq / 2.2 );
				freqs.push( freq / 3 );
				break;
			case 4:
				freqs.push( freq * 2 );
				freqs.push( freq / 2 );
				break;

		}
		if( vibrato ) {
			freqs.push( freq * (freq / ( freq -5 ) ) );
		}
		return freqs;
	};
}( window, document, $ )); 
     
     </script>