使用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:
- 使用长时间预先录制的ogg / mp3采样音,将其embedded到独立的
audio
元素中,并在按键时启动和停止。 - 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); };