<!DOCTYPE html>

<!--
Tests that an audio-rate signal (AudioNode output) can be connected to an AudioParam.
Specifically, this tests that an audio-rate signal coming from an AudioBufferSourceNode
playing an AudioBuffer containing a specific curve can be connected to an AudioGainNode's
.gain attribute (an AudioParam).  Another AudioBufferSourceNode will be the audio source
having its gain changed.  We load this one with an AudioBuffer containing a constant value of 1.
Thus it's easy to check that the resultant signal should be equal to the gain-scaling curve.
-->

<html>
<head>
<script src="resources/audio-testing.js"></script>
<script src="../resources/js-test.js"></script>

</head>
<body>

<script>

var sampleRate = 44100.0;
var lengthInSeconds = 1;

var context = 0;
var constantOneBuffer = 0;
var linearRampBuffer = 0;

function checkResult(event) {
    var renderedBuffer = event.renderedBuffer;
    var renderedData = renderedBuffer.getChannelData(0);
    var expectedData = linearRampBuffer.getChannelData(0);
    var n = renderedBuffer.length;

    if (n == linearRampBuffer.length) {
        testPassed("Rendered signal is of correct length.");
    } else {
        testFailed("Rendered signal is not of correct length.");
    }

    // Check that the rendered result exactly matches the buffer used to control gain.
    // This is because we're changing the gain of a signal having constant value 1.
    var success = true;
    for (var i = 0; i < n; ++i) {
        if (renderedData[i] != expectedData[i]) {
            success = false;
            break;
        }
    }

    if (success) {
        testPassed("Rendered signal exactly matches the audio-rate gain changing signal.");
    } else {
        testFailed("Rendered signal differs from the audio-rate gain changing signal.");
    }

    finishJSTest();
}

function runTest() {
    window.jsTestIsAsync = true;

    var sampleFrameLength = sampleRate * lengthInSeconds;

    // Create offline audio context.
    context = new OfflineAudioContext(1, sampleFrameLength, sampleRate);

    // Create buffer used by the source which will have its gain controlled.
    constantOneBuffer = createConstantBuffer(context, sampleFrameLength, 1);

    // Create buffer used to control gain.
    linearRampBuffer = createLinearRampBuffer(context, sampleFrameLength);

    // Create the two sources.

    var constantSource = context.createBufferSource();
    constantSource.buffer = constantOneBuffer;

    var gainChangingSource = context.createBufferSource();
    gainChangingSource.buffer = linearRampBuffer;

    // Create a gain node controlling the gain of constantSource and make the connections.
    var gainNode = context.createGain();

    // Intrinsic baseline gain of zero.
    gainNode.gain.value = 0;

    constantSource.connect(gainNode);
    gainNode.connect(context.destination);

    // Connect an audio-rate signal to control the .gain AudioParam.
    // This is the heart of what is being tested.
    gainChangingSource.connect(gainNode.gain);

    // Start both sources at time 0.
    constantSource.start(0);
    gainChangingSource.start(0);

    context.oncomplete = checkResult;
    context.startRendering();
}

runTest();

</script>
</body>
</html>
