Bug 878875 - Import PannerNode tests from Blink. r=ehsan
[gecko.git] / content / media / webaudio / test / blink / audio-testing.js
blobd46723559fd245718ed10307f7a12ea37656290e
1 if (window.testRunner)
2     testRunner.overridePreference("WebKitWebAudioEnabled", "1");
4 function writeString(s, a, offset) {
5     for (var i = 0; i < s.length; ++i) {
6         a[offset + i] = s.charCodeAt(i);
7     }
10 function writeInt16(n, a, offset) {
11     n = Math.floor(n);
12    
13     var b1 = n & 255;
14     var b2 = (n >> 8) & 255;
16     a[offset + 0] = b1;
17     a[offset + 1] = b2;
20 function writeInt32(n, a, offset) {
21     n = Math.floor(n);
22     var b1 = n & 255;
23     var b2 = (n >> 8) & 255;
24     var b3 = (n >> 16) & 255;
25     var b4 = (n >> 24) & 255;
27     a[offset + 0] = b1;
28     a[offset + 1] = b2;
29     a[offset + 2] = b3;
30     a[offset + 3] = b4;
33 function writeAudioBuffer(audioBuffer, a, offset) {
34     var n = audioBuffer.length;
35     var channels = audioBuffer.numberOfChannels;
36    
37     for (var i = 0; i < n; ++i) {
38         for (var k = 0; k < channels; ++k) {
39             var buffer = audioBuffer.getChannelData(k);
40             var sample = buffer[i] * 32768.0;
42             // Clip samples to the limitations of 16-bit.
43             // If we don't do this then we'll get nasty wrap-around distortion.
44             if (sample < -32768)
45                 sample = -32768;
46             if (sample > 32767)
47                 sample = 32767;
49             writeInt16(sample, a, offset);
50             offset += 2;
51         }
52     }
55 function createWaveFileData(audioBuffer) {
56     var frameLength = audioBuffer.length;
57     var numberOfChannels = audioBuffer.numberOfChannels;
58     var sampleRate = audioBuffer.sampleRate;
59     var bitsPerSample = 16;
60     var byteRate = sampleRate * numberOfChannels * bitsPerSample/8;
61     var blockAlign = numberOfChannels * bitsPerSample/8;
62     var wavDataByteLength = frameLength * numberOfChannels * 2; // 16-bit audio
63     var headerByteLength = 44;
64     var totalLength = headerByteLength + wavDataByteLength;
66     var waveFileData = new Uint8Array(totalLength);
67    
68     var subChunk1Size = 16; // for linear PCM
69     var subChunk2Size = wavDataByteLength;
70     var chunkSize = 4 + (8 + subChunk1Size) + (8 + subChunk2Size);
72     writeString("RIFF", waveFileData, 0);
73     writeInt32(chunkSize, waveFileData, 4);
74     writeString("WAVE", waveFileData, 8);
75     writeString("fmt ", waveFileData, 12);
76    
77     writeInt32(subChunk1Size, waveFileData, 16);      // SubChunk1Size (4)
78     writeInt16(1, waveFileData, 20);                  // AudioFormat (2)
79     writeInt16(numberOfChannels, waveFileData, 22);   // NumChannels (2)
80     writeInt32(sampleRate, waveFileData, 24);         // SampleRate (4)
81     writeInt32(byteRate, waveFileData, 28);           // ByteRate (4)
82     writeInt16(blockAlign, waveFileData, 32);         // BlockAlign (2)
83     writeInt32(bitsPerSample, waveFileData, 34);      // BitsPerSample (4)
84                                                      
85     writeString("data", waveFileData, 36);            
86     writeInt32(subChunk2Size, waveFileData, 40);      // SubChunk2Size (4)
87    
88     // Write actual audio data starting at offset 44.
89     writeAudioBuffer(audioBuffer, waveFileData, 44);
90    
91     return waveFileData;
94 function createAudioData(audioBuffer) {
95     return createWaveFileData(audioBuffer);
98 function finishAudioTest(event) {
99     var audioData = createAudioData(event.renderedBuffer);
100     testRunner.setAudioData(audioData);
101     testRunner.notifyDone();
104 // Create an impulse in a buffer of length sampleFrameLength
105 function createImpulseBuffer(context, sampleFrameLength) {
106     var audioBuffer = context.createBuffer(1, sampleFrameLength, context.sampleRate);
107     var n = audioBuffer.length;
108     var dataL = audioBuffer.getChannelData(0);
110     for (var k = 0; k < n; ++k) {
111         dataL[k] = 0;
112     }
113     dataL[0] = 1;
115     return audioBuffer;
118 // Create a buffer of the given length with a linear ramp having values 0 <= x < 1.
119 function createLinearRampBuffer(context, sampleFrameLength) {
120     var audioBuffer = context.createBuffer(1, sampleFrameLength, context.sampleRate);
121     var n = audioBuffer.length;
122     var dataL = audioBuffer.getChannelData(0);
124     for (var i = 0; i < n; ++i)
125         dataL[i] = i / n;
127     return audioBuffer;
130 // Create a buffer of the given length having a constant value.
131 function createConstantBuffer(context, sampleFrameLength, constantValue) {
132     var audioBuffer = context.createBuffer(1, sampleFrameLength, context.sampleRate);
133     var n = audioBuffer.length;
134     var dataL = audioBuffer.getChannelData(0);
136     for (var i = 0; i < n; ++i)
137         dataL[i] = constantValue;
139     return audioBuffer;
142 // Create a stereo impulse in a buffer of length sampleFrameLength
143 function createStereoImpulseBuffer(context, sampleFrameLength) {
144     var audioBuffer = context.createBuffer(2, sampleFrameLength, context.sampleRate);
145     var n = audioBuffer.length;
146     var dataL = audioBuffer.getChannelData(0);
147     var dataR = audioBuffer.getChannelData(1);
149     for (var k = 0; k < n; ++k) {
150         dataL[k] = 0;
151         dataR[k] = 0;
152     }
153     dataL[0] = 1;
154     dataR[0] = 1;
156     return audioBuffer;
159 // Convert time (in seconds) to sample frames.
160 function timeToSampleFrame(time, sampleRate) {
161     return Math.floor(0.5 + time * sampleRate);
164 // Compute the number of sample frames consumed by noteGrainOn with
165 // the specified |grainOffset|, |duration|, and |sampleRate|.
166 function grainLengthInSampleFrames(grainOffset, duration, sampleRate) {
167     var startFrame = timeToSampleFrame(grainOffset, sampleRate);
168     var endFrame = timeToSampleFrame(grainOffset + duration, sampleRate);
170     return endFrame - startFrame;
173 // True if the number is not an infinity or NaN
174 function isValidNumber(x) {
175     return !isNaN(x) && (x != Infinity) && (x != -Infinity);
178 function shouldThrowTypeError(func, text) {
179     var ok = false;
180     try {
181         func();
182     } catch (e) {
183         if (e instanceof TypeError) {
184             ok = true;
185         }
186     }
187     if (ok) {
188         testPassed(text + " threw TypeError.");
189     } else {
190         testFailed(text + " should throw TypeError.");
191     }