buffer-resampling.html (3241B)
1 <!doctype html> 2 <html> 3 <head> 4 <title>Test Extrapolation at end of AudibBuffer in an AudioBufferSourceNode</title> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script src="/webaudio/resources/audit-util.js"></script> 8 </head> 9 <body> 10 <script> 11 const sampleRate = 48000; 12 13 // For testing we only need a few render quanta. 14 const renderSamples = 512; 15 16 // Sample rate for our buffers. This is the lowest sample rate that is 17 // required to be supported. 18 const bufferRate = 8000; 19 20 // Number of samples in each AudioBuffer; this is fairly arbitrary but 21 // should be less than a render quantum. 22 const bufferLength = 30; 23 24 // Frequency of the sine wave for testing. 25 const frequency = 440; 26 27 promise_test(async t => { 28 // The first channel is for the interpolated signal, and the second 29 // channel is for the reference signal from an oscillator. 30 const context = new OfflineAudioContext({ 31 numberOfChannels: 2, 32 length: renderSamples, 33 sampleRate: sampleRate 34 }); 35 36 const merger = new ChannelMergerNode( 37 context, {numberOfChannels: context.destination.channelCount}); 38 merger.connect(context.destination); 39 40 // Create a set of AudioBuffers which are samples from a pure sine 41 // wave with frequency |frequency|. 42 const nBuffers = Math.floor(context.length / bufferLength); 43 const omega = 2 * Math.PI * frequency / bufferRate; 44 45 let frameNumber = 0; 46 let startTime = 0; 47 48 for (let k = 0; k < nBuffers; ++k) { 49 const buffer = new AudioBuffer( 50 {length: bufferLength, sampleRate: bufferRate}); 51 const data = buffer.getChannelData(0); 52 53 for (let n = 0; n < bufferLength; ++n) { 54 data[n] = Math.sin(omega * frameNumber); 55 ++frameNumber; 56 } 57 58 // Create a source using this buffer and start it at the end of 59 // the previous buffer. 60 const src = new AudioBufferSourceNode(context, {buffer: buffer}); 61 src.connect(merger, 0, 0); 62 src.start(startTime); 63 startTime += buffer.duration; 64 } 65 66 // Create the reference sine signal using an oscillator. 67 const osc = new OscillatorNode( 68 context, {type: 'sine', frequency: frequency}); 69 osc.connect(merger, 0, 1); 70 osc.start(); 71 72 const audioBuffer = await context.startRendering(); 73 74 const actual = audioBuffer.getChannelData(0); 75 const expected = audioBuffer.getChannelData(1); 76 77 // Verify that the interpolated sine wave closely matches the reference. 78 assert_array_approx_equals( 79 actual, expected, 9.0348e-2, 80 'Interpolated sine wave should match reference oscillator'); 81 82 // Compute SNR between them. 83 const snr = 10 * Math.log10(computeSNR(actual, expected)); 84 assert_greater_than_equal( 85 snr, 37.17, 86 `SNR (${snr.toPrecision(4)} dB) should be >= 37.17 dB`); 87 }, 'Interpolation of AudioBuffers to context sample rate'); 88 </script> 89 </body> 90 </html>