Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: third_party/WebKit/LayoutTests/webaudio/resources/audit-util.js

Issue 2737653007: Allow saving reference file as a float32 WAV file (Closed)
Patch Set: Address review comments Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698