Javascript Web Audio API如何获得已播放的缓冲区数量,并安排下一个缓冲区在连续播放后立即播放?
硬编码音频效果是一个重要的工具,但有时您需要的是在采样级别通过每个采样的潜在不同且非常非线性甚至图灵完整函数不断重新定义声音,因此唯一的方法是将范围为-1到1的数字直接写入缓冲区 人们常说,用javascript生成实时声音样本有时间问题 因为它的实时声音将取决于其他游戏控件,比如频率与鼠标位置成比例,或者摄像机看到的东西,所以我需要知道每次javascript再次运行时,需要多少缓冲区来预计算和安排播放时间,可能是在间隔几毫秒的计时器上,或者在某些事件上(哪些活动可以做到这一点?) 在我的java软件中,我做到了这一点,它保存了麦克风缓冲区中剩余消耗数据和扬声器缓冲区中排队数据的统计信息,并使用这些统计信息以线性插值的方式连续调整消耗麦克风帧与产生扬声器帧的比率,主要在.99和1.01之间,因此当一个缓冲区被点亮时tle太大它收缩得更快,而扬声器和麦克风之间的延迟,对于Java函数中定义的任何可能的声音效果,都会迅速收缩。您得到的延迟更少,因为它通过统计数据观察计时并调整缓冲区的使用Javascript Web Audio API如何获得已播放的缓冲区数量,并安排下一个缓冲区在连续播放后立即播放?,javascript,web-audio-api,timing,Javascript,Web Audio Api,Timing,硬编码音频效果是一个重要的工具,但有时您需要的是在采样级别通过每个采样的潜在不同且非常非线性甚至图灵完整函数不断重新定义声音,因此唯一的方法是将范围为-1到1的数字直接写入缓冲区 人们常说,用javascript生成实时声音样本有时间问题 因为它的实时声音将取决于其他游戏控件,比如频率与鼠标位置成比例,或者摄像机看到的东西,所以我需要知道每次javascript再次运行时,需要多少缓冲区来预计算和安排播放时间,可能是在间隔几毫秒的计时器上,或者在某些事件上(哪些活动可以做到这一点?) 在我的ja
我想用Web音频API来做这件事,如果可能的话,在JavaScript级别,或者如果需要的话,我会考虑将一些JSoNoCARD代码移植到该项目中,如果它们的计算声音的方式是兼容的。 我应该怎么做才能访问缓冲区的使用量
如何安排另一个缓冲区在播放之前启动的缓冲区结束时立即继续播放 我需要知道播放第一个缓冲区还剩下多少,以选择要添加多少缓冲区,因为计时中的小错误会导致大延迟 下面是javascript代码(适用于Windows 7中的Chrome、Firefox和Opera),用于生成从特定时间开始的一次性声音(频率不断上升):var audConType = window.AudioContext || window.webkitAudioContext;
var context = new audConType();
var around = 0;
var aroundSpeed = .1;
var soundFunc = function(amplitudeIn){ //ignore amplitudeIn for now
aroundSpeed += .000002;
return Math.sin(around += aroundSpeed);
};
var channels = 1;
var howManyFrames = 50000;
var rate = 44100;
var buffer = context.createBuffer(channels, howManyFrames, rate);
for(var channel=0; channel<channels; channel++){
var chanBuf = buffer.getChannelData(channel);
for (var f=0; f<howManyFrames; f++){
chanBuf[f] = soundFunc(0);
}
}
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.start();
var audConType=window.AudioContext | | window.webkitadiocontext;
var context=new audConType();
var约为0;
var aroundSpeed=.1;
var soundFunc=函数(amplitudeIn){//暂时忽略amplitudeIn
速度+=0.000002左右;
返回Math.sin(大约+=大约速度);
};
var通道=1;
var howManyFrames=50000;
var率=44100;
var buffer=context.createBuffer(通道、多少帧、速率);
对于(var channel=0;channel执行此操作的最佳方法不是使用AudioBuffers,而是使用ScriptProcessor(目前,这将由AudioWorker取代,但尚未在任何地方实现)。这将使您能够以动态方式完全控制音频位。For me缓冲区在每次启动和停止后都能正常工作。它们允许缓冲任意数量的音频,而无需任何延迟(只是生成缓冲区的时间)然而,尽管缓冲区大小很小,处理器仍有16k样本的限制,延迟非常糟糕。缓冲区也可以立即停止并重新启动。当UI被长时间阻止时(例如,当您想关闭此页面的弹出窗口处于活动状态时),处理器将产生可怕的噪音。缓冲区工作得如此之好,我甚至不知道在它最终实现时我会使用audioworker。引用原始问题:“有时,你想要的是通过每个样本的潜在不同的、非常非线性的甚至图灵完全函数,在样本级别上不断地重新定义声音,因此唯一的方法是将范围为-1到1的数字直接写入缓冲区。”这听起来与AudioWorkers的目标场景一模一样。(AudioWorker将解决ScriptProcessor的实际问题,如UI阻塞问题。)如果缓冲区适合您,请使用它们;缓冲区的正确调度经常会出现问题,这就是为什么我不会首先指出该解决方案的原因。
var volume = .7;
var maxMicrophoneAmplitude = 1;
var soundFunc = function(ins, outs){
var microphoneAmplitude = ins[0];
var estimatedFramesPerSecond = 44100;
var decaySeconds = .1;
var decay = 1/(estimatedFramesPerSecond*decaySeconds);
maxMicrophoneAmplitude = Math.max(maxMicrophoneAmplitude, microphoneAmplitude)*(1-decay);
microphoneAmplitude/maxMicrophoneAmplitude * volume
outs[0] = microphoneAmplitude/maxMicrophoneAmplitude * volume;
};
soundFunc.inSize = 1;
soundFunc.outSize = 1;
var inputNodes = {};
window.onload = function(){
var context = new AudioContext();
if(!navigator.getUserMedia && navigator['mozGetUserMedia']){
navigator.getUserMedia = navigator['mozGetUserMedia'];
}
if(!navigator.getUserMedia && navigator['webkitGetUserMedia']){
navigator.getUserMedia = navigator['webkitGetUserMedia'];
}
if(!navigator.getUserMedia && navigator['msGetUserMedia']){
navigator.getUserMedia = navigator['msGetUserMedia'];
}
var framesPerBuffer = 1024;
var scriptNode = context.createScriptProcessor(framesPerBuffer, 1, 1);
scriptNode.onaudioprocess = function(audioProcessingEvent){
var inputBuffer = audioProcessingEvent.inputBuffer;
var outputBuffer = audioProcessingEvent.outputBuffer;
var chansIn = [];
var chansOut = [];
for(var c=0; c<inputBuffer.numberOfChannels; c++){
chansIn[c] = inputBuffer.getChannelData(c);
}
for(var c=0; c<outputBuffer.numberOfChannels; c++){
chansOut[c] = outputBuffer.getChannelData(c);
}
var ins = new Float32Array(inputBuffer.numberOfChannels);
var outs = new Float32Array(outputBuffer.numberOfChannels);
for(var f=0; f<framesPerBuffer; f++){
for(var c=0; c<inputBuffer.numberOfChannels; c++){
ins[c] = chansIn[c][f];
}
soundFunc(ins, outs);
for(var c=0; c<outputBuffer.numberOfChannels; c++){
chansOut[c][f] = outs[c];
}
}
}
if(navigator.getUserMedia){
navigator.getUserMedia(
{'audio':true},
function(stream){
var input = context.createMediaStreamSource(stream);
//http://stackoverflow.com/questions/22860468/html5-microphone-capture-stops-after-5-seconds-in-firefox says to save a reference to avoid sound ending after 5 seconds
inputNodes.mic = input;
input.connect(scriptNode);
scriptNode.connect(context.destination);
input.start();
},
function(e){ alert('Error capturing audio. e='+e); }
);
}else alert('getUserMedia not supported in this browser.');
};