function HOARotator(context, ambisonicOrder) {
  this._context = context;
  this._ambisonicOrder = ambisonicOrder;

  // We need to determine the number of channels K based on the ambisonic order
  // N where K = (N + 1)^2.
  const numberOfChannels = (ambisonicOrder + 1) * (ambisonicOrder + 1);

  this._splitter = this._context.createChannelSplitter(numberOfChannels);
  this._merger = this._context.createChannelMerger(numberOfChannels);

  // Create a set of per-order rotation matrices using gain nodes.
  this._gainNodeMatrix = [];
  let orderOffset;
  let rows;
  let inputIndex;
  let outputIndex;
  let matrixIndex;
  for (let i = 1; i <= ambisonicOrder; i++) {
    // Each ambisonic order requires a separate (2l + 1) x (2l + 1) rotation
    // matrix. We compute the offset value as the first channel index of the
    // current order where
    //   k_last = l^2 + l + m,
    // and m = -l
    //   k_last = l^2
    orderOffset = i * i;

    // Uses row-major indexing.
    rows = (2 * i + 1);

    this._gainNodeMatrix[i - 1] = [];
    for (let j = 0; j < rows; j++) {
      inputIndex = orderOffset + j;
      for (let k = 0; k < rows; k++) {
        outputIndex = orderOffset + k;
        matrixIndex = j * rows + k;
        this._gainNodeMatrix[i - 1][matrixIndex] = this._context.createGain();
        this._splitter.connect(
            this._gainNodeMatrix[i - 1][matrixIndex], inputIndex);
        this._gainNodeMatrix[i - 1][matrixIndex].connect(
            this._merger, 0, outputIndex);
      }
    }
  }

  // W-channel is not involved in rotation, skip straight to ouput.
  this._splitter.connect(this._merger, 0, 0);

  // Default Identity matrix.
  this.setRotationMatrix3(new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]));

  // Input/Output proxy.
  this.input = this._splitter;
  this.output = this._merger;
}
Higher-order-ambisonic decoder based on gain node network. We expect
the order of the channels to conform to ACN ordering. Below are the helper
methods to compute SH rotation using recursion. The code uses maths described
in the following papers:
 [1] R. Green, "Spherical Harmonic Lighting: The Gritty Details", GDC 2003,
     http://www.research.scea.com/gdc2003/spherical-harmonic-lighting.pdf
 [2] J. Ivanic and K. Ruedenberg, "Rotation Matrices for Real
     Spherical Harmonics. Direct Determination by Recursion", J. Phys.
     Chem., vol. 100, no. 15, pp. 6342-6347, 1996.
     http://pubs.acs.org/doi/pdf/10.1021/jp953350u
 [2b] Corrections to initial publication:
      http://pubs.acs.org/doi/pdf/10.1021/jp9833350
@constructor
@param {AudioContext} context - Associated AudioContext.
@param {Number} ambisonicOrder - Ambisonic order.