| OLD | NEW |
| 1 // Globals, to make testing and debugging easier. | 1 // Globals, to make testing and debugging easier. |
| 2 var context; | 2 var context; |
| 3 var filter; | 3 var filter; |
| 4 var signal; | 4 var signal; |
| 5 var renderedBuffer; | 5 var renderedBuffer; |
| 6 var renderedData; | 6 var renderedData; |
| 7 | 7 |
| 8 var sampleRate = 44100.0; | 8 var sampleRate = 44100.0; |
| 9 var pulseLengthFrames = .1 * sampleRate; | 9 var pulseLengthFrames = .1 * sampleRate; |
| 10 | 10 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 filter[k].detune.value = (filterParameters[k].detune === undefined) ? 0
: filterParameters[k].detune; | 69 filter[k].detune.value = (filterParameters[k].detune === undefined) ? 0
: filterParameters[k].detune; |
| 70 filter[k].Q.value = filterParameters[k].q; | 70 filter[k].Q.value = filterParameters[k].q; |
| 71 filter[k].gain.value = filterParameters[k].gain; | 71 filter[k].gain.value = filterParameters[k].gain; |
| 72 | 72 |
| 73 signal[k].connect(filter[k]); | 73 signal[k].connect(filter[k]); |
| 74 filter[k].connect(context.destination); | 74 filter[k].connect(context.destination); |
| 75 | 75 |
| 76 signal[k].start(timeStep * k); | 76 signal[k].start(timeStep * k); |
| 77 } | 77 } |
| 78 | 78 |
| 79 context.oncomplete = checkFilterResponse(filterType, testParameters); | 79 return context.startRendering() |
| 80 context.startRendering(); | 80 .then(buffer => { |
| 81 checkFilterResponse(buffer, filterType, testParameters); |
| 82 }); |
| 81 } | 83 } |
| 82 | 84 |
| 83 function addSignal(dest, src, destOffset) { | 85 function addSignal(dest, src, destOffset) { |
| 84 // Add src to dest at the given dest offset. | 86 // Add src to dest at the given dest offset. |
| 85 for (var k = destOffset, j = 0; k < dest.length, j < src.length; ++k, ++j) { | 87 for (var k = destOffset, j = 0; k < dest.length, j < src.length; ++k, ++j) { |
| 86 dest[k] += src[j]; | 88 dest[k] += src[j]; |
| 87 } | 89 } |
| 88 } | 90 } |
| 89 | 91 |
| 90 function generateReference(filterType, filterParameters) { | 92 function generateReference(filterType, filterParameters) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 109 filterParameters[k].gain); | 111 filterParameters[k].gain); |
| 110 var y = filterData(filterCoef, data, renderLengthSamples); | 112 var y = filterData(filterCoef, data, renderLengthSamples); |
| 111 | 113 |
| 112 // Accumulate this filtered data into the final output at the desired of
fset. | 114 // Accumulate this filtered data into the final output at the desired of
fset. |
| 113 addSignal(result, y, timeToSampleFrame(timeStep * k, sampleRate)); | 115 addSignal(result, y, timeToSampleFrame(timeStep * k, sampleRate)); |
| 114 } | 116 } |
| 115 | 117 |
| 116 return result; | 118 return result; |
| 117 } | 119 } |
| 118 | 120 |
| 119 function checkFilterResponse(filterType, testParameters) { | 121 function checkFilterResponse(renderedBuffer, filterType, testParameters) { |
| 120 return function(event) { | 122 var filterParameters = testParameters.filterParameters; |
| 121 var filterParameters = testParameters.filterParameters; | 123 var maxAllowedError = testParameters.threshold; |
| 122 var maxAllowedError = testParameters.threshold; | 124 var should = testParameters.should; |
| 123 renderedBuffer = event.renderedBuffer; | |
| 124 renderedData = renderedBuffer.getChannelData(0); | |
| 125 | 125 |
| 126 reference = generateReference(filterType, filterParameters); | 126 renderedData = renderedBuffer.getChannelData(0); |
| 127 | |
| 128 var len = Math.min(renderedData.length, reference.length); | |
| 129 | 127 |
| 130 var success = true; | 128 reference = generateReference(filterType, filterParameters); |
| 131 | 129 |
| 132 // Maximum error between rendered data and expected data | 130 var len = Math.min(renderedData.length, reference.length); |
| 133 var maxError = 0; | |
| 134 | 131 |
| 135 // Sample offset where the maximum error occurred. | 132 var success = true; |
| 136 var maxPosition = 0; | |
| 137 | 133 |
| 138 // Number of infinities or NaNs that occurred in the rendered data. | 134 // Maximum error between rendered data and expected data |
| 139 var invalidNumberCount = 0; | 135 var maxError = 0; |
| 140 | 136 |
| 141 if (nFilters != filterParameters.length) { | 137 // Sample offset where the maximum error occurred. |
| 142 testFailed("Test wanted " + filterParameters.length + " filters but
only " + maxFilters + " allowed."); | 138 var maxPosition = 0; |
| 143 success = false; | 139 |
| 140 // Number of infinities or NaNs that occurred in the rendered data. |
| 141 var invalidNumberCount = 0; |
| 142 |
| 143 should(nFilters, "Number of filters tested") |
| 144 .beEqualTo(filterParameters.length); |
| 145 |
| 146 // Compare the rendered signal with our reference, keeping |
| 147 // track of the maximum difference (and the offset of the max |
| 148 // difference.) Check for bad numbers in the rendered output |
| 149 // too. There shouldn't be any. |
| 150 for (var k = 0; k < len; ++k) { |
| 151 var err = Math.abs(renderedData[k] - reference[k]); |
| 152 if (err > maxError) { |
| 153 maxError = err; |
| 154 maxPosition = k; |
| 144 } | 155 } |
| 156 if (!isValidNumber(renderedData[k])) { |
| 157 ++invalidNumberCount; |
| 158 } |
| 159 } |
| 145 | 160 |
| 146 // Compare the rendered signal with our reference, keeping | 161 should(invalidNumberCount, |
| 147 // track of the maximum difference (and the offset of the max | 162 "Number of non-finite values in the rendered output") |
| 148 // difference.) Check for bad numbers in the rendered output | 163 .beEqualTo(0); |
| 149 // too. There shouldn't be any. | |
| 150 for (var k = 0; k < len; ++k) { | |
| 151 var err = Math.abs(renderedData[k] - reference[k]); | |
| 152 if (err > maxError) { | |
| 153 maxError = err; | |
| 154 maxPosition = k; | |
| 155 } | |
| 156 if (!isValidNumber(renderedData[k])) { | |
| 157 ++invalidNumberCount; | |
| 158 } | |
| 159 } | |
| 160 | 164 |
| 161 if (invalidNumberCount > 0) { | 165 should(maxError, |
| 162 testFailed("Rendered output has " + invalidNumberCount + " infinitie
s or NaNs."); | 166 "Max error in " + filterTypeName[filterType] + " response") |
| 163 success = false; | 167 .beLessThanOrEqualTo(maxAllowedError); |
| 164 } else { | |
| 165 testPassed("Rendered output did not have infinities or NaNs."); | |
| 166 } | |
| 167 | |
| 168 if (maxError <= maxAllowedError) { | |
| 169 testPassed(filterTypeName[filterType] + " response is correct."); | |
| 170 } else { | |
| 171 testFailed(filterTypeName[filterType] + " response is incorrect. Ma
x err = " + maxError + " at " + maxPosition + ". Threshold = " + maxAllowedErro
r); | |
| 172 success = false; | |
| 173 } | |
| 174 | |
| 175 if (success) { | |
| 176 testPassed("Test signal was correctly filtered."); | |
| 177 } else { | |
| 178 testFailed("Test signal was not correctly filtered."); | |
| 179 } | |
| 180 finishJSTest(); | |
| 181 } | |
| 182 } | 168 } |
| OLD | NEW |