| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 | 5 |
| 6 /** | 6 /** |
| 7 * @fileOverview This file includes legacy utility functions for the layout | 7 * @fileOverview This file includes legacy utility functions for the layout |
| 8 * test. | 8 * test. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 var b2 = (n >> 8) & 255; | 31 var b2 = (n >> 8) & 255; |
| 32 var b3 = (n >> 16) & 255; | 32 var b3 = (n >> 16) & 255; |
| 33 var b4 = (n >> 24) & 255; | 33 var b4 = (n >> 24) & 255; |
| 34 | 34 |
| 35 a[offset + 0] = b1; | 35 a[offset + 0] = b1; |
| 36 a[offset + 1] = b2; | 36 a[offset + 1] = b2; |
| 37 a[offset + 2] = b3; | 37 a[offset + 2] = b3; |
| 38 a[offset + 3] = b4; | 38 a[offset + 3] = b4; |
| 39 } | 39 } |
| 40 | 40 |
| 41 function writeAudioBuffer(audioBuffer, a, offset) { | 41 // Return the bits of the float as a 32-bit integer value. This |
| 42 // produces the raw bits; no intepretation of the value is done. |
| 43 function floatBits(f) { |
| 44 var buf = new ArrayBuffer(4); |
| 45 (new Float32Array(buf))[0] = f; |
| 46 var bits = (new Uint32Array(buf))[0]; |
| 47 // Return as a signed integer. |
| 48 return bits | 0; |
| 49 } |
| 50 |
| 51 function writeAudioBuffer(audioBuffer, a, offset, asFloat) { |
| 42 var n = audioBuffer.length; | 52 var n = audioBuffer.length; |
| 43 var channels = audioBuffer.numberOfChannels; | 53 var channels = audioBuffer.numberOfChannels; |
| 44 | 54 |
| 45 for (var i = 0; i < n; ++i) { | 55 for (var i = 0; i < n; ++i) { |
| 46 for (var k = 0; k < channels; ++k) { | 56 for (var k = 0; k < channels; ++k) { |
| 47 var buffer = audioBuffer.getChannelData(k); | 57 var buffer = audioBuffer.getChannelData(k); |
| 48 var sample = buffer[i] * 32768.0; | 58 if (asFloat) { |
| 59 var sample = floatBits(buffer[i]); |
| 60 writeInt32(sample, a, offset); |
| 61 offset += 4; |
| 62 } else { |
| 63 var sample = buffer[i] * 32768.0; |
| 49 | 64 |
| 50 // Clip samples to the limitations of 16-bit. | 65 // Clip samples to the limitations of 16-bit. |
| 51 // If we don't do this then we'll get nasty wrap-around distortion. | 66 // If we don't do this then we'll get nasty wrap-around distortion
. |
| 52 if (sample < -32768) | 67 if (sample < -32768) |
| 53 sample = -32768; | 68 sample = -32768; |
| 54 if (sample > 32767) | 69 if (sample > 32767) |
| 55 sample = 32767; | 70 sample = 32767; |
| 56 | 71 |
| 57 writeInt16(sample, a, offset); | 72 writeInt16(sample, a, offset); |
| 58 offset += 2; | 73 offset += 2; |
| 74 } |
| 59 } | 75 } |
| 60 } | 76 } |
| 61 } | 77 } |
| 62 | 78 |
| 63 function createWaveFileData(audioBuffer) { | 79 // See http://soundfile.sapp.org/doc/WaveFormat/ and |
| 80 // http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html |
| 81 // for a quick introduction to the WAVE PCM format. |
| 82 function createWaveFileData(audioBuffer, asFloat) { |
| 83 var bytesPerSample = asFloat ? 4 : 2; |
| 64 var frameLength = audioBuffer.length; | 84 var frameLength = audioBuffer.length; |
| 65 var numberOfChannels = audioBuffer.numberOfChannels; | 85 var numberOfChannels = audioBuffer.numberOfChannels; |
| 66 var sampleRate = audioBuffer.sampleRate; | 86 var sampleRate = audioBuffer.sampleRate; |
| 67 var bitsPerSample = 16; | 87 var bitsPerSample = 8 * bytesPerSample; |
| 68 var byteRate = sampleRate * numberOfChannels * bitsPerSample/8; | 88 var byteRate = sampleRate * numberOfChannels * bitsPerSample/8; |
| 69 var blockAlign = numberOfChannels * bitsPerSample/8; | 89 var blockAlign = numberOfChannels * bitsPerSample/8; |
| 70 var wavDataByteLength = frameLength * numberOfChannels * 2; // 16-bit audio | 90 var wavDataByteLength = frameLength * numberOfChannels * bytesPerSample; |
| 71 var headerByteLength = 44; | 91 var headerByteLength = 44; |
| 72 var totalLength = headerByteLength + wavDataByteLength; | 92 var totalLength = headerByteLength + wavDataByteLength; |
| 73 | 93 |
| 74 var waveFileData = new Uint8Array(totalLength); | 94 var waveFileData = new Uint8Array(totalLength); |
| 75 | 95 |
| 76 var subChunk1Size = 16; // for linear PCM | 96 var subChunk1Size = 16; // for linear PCM |
| 77 var subChunk2Size = wavDataByteLength; | 97 var subChunk2Size = wavDataByteLength; |
| 78 var chunkSize = 4 + (8 + subChunk1Size) + (8 + subChunk2Size); | 98 var chunkSize = 4 + (8 + subChunk1Size) + (8 + subChunk2Size); |
| 79 | 99 |
| 80 writeString("RIFF", waveFileData, 0); | 100 writeString("RIFF", waveFileData, 0); |
| 81 writeInt32(chunkSize, waveFileData, 4); | 101 writeInt32(chunkSize, waveFileData, 4); |
| 82 writeString("WAVE", waveFileData, 8); | 102 writeString("WAVE", waveFileData, 8); |
| 83 writeString("fmt ", waveFileData, 12); | 103 writeString("fmt ", waveFileData, 12); |
| 84 | 104 |
| 85 writeInt32(subChunk1Size, waveFileData, 16); // SubChunk1Size (4) | 105 writeInt32(subChunk1Size, waveFileData, 16); // SubChunk1Size (4) |
| 86 writeInt16(1, waveFileData, 20); // AudioFormat (2) | 106 // The format tag value is 1 for integer PCM data and 3 for IEEE |
| 107 // float data. |
| 108 writeInt16(asFloat ? 3 : 1, waveFileData, 20); // AudioFormat (2) |
| 87 writeInt16(numberOfChannels, waveFileData, 22); // NumChannels (2) | 109 writeInt16(numberOfChannels, waveFileData, 22); // NumChannels (2) |
| 88 writeInt32(sampleRate, waveFileData, 24); // SampleRate (4) | 110 writeInt32(sampleRate, waveFileData, 24); // SampleRate (4) |
| 89 writeInt32(byteRate, waveFileData, 28); // ByteRate (4) | 111 writeInt32(byteRate, waveFileData, 28); // ByteRate (4) |
| 90 writeInt16(blockAlign, waveFileData, 32); // BlockAlign (2) | 112 writeInt16(blockAlign, waveFileData, 32); // BlockAlign (2) |
| 91 writeInt32(bitsPerSample, waveFileData, 34); // BitsPerSample (4) | 113 writeInt32(bitsPerSample, waveFileData, 34); // BitsPerSample (4) |
| 92 | 114 |
| 93 writeString("data", waveFileData, 36); | 115 writeString("data", waveFileData, 36); |
| 94 writeInt32(subChunk2Size, waveFileData, 40); // SubChunk2Size (4) | 116 writeInt32(subChunk2Size, waveFileData, 40); // SubChunk2Size (4) |
| 95 | 117 |
| 96 // Write actual audio data starting at offset 44. | 118 // Write actual audio data starting at offset 44. |
| 97 writeAudioBuffer(audioBuffer, waveFileData, 44); | 119 writeAudioBuffer(audioBuffer, waveFileData, 44, asFloat); |
| 98 | 120 |
| 99 return waveFileData; | 121 return waveFileData; |
| 100 } | 122 } |
| 101 | 123 |
| 102 function createAudioData(audioBuffer) { | 124 function createAudioData(audioBuffer, asFloat) { |
| 103 return createWaveFileData(audioBuffer); | 125 return createWaveFileData(audioBuffer, asFloat); |
| 104 } | 126 } |
| 105 | 127 |
| 106 function finishAudioTest(event) { | 128 function finishAudioTest(event) { |
| 107 var audioData = createAudioData(event.renderedBuffer); | 129 var audioData = createAudioData(event.renderedBuffer); |
| 108 testRunner.setAudioData(audioData); | 130 testRunner.setAudioData(audioData); |
| 109 testRunner.notifyDone(); | 131 testRunner.notifyDone(); |
| 110 } | 132 } |
| 111 | 133 |
| 112 // Save the given |audioBuffer| to a 16-bit WAV file using the name | 134 // Save the given |audioBuffer| to a WAV file using the name given by |
| 113 // given by |filename|. This is intended to be run from a browser. | 135 // |filename|. This is intended to be run from a browser. The |
| 114 // The developer is expected to use the console to run | 136 // developer is expected to use the console to run downloadAudioBuffer |
| 115 // downloadAudioBuffer when necessary to create a new reference file | 137 // when necessary to create a new reference file for a test. If |
| 116 // for a test. | 138 // |asFloat| is given and is true, the WAV file produced uses 32-bit |
| 117 function downloadAudioBuffer(audioBuffer, filename) { | 139 // float format (full WebAudio resolution). Otherwise a 16-bit PCM |
| 140 // WAV file is produced. |
| 141 function downloadAudioBuffer(audioBuffer, filename, asFloat) { |
| 118 // Don't download if testRunner is defined; we're running a layout | 142 // Don't download if testRunner is defined; we're running a layout |
| 119 // test where this won't be useful in general. | 143 // test where this won't be useful in general. |
| 120 if (window.testRunner) | 144 if (window.testRunner) |
| 121 return false; | 145 return false; |
| 122 // Convert the audio buffer to an array containing the WAV file | 146 // Convert the audio buffer to an array containing the WAV file |
| 123 // contents. Then convert it to a blob that can be saved as a WAV | 147 // contents. Then convert it to a blob that can be saved as a WAV |
| 124 // file. | 148 // file. |
| 125 let wavData = createAudioData(audioBuffer); | 149 let wavData = createAudioData(audioBuffer, asFloat); |
| 126 let blob = new Blob([wavData], {type: 'audio/wav'}); | 150 let blob = new Blob([wavData], {type: 'audio/wav'}); |
| 127 // Manually create html tags for downloading, and simulate a click | 151 // Manually create html tags for downloading, and simulate a click |
| 128 // to download the file to the given file name. | 152 // to download the file to the given file name. |
| 129 let a = document.createElement('a'); | 153 let a = document.createElement('a'); |
| 130 a.style.display = 'none'; | 154 a.style.display = 'none'; |
| 131 a.download = filename; | 155 a.download = filename; |
| 132 let audioURL = window.URL.createObjectURL(blob); | 156 let audioURL = window.URL.createObjectURL(blob); |
| 133 let audio = new Audio(); | 157 let audio = new Audio(); |
| 134 audio.src = audioURL; | 158 audio.src = audioURL; |
| 135 a.href = audioURL; | 159 a.href = audioURL; |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 var length = Math.min(actual.length, expected.length); | 321 var length = Math.min(actual.length, expected.length); |
| 298 | 322 |
| 299 for (var k = 0; k < length; ++k) { | 323 for (var k = 0; k < length; ++k) { |
| 300 var diff = actual[k] - expected[k]; | 324 var diff = actual[k] - expected[k]; |
| 301 signalPower += expected[k] * expected[k]; | 325 signalPower += expected[k] * expected[k]; |
| 302 noisePower += diff * diff; | 326 noisePower += diff * diff; |
| 303 } | 327 } |
| 304 | 328 |
| 305 return signalPower / noisePower; | 329 return signalPower / noisePower; |
| 306 } | 330 } |
| OLD | NEW |