mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-11-20 10:33:36 +00:00
87 lines
3.1 KiB
HTML
87 lines
3.1 KiB
HTML
|
<!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>
|