使用javascript / html5即时生成声音

是否有可能与JavaScript / HTML生成一个不断的声音stream? 例如,为了产生一个永久的正弦波,我会有一个callback函数,当输出缓冲区变为空的时候会被调用:

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

(这个想法是用这个来制作一个交互式的合成器,我不知道一个键被按下多久,所以我不能使用一个固定长度的缓冲器)

使用HTML5audio元素

使用JavaScript和audio元素的跨浏览器生成持续audio目前是不可能的,正如Steven Wittens 在创buildJavaScript合成器的博客文章中指出的那样:

“…没有办法排队合成audio块无缝播放”。

使用WebaudioAPI

Web Audio API旨在促进JavaScriptaudio合成。 Mozilla开发者networking有一个基于Web的audio发生器 ,可以在Firefox 4 + [ demo 1 ]中使用。 将这两行代码添加到该代码中,并且在按键时有一个可生成持续audio的工作合成器[ 演示2 – 仅在Firefox 4中工作,请先单击“结果”区域,然后按任意键):

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

BBC的Web Audio API页面也值得一读 。 不幸的是,对Web Audio API的支持还没有扩展到其他浏览器。

可能的解决方法

要创build一个跨浏览器合成器目前,你可能会不得不回落预先录制的audio:

  1. 使用长时间预先录制的ogg / mp3采样音,将其embedded到独立的audio元素中,并在按键时启动和停止。
  2. embedded包含audio元素的swf文件并通过JavaScript控制播放。 (这似乎是Google Les Paul Doodle采用的方法。)

您现在可以在大多数浏览器中使用Web Audio API ( IE和Opera Mini除外 )。

试试这个代码:

 // 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 

networkingaudioAPI即将到来。 请参阅http://googlechrome.github.io/web-audio-samples/samples/audio/index.html

按照“入门”中的说明,然后查看令人印象深刻的演示。

更新(2017):现在这是一个更成熟的界面。 该APIlogging在https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API

当然! 你可以在这个演示中使用音调合成器:

在这里输入图像说明

 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> 

对于你的问题,这不是真正的答案,因为你已经要求JavaScript解决scheme,但是你可以使用ActionScript。 它应该在所有主stream浏览器上运行。

  • ActionScript APIaudio生成

您可以从JavaScript中调用ActionScript函数。

  • ActionScript API调用JavaScript

通过这种方式,您可以包装ActionScript声音生成函数并对其进行JavaScript实现。 只需使用Adobe Flex构build一个小的swf,然后将其用作JavaScript代码的后端。

这就是我一直在寻找的东西,最终我自己就像我想要的那样去做。 也许你也会喜欢它。 简单地滑动频率,并推动/closuresHTML

 <pre> <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" /> </div> </pre>`enter code here 

`

JAVASCRIPT



     buttonClickResult = function(){
         var button = document.getElementById('btn1');

         button.onclick = function buttonClicked(){

            如果(button.className ==“off”){
                 button.className = “上”;
                 oscOn();
             }

             else if(button.className ==“on”){
                 button.className = “关”;
                 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);


     };