Reputation: 3794
I want a function that works like this:
playSound(345, 1000)
Which would play a tone of 345 hz for 1000 milliseconds. What is the simplest way to achieve this in JavaScript? I don't mind if it uses a sample (maybe of a sin wave, or piano), or uses the computer's hardware to generate the sound.
Upvotes: 19
Views: 18580
Reputation: 2306
As already pointed out in the comments, the way to do it is through the OscillatorNode
.
// create web audio api context
var audioCtx = new(window.AudioContext || window.webkitAudioContext)();
function playNote(frequency, duration) {
// create Oscillator node
var oscillator = audioCtx.createOscillator();
oscillator.type = 'square';
oscillator.frequency.value = frequency; // value in hertz
oscillator.connect(audioCtx.destination);
oscillator.start();
setTimeout(
function() {
oscillator.stop();
playMelody();
}, duration);
}
function playMelody() {
if (notes.length > 0) {
note = notes.pop();
playNote(note[0], 1000 * 256 / (note[1] * tempo));
}
}
notes = [
[659, 4],
[659, 4],
[659, 4],
[523, 8],
[0, 16],
[783, 16],
[659, 4],
[523, 8],
[0, 16],
[783, 16],
[659, 4],
[0, 4],
[987, 4],
[987, 4],
[987, 4],
[1046, 8],
[0, 16],
[783, 16],
[622, 4],
[523, 8],
[0, 16],
[783, 16],
[659, 4]
];
notes.reverse();
tempo = 100;
playMelody();
Upvotes: 31
Reputation: 213
There is a library called simpleTones.js that greatly simplifies the Web Audio API to do exactly what you are attempting.
Once the library is included in your project, playing a timed frequency is as easy as calling
playTone(345, sine, 1)
345 being the frequency in Hz, sine being the wave pattern(there are other wave pattern options as well) and "1" being one second, or 1000 milliseconds.
You can download the library and read the documentation here: https://github.com/escottalexander/simpleTones.js
Best of luck on your project.
Upvotes: 10