Reputation: 171
I've created a simple jsfiddle using ChannelMergerNode, to play oscillator on the right speaker. It works as expected on Chrome, but on Safari the sound plays to both speakers (right and left).
var audioContext = window.AudioContext || window.webkitAudioContext;
var context = new audioContext();
var merger = context.createChannelMerger();
merger.connect(context.destination);
var osc = context.createOscillator();
osc.connect(merger, 0, 1);
osc.start();
osc.stop(10.0);
https://jsfiddle.net/RivkaB/tcnofjy1/16/
Any idea how solve this issue? Thank you.
Upvotes: 0
Views: 427
Reputation: 6048
I think Safari hasn't updated its ChannelMergerNode
to follow the spec. It's been a while, but I think what's happening is that since you only connect one input, the output contains just the one channel, basically ignoring the unconnected input 0.
If you want this to work with Safari, you need to connect something to input 0. This could be your oscillator connected to a zero-gain node. Or maybe a looping AudioBufferSourceNode
with a buffer of all zeros.
But I'm not 100% sure this will work either. If this doesn't work, use AudioBufferSourceNode
with a very very tiny value, like 1e-20.
Upvotes: 0
Reputation: 20934
The ChannelMergerNode
interface is used to merge channels that have been split-up by a ChannelSplitterNode
into a single channel. The panning effect that you get might be a side effect of the Chrome implementation of that node, although I'm not sure.
If you wan't to create a stereo panning effect then create a StereoPannerNode
which allows you to control the output on the left and right side.
The StereoPannerNode
has a pan
property. This property has a value
property which can be a number ranging from -1
(left) to 1
(right), with 0
being the center.
const buttons = document.querySelectorAll('button');
const audioContext = new AudioContext();
const stereoPannerNode = audioContext.createStereoPanner();
const oscillatorNode = audioContext.createOscillator();
oscillatorNode.connect(stereoPannerNode);
stereoPannerNode.connect(audioContext.destination);
for (const button of buttons) {
button.addEventListener('click', function() {
if (button.value === 'play') {
oscillatorNode.start();
} else if (button.value === 'left') {
stereoPannerNode.pan.value = -1;
} else if (button.value === 'right') {
stereoPannerNode.pan.value = 1;
} else {
stereoPannerNode.pan.value = 0;
}
});
}
<button value="play">Play</button>
<button value="left">Only left</button>
<button value="right">Only right</button>
<button value="both">Both</button>
Upvotes: 1