【问题标题】:How to set microphone buffer size in Web Audio API to avoid the 1/3 second delay (which is much faster in Java)?如何在 Web Audio API 中设置麦克风缓冲区大小以避免 1/3 秒延迟(这在 Java 中要快得多)?
【发布时间】:2015-10-20 14:39:18
【问题描述】:

此代码适用于 Windows 7 的 Firefox。它在扬声器上播放转换后的麦克风。它由 javascript 代码转换为音频幅度从 -1 到 1 的数字,每秒多次。它有 1/3 秒的延迟,但相同的硬件在 java 中运行得更快,我的https://sourceforge.net/projects/jsoundcard 软件通过时序统计调整缓冲区使用。当 OS 进程线程优先级提高时,它们都会变得更快,但 java 仍然快得多。没有理由 Firefox 或 Web Audio API 应该有更多的延迟,即使它已成为浏览器中无法正常运行的规范,但随着 HTML5(这是一个正在开发的开放标准)的变化。 Web Audio API 中是否有调整麦克风缓冲区大小的地方?

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.'); 
};

【问题讨论】:

    标签: buffer delay web-audio-api microphone


    【解决方案1】:

    我确实相信(如果我错了,@cwilso 可能会纠正我)API 使用的模型是从节点中提取样本,而不是节点将样本推送到其后的节点。这意味着您在脚本处理器中设置的缓冲区大小是延迟的来源,而不是麦克风流的输入缓冲区大小。尝试将缓冲区大小设置得更低。

    var framesPerBuffer = 256;
    var scriptNode = context.createScriptProcessor(framesPerBuffer, 1, 1);
    

    【讨论】:

    • 1/3 秒(300 毫秒)似乎非常高。是的,脚本处理器的缓冲区大小是一个很大的成本 - 越小越好,尽管它需要更快的 CPU(即,这是一个折衷 - 不是每个系统都可以支持 256 的缓冲区而不会出现故障)。 AudioWorkers 将对此有所帮助;在那之前,您真的希望使用本机 Web 音频节点而不是 ScriptProcessor 进行尽可能多的处理。 (从 Web 音频线程到主线程的跳跃非常缓慢。)我猜出于某种原因,您的设备上的输入缓冲区非常大。在 Chrome 中怎么样?
    猜你喜欢
    • 2018-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-24
    相关资源
    最近更新 更多