How to play a specific frequency with Javascript?

2020-08-09 10:31发布

问题:

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.

回答1:

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();



回答2:

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.