An HTML5 audio keyboard

After playing with a couple of keyboard and drum apps on the iPhone and being underwhelmed, I set out to see what kind of keyboard I could make in HTML5 and its new audio features.

I haven't gotten this to work very well on Safari on iPhone, which passes the audio off to QuickTime in a new window, but it works well in desktop versions of Safari and Chrome. Chrome is the most responsive - other bowsers are a little sluggish. In order to get this to work in Firefox, I had to save the audio as .ogg as well as .mp3, since Firefox won't play an mp3.

All keyboards are basically just "buttons" that trigger a sound. The sound could be anything - a drum sound, a piano note, or in this case, guitar chords.

To see a demo, click here.

The HTML, CSS, and javascript for this web app is pretty short and sweet (Just 30 lines of HTML and 6 elements styled in the CSS). Before that though a little about the sounds themselves.

To create my chord sounds, I recorded the series of chords using Audacity and exported each one by using Audacity's "Export selection to mp3" and "Export selection to Ogg" as shown in this screenshot. (For example "C.mp3" and "C.ogg" for the C chord.)

As with most things, there are several ways to accomplish the playing of audio. The most common way would be to use the <audio> tag.

For example, the following HTML would create an audio player, complete with controls (play, pause, etc.).


<audio controls>
<source src="mySong.mp3">
<source src="mySong.ogg">
</audio>

Note that the audio tag allows multiple sources. It will try to play each source in turn until it finds one that works.

This approach would work great to play songs, but in my case I want a user's click to generate a short sound, so I used javascript to play the audio. It's saved as "script.js".


function playme(x) {
var snd = x;
var sndmp = snd + ".mp3";
var sndog = snd + ".ogg";
var snd2 = new Audio(sndmp);
snd2.play();
var snd3 = new Audio(sndog);
snd3.play();
}

Originally this was just 2 lines of code, but as mentioned earlier, to get it to work in Firefox, I had to modify the script so it handled both .mp3's and .ogg's. Still it pretty simple.

Each button is created as an anchor tag that calls the playme function. For example:


<a href="#" onmousedown="playme('C')">C</a>

I originally used "onClick" but found that "onmousedown" was more responsive.

That's about all there is to it. Here is complete HTML source code:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="description" content="A mobile web app for playing sounds." />
<meta name="author" content="Bob Hay" />
<meta name="viewport" content="user-scalable=yes, width=device-width" />
<title>LIX - netnik.com</title>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body>
<div id="page">
<div id="header">
LIX
</div>
<div id="keyboard">
<a href="#" onmousedown="playme('C')">C</a>
<a href="#" onmousedown="playme('F')">F</a>
<a href="#" onmousedown="playme('G')">G</a>
<a href="#" onmousedown="playme('D')">D</a>
<a href="#" onmousedown="playme('A')">A</a>
<a href="#" onmousedown="playme('E')">E</a>
<a href="#" onmousedown="playme('Em')">Em</a>
<a href="#" onmousedown="playme('Am')">Am</a>
<a href="#" onmousedown="playme('Bm')">Bm</a>
</div>
</div>
</body>
</html>

And here is the CSS stylesheet:


html { height: 102%; }
body {
background-color: #333;
color: #444;
font-size: 16px;
font-family: helvetica, arial, sans-serif;
margin: 0;
padding: 0;
}
#header {
color: #fff;
background-color: #666;
font-size: 1.5em;
font-weight: bold;
padding: 4px 12px;
}
#page { max-width: 480px; margin: 0 auto; background-color: #eee; height: 400px; }
#keyboard a {
display: block;
height: 60px;
width: 22%;
background-color: #bbb;
float: left;
margin: 5px;
border: 1px solid #333;
text-decoration: none;
text-align: center;
padding: 10px;
font-size: 2em;
font-weight: bold;
color: #333;
-moz-box-shadow: 2px 2px 3px #333;
-webkit-box-shadow: 2px 2px 3px #333;
box-shadow: 2px 2px 3px #333;
outline: none;
}
#keyboard a:active {
background-color: #ace;
color: #f00;
}