Skip to content

Instantly share code, notes, and snippets.

@sevaa
Last active August 25, 2025 15:59
Show Gist options
  • Select an option

  • Save sevaa/2d84822540bf1fc8b8deab255d6209eb to your computer and use it in GitHub Desktop.

Select an option

Save sevaa/2d84822540bf1fc8b8deab255d6209eb to your computer and use it in GitHub Desktop.
Generating a simple musical tone purely from JavaScript
function GenerateTone(frequency, duration, volume, rate)
{
if (!volume)
volume = 30000;
if (!rate)
rate = 8000;
const nSamples = rate * duration,
w = (2 * Math.PI * frequency) / rate,
wav = new ArrayBuffer(44 + nSamples*2);
(new Int32Array(wav, 0, 11)).set(
[0x46464952, 36 + nSamples*2, 0x45564157,
0x20746d66, 16, 0x10001, rate, rate*2, 0x100002,
0x61746164, nSamples*2], 0);
const samples = new Int16Array(wav, 44, nSamples);
for (let i = 0; i < nSamples; i++)
samples[i] = volume * Math.sin(w * i);
return URL.createObjectURL(new Blob([wav], {type: "audio/wav"}));
}
@sevaa
Copy link
Author

sevaa commented Nov 7, 2016

Today's snippet: generating a simple musical tone purely from JavaScript. I saw some online samples for doing it on a server (e. g. in PHP) and sending to the client, but that's a waste of bandwidth.

The ingredients are twofold:

  • An element with a source that's populated from a blob: URI
  • An ArrayBuffer object with WAV data inside

There's a concise description of the WAV format here. My implementation limits the format to 16-bit mono PCM.

The GenerateTone() function returns a blob: URI with a WAV file in it. The parameters are:

  • frequency in Hz
  • duration in seconds
  • volume - max is 32768, min is 0
  • rate - in samples per second, default 8000 is enough for simple beeps

That's it. All that remains is feeding that data to an element. Assuming you have an <audio id="MyAudio"> element on the page:

var audio = document.getElementById("MyAudio");
audio.src = GenerateTone(349.23, 0.5); //The F note
audio.play(); 

An older version of this gist used a data: URL and contained a ToBase64() function. Check the gist history if you need one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment