var audioContext = new AudioContext(); var note = null; function playNote(frequency) { if(note !== null) { stopNote(note.frequency.value); } note = audioContext.createOscillator(); note.frequency.value = frequency; note.detune.value = 0; note.type = 'sine'; note.connect(audioContext.destination); note.start(0); $('[data-note="'+frequency+'"]').addClass('active'); } function stopNote(frequency) { if(note !== null && note.frequency.value == frequency) { note.stop(); note = null; $('[data-note="'+frequency+'"]').removeClass('active'); } } $(document).on('click', '[data-key]:not(.active)', function(){ playNote($(this).data('note')); }); $(document).on('click', '[data-key].active', function(){ stopNote($(this).data('note')); }); $(document).on('keydown', function(event){ var key = $('[data-key="'+String.fromCharCode(event.which)+'"]'); if(!key.is('.active')) { key.trigger('click'); } }); $(document).on('keyup', function(event){ var key = $('[data-key="'+String.fromCharCode(event.which)+'"]'); if(key.is('.active')) { key.trigger('click'); } });