1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/webaudio/test/blink/audio-testing.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,192 @@ 1.4 +if (window.testRunner) 1.5 + testRunner.overridePreference("WebKitWebAudioEnabled", "1"); 1.6 + 1.7 +function writeString(s, a, offset) { 1.8 + for (var i = 0; i < s.length; ++i) { 1.9 + a[offset + i] = s.charCodeAt(i); 1.10 + } 1.11 +} 1.12 + 1.13 +function writeInt16(n, a, offset) { 1.14 + n = Math.floor(n); 1.15 + 1.16 + var b1 = n & 255; 1.17 + var b2 = (n >> 8) & 255; 1.18 + 1.19 + a[offset + 0] = b1; 1.20 + a[offset + 1] = b2; 1.21 +} 1.22 + 1.23 +function writeInt32(n, a, offset) { 1.24 + n = Math.floor(n); 1.25 + var b1 = n & 255; 1.26 + var b2 = (n >> 8) & 255; 1.27 + var b3 = (n >> 16) & 255; 1.28 + var b4 = (n >> 24) & 255; 1.29 + 1.30 + a[offset + 0] = b1; 1.31 + a[offset + 1] = b2; 1.32 + a[offset + 2] = b3; 1.33 + a[offset + 3] = b4; 1.34 +} 1.35 + 1.36 +function writeAudioBuffer(audioBuffer, a, offset) { 1.37 + var n = audioBuffer.length; 1.38 + var channels = audioBuffer.numberOfChannels; 1.39 + 1.40 + for (var i = 0; i < n; ++i) { 1.41 + for (var k = 0; k < channels; ++k) { 1.42 + var buffer = audioBuffer.getChannelData(k); 1.43 + var sample = buffer[i] * 32768.0; 1.44 + 1.45 + // Clip samples to the limitations of 16-bit. 1.46 + // If we don't do this then we'll get nasty wrap-around distortion. 1.47 + if (sample < -32768) 1.48 + sample = -32768; 1.49 + if (sample > 32767) 1.50 + sample = 32767; 1.51 + 1.52 + writeInt16(sample, a, offset); 1.53 + offset += 2; 1.54 + } 1.55 + } 1.56 +} 1.57 + 1.58 +function createWaveFileData(audioBuffer) { 1.59 + var frameLength = audioBuffer.length; 1.60 + var numberOfChannels = audioBuffer.numberOfChannels; 1.61 + var sampleRate = audioBuffer.sampleRate; 1.62 + var bitsPerSample = 16; 1.63 + var byteRate = sampleRate * numberOfChannels * bitsPerSample/8; 1.64 + var blockAlign = numberOfChannels * bitsPerSample/8; 1.65 + var wavDataByteLength = frameLength * numberOfChannels * 2; // 16-bit audio 1.66 + var headerByteLength = 44; 1.67 + var totalLength = headerByteLength + wavDataByteLength; 1.68 + 1.69 + var waveFileData = new Uint8Array(totalLength); 1.70 + 1.71 + var subChunk1Size = 16; // for linear PCM 1.72 + var subChunk2Size = wavDataByteLength; 1.73 + var chunkSize = 4 + (8 + subChunk1Size) + (8 + subChunk2Size); 1.74 + 1.75 + writeString("RIFF", waveFileData, 0); 1.76 + writeInt32(chunkSize, waveFileData, 4); 1.77 + writeString("WAVE", waveFileData, 8); 1.78 + writeString("fmt ", waveFileData, 12); 1.79 + 1.80 + writeInt32(subChunk1Size, waveFileData, 16); // SubChunk1Size (4) 1.81 + writeInt16(1, waveFileData, 20); // AudioFormat (2) 1.82 + writeInt16(numberOfChannels, waveFileData, 22); // NumChannels (2) 1.83 + writeInt32(sampleRate, waveFileData, 24); // SampleRate (4) 1.84 + writeInt32(byteRate, waveFileData, 28); // ByteRate (4) 1.85 + writeInt16(blockAlign, waveFileData, 32); // BlockAlign (2) 1.86 + writeInt32(bitsPerSample, waveFileData, 34); // BitsPerSample (4) 1.87 + 1.88 + writeString("data", waveFileData, 36); 1.89 + writeInt32(subChunk2Size, waveFileData, 40); // SubChunk2Size (4) 1.90 + 1.91 + // Write actual audio data starting at offset 44. 1.92 + writeAudioBuffer(audioBuffer, waveFileData, 44); 1.93 + 1.94 + return waveFileData; 1.95 +} 1.96 + 1.97 +function createAudioData(audioBuffer) { 1.98 + return createWaveFileData(audioBuffer); 1.99 +} 1.100 + 1.101 +function finishAudioTest(event) { 1.102 + var audioData = createAudioData(event.renderedBuffer); 1.103 + testRunner.setAudioData(audioData); 1.104 + testRunner.notifyDone(); 1.105 +} 1.106 + 1.107 +// Create an impulse in a buffer of length sampleFrameLength 1.108 +function createImpulseBuffer(context, sampleFrameLength) { 1.109 + var audioBuffer = context.createBuffer(1, sampleFrameLength, context.sampleRate); 1.110 + var n = audioBuffer.length; 1.111 + var dataL = audioBuffer.getChannelData(0); 1.112 + 1.113 + for (var k = 0; k < n; ++k) { 1.114 + dataL[k] = 0; 1.115 + } 1.116 + dataL[0] = 1; 1.117 + 1.118 + return audioBuffer; 1.119 +} 1.120 + 1.121 +// Create a buffer of the given length with a linear ramp having values 0 <= x < 1. 1.122 +function createLinearRampBuffer(context, sampleFrameLength) { 1.123 + var audioBuffer = context.createBuffer(1, sampleFrameLength, context.sampleRate); 1.124 + var n = audioBuffer.length; 1.125 + var dataL = audioBuffer.getChannelData(0); 1.126 + 1.127 + for (var i = 0; i < n; ++i) 1.128 + dataL[i] = i / n; 1.129 + 1.130 + return audioBuffer; 1.131 +} 1.132 + 1.133 +// Create a buffer of the given length having a constant value. 1.134 +function createConstantBuffer(context, sampleFrameLength, constantValue) { 1.135 + var audioBuffer = context.createBuffer(1, sampleFrameLength, context.sampleRate); 1.136 + var n = audioBuffer.length; 1.137 + var dataL = audioBuffer.getChannelData(0); 1.138 + 1.139 + for (var i = 0; i < n; ++i) 1.140 + dataL[i] = constantValue; 1.141 + 1.142 + return audioBuffer; 1.143 +} 1.144 + 1.145 +// Create a stereo impulse in a buffer of length sampleFrameLength 1.146 +function createStereoImpulseBuffer(context, sampleFrameLength) { 1.147 + var audioBuffer = context.createBuffer(2, sampleFrameLength, context.sampleRate); 1.148 + var n = audioBuffer.length; 1.149 + var dataL = audioBuffer.getChannelData(0); 1.150 + var dataR = audioBuffer.getChannelData(1); 1.151 + 1.152 + for (var k = 0; k < n; ++k) { 1.153 + dataL[k] = 0; 1.154 + dataR[k] = 0; 1.155 + } 1.156 + dataL[0] = 1; 1.157 + dataR[0] = 1; 1.158 + 1.159 + return audioBuffer; 1.160 +} 1.161 + 1.162 +// Convert time (in seconds) to sample frames. 1.163 +function timeToSampleFrame(time, sampleRate) { 1.164 + return Math.floor(0.5 + time * sampleRate); 1.165 +} 1.166 + 1.167 +// Compute the number of sample frames consumed by start with 1.168 +// the specified |grainOffset|, |duration|, and |sampleRate|. 1.169 +function grainLengthInSampleFrames(grainOffset, duration, sampleRate) { 1.170 + var startFrame = timeToSampleFrame(grainOffset, sampleRate); 1.171 + var endFrame = timeToSampleFrame(grainOffset + duration, sampleRate); 1.172 + 1.173 + return endFrame - startFrame; 1.174 +} 1.175 + 1.176 +// True if the number is not an infinity or NaN 1.177 +function isValidNumber(x) { 1.178 + return !isNaN(x) && (x != Infinity) && (x != -Infinity); 1.179 +} 1.180 + 1.181 +function shouldThrowTypeError(func, text) { 1.182 + var ok = false; 1.183 + try { 1.184 + func(); 1.185 + } catch (e) { 1.186 + if (e instanceof TypeError) { 1.187 + ok = true; 1.188 + } 1.189 + } 1.190 + if (ok) { 1.191 + testPassed(text + " threw TypeError."); 1.192 + } else { 1.193 + testFailed(text + " should throw TypeError."); 1.194 + } 1.195 +}