如何在使用compressor.reduction.value监视压缩减少时修复冻结的div

时间:2014-10-16 20:51:51

标签: javascript settimeout html5-audio web-audio

我的问题如下。 我试图将压缩器节点的compress.reduction.value连接到div的高度,以便我可以动态监视压缩减少效果。这很好用。问题是当音频信号停止div在其当前位置冻结时。我希望div不会冻结并让它的高度变为零。我修复它的方法是使用setInterval检查div 的高度,如果它在完全保持相同的高度超过几秒钟然后显示设置为无效有效隐藏div。现在我的问题是双重的。首先,如果有更好的方法可以做到这一点请分享,但无论有什么东西让我烦恼,我无法弄明白。当我编写代码时,它可以工作。但是,由于压缩器节点在播放功能之外,它看起来有点难看..........

var compressor = audioContext.createDynamicsCompressor();

soundObj.play = function() {

    $(".compression-meter").css("display", "block");
    var playSound = audioContext.createBufferSource();
    compressor.threshold.value = -40;
    compressor.ratio.value = 20;

    playSound.buffer = soundObj.soundToPlay;
    playSound.connect(compressor);
    compressor.connect(audioContext.destination)
    playSound.start(audioContext.currentTime);
    compReductionMeter()
}

/*______________ Compressor metering __________*/

var cachedMeterValue = null

function compReductionMeter() {
    cachedMeterValue = $(".compression-meter").height()
    var reduction = compressor.reduction.value;
    var bar = $(".compression-meter");
    bar.height((-1 * reduction) + '%');
    requestAnimationFrame(compReductionMeter);

};



window.setInterval(function() {
    if ($(".compression-meter").height() == cachedMeterValue) {
        console.log("checking compression meter height when matched with cachedMeterValue.It is " + $(".compression-meter").height())
        $(".compression-meter").css("display", "none")
    }
}, 2000);

当我写这样的代码时,div甚至不会出现,我不知道为什么。从我看来它应该"应该"工作,我真的想知道为什么它不会和我失踪的东西。

   soundObj.play = function() {

            $(".compression-meter").css("display", "block");
            var playSound = audioContext.createBufferSource();
            var compressor = audioContext.createDynamicsCompressor(); // modified placement
            compressor.threshold.value = -40;
            compressor.ratio.value = 20;

            playSound.buffer = soundObj.soundToPlay;
            playSound.connect(compressor);
            compressor.connect(audioContext.destination)
            playSound.start(audioContext.currentTime);
            compReductionMeter(compressor.reduction.value)            // modified - added argument
        }

        /*______________ Compressor metering __________*/

        var cachedMeterValue = null

        function compReductionMeter(compVal) {                        // modified - added parameter
            cachedMeterValue = $(".compression-meter").height()
            var reduction = compVal;                                  // modified - is now param value
            var bar = $(".compression-meter");
            bar.height((-1 * reduction) + '%');
            requestAnimationFrame(compReductionMeter);

        };



        window.setInterval(function() {
            if ($(".compression-meter").height() == cachedMeterValue) {
                console.log("checking compression meter height when matched with cachedMeterValue.It is " + $(".compression-meter").height())
                $(".compression-meter").css("display", "none")
            }
        }, 2000);

谢谢。

3 个答案:

答案 0 :(得分:2)

DynamicsComporessorNode中的这种烦恼将在Chrome版本M40中修复。

https://codereview.chromium.org/645853010/

答案 1 :(得分:0)

不幸的是,当来自源节点的流停止时,DynamicCompressorNode的当前设计保持增益减少值不被更新。也就是说,仅在活动音频流运行时才更新GR值。 AnalyserNode有同样的问题。

如果您的音频图只是使用单个源节点,则可以使用源节点中的.onended事件将DIV的高度归零。但是,如果您更喜欢复杂的音频图表,那么它将会更复杂一些。

http://www.w3.org/TR/webaudio/#dfn-onended_AudioBufferSourceNode

答案 2 :(得分:0)

这可能是为压缩器和分析仪提供零点的黑客攻击。创建全零的新缓冲区。将其分配给新的AudioBufferSourceNode。将此节点连接到压缩器和/或分析器,并在源结束时(或稍前)安排源启动。这应该使压缩器/分析器节点处理,使GR值和分析器节点降至零。

我实际上没有试过这个。