| OLD | NEW |
| 1 function createTestBuffer(context, sampleFrameLength) { | 1 function createTestBuffer(context, sampleFrameLength) { |
| 2 var audioBuffer = context.createBuffer(1, sampleFrameLength, context.sampleR
ate); | 2 let audioBuffer = |
| 3 var channelData = audioBuffer.getChannelData(0); | 3 context.createBuffer(1, sampleFrameLength, context.sampleRate); |
| 4 let channelData = audioBuffer.getChannelData(0); |
| 4 | 5 |
| 5 // Create a simple linear ramp starting at zero, with each value in the buff
er equal to its index position. | 6 // Create a simple linear ramp starting at zero, with each value in the buffer |
| 6 for (var i = 0; i < sampleFrameLength; ++i) | 7 // equal to its index position. |
| 7 channelData[i] = i; | 8 for (let i = 0; i < sampleFrameLength; ++i) |
| 9 channelData[i] = i; |
| 8 | 10 |
| 9 return audioBuffer; | 11 return audioBuffer; |
| 10 } | 12 } |
| 11 | 13 |
| 12 function checkSingleTest(renderedBuffer, i) { | 14 function checkSingleTest(renderedBuffer, i, should) { |
| 13 var renderedData = renderedBuffer.getChannelData(0); | 15 let renderedData = renderedBuffer.getChannelData(0); |
| 14 var offsetFrame = i * testSpacingFrames; | 16 let offsetFrame = i * testSpacingFrames; |
| 15 | 17 |
| 16 var test = tests[i]; | 18 let test = tests[i]; |
| 17 var expected = test.expected; | 19 let expected = test.expected; |
| 18 var success = true; | 20 let description; |
| 19 var description; | |
| 20 | 21 |
| 21 if (test.description) { | 22 if (test.description) { |
| 22 description = test.description; | 23 description = test.description; |
| 23 } else { | 24 } else { |
| 24 // No description given, so create a basic one from the given test param
eters. | 25 // No description given, so create a basic one from the given test |
| 25 description = "loop from " + test.loopStartFrame + " -> " + test.loopEnd
Frame; | 26 // parameters. |
| 26 if (test.offsetFrame) | 27 description = |
| 27 description += " with offset " + test.offsetFrame; | 28 'loop from ' + test.loopStartFrame + ' -> ' + test.loopEndFrame; |
| 28 if (test.playbackRate && test.playbackRate != 1) | 29 if (test.offsetFrame) |
| 29 description += " with playbackRate of " + test.playbackRate; | 30 description += ' with offset ' + test.offsetFrame; |
| 30 } | 31 if (test.playbackRate && test.playbackRate != 1) |
| 32 description += ' with playbackRate of ' + test.playbackRate; |
| 33 } |
| 31 | 34 |
| 32 var framesToTest; | 35 let framesToTest; |
| 33 | 36 |
| 34 if (test.renderFrames) | 37 if (test.renderFrames) |
| 35 framesToTest = test.renderFrames; | 38 framesToTest = test.renderFrames; |
| 36 else if (test.durationFrames) | 39 else if (test.durationFrames) |
| 37 framesToTest = test.durationFrames; | 40 framesToTest = test.durationFrames; |
| 38 | 41 |
| 39 // Verify that the output matches | 42 // Verify that the output matches |
| 40 for (var j = 0; j < framesToTest; ++j) { | 43 let prefix = 'Case ' + i + ': '; |
| 41 if (expected[j] != renderedData[offsetFrame + j]) { | 44 should( |
| 42 // Copy from Float32Array to regular JavaScript array for error mess
age. | 45 renderedData.slice(offsetFrame, offsetFrame + framesToTest), |
| 43 var renderedArray = new Array(); | 46 prefix + description) |
| 44 for (var j = 0; j < test.renderFrames; ++j) | 47 .beEqualToArray(expected); |
| 45 renderedArray[j] = renderedData[offsetFrame + j]; | |
| 46 | 48 |
| 47 var s = description + ": expected: " + expected + " actual: " + rend
eredArray; | 49 // Verify that we get all zeroes after the buffer (or duration) has passed. |
| 48 success = false; | 50 should( |
| 49 Should(s, success).beEqualTo(true); | 51 renderedData.slice( |
| 50 break; | 52 offsetFrame + framesToTest, offsetFrame + testSpacingFrames), |
| 51 } | 53 prefix + description + ': tail') |
| 52 } | 54 .beConstantValueOf(0); |
| 53 | |
| 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 mess
age. | |
| 58 var renderedArray = new Array(); | |
| 59 for (var j = framesToTest; j < testSpacingFrames; ++j) | |
| 60 renderedArray[j - framesToTest] = renderedData[offsetFrame + j]; | |
| 61 | |
| 62 var s = description + ": expected: all zeroes actual: " + renderedAr
ray; | |
| 63 success = false; | |
| 64 Should(s, success).beEqualTo(true); | |
| 65 break; | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 Should("", success) | |
| 70 .summarize(description, description); | |
| 71 | |
| 72 return success; | |
| 73 } | 55 } |
| 74 | 56 |
| 75 function checkAllTests(event) { | 57 function checkAllTests(renderedBuffer, should) { |
| 76 var renderedBuffer = event.renderedBuffer; | 58 for (let i = 0; i < tests.length; ++i) |
| 77 for (var i = 0; i < tests.length; ++i) | 59 checkSingleTest(renderedBuffer, i, should); |
| 78 checkSingleTest(renderedBuffer, i); | |
| 79 | |
| 80 finishJSTest(); | |
| 81 } | 60 } |
| 82 | 61 |
| 83 | 62 |
| 84 // Create the actual result by modulating playbackRate or detune AudioParam of | 63 // Create the actual result by modulating playbackRate or detune AudioParam of |
| 85 // ABSN. |modTarget| is a string of AudioParam name, |modOffset| is the offset | 64 // ABSN. |modTarget| is a string of AudioParam name, |modOffset| is the offset |
| 86 // (anchor) point of modulation, and |modRange| is the range of modulation. | 65 // (anchor) point of modulation, and |modRange| is the range of modulation. |
| 87 // | 66 // |
| 88 // createSawtoothWithModulation(context, 'detune', 440, 1200); | 67 // createSawtoothWithModulation(context, 'detune', 440, 1200); |
| 89 // | 68 // |
| 90 // The above will perform a modulation on detune within the range of | 69 // The above will perform a modulation on detune within the range of |
| 91 // [1200, -1200] around the sawtooth waveform on 440Hz. | 70 // [1200, -1200] around the sawtooth waveform on 440Hz. |
| 92 function createSawtoothWithModulation(context, modTarget, modOffset, modRange) { | 71 function createSawtoothWithModulation(context, modTarget, modOffset, modRange) { |
| 93 var lfo = context.createOscillator(); | 72 let lfo = context.createOscillator(); |
| 94 var amp = context.createGain(); | 73 let amp = context.createGain(); |
| 95 | 74 |
| 96 // Create a sawtooth generator with the signal range of [0, 1]. | 75 // Create a sawtooth generator with the signal range of [0, 1]. |
| 97 var phasor = context.createBufferSource(); | 76 let phasor = context.createBufferSource(); |
| 98 var phasorBuffer = context.createBuffer(1, sampleRate, sampleRate); | 77 let phasorBuffer = context.createBuffer(1, sampleRate, sampleRate); |
| 99 var phasorArray = phasorBuffer.getChannelData(0); | 78 let phasorArray = phasorBuffer.getChannelData(0); |
| 100 var phase = 0, phaseStep = 1 / sampleRate; | 79 let phase = 0, phaseStep = 1 / sampleRate; |
| 101 for (var i = 0; i < phasorArray.length; i++) { | 80 for (let i = 0; i < phasorArray.length; i++) { |
| 102 phasorArray[i] = phase % 1.0; | 81 phasorArray[i] = phase % 1.0; |
| 103 phase += phaseStep; | 82 phase += phaseStep; |
| 104 } | 83 } |
| 105 phasor.buffer = phasorBuffer; | 84 phasor.buffer = phasorBuffer; |
| 106 phasor.loop = true; | 85 phasor.loop = true; |
| 107 | 86 |
| 108 // 1Hz for audible (human-perceivable) parameter modulation by LFO. | 87 // 1Hz for audible (human-perceivable) parameter modulation by LFO. |
| 109 lfo.frequency.value = 1.0; | 88 lfo.frequency.value = 1.0; |
| 110 | 89 |
| 111 amp.gain.value = modRange; | 90 amp.gain.value = modRange; |
| 112 phasor.playbackRate.value = modOffset; | 91 phasor.playbackRate.value = modOffset; |
| 113 | 92 |
| 114 // The oscillator output should be amplified accordingly to drive the | 93 // The oscillator output should be amplified accordingly to drive the |
| 115 // modulation within the desired range. | 94 // modulation within the desired range. |
| 116 lfo.connect(amp); | 95 lfo.connect(amp); |
| 117 amp.connect(phasor[modTarget]); | 96 amp.connect(phasor[modTarget]); |
| 118 | 97 |
| 119 phasor.connect(context.destination); | 98 phasor.connect(context.destination); |
| 120 | 99 |
| 121 lfo.start(); | 100 lfo.start(); |
| 122 phasor.start(); | 101 phasor.start(); |
| 123 } | 102 } |
| OLD | NEW |