summaryrefslogtreecommitdiffstats
path: root/dom/media/webaudio/test/test_periodicWaveBandLimiting.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/webaudio/test/test_periodicWaveBandLimiting.html')
-rw-r--r--dom/media/webaudio/test/test_periodicWaveBandLimiting.html86
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>