1 function createTestBuffer(context, sampleFrameLength) {
2 var audioBuffer = context.createBuffer(1, sampleFrameLength, context.sampleRate);
3 var channelData = audioBuffer.getChannelData(0);
5 // Create a simple linear ramp starting at zero, with each value in the buffer equal to its index position.
6 for (var i = 0; i < sampleFrameLength; ++i)
12 function checkSingleTest(renderedBuffer, i) {
13 var renderedData = renderedBuffer.getChannelData(0);
14 var offsetFrame = i * testSpacingFrames;
17 var expected = test.expected;
21 if (test.description) {
22 description = test.description;
24 // No description given, so create a basic one from the given test parameters.
25 description = "loop from " + test.loopStartFrame + " -> " + test.loopEndFrame;
27 description += " with offset " + test.offsetFrame;
28 if (test.playbackRate && test.playbackRate != 1)
29 description += " with playbackRate of " + test.playbackRate;
34 if (test.renderFrames)
35 framesToTest = test.renderFrames;
36 else if (test.durationFrames)
37 framesToTest = test.durationFrames;
39 // Verify that the output matches
40 for (var j = 0; j < framesToTest; ++j) {
41 if (expected[j] != renderedData[offsetFrame + j]) {
42 // Copy from Float32Array to regular JavaScript array for error message.
43 var renderedArray = new Array();
44 for (var j = 0; j < test.renderFrames; ++j)
45 renderedArray[j] = renderedData[offsetFrame + j];
47 var s = description + ": expected: " + expected + " actual: " + renderedArray;
54 // Verify that we get all zeroes after the buffer (or duration) has passed.
55 for (var j = framesToTest; j < testSpacingFrames; ++j) {
56 if (renderedData[offsetFrame + j]) {
57 // Copy from Float32Array to regular JavaScript array for error message.
58 var renderedArray = new Array();
59 for (var j = framesToTest; j < testSpacingFrames; ++j)
60 renderedArray[j - framesToTest] = renderedData[offsetFrame + j];
62 var s = description + ": expected: all zeroes actual: " + renderedArray;
70 testPassed(description);
75 function checkAllTests(event) {
76 var renderedBuffer = event.renderedBuffer;
77 for (var i = 0; i < tests.length; ++i)
78 checkSingleTest(renderedBuffer, i);
84 // Create the actual result by modulating playbackRate or detune AudioParam of
85 // ABSN. |modTarget| is a string of AudioParam name, |modOffset| is the offset
86 // (anchor) point of modulation, and |modRange| is the range of modulation.
88 // createSawtoothWithModulation(context, 'detune', 440, 1200);
90 // The above will perform a modulation on detune within the range of
91 // [1200, -1200] around the sawtooth waveform on 440Hz.
92 function createSawtoothWithModulation(context, modTarget, modOffset, modRange) {
93 var lfo = context.createOscillator();
94 var amp = context.createGain();
96 // Create a sawtooth generator with the signal range of [0, 1].
97 var phasor = context.createBufferSource();
98 var phasorBuffer = context.createBuffer(1, sampleRate, sampleRate);
99 var phasorArray = phasorBuffer.getChannelData(0);
100 var phase = 0, phaseStep = 1 / sampleRate;
101 for (var i = 0; i < phasorArray.length; i++) {
102 phasorArray[i] = phase % 1.0;
105 phasor.buffer = phasorBuffer;
108 // 1Hz for audible (human-perceivable) parameter modulation by LFO.
109 lfo.frequency.value = 1.0;
111 amp.gain.value = modRange;
112 phasor.playbackRate.value = modOffset;
114 // The oscillator output should be amplified accordingly to drive the
115 // modulation within the desired range.
117 amp.connect(phasor[modTarget]);
119 phasor.connect(context.destination);