var sampleRate = 44100.0;

var renderLengthSeconds = 8;
var pulseLengthSeconds = 1;
var pulseLengthFrames = pulseLengthSeconds * sampleRate;

function createSquarePulseBuffer(context, sampleFrameLength) {
    var audioBuffer = context.createBuffer(1, sampleFrameLength, context.sampleRate);

    var n = audioBuffer.length;
    var data = audioBuffer.getChannelData(0);

    for (var i = 0; i < n; ++i)
        data[i] = 1;

    return audioBuffer;
}

// The triangle buffer holds the expected result of the convolution.
// It linearly ramps up from 0 to its maximum value (at the center)
// then linearly ramps down to 0.  The center value corresponds to the
// point where the two square pulses overlap the most.
function createTrianglePulseBuffer(context, sampleFrameLength) {
    var audioBuffer = context.createBuffer(1, sampleFrameLength, context.sampleRate);

    var n = audioBuffer.length;
    var halfLength = n / 2;
    var data = audioBuffer.getChannelData(0);
    
    for (var i = 0; i < halfLength; ++i)
        data[i] = i + 1;

    for (var i = halfLength; i < n; ++i)
        data[i] = n - i - 1;

    return audioBuffer;
}

function log10(x) {
  return Math.log(x)/Math.LN10;
}

function linearToDecibel(x) {
  return 20*log10(x);
}

// Verify that the rendered result is very close to the reference
// triangular pulse.
function checkTriangularPulse(rendered, reference) {
    var match = true;
    var maxDelta = 0;
    var valueAtMaxDelta = 0;
    var maxDeltaIndex = 0;

    for (var i = 0; i < reference.length; ++i) {
        var diff = rendered[i] - reference[i];
        var x = Math.abs(diff);
        if (x > maxDelta) {
            maxDelta = x;
            valueAtMaxDelta = reference[i];
            maxDeltaIndex = i;
        }
    }

    // allowedDeviationFraction was determined experimentally.  It
    // is the threshold of the relative error at the maximum
    // difference between the true triangular pulse and the
    // rendered pulse.
    var allowedDeviationDecibels = -133.2;
    var maxDeviationDecibels = linearToDecibel(maxDelta / valueAtMaxDelta);

    if (maxDeviationDecibels <= allowedDeviationDecibels) {
        testPassed("Triangular portion of convolution is correct.");
    } else {
        testFailed("Triangular portion of convolution is not correct.  Max deviation = " + maxDeviationDecibels + " dB at " + maxDeltaIndex);
        match = false;
    }

    return match;
}        

// Verify that the rendered data is close to zero for the first part
// of the tail.
function checkTail1(data, reference, breakpoint) {
    var isZero = true;
    var tail1Max = 0;

    for (var i = reference.length; i < reference.length + breakpoint; ++i) {
        var mag = Math.abs(data[i]);
        if (mag > tail1Max) {
            tail1Max = mag;
        }
    }

    // Let's find the peak of the reference (even though we know a
    // priori what it is).
    var refMax = 0;
    for (var i = 0; i < reference.length; ++i) {
      refMax = Math.max(refMax, Math.abs(reference[i]));
    }

    // This threshold is experimentally determined by examining the
    // value of tail1MaxDecibels.
    var threshold1 = -129.7;

    var tail1MaxDecibels = linearToDecibel(tail1Max/refMax);
    if (tail1MaxDecibels <= threshold1) {
        testPassed("First part of tail of convolution is sufficiently small.");
    } else {
        testFailed("First part of tail of convolution is not sufficiently small: " + tail1MaxDecibels + " dB");
        isZero = false;
    }

    return isZero;
}

// Verify that the second part of the tail of the convolution is
// exactly zero.
function checkTail2(data, reference, breakpoint) {
    var isZero = true;
    var tail2Max = 0;
    // For the second part of the tail, the maximum value should be
    // exactly zero.
    var threshold2 = 0;
    for (var i = reference.length + breakpoint; i < data.length; ++i) {
        if (Math.abs(data[i]) > 0) {
            isZero = false; 
            break;
        }
    }

    if (isZero) {
        testPassed("Rendered signal after tail of convolution is silent.");
    } else {
        testFailed("Rendered signal after tail of convolution should be silent.");
    }

    return isZero;
}

function checkConvolvedResult(trianglePulse) {
    return function(event) {
        var renderedBuffer = event.renderedBuffer;

        var referenceData = trianglePulse.getChannelData(0);
        var renderedData = renderedBuffer.getChannelData(0);
    
        var success = true;
    
        // Verify the triangular pulse is actually triangular.

        success = success && checkTriangularPulse(renderedData, referenceData);
        
        // Make sure that portion after convolved portion is totally
        // silent.  But round-off prevents this from being completely
        // true.  At the end of the triangle, it should be close to
        // zero.  If we go farther out, it should be even closer and
        // eventually zero.

        // For the tail of the convolution (where the result would be
        // theoretically zero), we partition the tail into two
        // parts.  The first is the at the beginning of the tail,
        // where we tolerate a small but non-zero value.  The second part is
        // farther along the tail where the result should be zero.
        
        // breakpoint is the point dividing the first two tail parts
        // we're looking at.  Experimentally determined.
        var breakpoint = 12800;

        success = success && checkTail1(renderedData, referenceData, breakpoint);
        
        success = success && checkTail2(renderedData, referenceData, breakpoint);
        
        if (success) {
            testPassed("Test signal was correctly convolved.");
        } else {
            testFailed("Test signal was not correctly convolved.");
        }

        finishJSTest();
    }
}
