| Index: third_party/WebKit/LayoutTests/webaudio/resources/audit-util.js
|
| diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/audit-util.js b/third_party/WebKit/LayoutTests/webaudio/resources/audit-util.js
|
| index 16f94c98a615f7276f9656fdf516cc03bf35afaa..fb4c93c640456a986fa7882ffafecc530e21c1a1 100644
|
| --- a/third_party/WebKit/LayoutTests/webaudio/resources/audit-util.js
|
| +++ b/third_party/WebKit/LayoutTests/webaudio/resources/audit-util.js
|
| @@ -38,36 +38,56 @@ function writeInt32(n, a, offset) {
|
| a[offset + 3] = b4;
|
| }
|
|
|
| -function writeAudioBuffer(audioBuffer, a, offset) {
|
| +// Return the bits of the float as a 32-bit integer value. This
|
| +// produces the raw bits; no intepretation of the value is done.
|
| +function floatBits(f) {
|
| + var buf = new ArrayBuffer(4);
|
| + (new Float32Array(buf))[0] = f;
|
| + var bits = (new Uint32Array(buf))[0];
|
| + // Return as a signed integer.
|
| + return bits | 0;
|
| +}
|
| +
|
| +function writeAudioBuffer(audioBuffer, a, offset, asFloat) {
|
| var n = audioBuffer.length;
|
| var channels = audioBuffer.numberOfChannels;
|
|
|
| for (var i = 0; i < n; ++i) {
|
| for (var k = 0; k < channels; ++k) {
|
| var buffer = audioBuffer.getChannelData(k);
|
| - var sample = buffer[i] * 32768.0;
|
| -
|
| - // Clip samples to the limitations of 16-bit.
|
| - // If we don't do this then we'll get nasty wrap-around distortion.
|
| - if (sample < -32768)
|
| + if (asFloat) {
|
| + var sample = floatBits(buffer[i]);
|
| + writeInt32(sample, a, offset);
|
| + offset += 4;
|
| + } else {
|
| + var sample = buffer[i] * 32768.0;
|
| +
|
| + // Clip samples to the limitations of 16-bit.
|
| + // If we don't do this then we'll get nasty wrap-around distortion.
|
| + if (sample < -32768)
|
| sample = -32768;
|
| - if (sample > 32767)
|
| + if (sample > 32767)
|
| sample = 32767;
|
|
|
| - writeInt16(sample, a, offset);
|
| - offset += 2;
|
| + writeInt16(sample, a, offset);
|
| + offset += 2;
|
| + }
|
| }
|
| }
|
| }
|
|
|
| -function createWaveFileData(audioBuffer) {
|
| +// See http://soundfile.sapp.org/doc/WaveFormat/ and
|
| +// http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
|
| +// for a quick introduction to the WAVE PCM format.
|
| +function createWaveFileData(audioBuffer, asFloat) {
|
| + var bytesPerSample = asFloat ? 4 : 2;
|
| var frameLength = audioBuffer.length;
|
| var numberOfChannels = audioBuffer.numberOfChannels;
|
| var sampleRate = audioBuffer.sampleRate;
|
| - var bitsPerSample = 16;
|
| + var bitsPerSample = 8 * bytesPerSample;
|
| var byteRate = sampleRate * numberOfChannels * bitsPerSample/8;
|
| var blockAlign = numberOfChannels * bitsPerSample/8;
|
| - var wavDataByteLength = frameLength * numberOfChannels * 2; // 16-bit audio
|
| + var wavDataByteLength = frameLength * numberOfChannels * bytesPerSample;
|
| var headerByteLength = 44;
|
| var totalLength = headerByteLength + wavDataByteLength;
|
|
|
| @@ -83,7 +103,9 @@ function createWaveFileData(audioBuffer) {
|
| writeString("fmt ", waveFileData, 12);
|
|
|
| writeInt32(subChunk1Size, waveFileData, 16); // SubChunk1Size (4)
|
| - writeInt16(1, waveFileData, 20); // AudioFormat (2)
|
| + // The format tag value is 1 for integer PCM data and 3 for IEEE
|
| + // float data.
|
| + writeInt16(asFloat ? 3 : 1, waveFileData, 20); // AudioFormat (2)
|
| writeInt16(numberOfChannels, waveFileData, 22); // NumChannels (2)
|
| writeInt32(sampleRate, waveFileData, 24); // SampleRate (4)
|
| writeInt32(byteRate, waveFileData, 28); // ByteRate (4)
|
| @@ -94,13 +116,13 @@ function createWaveFileData(audioBuffer) {
|
| writeInt32(subChunk2Size, waveFileData, 40); // SubChunk2Size (4)
|
|
|
| // Write actual audio data starting at offset 44.
|
| - writeAudioBuffer(audioBuffer, waveFileData, 44);
|
| + writeAudioBuffer(audioBuffer, waveFileData, 44, asFloat);
|
|
|
| return waveFileData;
|
| }
|
|
|
| -function createAudioData(audioBuffer) {
|
| - return createWaveFileData(audioBuffer);
|
| +function createAudioData(audioBuffer, asFloat) {
|
| + return createWaveFileData(audioBuffer, asFloat);
|
| }
|
|
|
| function finishAudioTest(event) {
|
| @@ -109,12 +131,14 @@ function finishAudioTest(event) {
|
| testRunner.notifyDone();
|
| }
|
|
|
| -// Save the given |audioBuffer| to a 16-bit WAV file using the name
|
| -// given by |filename|. This is intended to be run from a browser.
|
| -// The developer is expected to use the console to run
|
| -// downloadAudioBuffer when necessary to create a new reference file
|
| -// for a test.
|
| -function downloadAudioBuffer(audioBuffer, filename) {
|
| +// Save the given |audioBuffer| to a WAV file using the name given by
|
| +// |filename|. This is intended to be run from a browser. The
|
| +// developer is expected to use the console to run downloadAudioBuffer
|
| +// when necessary to create a new reference file for a test. If
|
| +// |asFloat| is given and is true, the WAV file produced uses 32-bit
|
| +// float format (full WebAudio resolution). Otherwise a 16-bit PCM
|
| +// WAV file is produced.
|
| +function downloadAudioBuffer(audioBuffer, filename, asFloat) {
|
| // Don't download if testRunner is defined; we're running a layout
|
| // test where this won't be useful in general.
|
| if (window.testRunner)
|
| @@ -122,7 +146,7 @@ function downloadAudioBuffer(audioBuffer, filename) {
|
| // Convert the audio buffer to an array containing the WAV file
|
| // contents. Then convert it to a blob that can be saved as a WAV
|
| // file.
|
| - let wavData = createAudioData(audioBuffer);
|
| + let wavData = createAudioData(audioBuffer, asFloat);
|
| let blob = new Blob([wavData], {type: 'audio/wav'});
|
| // Manually create html tags for downloading, and simulate a click
|
| // to download the file to the given file name.
|
|
|