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

Unified Diff: third_party/WebKit/LayoutTests/webaudio/resources/mixing-rules.js

Issue 1773973002: Complete the implementation of up/down-mixing rules for AudioNode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressing Feedback (1) Created 4 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/LayoutTests/webaudio/resources/mixing-rules.js
diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/mixing-rules.js b/third_party/WebKit/LayoutTests/webaudio/resources/mixing-rules.js
new file mode 100644
index 0000000000000000000000000000000000000000..4d434869586781bfd486d3116aa3096fa7c42463
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/webaudio/resources/mixing-rules.js
@@ -0,0 +1,345 @@
+// Utilities for mixing rule testing.
+// http://webaudio.github.io/web-audio-api/#channel-up-mixing-and-down-mixing
+
+
+/**
+ * Create an n-channel buffer, with all sample data zero except for a shifted
+ * impulse. The impulse position depends on the channel index. For example, for
+ * a 4-channel buffer:
+ * channel 0: 1 0 0 0 0 0 0 0
+ * channel 1: 0 1 0 0 0 0 0 0
+ * channel 2: 0 0 1 0 0 0 0 0
+ * channel 3: 0 0 0 1 0 0 0 0
+ * @param {AudioContext} context Associated AudioContext.
+ * @param {Number} numberOfChannels Number of channels of test buffer.
+ * @param {Number} frameLength Buffer length in frames.
+ * @return {AudioBuffer}
+ */
+function createShiftedImpulseBuffer(context, numberOfChannels, frameLength) {
+ var shiftedImpulseBuffer = context.createBuffer(numberOfChannels, frameLength, context.sampleRate);
+ for (var channel = 0; channel < numberOfChannels; ++channel) {
+ var data = shiftedImpulseBuffer.getChannelData(channel);
+ data[channel] = 1;
+ }
+
+ return shiftedImpulseBuffer;
+}
+
+/**
+ * Create a string displays the content of AudioBuffer.
Raymond Toy 2016/03/09 22:14:19 "string displays" -> "string that displays"
hongchan 2016/03/09 23:26:11 Done.
+ * @param {AudioBuffer} audioBuffer AudioBuffer object to stringify.
+ * @param {Number} frameLength Number of frames to be printed.
+ * @param {Number} frameOffset Starting frame position for printing.
+ * @return {String}
+ */
+function stringifyBuffer(audioBuffer, frameLength, frameOffset) {
+ frameOffset = (frameOffset || 0);
+
+ var stringifiedBuffer = '';
+ for (var channel = 0; channel < audioBuffer.numberOfChannels; ++channel) {
+ var channelData = audioBuffer.getChannelData(channel);
+ for (var i = 0; i < frameLength; ++i)
+ stringifiedBuffer += channelData[i + frameOffset] + ' ';
+ stringifiedBuffer += '\n';
+ }
+
+ return stringifiedBuffer;
+}
+
+/**
+ * Compute number of channels from the connection.
+ * @param {String} connections A string specifies the connection. For
+ * example, the string "128" means 3
+ * connections, having 1, 2, and 8 channels
+ * respectively.
+ * @param {Number} channelCount Channel count.
+ * @param {String} channelCountMode Channel count mode.
+ * @return {Number} Computed number of channels.
+ */
+function computeNumberOfChannels(connections, channelCount, channelCountMode) {
+ if (channelCountMode == "explicit")
+ return channelCount;
+
+ // Must have at least one channel.
+ var computedNumberOfChannels = 1;
+
+ // Compute "computedNumberOfChannels" based on all the connections.
+ for (var i = 0; i < connections.length; ++i) {
+ var connectionNumberOfChannels = parseInt(connections[i]);
+ computedNumberOfChannels = Math.max(computedNumberOfChannels, connectionNumberOfChannels);
+ }
+
+ if (channelCountMode == "clamped-max")
+ computedNumberOfChannels = Math.min(computedNumberOfChannels, channelCount);
+
+ return computedNumberOfChannels;
+}
+
+/**
+ * Apply up/down-mixing (in-place summing) based on 'speaker' interpretation.
+ * @param {AudioBuffer} input Input audio buffer.
+ * @param {AudioBuffer} output Output audio buffer.
+ */
+function speakersSum(input, output) {
+ if (input.length != output.length) {
+ throw '[mixing-rules.js] speakerSum(): buffer lengths mismatch (input: '
+ + input.length + ', output: ' + output.length + ')';
+ }
+
+ if (input.numberOfChannels === output.numberOfChannels) {
+ for (var channel = 0; channel < output.numberOfChannels; ++channel) {
+ var inputChannel = input.getChannelData(channel);
+ var outputChannel = output.getChannelData(channel);
+ for (var i = 0; i < outputChannel.length; i++)
+ outputChannel[i] += inputChannel[i];
+ }
+ } else if (input.numberOfChannels < output.numberOfChannels) {
+ processUpMix(input, output);
+ } else {
+ processDownMix(input, output);
+ }
+}
+
+/**
+ * In-place summing to |output| based on 'discrete' channel interpretation.
+ * @param {AudioBuffer} input Input audio buffer.
+ * @param {AudioBuffer} output Output audio buffer.
+ */
+function discreteSum(input, output) {
+ if (input.length != output.length) {
+ throw '[mixing-rules.js] speakerSum(): buffer lengths mismatch (input: '
+ + input.length + ', output: ' + output.length + ')';
+ }
+
+ var numberOfChannels = Math.min(input.numberOfChannels, output.numberOfChannels)
+
+ for (var channel = 0; channel < numberOfChannels; ++channel) {
+ var inputChannel = input.getChannelData(channel);
+ var outputChannel = output.getChannelData(channel);
+ for (var i = 0; i < outputChannel.length; i++)
+ outputChannel[i] += inputChannel[i];
+ }
+}
+
+/**
+ * Perform up-mix by in-place summing to |output| buffer.
Raymond Toy 2016/03/09 22:14:19 For consistency, you probably want to add this com
hongchan 2016/03/09 23:26:11 Done.
+ * @param {AudioBuffer} input Input audio buffer.
+ * @param {AudioBuffer} output Output audio buffer.
+ */
+function processUpMix(input, output) {
+ var numberOfInputChannels = input.numberOfChannels;
+ var numberOfOutputChannels = output.numberOfChannels;
+ var i, length = output.length;
+
+ // Up-mixing: 1 -> 2, 1 -> 4
+ // output.L += input
+ // output.R += input
+ // output.SL += 0 (in the case of 1 -> 4)
+ // output.SR += 0 (in the case of 1 -> 4)
+ if ((numberOfInputChannels === 1 && numberOfOutputChannels === 2) ||
+ (numberOfInputChannels === 1 && numberOfOutputChannels === 4)) {
+ var inputChannel = input.getChannelData(0);
+ var outputChannel0 = output.getChannelData(0);
+ var outputChannel1 = output.getChannelData(1);
+ for (i = 0; i < length; i++) {
+ outputChannel0[i] += inputChannel[i];
+ outputChannel1[i] += inputChannel[i];
+ }
+
+ return;
+ }
+
+ // Up-mixing: 1 -> 5.1
+ // output.L += 0
+ // output.R += 0
+ // output.C += input
+ // output.LFE += 0
+ // output.SL += 0
+ // output.SR += 0
+ if (numberOfInputChannels == 1 && numberOfOutputChannels == 6) {
+ var inputChannel = input.getChannelData(0);
+ var outputChannel2 = output.getChannelData(2);
+ for (i = 0; i < length; i++)
+ outputChannel2[i] += inputChannel[i];
+
+ return;
+ }
+
+ // Up-mixing: 2 -> 4, 2 -> 5.1
+ // output.L += input.L
+ // output.R += input.R
+ // output.C += 0 (in the case of 2 -> 5.1)
+ // output.LFE += 0 (in the case of 2 -> 5.1)
+ // output.SL += 0
+ // output.SR += 0
+ if ((numberOfInputChannels === 2 && numberOfOutputChannels === 4) ||
+ (numberOfInputChannels === 2 && numberOfOutputChannels === 6)) {
+ var inputChannel0 = input.getChannelData(0);
+ var inputChannel1 = input.getChannelData(1);
+ var outputChannel0 = output.getChannelData(0);
+ var outputChannel1 = output.getChannelData(1);
+ for (i = 0; i < length; i++) {
+ outputChannel0[i] += inputChannel0[i];
+ outputChannel1[i] += inputChannel1[i];
+ }
+
+ return;
+ }
+
+ // Up-mixing: 4 -> 5.1
+ // output.L += input.L
+ // output.R += input.R
+ // output.C += 0
+ // output.LFE += 0
+ // output.SL += input.SL
+ // output.SR += input.SR
+ if (numberOfInputChannels === 4 && numberOfOutputChannels === 6) {
+ var inputChannel0 = input.getChannelData(0); // input.L
+ var inputChannel1 = input.getChannelData(1); // input.R
+ var inputChannel2 = input.getChannelData(2); // input.SL
+ var inputChannel3 = input.getChannelData(3); // input.SR
+ var outputChannel0 = output.getChannelData(0); // output.L
+ var outputChannel1 = output.getChannelData(1); // output.R
+ var outputChannel4 = output.getChannelData(4); // output.SL
+ var outputChannel5 = output.getChannelData(5); // output.SR
+ for (i = 0; i < length; i++) {
+ outputChannel0[i] += inputChannel0[i];
+ outputChannel1[i] += inputChannel1[i];
+ outputChannel4[i] += inputChannel2[i];
+ outputChannel5[i] += inputChannel3[i];
+ }
+
+ return;
+ }
+
+ // All other cases, fall back to the discrete sum.
+ discreteSum(input, output);
+}
+
+/**
+ * Process down-mix from source to destination by summing into the existing data.
+ * @param {AudioBuffer} input Input audio buffer.
+ * @param {AudioBuffer} output Output audio buffer.
+ */
+function processDownMix(input, output) {
+ var numberOfInputChannels = input.numberOfChannels;
+ var numberOfOutputChannels = output.numberOfChannels;
+ var i, length = output.length;
+
+ // Down-mixing: 2 -> 1
+ // output += 0.5 * (input.L + input.R)
+ if (numberOfInputChannels === 2 && numberOfOutputChannels === 1) {
+ var inputChannel0 = input.getChannelData(0); // input.L
+ var inputChannel1 = input.getChannelData(1); // input.R
+ var outputChannel0 = output.getChannelData(0);
+ for (i = 0; i < length; i++)
+ outputChannel0[i] += 0.5 * (inputChannel0[i] + inputChannel1[i]);
+
+ return;
+ }
+
+ // Down-mixing: 4 -> 1
+ // output += 0.25 * (input.L + input.R + input.SL + input.SR)
+ if (numberOfInputChannels === 4 && numberOfOutputChannels === 1) {
+ var inputChannel0 = input.getChannelData(0); // input.L
+ var inputChannel1 = input.getChannelData(1); // input.R
+ var inputChannel2 = input.getChannelData(2); // input.SL
+ var inputChannel3 = input.getChannelData(3); // input.SR
+ var outputChannel0 = output.getChannelData(0);
+ for (i = 0; i < length; i++) {
+ outputChannel0[i] += 0.25 * (inputChannel0[i] + inputChannel1[i]
+ + inputChannel2[i] + inputChannel3[i]);
+ }
+
+ return;
+ }
+
+ // Down-mixing: 5.1 -> 1
+ // output += sqrt(1/2) * (input.L + input.R) + input.C
+ // + 0.5 * (input.SL + input.SR)
+ if (numberOfInputChannels === 6 && numberOfOutputChannels === 1) {
+ var inputChannel0 = input.getChannelData(0); // input.L
+ var inputChannel1 = input.getChannelData(1); // input.R
+ var inputChannel2 = input.getChannelData(2); // input.C
+ var inputChannel4 = input.getChannelData(4); // input.SL
+ var inputChannel5 = input.getChannelData(5); // input.SR
+ var outputChannel0 = output.getChannelData(0);
+ var scaleSqrtHalf = Math.sqrt(0.5);
+ for (i = 0; i < length; i++) {
+ outputChannel0[i] +=
+ scaleSqrtHalf * (inputChannel0[i] + inputChannel1[i])
+ + inputChannel2[i] + 0.5 * (inputChannel4[i] + inputChannel5[i]);
+ }
+
+ return;
+ }
+
+ // Down-mixing: 4 -> 2
+ // output.L += 0.5 * (input.L + input.SL)
+ // output.R += 0.5 * (input.R + input.SR)
+ if (numberOfInputChannels == 4 && numberOfOutputChannels == 2) {
+ var inputChannel0 = input.getChannelData(0); // input.L
+ var inputChannel1 = input.getChannelData(1); // input.R
+ var inputChannel2 = input.getChannelData(2); // input.SL
+ var inputChannel3 = input.getChannelData(3); // input.SR
+ var outputChannel0 = output.getChannelData(0); // output.L
+ var outputChannel1 = output.getChannelData(1); // output.R
+ for (i = 0; i < length; i++) {
+ outputChannel0[i] += 0.5 * (inputChannel0[i] + inputChannel2[i]);
+ outputChannel1[i] += 0.5 * (inputChannel1[i] + inputChannel3[i]);
+ }
+
+ return;
+ }
+
+ // Down-mixing: 5.1 -> 2
+ // output.L += input.L + sqrt(1/2) * (input.C + input.SL)
+ // output.R += input.R + sqrt(1/2) * (input.C + input.SR)
+ if (numberOfInputChannels == 6 && numberOfOutputChannels == 2) {
+ var inputChannel0 = input.getChannelData(0); // input.L
+ var inputChannel1 = input.getChannelData(1); // input.R
+ var inputChannel2 = input.getChannelData(2); // input.C
+ var inputChannel4 = input.getChannelData(4); // input.SL
+ var inputChannel5 = input.getChannelData(5); // input.SR
+ var outputChannel0 = output.getChannelData(0); // output.L
+ var outputChannel1 = output.getChannelData(1); // output.R
+ var scaleSqrtHalf = Math.sqrt(0.5);
+ for (i = 0; i < length; i++) {
+ outputChannel0[i] += inputChannel0[i]
+ + scaleSqrtHalf * (inputChannel2[i] + inputChannel4[i]);
+ outputChannel1[i] += inputChannel1[i]
+ + scaleSqrtHalf * (inputChannel2[i] + inputChannel5[i]);
+ }
+
+ return;
+ }
+
+ // Down-mixing: 5.1 -> 4
+ // output.L += input.L + sqrt(1/2) * input.C
+ // output.R += input.R + sqrt(1/2) * input.C
+ // output.SL += input.SL
+ // output.SR += input.SR
+ if (numberOfInputChannels === 6 && numberOfOutputChannels === 4) {
+ var inputChannel0 = input.getChannelData(0); // input.L
+ var inputChannel1 = input.getChannelData(1); // input.R
+ var inputChannel2 = input.getChannelData(2); // input.C
+ var inputChannel4 = input.getChannelData(4); // input.SL
+ var inputChannel5 = input.getChannelData(5); // input.SR
+ var outputChannel0 = output.getChannelData(0); // output.L
+ var outputChannel1 = output.getChannelData(1); // output.R
+ var outputChannel2 = output.getChannelData(2); // output.SL
+ var outputChannel3 = output.getChannelData(3); // output.SR
+ var scaleSqrtHalf = Math.sqrt(0.5);
+ for (i = 0; i < length; i++) {
+ outputChannel0[i] += inputChannel0[i] + scaleSqrtHalf * inputChannel2[i];
+ outputChannel1[i] += inputChannel1[i] + scaleSqrtHalf * inputChannel2[i];
+ outputChannel2[i] += inputChannel4[i];
+ outputChannel3[i] += inputChannel5[i];
+ }
+
+ return;
+ }
+
+ // All other cases, fall back to the discrete sum.
+ discreteSum(input, output);
+}

Powered by Google App Engine
This is Rietveld 408576698