var sampleRate = 44100.0;

// HRTF extra frames.  This is a magic constant currently in
// AudioBufferSourceNode::process that always extends the
// duration by this number of samples.  See bug 77224
// (https://bugs.webkit.org/show_bug.cgi?id=77224).
var extraFramesHRTF = 512;

// How many grains to play.
var numberOfTests = 100;

// Duration of each grain to be played
var duration = 0.01;

// Time step between the start of each grain.  We need to add a little
// bit of silence so we can detect grain boundaries and also account
// for the extra frames for HRTF.
var timeStep = duration + .005 + extraFramesHRTF / sampleRate;

// Time step between the start for each grain.
var grainOffsetStep = 0.001;

// How long to render to cover all of the grains.
var renderTime = (numberOfTests + 1) * timeStep;

var context;
var renderedData;

// Create a buffer containing the data that we want.  The function f
// returns the desired value at sample frame k.
function createSignalBuffer(context, f) {

    // Make sure the buffer has enough data for all of the possible
    // grain offsets and durations.  Need to include the extra frames
    // for HRTF.  The additional 1 is for any round-off errors.
    var signalLength = Math.floor(1 + extraFramesHRTF + sampleRate * (numberOfTests * grainOffsetStep + duration));

    var buffer = context.createBuffer(2, signalLength, sampleRate);
    var data = buffer.getChannelData(0);

    for (var k = 0; k < signalLength; ++k) {
        data[k] = f(k);
    }

    return buffer;
}

// From the data array, find the start and end sample frame for each
// grain.  This depends on the data having 0's between grain, and
// that the grain is always strictly non-zero.
function findStartAndEndSamples(data) {
    var nSamples = data.length;

    var startTime = [];
    var endTime = [];
    var lookForStart = true;
      
    // Look through the rendered data to find the start and stop
    // times of each grain.
    for (var k = 0; k < nSamples; ++k) {
        if (lookForStart) {
            // Find a non-zero point and record the start.  We're not
            // concerned with the value in this test, only that the
            // grain started here.
            if (renderedData[k]) {
                startTime.push(k);
                lookForStart = false;
            }
        } else {
            // Find a zero and record the end of the grain.
            if (!renderedData[k]) {
                endTime.push(k);
                lookForStart = true;
            }
        }
    }

    return {start : startTime, end : endTime};
}

function playGrain(context, source, time, offset, duration) {
    var bufferSource = context.createBufferSource();

    bufferSource.buffer = source;
    bufferSource.connect(context.destination);
    bufferSource.start(time, offset, duration);
}

// Play out all grains.  Returns a object containing two arrays, one
// for the start time and one for the grain offset time.
function playAllGrains(context, source, numberOfNotes) {
    var startTimes = new Array(numberOfNotes);
    var offsets = new Array(numberOfNotes);

    for (var k = 0; k < numberOfNotes; ++k) {
        var timeOffset = k * timeStep;
        var grainOffset = k * grainOffsetStep;

        playGrain(context, source, timeOffset, grainOffset, duration);
        startTimes[k] = timeOffset;
        offsets[k] = grainOffset;
    }

    return { startTimes : startTimes, grainOffsetTimes : offsets };
}

// Verify that the start and end frames for each grain match our
// expected start and end frames.
function verifyStartAndEndFrames(startEndFrames) {
    var startFrames = startEndFrames.start;
    var endFrames = startEndFrames.end;
      
    var success = true;

    // Count of how many grains started at the incorrect time.
    var errorCountStart = 0;

    // Count of how many grains ended at the incorrect time.
    var errorCountEnd = 0;

    if (startFrames.length != endFrames.length) {
        testFailed("Could not find the beginning or end of a grain.");
        success = false;
    }

    if (startFrames.length == numberOfTests && endFrames.length == numberOfTests) {
        testPassed("Found all " + numberOfTests + " grains.");
    } else {
        testFailed("Did not find all " + numberOfTests + " grains.");
    }

    // Examine the start and stop times to see if they match our
    // expectations.
    for (var k = 0; k < startFrames.length; ++k) {
        var expectedStart = timeToSampleFrame(k * timeStep, sampleRate);
        // The end point is the duration, plus the extra frames
        // for HRTF.
        var expectedEnd = extraFramesHRTF + expectedStart + grainLengthInSampleFrames(k * grainOffsetStep, duration, sampleRate);

        if (startFrames[k] != expectedStart) {
            testFailed("Pulse " + k + " started at " + startFrames[k] + " but expected at " + expectedStart);
            ++errorCountStart;
            success = false;
        }

        if (endFrames[k] != expectedEnd) {
            testFailed("Pulse " + k + " ended at " + endFrames[k] + " but expected at " + expectedEnd);
            ++errorCountEnd;
            success = false;
        }
    }

    // Check that all the grains started or ended at the correct time.
    if (!errorCountStart) {
        if (startFrames.length == numberOfTests) {
            testPassed("All " + numberOfTests + " grains started at the correct time.");
        } else {
            testFailed("All grains started at the correct time, but only " + startFrames.length + " grains found.");
            success = false;
        }
    } else {
        testFailed(errorCountStart + " out of " + numberOfTests + " grains started at the wrong time.");
        success = false;
    }

    if (!errorCountEnd) {
        if (endFrames.length == numberOfTests) {
            testPassed("All " + numberOfTests + " grains ended at the correct time.");
        } else {
            testFailed("All grains ended at the correct time, but only " + endFrames.length + " grains found.");
            success = false;
        }
    } else {
        testFailed(errorCountEnd + " out of " + numberOfTests + " grains ended at the wrong time.");
        success = false;
    }

    return success;
}
