content/media/webaudio/test/blink/audio-testing.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial