1

My problem is the following. I am attempting to connect the compressor.reduction.value of the compressor node to a div's height so I can monitor the compression reduction effect dynamically. This works fine. The problem is when the audio signal stops the div freezes at its current position. I would like the div to not freeze and have it's height go to zero. The way I fixed this is by using a setInterval that checks for the height of the div and if it remains at exactly the same height for more than a few seconds then the display is set to none effectively hiding the div. Now my question is two fold. First, if there is a better way to do this please share, but irrespective there is one little thing that is irking me that I can't figure out. When I write the code as such it works. However, it looks a bit ugly since the compressor node is outside the play function..........

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);

When I write the code like this the div doesn't even appear and I am not sure why. From my view it "should" work and I really want to know why it doesn't and what I'm missing.

   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);

Thank you.

William
  • 4,422
  • 17
  • 55
  • 108

3 Answers3

2

This annoyance in DynamicsComporessorNode will be fixed at Chrome version M40.

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

hoch
  • 106
  • 3
0

Unfortunately, the current design of DynamicCompressorNode keeps the gain reduction value from being updated when the stream from source node stops. That is, the GR value is only being updated when the active audio stream is running. AnalyserNode has the very same issue.

If your audio graph is simply using a single source node, you can use .onended event from the source node to zero the height of DIV. However, if you rather have a complex audio graph, then it is going to be a bit more involved.

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

hoch
  • 106
  • 3
  • I'm curious if there is a (dare I say simple..ha!) way to tack on some dead noise to the end of the buffer stream once the signal falls below a certain threshold as a means to get the com reduction value or analyzer node to drop to "zero". I figure my way in the code above is simpler but maybe a utility that does it the other way could be helpful. – William Oct 21 '14 at 02:11
0

Here is a possible hack to get zeroes to the compressor and analyzer. Create a new buffer of all zeroes. Assign that to a new AudioBufferSourceNode. Connect this node to the compressor and/or analyser and schedule the source to start when your source ends (or slightly before). This should keep the compressor/analyser node processing so the GR value and analyser node to drop to zero.

I didn't actually try this.

Raymond Toy
  • 5,490
  • 10
  • 13