diff options
Diffstat (limited to 'dom/media/webaudio/test/test_periodicWaveBandLimiting.html')
-rw-r--r-- | dom/media/webaudio/test/test_periodicWaveBandLimiting.html | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/dom/media/webaudio/test/test_periodicWaveBandLimiting.html b/dom/media/webaudio/test/test_periodicWaveBandLimiting.html new file mode 100644 index 000000000..70fbb09e2 --- /dev/null +++ b/dom/media/webaudio/test/test_periodicWaveBandLimiting.html @@ -0,0 +1,86 @@ +<!DOCTYPE html> +<title>Test effect of band limiting on PeriodicWave signals</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +const sampleRate = 48000; +const bufferSize = 12800; +const epsilon = 0.01; + +// "All implementations must support arrays up to at least 8192", but the +// linear interpolation of the current implementation distorts the higher +// frequency components too much to pass this test. +const frequencyIndexMax = 200; + +// A set of oscillators are created near the Nyquist frequency. +// These are factors giving each oscillator frequency relative to the Nyquist. +// The first is an octave below Nyquist and the last is just above. +const OCTAVE_BELOW = 0; +const HALF_BELOW = 1; +const NEAR_BELOW = 2; +const ABOVE = 3; +const oscillatorFactors = [0.5, Math.sqrt(0.5), 0.99, 1.01]; +const oscillatorCount = oscillatorFactors.length; + +// Return magnitude relative to unit sine wave +function magnitude(array) { + var mag = 0 + for (var i = 0; i < array.length; ++i) { + sample = array[i]; + mag += sample * sample; + } + return Math.sqrt(2 * mag / array.length); +} + +function test_frequency_index(frequencyIndex) { + + var context = + new OfflineAudioContext(oscillatorCount, bufferSize, sampleRate); + + var merger = context.createChannelMerger(oscillatorCount); + merger.connect(context.destination); + + var real = new Float32Array(frequencyIndex + 1); + real[frequencyIndex] = 1; + var image = new Float32Array(real.length); + var wave = context.createPeriodicWave(real, image); + + for (var i = 0; i < oscillatorCount; ++i) { + var oscillator = context.createOscillator(); + oscillator.frequency.value = + oscillatorFactors[i] * sampleRate / (2 * frequencyIndex); + oscillator.connect(merger, 0, i); + oscillator.setPeriodicWave(wave); + oscillator.start(0); + } + + return context.startRendering(). + then((buffer) => { + assert_equals(buffer.numberOfChannels, oscillatorCount); + var magnitudes = []; + for (var i = 0; i < oscillatorCount; ++i) { + magnitudes[i] = magnitude(buffer.getChannelData(i)); + } + // Unaffected by band-limiting one octave below Nyquist. + assert_approx_equals(magnitudes[OCTAVE_BELOW], 1, epsilon, + "magnitude with frequency octave below Nyquist"); + // Still at least half the amplitude at half octave below Nyquist. + assert_greater_than(magnitudes[HALF_BELOW], 0.5 * (1 - epsilon), + "magnitude with frequency half octave below Nyquist"); + // Approaching zero or zero near Nyquist. + assert_less_than(magnitudes[NEAR_BELOW], 0.1, + "magnitude with frequency near Nyquist"); + assert_equals(magnitudes[ABOVE], 0, + "magnitude with frequency above Nyquist"); + }); +} + +// The 5/4 ratio with rounding up provides sampling across a range of +// octaves and offsets within octaves. +for (var frequencyIndex = 1; + frequencyIndex < frequencyIndexMax; + frequencyIndex = Math.floor((5 * frequencyIndex + 3) / 4)) { + promise_test(test_frequency_index.bind(null, frequencyIndex), + "Frequency " + frequencyIndex); +} +</script> |