Edit in JSFiddle

var log = console.log.bind(console),
    keyData = document.getElementById('key_data'),
    midi;
var AudioContext = AudioContext || webkitAudioContext; // for ios/safari
var context = new AudioContext();
var btnBox = document.getElementById('content'),
    btn = document.getElementsByClassName('button');
var data, cmd, channel, type, note, velocity;

// request MIDI access
if (navigator.requestMIDIAccess) {
    navigator.requestMIDIAccess({
        sysex: false
    }).then(onMIDISuccess, onMIDIFailure);
} else {
    alert("No MIDI support in your browser.");
}

// add event listeners
document.addEventListener('keydown', keyController);
document.addEventListener('keyup', keyController);
for (var i = 0; i < btn.length; i++) {
    btn[i].addEventListener('mousedown', clickPlayOn);
    btn[i].addEventListener('mouseup', clickPlayOff);
}
// prepare audio files
for (var i = 0; i < btn.length; i++) {
    addAudioProperties(btn[i]);
}
// this maps the MIDI key value (60 - 64) to our samples
var sampleMap = {
    key60: 1,
    key61: 2,
    key62: 3,
    key63: 4,
    key64: 5
};
// user interaction, mouse click
function clickPlayOn(e) {
    e.target.classList.add('active');
    e.target.play();
}

function clickPlayOff(e) {
    e.target.classList.remove('active');
}
// qwerty keyboard controls. [q,w,e,r,t]
function keyController(e) {
    if (e.type == "keydown") {
        switch (e.keyCode) {
            case 81:
                btn[0].classList.add('active');
                btn[0].play();
                break;
            case 87:
                btn[1].classList.add('active');
                btn[1].play();
                break;
            case 69:
                btn[2].classList.add('active');
                btn[2].play();
                break;
            case 82:
                btn[3].classList.add('active');
                btn[3].play();
                break;
            case 84:
                btn[4].classList.add('active');
                btn[4].play();
                break;
            default:
                //console.log(e);
        }
    } else if (e.type == "keyup") {
        switch (e.keyCode) {
            case 81:
                btn[0].classList.remove('active');
                break;
            case 87:
                btn[1].classList.remove('active');
                break;
            case 69:
                btn[2].classList.remove('active');
                break;
            case 82:
                btn[3].classList.remove('active');
                break;
            case 84:
                btn[4].classList.remove('active');
                break;
            default:
                //console.log(e.keyCode);
        }
    }
}

// midi functions
function onMIDISuccess(midiAccess) {
    midi = midiAccess;
    var inputs = midi.inputs.values();
    // loop through all inputs
    for (var input = inputs.next(); input && !input.done; input = inputs.next()) {
        // listen for midi messages
        input.value.onmidimessage = onMIDIMessage;
        // this just lists our inputs in the console
        listInputs(input);
    }
    // listen for connect/disconnect message
    midi.onstatechange = onStateChange;
}

function onMIDIMessage(event) {
    data = event.data,
    cmd = data[0] >> 4,
    channel = data[0] & 0xf,
    type = data[0] & 0xf0, // channel agnostic message type. Thanks, Phil Burk.
    note = data[1],
    velocity = data[2];
    // with pressure and tilt off
    // note off: 128, cmd: 8 
    // note on: 144, cmd: 9
    // pressure / tilt on
    // pressure: 176, cmd 11: 
    // bend: 224, cmd: 14

    switch (type) {
        case 144: // noteOn message 
             noteOn(note, velocity);
             break;
        case 128: // noteOff message 
            noteOff(note, velocity);
            break;
    }

    //console.log('data', data, 'cmd', cmd, 'channel', channel);
    logger(keyData, 'key data', data);
}

function onStateChange(event) {
    var port = event.port,
        state = port.state,
        name = port.name,
        type = port.type;
    if (type == "input") console.log("name", name, "port", port, "state", state);
}

function listInputs(inputs) {
    var input = inputs.value;
    log("Input port : [ type:'" + input.type + "' id: '" + input.id +
        "' manufacturer: '" + input.manufacturer + "' name: '" + input.name +
        "' version: '" + input.version + "']");
}

function noteOn(midiNote, velocity) {
    player(midiNote, velocity);
}

function noteOff(midiNote, velocity) {
    player(midiNote, velocity);
}

function player(note, velocity) {
    var sample = sampleMap['key' + note];
    if (sample) {
        if (type == (0x80 & 0xf0) || velocity == 0) { //QuNexus always returns 144
            btn[sample - 1].classList.remove('active');
            return;
        }
        btn[sample - 1].classList.add('active');
        btn[sample - 1].play(velocity);
    }
}

function onMIDIFailure(e) {
    log("No access to MIDI devices or your browser doesn't support WebMIDI API. Please use WebMIDIAPIShim " + e);
}

// audio functions
// We'll go over these in detail in future posts
function loadAudio(object, url) {
    var request = new XMLHttpRequest();
    request.open('GET', url, true);
    request.responseType = 'arraybuffer';
    request.onload = function () {
        context.decodeAudioData(request.response, function (buffer) {
            object.buffer = buffer;
        });
    }
    request.send();
}

function addAudioProperties(object) {
    object.name = object.id;
    object.source = object.dataset.sound;
    loadAudio(object, object.source);
    object.play = function (volume) {
        var s = context.createBufferSource();
        var g = context.createGain();
        var v;
        s.buffer = object.buffer;
        s.playbackRate.value = randomRange(0.5, 2);
        if (volume) {
            v = rangeMap(volume, 1, 127, 0.2, 2);
            s.connect(g);
            g.gain.value = v * v;
            g.connect(context.destination);
        } else {
            s.connect(context.destination);
        }

        s.start();
        object.s = s;
    }
}

// utility functions
function randomRange(min, max) {
    return Math.random() * (max + min) + min;
}

function rangeMap(x, a1, a2, b1, b2) {
    return ((x - a1) / (a2 - a1)) * (b2 - b1) + b1;
}

function frequencyFromNoteNumber(note) {
    return 440 * Math.pow(2, (note - 69) / 12);
}

function logger(container, label, data) {
    messages = label + " [channel: " + (data[0] & 0xf) + ", cmd: " + (data[0] >> 4) + ", type: " + (data[0] & 0xf0) + " , note: " + data[1] + " , velocity: " + data[2] + "]";
    container.textContent = messages;
}
<div id="content">
    <div class="button" data-key="q" data-sound="https://dl.dropboxusercontent.com/s/h9sow482vkw06xe/dinky-kick.mp3"></div>
    <div class="button" data-key="w" data-sound="https://dl.dropboxusercontent.com/s/kkikcupdg9n1qiy/dinky-snare.mp3"></div>
    <div class="button" data-key="e" data-sound="https://dl.dropboxusercontent.com/s/d7jlxp5v4z0n62q/dinky-hat-2.mp3"></div>
    <div class="button" data-key="r" data-sound="https://dl.dropboxusercontent.com/s/rblgnob6tvriudy/dinky-cym.mp3"></div>
    <div class="button" data-key="t" data-sound="https://dl.dropboxusercontent.com/s/umm8cmrmn8n4a46/dinky-cym-noise.mp3"></div>
</div>
<div id="device_info">
    <div id="key_data"></div>
</div>
*:before, *:after {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}
h4 {
    margin: 0 0 5px 0;
}
p {
    margin: 0 0 10px 0;
}
#content, #device_info {
    max-width: 800px;
    /*height: 125px;*/
    margin: 0 auto;
    padding: 10px 0;
    font-family: sans-serif;
    font-size: 12px;
    line-height: 12px;
    letter-spacing: 1.5px;
}
#content, #key_data {
    margin-top: 0px;
    text-align: center;
}
#inputs, #outputs {
    display: inline-block;
    width: 49%;
    margin-top: 10px;
    vertical-align: top;
}
#outputs {
    text-align: right;
}
.info {
    padding: 20px;
    border-radius: 3px;
    box-shadow: inset 0 0 10px #ccc;
    background-color: rgba(233, 233, 233, 0.25);
}
.small {
    border-bottom: 1px solid #ccc;
    margin-left: 10px;
}
p:not(.small) {
    text-transform: uppercase;
    font-weight: 800;
}
.button {
    display: inline-block;
    width: 100px;
    height: 100px;
    margin: 10px;
    background-color: #00adef;
    border-radius: 10px;
    opacity: 1;
    cursor: pointer;
    border: 2px solid white;
    transition: all 0.2s;
}
.button.active {
    background-color: #9a6aad;
    opacity: 0.25;
    box-shadow: inset 0px 0px 30px orange;
    border: 2px solid rgba(100, 100, 100, 0.3);
    animation: shake .2s ease-in-out;
}
@keyframes shake {
    0% {
        transform: translateX(0);
        transform: translateY(0);
        transform: scale(1, 1);
    }
    20% {
        transform: translateX(-10px);
        transform: translateY(-100px);
        transform: scale(0.5, 0.75);
    }
    40% {
        transform: translateX(10px);
        transform: translateY(0px);
        transform: scale(1.5, 2);
    }
    60% {
        transform: translateX(-10px);
        transform: translateY(-50px);
        transform: scale(0.5, 0.75);
    }
    80% {
        transform: translateX(10px);
        transform: translateY(50px);
        transform: scale(1.3, 2);
    }
    100% {
        transform: translateX(0);
        transform: translateY(0);
    }
}