Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating sound on the fly with javascript/html5

Is it possible to generate a constant sound stream with javascript/html5? For example, to generate a perpetual sine wave, I would have a callback function, that would be called whenever the output buffer is about to become empty:

function getSampleAt(timestep) {     return Math.sin(timestep); } 

(The idea is to use this to make an interactive synth. I don't know in advance how long a key will be pressed, so I can't use a fixed length buffer)

like image 716
Johannes Hoff Avatar asked Jun 14 '11 12:06

Johannes Hoff


People also ask

Can JavaScript generate sound?

The Web Audio API is used to control audio, which allows you to choose audio sources. You can also add effects; create audio visualizations, panning, etc.


2 Answers

You can use the Web Audio API in most browsers now (excepting IE and Opera Mini).

Try out this code:

// one context per document  var context = new (window.AudioContext || window.webkitAudioContext)();  var osc = context.createOscillator(); // instantiate an oscillator  osc.type = 'sine'; // this is the default - also square, sawtooth, triangle  osc.frequency.value = 440; // Hz  osc.connect(context.destination); // connect it to the destination  osc.start(); // start the oscillator  osc.stop(context.currentTime + 2); // stop 2 seconds after the current time

If you want the volume lower, you can do something like this:

var context = new webkitAudioContext(); var osc = context.createOscillator(); var vol = context.createGain();  vol.gain.value = 0.1; // from 0 to 1, 1 full volume, 0 is muted osc.connect(vol); // connect osc to vol vol.connect(context.destination); // connect vol to context destination osc.start(context.currentTime + 3); // start it three seconds from now 

I got most of this from experimenting in chromium while reading the Web Audio API Working Draft, which I found from @brainjam 's link.

I hope that helps. Lastly, it is very helpful to inspect the various objects in the chrome inspector (ctrl-shift-i).

like image 170
snapfractalpop Avatar answered Sep 24 '22 02:09

snapfractalpop


Using the HTML5 audio element

Cross-browser generative sustained audio using JavaScript and the audio element isn't currently possible, as Steven Wittens notes in a blog post on creating a JavaScript synth:

"...there is no way to queue up chunks of synthesized audio for seamless playback".

Using the Web Audio API

The Web Audio API was designed to facilitate JavaScript audio synthesis. The Mozilla Developer Network has a Web Based Tone Generator that works in Firefox 4+ [demo 1]. Add these two lines to that code and you have a working synth with generative sustained audio upon keypress [demo 2 - works in Firefox 4 only, click the 'Results' area first, then press any key]:

window.onkeydown = start;   window.onkeyup = stop; 

The BBC's page on the Web Audio API is worth reviewing too. Unfortunately, support for the Web Audio API doesn't extend to other browsers yet.

Possible workarounds

To create a cross-browser synth at present, you'll likely have to fall back on prerecorded audio by:

  1. Using long prerecorded ogg/mp3 sample tones, embedding them in separate audio elements and starting and stopping them upon keypress.
  2. Embedding an swf file containing the audio elements and controlling playback via JavaScript. (This appears to be the method that the Google Les Paul Doodle employs.)
like image 35
Nick Avatar answered Sep 25 '22 02:09

Nick