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

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: Initial Patch 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..7e9423e9dba7e823034eca403f3fecd6bc29f2a7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/webaudio/resources/mixing-rules.js
@@ -0,0 +1,343 @@
+// 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 {Number} numberOfChannels Number of channels of test buffer.
Raymond Toy 2016/03/08 18:04:06 If you're going to document the code this way, don
hongchan 2016/03/08 23:53:34 Done.
+ * @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;
+}
+
+/**
+ * Stringify AudioBuffer content with options.
Raymond Toy 2016/03/08 18:04:07 Not obvious how you want to stringify the AudioBuf
hongchan 2016/03/08 23:53:35 Done.
+ * @param {AudioBuffer} audioBuffer AudioBuffer object to stringify.
Raymond Toy 2016/03/08 18:04:07 The other parameters/outputs have the description
hongchan 2016/03/08 23:53:34 Done.
+ * @param {Number} frameLength Length to print.
+ * @param {Number} frameOffset Offset frames to print.
Raymond Toy 2016/03/08 18:04:07 This description of frameOffset doesn't really say
hongchan 2016/03/08 23:53:34 Done.
+ * @return {String} Assembled string for printing.
+ */
+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;
+}
+
+/**
+ * Computer number of channels from the connection.
Raymond Toy 2016/03/08 18:04:06 Typo: "Computer" -> "Compute"
hongchan 2016/03/08 23:53:35 Done.
+ * @param {String} connections A string specifies the connection. The
+ * string "128" means 3 connections, having
Raymond Toy 2016/03/08 18:04:06 Description doesn't line up with the rest of the d
hongchan 2016/03/08 23:53:34 Done.
+ * 1, 2, and 8 channels respectively.
+ * @param {Number} channelCount Channel count.
+ * @param {String} channelCountMode Channel count mode.
+ * @return {Number} A computed number of channels.
Raymond Toy 2016/03/08 18:04:06 A link to the spec would be nice. I can never reme
hongchan 2016/03/08 23:53:35 URL is at the top of this file, and I don't think
Raymond Toy 2016/03/08 23:56:54 That link is for the mixing rules. This function
hongchan 2016/03/09 19:34:24 It does not have a separate section, but a definit
+ */
+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 rules based on 'speaker' interpretation.
+ * @param {AudioBuffer} source Source audio buffer.
+ * @param {AudioBuffer} destination Destination audio buffer.
+ */
+function speakersSum(source, destination) {
+ if (source.length != destination.length)
+ throw "[mixing-rules.js] speakerSum(): buffer lengths mismatch";
Raymond Toy 2016/03/08 18:04:06 Since you know the lengths, print them out in the
hongchan 2016/03/08 23:53:35 Done.
+
+ if (source.numberOfChannels === destination.numberOfChannels) {
+ for (var channel = 0; channel < destination.numberOfChannels; ++channel) {
+ var sourceChannel = source.getChannelData(channel);
+ var destinationChannel = destination.getChannelData(channel);
+ for (var i = 0; i < destinationChannel.length; i++)
+ destinationChannel[i] += sourceChannel[i];
+ }
+
+ return;
+ }
+
+ if (source.numberOfChannels < destination.numberOfChannels)
Raymond Toy 2016/03/08 18:04:07 I find this style confusing. I think it's clearer
hongchan 2016/03/08 23:53:34 Done.
+ processUpMix(source, destination);
+ else
+ processDownMix(source, destination);
+}
+
+/**
+ * Discrete channel interpretation mixing.
+ * @param {AudioBuffer} source Source audio buffer.
+ * @param {AudioBuffer} destination Destination audio buffer.
Raymond Toy 2016/03/08 18:04:07 Since nothing is returned, I suggest saying that t
hongchan 2016/03/08 23:53:34 Done.
+ */
+function discreteSum(source, destination) {
+ if (source.length != destination.length)
+ throw "[mixing-rules.js] discreteSum(): buffer lengths mismatch";
Raymond Toy 2016/03/08 18:04:06 Give lengths in message.
hongchan 2016/03/08 23:53:35 Done.
+
+ var numberOfChannels = source.numberOfChannels < destination.numberOfChannels
+ ? source.numberOfChannels
+ : destination.numberOfChannels;
Raymond Toy 2016/03/08 18:04:07 numberOfChannels = Math.min(source.numberOfChannel
hongchan 2016/03/08 23:53:34 Done. I was following the original test code - but
+
+ for (var channel = 0; channel < numberOfChannels; ++channel) {
+ var sourceChannel = source.getChannelData(channel);
+ var destinationChannel = destination.getChannelData(channel);
+ for (var i = 0; i < destinationChannel.length; i++)
+ destinationChannel[i] += sourceChannel[i];
+ }
+}
+
+/**
+ * Process up-mix.
+ * @param {AudioBuffer} source Source audio buffer.
+ * @param {AudioBuffer} destination Destination audio buffer.
Raymond Toy 2016/03/08 18:04:07 Say that the destination is modified.
hongchan 2016/03/08 23:53:35 Done.
+ */
+function processUpMix(source, destination) {
+ var numberOfSourceChannels = source.numberOfChannels;
+ var numberOfDestinationChannels = destination.numberOfChannels;
+ var i, length = destination.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)
Raymond Toy 2016/03/08 18:04:06 Make comment notation match code notation more clo
hongchan 2016/03/08 23:53:35 Done.
+ if ((numberOfSourceChannels === 1 && numberOfDestinationChannels === 2) ||
+ (numberOfSourceChannels === 1 && numberOfDestinationChannels === 4)) {
+ var sourceChannel = source.getChannelData(0);
+ var destinationChannel0 = destination.getChannelData(0);
+ var destinationChannel1 = destination.getChannelData(1);
+ for (i = 0; i < length; i++) {
+ destinationChannel0[i] += sourceChannel[i];
Raymond Toy 2016/03/08 18:04:06 This doesn't match the comment. You're summing the
hongchan 2016/03/08 23:53:34 Done.
+ destinationChannel1[i] += sourceChannel[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 (numberOfSourceChannels == 1 && numberOfDestinationChannels == 6) {
+ var sourceChannel = source.getChannelData(0);
+ var destinationChannel2 = destination.getChannelData(2);
+ for (i = 0; i < length; i++)
+ destinationChannel2[i] += sourceChannel[i];
Raymond Toy 2016/03/08 18:04:06 Again, this doesn't match the comment. Update com
hongchan 2016/03/08 23:53:34 Done.
+
+ 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 ((numberOfSourceChannels === 2 && numberOfDestinationChannels === 4) ||
+ (numberOfSourceChannels === 2 && numberOfDestinationChannels === 6)) {
+ var sourceChannel0 = source.getChannelData(0);
+ var sourceChannel1 = source.getChannelData(1);
+ var destinationChannel0 = destination.getChannelData(0);
+ var destinationChannel1 = destination.getChannelData(1);
+ for (i = 0; i < length; i++) {
+ destinationChannel0[i] += sourceChannel0[i];
+ destinationChannel1[i] += sourceChannel1[i];
Raymond Toy 2016/03/08 18:04:07 Again, this doesn't match the comment. Update com
hongchan 2016/03/08 23:53:35 Done.
+ }
+
+ 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 (numberOfSourceChannels === 4 && numberOfDestinationChannels === 6) {
+ var sourceChannel0 = source.getChannelData(0);
+ var sourceChannel1 = source.getChannelData(1);
+ var sourceChannel2 = source.getChannelData(2);
+ var sourceChannel3 = source.getChannelData(3);
+ var destinationChannel0 = destination.getChannelData(0);
+ var destinationChannel1 = destination.getChannelData(1);
+ var destinationChannel4 = destination.getChannelData(4);
+ var destinationChannel5 = destination.getChannelData(5);
+ for (i = 0; i < length; i++) {
+ destinationChannel0[i] += sourceChannel0[i];
+ destinationChannel1[i] += sourceChannel1[i];
+ destinationChannel4[i] += sourceChannel2[i];
+ destinationChannel5[i] += sourceChannel3[i];
+ }
+
+ return;
+ }
+
+ // All other cases, fall back to the discrete sum.
+ discreteSum(source, destination);
+}
+
+/**
+ * Process down-mix from source to destination by summing into the existing data.
+ * @param {AudioBuffer} source Source audio buffer.
+ * @param {AudioBuffer} destination Destination audio buffer.
+ */
+function processDownMix(source, destination) {
+ var numberOfSourceChannels = source.numberOfChannels;
+ var numberOfDestinationChannels = destination.numberOfChannels;
+ var i, length = destination.length;
+
+ // Down-mixing: 2 -> 1
+ // output = 0.5 * (input.L + input.R)
+ if (numberOfSourceChannels === 2 && numberOfDestinationChannels === 1) {
+ var sourceChannel0 = source.getChannelData(0);
+ var sourceChannel1 = source.getChannelData(1);
+ var destinationChannel0 = destination.getChannelData(0);
+ for (i = 0; i < length; i++)
+ destinationChannel0[i] += 0.5 * (sourceChannel0[i] + sourceChannel1[i]);
Raymond Toy 2016/03/08 18:04:07 Again, this doesn't match the comment. Update com
hongchan 2016/03/08 23:53:35 Done.
+
+ return;
+ }
+
+ // Down-mixing: 4 -> 1
+ // output = 0.25 * (input.L + input.R + input.SL + input.SR)
+ if (numberOfSourceChannels === 4 && numberOfDestinationChannels === 1) {
+ var sourceChannel0 = source.getChannelData(0);
+ var sourceChannel1 = source.getChannelData(1);
+ var sourceChannel2 = source.getChannelData(2);
+ var sourceChannel3 = source.getChannelData(3);
+ var destinationChannel0 = destination.getChannelData(0);
+ for (i = 0; i < length; i++) {
+ destinationChannel0[i] += 0.25 * (sourceChannel0[i] + sourceChannel1[i]
Raymond Toy 2016/03/08 18:04:07 Again, this doesn't match the comment. Update com
hongchan 2016/03/08 23:53:35 Done.
+ + sourceChannel2[i] + sourceChannel3[i]);
+ }
+
+ return;
+ }
+
+ // Down-mixing: 5.1 -> 1
+ // output = sqrt(1/2) * (input.L + input.R) + input.C
+ // + 0.5 * (input.SL + input.SR)
+ if (numberOfSourceChannels === 6 && numberOfDestinationChannels === 1) {
+ var sourceChannel0 = source.getChannelData(0);
+ var sourceChannel1 = source.getChannelData(1);
+ var sourceChannel2 = source.getChannelData(2);
+ var sourceChannel4 = source.getChannelData(4);
+ var sourceChannel5 = source.getChannelData(5);
+ var destinationChannel0 = destination.getChannelData(0);
+ var scaleSqrtHalf = Math.sqrt(0.5);
+ for (i = 0; i < length; i++) {
+ destinationChannel0[i] +=
Raymond Toy 2016/03/08 18:04:07 This doesn't match the comment. Update comment or
hongchan 2016/03/08 23:53:34 Done.
+ scaleSqrtHalf * (sourceChannel0[i] + sourceChannel1[i])
+ + sourceChannel2[i] + 0.5 * (sourceChannel4[i] + sourceChannel5[i]);
+ }
+
+ return;
+ }
+
+ // Down-mixing: 4 -> 2
+ // output.L = 0.5 * (input.L + input.SL)
+ // output.R = 0.5 * (input.R + input.SR)
+ if (numberOfSourceChannels == 4 && numberOfDestinationChannels == 2) {
+ var sourceChannel0 = source.getChannelData(0);
Raymond Toy 2016/03/08 18:04:07 Probably want to say how sourceChannel<n> is assig
hongchan 2016/03/08 23:53:34 Done.
+ var sourceChannel1 = source.getChannelData(1);
+ var sourceChannel2 = source.getChannelData(2);
+ var sourceChannel3 = source.getChannelData(3);
+ var destinationChannel0 = destination.getChannelData(0);
+ var destinationChannel1 = destination.getChannelData(1);
+ for (i = 0; i < length; i++) {
+ destinationChannel0[i] += 0.5 * (sourceChannel0[i] + sourceChannel2[i]);
+ destinationChannel1[i] += 0.5 * (sourceChannel1[i] + sourceChannel3[i]);
Raymond Toy 2016/03/08 18:04:07 This doesn't match the comment. Update comment or
hongchan 2016/03/08 23:53:35 Done.
+ }
+
+ 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 (numberOfSourceChannels == 6 && numberOfDestinationChannels == 2) {
+ var sourceChannel0 = source.getChannelData(0);
+ var sourceChannel1 = source.getChannelData(1);
+ var sourceChannel2 = source.getChannelData(2);
+ var sourceChannel4 = source.getChannelData(4);
+ var sourceChannel5 = source.getChannelData(5);
+ var destinationChannel0 = destination.getChannelData(0);
+ var destinationChannel1 = destination.getChannelData(1);
+ var scaleSqrtHalf = Math.sqrt(0.5);
+ for (i = 0; i < length; i++) {
+ destinationChannel0[i] += sourceChannel0[i]
+ + scaleSqrtHalf * (sourceChannel2[i] + sourceChannel4[i]);
+ destinationChannel1[i] += sourceChannel1[i]
+ + scaleSqrtHalf * (sourceChannel2[i] + sourceChannel5[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 (numberOfSourceChannels === 6 && numberOfDestinationChannels === 4) {
+ var sourceChannel0 = source.getChannelData(0);
+ var sourceChannel1 = source.getChannelData(1);
+ var sourceChannel2 = source.getChannelData(2);
+ var sourceChannel4 = source.getChannelData(4);
+ var sourceChannel5 = source.getChannelData(5);
+ var destinationChannel0 = destination.getChannelData(0);
+ var destinationChannel1 = destination.getChannelData(1);
+ var destinationChannel2 = destination.getChannelData(2);
+ var destinationChannel3 = destination.getChannelData(3);
+ var scaleSqrtHalf = Math.sqrt(0.5);
+ for (i = 0; i < length; i++) {
+ destinationChannel0[i] += sourceChannel0[i] + scaleSqrtHalf * sourceChannel2[i];
+ destinationChannel1[i] += sourceChannel1[i] + scaleSqrtHalf * sourceChannel2[i];
+ destinationChannel2[i] += sourceChannel4[i];
+ destinationChannel3[i] += sourceChannel5[i];
+ }
+
+ return;
+ }
+
+ // All other cases, fall back to the discrete sum.
+ discreteSum(source, destination);
+}

Powered by Google App Engine
This is Rietveld 408576698