Generating sound on the fly with javascript/html5

前端 未结 7 1879
庸人自扰
庸人自扰 2020-12-12 13:09

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 cal

相关标签:
7条回答
  • 2020-12-12 13:22

    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).

    0 讨论(0)
  • 2020-12-12 13:31

    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.)
    0 讨论(0)
  • 2020-12-12 13:34

    Web Audio API is coming to Chrome. See http://googlechrome.github.io/web-audio-samples/samples/audio/index.html

    Follow the directions in "Getting Started" there, and then check out the very impressive demos.

    Update(2017): by now this is a much more mature interface. The API is documented at https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API

    0 讨论(0)
  • 2020-12-12 13:34

    This is not real answer on your question because you have asked for a JavaScript solution, but you can use ActionScript. It should run on all major browsers.

    • ActionScript API Audio Generation

    You can call ActionScript functions from within JavaScript.

    • ActionScript API Call JavaScript

    In that way you can wrap the ActionScript sound generation functions and make a JavaScript implementation of them. Just use Adobe Flex to build a tiny swf and then use that as backend for your JavaScript code.

    0 讨论(0)
  • 2020-12-12 13:46

    Sure! You could use the tone synthesizer in this demo:

    audioCtx = new(window.AudioContext || window.webkitAudioContext)();
    
    show();
    
    function show() {
      frequency = document.getElementById("fIn").value;
      document.getElementById("fOut").innerHTML = frequency + ' Hz';
    
      switch (document.getElementById("tIn").value * 1) {
        case 0: type = 'sine'; break;
        case 1: type = 'square'; break;
        case 2: type = 'sawtooth'; break;
        case 3: type = 'triangle'; break;
      }
      document.getElementById("tOut").innerHTML = type;
    
      volume = document.getElementById("vIn").value / 100;
      document.getElementById("vOut").innerHTML = volume;
    
      duration = document.getElementById("dIn").value;
      document.getElementById("dOut").innerHTML = duration + ' ms';
    }
    
    function beep() {
      var oscillator = audioCtx.createOscillator();
      var gainNode = audioCtx.createGain();
    
      oscillator.connect(gainNode);
      gainNode.connect(audioCtx.destination);
    
      gainNode.gain.value = volume;
      oscillator.frequency.value = frequency;
      oscillator.type = type;
    
      oscillator.start();
    
      setTimeout(
        function() {
          oscillator.stop();
        },
        duration
      );
    };
    frequency
    <input type="range" id="fIn" min="40" max="6000" oninput="show()" />
    <span id="fOut"></span><br>
    type
    <input type="range" id="tIn" min="0" max="3" oninput="show()" />
    <span id="tOut"></span><br>
    volume
    <input type="range" id="vIn" min="0" max="100" oninput="show()" />
    <span id="vOut"></span><br>
    duration
    <input type="range" id="dIn" min="1" max="5000" oninput="show()" />
    <span id="dOut"></span>
    <br>
    <button onclick='beep();'>Play</button>

    Have fun!

    I got the solution from Houshalter here: How do I make Javascript beep?

    You can clone and tweak the code here: Tone synthesizer demo on JS Bin

    Compatible browsers:

    • Chrome mobile & desktop
    • Firefox mobile & desktop Opera mobile, mini & desktop
    • Android browser
    • Microsoft Edge browser
    • Safari on iPhone or iPad

    Not Compatible

    • Internet Explorer version 11 (but does work on the Edge browser)
    0 讨论(0)
  • 2020-12-12 13:47

    This is what I have looked for like forever and in the end I managed to do it myself like I wanted. Maybe you will like it too. Simple slider with frequency and push on/off:

    buttonClickResult = function () {
    	var button = document.getElementById('btn1');
    
    	button.onclick = function buttonClicked()  {
    
    		if(button.className=="off")  {
    			button.className="on";
    			oscOn ();
    		}
    
    		else if(button.className=="on")  {
    			button.className="off";
    			oscillator.disconnect();
    		}
    	}
    };
    
    buttonClickResult();
    
    var oscOn = function(){
    
    	window.AudioContext = window.AudioContext || window.webkitAudioContext;
    	var context = new AudioContext();
    	var gainNode = context.createGain ? context.createGain() : context.createGainNode();
    
    	//context = new window.AudioContext();
    	oscillator = context.createOscillator(),
    			oscillator.type ='sine';
    
    	oscillator.frequency.value = document.getElementById("fIn").value;
    	//gainNode = createGainNode();
    	oscillator.connect(gainNode);
    	gainNode.connect(context.destination);
    	gainNode.gain.value = 1;
    	oscillator.start(0);
    };
    <p class="texts">Frekvence [Hz]</p>
    <input type="range" id="fIn" min="20" max="20000" step="100" value="1234" oninput="show()" />
    <span id="fOut"></span><br>
    <input class="off" type="button" id="btn1" value="Start / Stop" />

    0 讨论(0)
提交回复
热议问题