4 <title>Test Custom Oscillator at Very Low Frequency
</title>
5 <script src=
"../resources/js-test.js"></script>
6 <script src=
"resources/compatibility.js"></script>
7 <script src=
"resources/audio-testing.js"></script>
12 description("Test Custom Oscillator at Very Low Frequency");
13 window
.jsTestIsAsync
= true;
15 // Create a custom oscillator and verify that the parts of a periodic wave that should be
16 // ignored really are ignored.
18 var sampleRate
= 48000;
20 // The desired frequency of the oscillator. The value to be used depends on the
21 // implementation of the PeriodicWave and should be less than then lowest fundamental
22 // frequency. The lowest frequency is the Nyquist frequency divided by the max number of
23 // coefficients used for the FFT. In the current implementation, the max number of
24 // coefficients is 2048 (for a sample rate of 48 kHz) so the lowest frequency is 24000/2048 =
26 var desiredFrequencyHz
= 1;
28 // Minimum allowed SNR between the actual oscillator and the expected result. Experimentally
30 var snrThreshold
= 130;
36 var audit
= Audit
.createTaskRunner();
38 // Compute the SNR between the actual result and expected cosine wave
39 function checkCosineResult(result
, freq
, sampleRate
) {
42 var omega
= 2 * Math
.PI
* freq
/ sampleRate
;
44 actual
= result
.getChannelData(0);
46 for (var k
= 0; k
< actual
.length
; ++k
) {
47 var x
= Math
.cos(omega
* k
);
48 var diff
= x
- actual
[k
];
53 var snr
= 10 * Math
.log10(signal
/ noise
);
55 Should("SNR of " + desiredFrequencyHz
+ " Hz sine wave", snr
).beGreaterThanOrEqualTo(snrThreshold
);
56 testPassed("PeriodicWave coefficients that must be ignored were correctly ignored.");
60 context
= new OfflineAudioContext(1, sampleRate
, sampleRate
);
61 osc
= context
.createOscillator();
63 // Create the custom oscillator. For simplicity of testing, we use just a cosine wave, but
64 // the initial elements of the real and imaginary parts are explicitly set to non-zero to
65 // test that they are ignored.
66 var r
= new Float32Array(2);
67 var i
= new Float32Array(2);
68 r
[0] = 1; // DC component to be ignored
69 r
[1] = 1; // Fundamental
70 i
[0] = 1; // Sine term that doesn't actually exist in a Fourier series
72 var wave
= context
.createPeriodicWave(r
, i
);
74 osc
.setPeriodicWave(wave
);
75 osc
.frequency
.value
= desiredFrequencyHz
;
76 osc
.connect(context
.destination
);
78 context
.startRendering().then(function (buffer
) {
79 checkCosineResult(buffer
, desiredFrequencyHz
, sampleRate
);
80 }).then(finishJSTest
);
84 successfullyParsed
= true;