HTML5 Audio API
Changing the audio tone with JavaScript
To load sounds I'm using this simple script.
Note: the g namespace and AUDIOFORMAT variables are common in my games. I also use jQuery in a few places throughout my game code.
var g = {
audioContext: null,
sound: { source : null, gainNode: null, soundname: "beat", buffer: null, volume: 0 }
};
var AUDIOFORMAT = "";
$(document).ready(function(){
setAudio();
loadSound(g.sound);
});
function setAudio()
{
try
{
var a = document.createElement('audio');
if (a)
{
g.audioContext = new (window.AudioContext || window.webkitAudioContext || window.mozAudioContext)();
if (!g.audioContext) g.audioContext = AudioContext();
if (g.audioContext)
AUDIOFORMAT = "mp3";
} else {
console.log("No HTML5 audio.");
}
}
catch (e)
{
console.log("setAudio: " + e.message);
}
};
function loadSound(o)
{
try
{
var request = new XMLHttpRequest();
var url = "sfx/" + o.soundname + "." + AUDIOFORMAT;
request.open('GET', url, true);
request.responseType = 'arraybuffer';
// Decode asynchronously
request.onload = function ()
{
try
{
g.audioContext.decodeAudioData(request.response,
function(buffer)
{
o.buffer = buffer;
o.volume = 1;
},
function()
{
console.log("Decode error: " + url + ", " + arguments[0]);
}
);
}
catch (e)
{
console.log("loadSound(onLoad): " + e.message);
}
}
request.send();
}
catch (e)
{
console.log("LoadSound: " + e.message);
}
};
function sfx(o)
{
try
{
var source = g.audioContext.createBufferSource();
var gainNode = g.audioContext.createGain();
source.buffer = o.buffer;
source.loop = false;
source.connect(gainNode);
gainNode.connect(g.audioContext.destination);
gainNode.gain.value = 1;
source.start(0);
}
catch (e)
{
console.log("sfx: " + e.message);
}
};
I like the idea of creating a game that is set in the dark and the player must locate the exit while being pursued by an unknown threat. If I could use the HTML5 Audio API to programmatically effect the pitch of a sound I might be able to emulate a motion sensor...
playbackRate.value
By adjusting the playbackRate value I can effect a shift in the pitch by slowing down or speed up the playback of the audio.
e.g. source.playbackRate.value = 1
is the default.
A value of 0.5 would reduce the pitch and a value of 2 would increase it.
I've amended the sfx() function to allow for a second parameter (r) to be passed in that changes the playbackRate:
function sfx(o,r)
{
try
{
var source = g.audioContext.createBufferSource();
var gainNode = g.audioContext.createGain();
source.buffer = o.buffer;
source.loop = false;
source.connect(gainNode);
gainNode.connect(g.audioContext.destination);
gainNode.gain.value = 1;
source.playbackRate.value = r;
source.start(0);
}
catch (e)
{
console.log("sfx: " + e.message);
}
};
I am using a beat sound effect from one of my games as a test: