Search code examples
web-audio-api

Why does the splitter node do away with panning?


With the web audio API, I want to pan sound (with a PannerNode), then feed the sound into a ChannelSplitterNode so I can apply an AnalyserNode to each channel.

However, the ChannelSplitterNode does away with the pan created by the earlier PannerNode.

This gist illustrates my problem. It's lengthy, but we can focus on the panAndPlay method:

// Pans and plays a sound.
function panAndPlay(source) {
  // Specify a pan.
  var panner = audioContext.createPanner();
  panner.panningModel = 'equalpower';
  panner.setPosition(1, 0, 0);

  // Create a splitter node that is supposed to split by channel.
  var splitter = audioContext.createChannelSplitter();

  // Create the audio graph: source -> panner -> splitter -> destination
  source.connect(panner);
  panner.connect(splitter);
  // Try to hook up both channels outputted by the splitter to destination.
  splitter.connect(audioContext.destination, 0);
  splitter.connect(audioContext.destination, 1);

  // The splitter seems to ignore the pan: You only hear the pan effect if you
  // bypass the splitter by directly connecting the panner to the
  // destination. Why does the splitter remove the pan effect? I want to use
  // a splitter so that I can hook up an analyzer node to each channel, but
  // I also want the pan effect ...

  // Start playing sound.
  source.start(0);
};

How can I get the splitter to heed the pan effect from earlier in its channel outputs?


Solution

  • The splitter outputs two mono signals. When you connect both of those mono signals to the destination, they get mixed into a single mono signal. You would have to use a merger node to turn them back into a stereo signal, and connect that to the destination, to hear it as stereo.

    But it would probably be better to connect the panner directly to the destination. You can also connect it to the splitter, and the splitter outputs to the two AnalyserNodes, and then don't connect the outputs of the AnalyserNodes to anything. This way you don't need a merger node.