Mixing and Splitting Audio
Working with audio signals inevitably leads to the need of mixing and splitting the signals. Whether you want to route a signal to distinct effect chains or mix different audio players and inputs, Switchboard SDK can help you with that. The specific nodes take care of the various use-cases you might encounter.
Important Terminology:
- Audio bus: A stream of audio that goes into or comes out of a node. It encapsulates one or more channels of audio.
Nodes for Mixing Audio
Mixing Audio Buses
The MixerNode
has two or more input audio buses that are mixed together in a single output audio bus with equal magnitude. The input and output audio bus channel numbers must match.
Using the MixerNode Class
- JSON
- Swift
- Kotlin
- C++
- JavaScript
{
"nodes": {
{ "id": "audioPlayerNode", "type": "AudioPlayerNode" },
{ "id": "mixerNode", "type": "MixerNode" }
},
"connections": {
{ "sourceNode": "inputNode", "destinationNode": "mixerNode" },
{ "sourceNode": "audioPlayerNode", "destinationNode": "mixerNode" },
{ "sourceNode": "mixerNode", "destinationNode": "outputNode" }
}
}
import SwitchboardSDK
...
let mixerNode = SBMixerNode()
let audioGraph = SBAudioGraph()
...
audioGraph.addNode(mixerNode)
audioGraph.connect(vocalsInputNode, to: mixerNode)
audioGraph.connect(musicInputNode, to: mixerNode)
audioGraph.connect(mixerNode, to: outputNode)
import com.synervoz.switchboard.sdk.audiograph.AudioGraph
import com.synervoz.switchboard.sdk.audiographnodes.MixerNode
...
private val mixerNode = MixerNode()
private val audioGraph = AudioGraph()
...
audioGraph.addNode(mixerNode)
audioGraph.connect(vocalsInputNode, mixerNode)
audioGraph.connect(musicInputNode, mixerNode)
audioGraph.connect(mixerNode, outputNode)
#include "AudioGraph.hpp"
#include "MixerNode.hpp"
using namespace switchboard;
...
MixerNode mixerNode;
AudioGraph audioGraph;
...
audioGraph.addNode(mixerNode);
audioGraph.connect(vocalsInputNode, mixerNode);
audioGraph.connect(musicInputNode, mixerNode);
audioGraph.connect(mixerNode, outputNode);
// Change the import to reflect the location of library
// relative to this publically accessible AudioWorklet
import {SwitchboardSDK} from "/libs/switchboard-sdk/index.js";
...
audioGraph.addNode(mixerNode);
audioGraph.connect(audioGraphInputNode1, mixerNode);
audioGraph.connect(audioGraphInputNode2, mixerNode);
audioGraph.connect(gainNode, audioGraphOutputNode);
For more information take a look at the Mixing
Mixing Audio Channels
The MultiChannelToMonoNode
has a single multichannel input audio bus and a single mono output audio bus. The channels of the input audio bus are mixed to mono with equal magnitude and normalized to 0 dBFS to avoid clipping.
Using the MultiChannelToMonoNode Class
- JSON
- Swift
- Kotlin
- C++
- JavaScript
{
"nodes": {
{ "id": "multiChannelToMonoNode", "type": "MultiChannelToMonoNode" }
},
"connections": {
{ "sourceNode": "inputNode", "destinationNode": "multiChannelToMonoNode" },
{ "sourceNode": "multiChannelToMonoNode", "destinationNode": "outputNode" }
}
}
import SwitchboardSDK
...
let multiChannelToMonoNode = SBMultiChannelToMonoNode()
let audioGraph = SBAudioGraph()
...
audioGraph.addNode(multiChannelToMonoNode)
audioGraph.connect(stereoInputNode, to: multiChannelToMonoNode)
audioGraph.connect(multiChannelToMonoNode, to: monoOutputNode)
import com.synervoz.switchboard.sdk.audiograph.AudioGraph
import com.synervoz.switchboard.sdk.audiographnodes.MultiChannelToMonoNode
...
private val multiChannelToMonoNode = MultiChannelToMonoNode()
private val audioGraph = AudioGraph()
...
audioGraph.addNode(multiChannelToMonoNode)
audioGraph.connect(stereoInputNode, multiChannelToMonoNode)
audioGraph.connect(multiChannelToMonoNode, monoOutputNode)
#include "AudioGraph.hpp"
#include "MultiChannelToMonoNode.hpp"
using namespace switchboard;
...
MultiChannelToMonoNode multiChannelToMonoNode;
AudioGraph audioGraph;
...
audioGraph.addNode(multiChannelToMonoNode);
audioGraph.connect(stereoInputNode, multiChannelToMonoNode);
audioGraph.connect(multiChannelToMonoNode, monoOutputNode);
// Change the import to reflect the location of library
// relative to this publically accessible AudioWorklet
import {SwitchboardSDK} from "/libs/switchboard-sdk/index.js";
...
audioGraph.addNode(multiChannelToMonoNode);
audioGraph.connect(audioGraphInputNode, multiChannelToMonoNode);
audioGraph.connect(multiChannelToMonoNode, audioGraphOutputNode);
Merging Audio Buses
The MonoBusMergerNode
has multiple mono input audio buses and a single output audio bus that has multiple channels matching the number of input audio buses. The channels of the input audio buses are merged into the output audio bus unaltered.
Using the MonoBusMergerNode Class
- JSON
- Swift
- Kotlin
- C++
- JavaScript
{
"nodes": {
{ "id": "monoPlayerNode", "type": "AudioPlayerNode" },
{ "id": "monoBusMergerNode", "type": "MonoBusMergerNode" }
},
"connections": {
{ "sourceNode": "inputNode", "destinationNode": "monoBusMergerNode" },
{ "sourceNode": "monoPlayerNode", "destinationNode": "monoBusMergerNode" },
{ "sourceNode": "monoBusMergerNode", "destinationNode": "outputNode" }
}
}
import SwitchboardSDK
...
let monoBusMergerNode = SBMonoBusMergerNode()
let audioGraph = SBAudioGraph()
...
audioGraph.addNode(monoBusMergerNode)
audioGraph.connect(monoInputNode1, to: monoBusMergerNode)
audioGraph.connect(monoInputNode2, to: monoBusMergerNode)
audioGraph.connect(monoBusMergerNode, to: stereoOutputNode)
import com.synervoz.switchboard.sdk.audiograph.AudioGraph
import com.synervoz.switchboard.sdk.audiographnodes.MonoBusMergerNode
...
private val monoBusMergerNode = MonoBusMergerNode()
private val audioGraph = AudioGraph()
...
audioGraph.addNode(monoBusMergerNode)
audioGraph.connect(monoInputNode1, monoBusMergerNode)
audioGraph.connect(monoInputNode2, monoBusMergerNode)
audioGraph.connect(monoBusMergerNode, stereoOutputNode)
#include "AudioGraph.hpp"
#include "MonoBusMergerNode.hpp"
using namespace switchboard;
...
MonoBusMergerNode monoBusMergerNode;
AudioGraph audioGraph;
...
audioGraph.addNode(monoBusMergerNode);
audioGraph.connect(monoInputNode1, monoBusMergerNode);
audioGraph.connect(monoInputNode2, monoBusMergerNode);
audioGraph.connect(monoBusMergerNode, stereoOutputNode);
// Change the import to reflect the location of library
// relative to this publically accessible AudioWorklet
import {SwitchboardSDK} from "/libs/switchboard-sdk/index.js";
...
audioGraph.addNode(monoBusMergerNode);
audioGraph.connect(audioGraphMonoInputNode1, monoBusMergerNode);
audioGraph.connect(audioGraphMonoInputNode2, monoBusMergerNode);
audioGraph.connect(monoBusMergerNode, audioGraphOutputNode);
The StereoBusMergerNode
has multiple stereo input audio buses and a single output audio bus that has multiple channels matching the number of input audio buses multiplied by two for the stereo input. The channels of the input audio buses are merged into the output audio bus unaltered.
Using the StereoBusMergerNode Class
- JSON
- Swift
- Kotlin
- C++
- JavaScript
{
"nodes": {
{ "id": "stereoPlayerNode", "type": "AudioPlayerNode" },
{ "id": "stereoBusMergerNode", "type": "StereoBusMergerNode" }
},
"connections": {
{ "sourceNode": "inputNode", "destinationNode": "stereoBusMergerNode" },
{ "sourceNode": "stereoPlayerNode", "destinationNode": "stereoBusMergerNode" },
{ "sourceNode": "stereoBusMergerNode", "destinationNode": "outputNode" }
}
}
import SwitchboardSDK
...
let stereoBusMergerNode = SBStereoBusMergerNode()
let audioGraph = SBAudioGraph()
...
audioGraph.addNode(stereoBusMergerNode)
audioGraph.connect(stereoInputNode1, to: stereoBusMergerNode)
audioGraph.connect(stereoInputNode2, to: stereoBusMergerNode)
audioGraph.connect(stereoBusMergerNode, to: quadOutputNode)
import com.synervoz.switchboard.sdk.audiograph.AudioGraph
import com.synervoz.switchboard.sdk.audiographnodes.StereoBusMergerNode
...
private val stereoBusMergerNode = StereoBusMergerNode()
private val audioGraph = AudioGraph()
...
audioGraph.addNode(stereoBusMergerNode)
audioGraph.connect(stereoInputNode1, stereoBusMergerNode)
audioGraph.connect(stereoInputNode2, stereoBusMergerNode)
audioGraph.connect(stereoBusMergerNode, quadOutputNode)
#include "AudioGraph.hpp"
#include "StereoBusMergerNode.hpp"
using namespace switchboard;
...
StereoBusMergerNode stereoBusMergerNode;
AudioGraph audioGraph;
...
audioGraph.addNode(stereoBusMergerNode);
audioGraph.connect(stereoInputNode1, stereoBusMergerNode);
audioGraph.connect(stereoInputNode2, stereoBusMergerNode);
audioGraph.connect(stereoBusMergerNode, quadOutputNode);
// Change the import to reflect the location of library
// relative to this publically accessible AudioWorklet
import {SwitchboardSDK} from "/libs/switchboard-sdk/index.js";
...
audioGraph.addNode(stereoBusMergerNode);
audioGraph.connect(audioGraphStereoInputNode1, stereoBusMergerNode);
audioGraph.connect(audioGraphStereoInputNode2, stereoBusMergerNode);
audioGraph.connect(stereoBusMergerNode, audioGraphOutputNode);
Selecting and Forwarding an Audio Bus
The BusSelectNode
has multiple input audio buses and a single output audio bus. An input audio bus can be selected and forwarded to the output audio bus. The number of channels of the input and output audio buses must match.
Using the BusSelectNode Class
- JSON
- Swift
- Kotlin
- C++
- JavaScript
{
"nodes": {
{ "id": "audioPlayerNode", "type": "AudioPlayerNode" },
{ "id": "busSelectNode", "type": "BusSelectNode" }
},
"connections": {
{ "sourceNode": "inputNode", "destinationNode": "busSelectNode" },
{ "sourceNode": "audioPlayerNode", "destinationNode": "busSelectNode" },
{ "sourceNode": "busSelectNode", "destinationNode": "outputNode" }
}
}
import SwitchboardSDK
...
let busSelectNode = SBBusSelectNode()
let audioGraph = SBAudioGraph()
...
audioGraph.addNode(busSelectNode)
audioGraph.connect(vocalsInputNode, to: busSelectNode)
audioGraph.connect(musicInputNode, to: busSelectNode)
audioGraph.connect(busSelectNode, to: outputNode)
// Select musicInputNode
busSelectNode.selectedBus = 1
import com.synervoz.switchboard.sdk.audiograph.AudioGraph
import com.synervoz.switchboard.sdk.audiographnodes.BusSelectNode
...
private val busSelectNode = BusSelectNode()
private val audioGraph = AudioGraph()
...
audioGraph.addNode(busSelectNode)
audioGraph.connect(vocalsInputNode, busSelectNode)
audioGraph.connect(musicInputNode, busSelectNode)
audioGraph.connect(busSelectNode, outputNode)
// Select musicInputNode
busSelectNode.selectedBus = 1
#include "AudioGraph.hpp"
#include "BusSelectNode.hpp"
using namespace switchboard;
...
BusSelectNode busSelectNode;
AudioGraph audioGraph;
...
audioGraph.addNode(busSelectNode);
audioGraph.connect(vocalsInputNode, busSelectNode);
audioGraph.connect(musicInputNode, busSelectNode);
audioGraph.connect(busSelectNode, outputNode);
// Select musicInputNode
busSelectNode.setSelectedBus(1);
// Change the import to reflect the location of library
// relative to this publically accessible AudioWorklet
import {SwitchboardSDK} from "/libs/switchboard-sdk/index.js";
...
audioGraph.addNode(busSelectNode);
audioGraph.connect(audioGraphInputNode1, busSelectNode);
audioGraph.connect(audioGraphInputNode2, busSelectNode);
audioGraph.connect(busSelectNode, audioGraphOutputNode);
busSelectNode.setSelectedBus(1);
Forwarding a single input bus to a single output bus out from multiple output buses
The BusSwitchNode
has a single input audio bus and multiple output audio buses. An output audio bus can be selected and the input audio bus forwarded to the selected output audio bus. The number of channels of the input and output audio buses must match.
Using the BusSwitchNode Class
- JSON
- Swift
- Kotlin
- C++
- JavaScript
{
"nodes": {
{ "id": "busSwitchNode", "type": "BusSwitchNode" },
{ "id": "vuMeterNode", "type": "VUMeterNode" }
},
"connections": {
{ "sourceNode": "inputNode", "destinationNode": "busSwitchNode" },
{ "sourceNode": "busSwitchNode", "destinationNode": "vuMeterNode" },
{ "sourceNode": "busSwitchNode", "destinationNode": "outputNode" }
}
}
import SwitchboardSDK
...
let busSwitchNode = SBBusSwitchNode()
let vuMeterNode = SBVUMeterNode()
let audioGraph = SBAudioGraph()
...
audioGraph.addNode(busSwitchNode)
audioGraph.addNode(vuMeterNode)
audioGraph.connect(inputNode, to: busSwitchNode)
audioGraph.connect(busSwitchNode, to: vuMeterNode)
audioGraph.connect(busSwitchNode, to: outputNode)
// Select outputNode
busSwitchNode.selectedBus = 1
import com.synervoz.switchboard.sdk.audiograph.AudioGraph
import com.synervoz.switchboard.sdk.audiographnodes.BusSwitchNode
import com.synervoz.switchboard.sdk.audiographnodes.VUMeterNode
...
private val busSwitchNode = BusSwitchNode()
private val vuMeterNode = VUMeterNode()
private val audioGraph = AudioGraph()
...
audioGraph.addNode(busSwitchNode)
audioGraph.addNode(vuMeterNode)
audioGraph.connect(inputNode, busSwitchNode)
audioGraph.connect(busSwitchNode, vuMeterNode)
audioGraph.connect(busSwitchNode, outputNode)
// Select outputNode
busSwitchNode.selectedBus = 1
#include "AudioGraph.hpp"
#include "BusSwitchNode.hpp"
#include "VUMeterNode.hpp"
using namespace switchboard;
...
BusSwitchNode busSwitchNode;
VUMeterNode vuMeterNode;
AudioGraph audioGraph;
...
audioGraph.addNode(busSwitchNode);
audioGraph.addNode(vuMeterNode);
audioGraph.connect(inputNode, busSwitchNode);
audioGraph.connect(busSwitchNode, vuMeterNode);
audioGraph.connect(busSwitchNode, outputNode);
// Select outputNode
busSwitchNode.setSelectedBus(1);
// Change the import to reflect the location of library
// relative to this publically accessible AudioWorklet
import {SwitchboardSDK} from "/libs/switchboard-sdk/index.js";
...
audioGraph.addNode(busSwitchNode);
audioGraph.addNode(vuMeterNode);
audioGraph.connect(audioGraphInputNode, busSwitchNode);
audioGraph.connect(busSwitchNode, vuMeterNode);
audioGraph.connect(busSwitchNode, audioGraphOutputNode);
busSwitchNode.setSelectedBus(1);
Nodes for Splitting Audio
Splitting Audio Buses
The SplitterNode
has a single input audio bus and multiple output audio buses. The input audio bus is forwarded to every output audio bus. The number of channels of the input and output audio buses must match.
Using the BusSplitterNode Class
- JSON
- Swift
- Kotlin
- C++
- JavaScript
{
"nodes": {
{ "id": "splitterNode", "type": "BusSplitterNode" },
{ "id": "recorderNode", "type": "RecorderNode" }
},
"connections": {
{ "sourceNode": "inputNode", "destinationNode": "splitterNode" },
{ "sourceNode": "splitterNode", "destinationNode": "recorderNode" },
{ "sourceNode": "splitterNode", "destinationNode": "outputNode" }
}
}
import SwitchboardSDK
...
let splitterNode = SBBusSplitterNode()
let audioGraph = SBAudioGraph()
...
audioGraph.addNode(splitterNode)
audioGraph.connect(vocalsInputNode, to: splitterNode)
audioGraph.connect(splitterNode, to: recorderNode)
audioGraph.connect(splitterNode, to: outputNode)
import com.synervoz.switchboard.sdk.audiograph.AudioGraph
import com.synervoz.switchboard.sdk.audiographnodes.BusSplitterNode
...
private val splitterNode = BusSplitterNode()
private val audioGraph = AudioGraph()
...
audioGraph.addNode(splitterNode)
audioGraph.connect(vocalsInputNode, splitterNode)
audioGraph.connect(splitterNode, recorderNode)
audioGraph.connect(splitterNode, outputNode)
#include "AudioGraph.hpp"
#include "BusSplitterNode.hpp"
using namespace switchboard;
...
SplitterNode splitterNode;
AudioGraph audioGraph;
...
audioGraph.addNode(splitterNode);
audioGraph.connect(vocalsInputNode, splitterNode);
audioGraph.connect(splitterNode, recorderNode);
audioGraph.connect(splitterNode, outputNode);
// Change the import to reflect the location of library
// relative to this publically accessible AudioWorklet
import {SwitchboardSDK} from "/libs/switchboard-sdk/index.js";
...
audioGraph.addNode(splitterNode);
audioGraph.addNode(recorderNode);
audioGraph.connect(audioGraphInputNode, splitterNode);
audioGraph.connect(splitterNode, recorderNode);
audioGraph.connect(splitterNode, audioGraphOutputNode);
Splitting Audio Channels into a Single Audio Bus
The MonoToMultiChannelNode
has a single mono input audio bus and a single multichannel output audio bus. The mono channel of the input audio bus is forwarded to every channel of the output audio bus.
Using the MonoToMultiChannelNode Class
- JSON
- Swift
- Kotlin
- C++
- JavaScript
{
"nodes": {
{ "id": "monoAudioPlayerNode", "type": "AudioPlayerNode" },
{ "id": "monoToMultiChannelNode", "type": "MonoToMultiChannelNode" }
},
"connections": {
{ "sourceNode": "monoAudioPlayerNode", "destinationNode": "monoToMultiChannelNode" },
{ "sourceNode": "monoToMultiChannelNode", "destinationNode": "outputNode" }
}
}
import SwitchboardSDK
...
let monoToMultiChannelNode = SBMonoToMultiChannelNode()
let audioGraph = SBAudioGraph()
...
audioGraph.addNode(monoToMultiChannelNode)
audioGraph.connect(monoInputNode, to: monoToMultiChannelNode)
audioGraph.connect(monoToMultiChannelNode, to: stereoOutputNode)
import com.synervoz.switchboard.sdk.audiograph.AudioGraph
import com.synervoz.switchboard.sdk.audiographnodes.MonoToMultiChannelNode
...
private val monoToMultiChannelNode = MonoToMultiChannelNode()
private val audioGraph = AudioGraph()
...
audioGraph.addNode(monoToMultiChannelNode)
audioGraph.connect(monoInputNode, monoToMultiChannelNode)
audioGraph.connect(monoToMultiChannelNode, stereoOutputNode)
#include "AudioGraph.hpp"
#include "MonoToMultiChannelNode.hpp"
using namespace switchboard;
...
MonoToMultiChannelNode monoToMultiChannelNode;
AudioGraph audioGraph;
...
audioGraph.addNode(monoToMultiChannelNode);
audioGraph.connect(monoInputNode, monoToMultiChannelNode);
audioGraph.connect(monoToMultiChannelNode, stereoOutputNode);
// Change the import to reflect the location of library
// relative to this publically accessible AudioWorklet
import {SwitchboardSDK} from "/libs/switchboard-sdk/index.js";
...
audioGraph.addNode(monoToMultiChannelNode);
audioGraph.connect(audioGraphMonoInputNode, monoToMultiChannelNode);
audioGraph.connect(monoToMultiChannelNode, audioGraphStereoOutputNode);
Splitting Audio Channels to Separate Audio Buses
The ChannelSplitterNode
has a single multichannel input audio bus and multiple mono output audio buses. The channels of the input audio bus are split to the separate output audio buses. The number of output audio buses must match the number of channels of the input bus.
Using the ChannelSplitterNode Class
- JSON
- Swift
- Kotlin
- C++
- JavaScript
{
"nodes": {
{ "id": "channelSplitterNode", "type": "ChannelSplitterNode" },
{ "id": "leftVUMeterNode", "type": "VUMeterNode" },
{ "id": "rightVUMeterNode", "type": "VUMeterNode" }
},
"connections": {
{ "sourceNode": "inputNode", "destinationNode": "channelSplitterNode" },
{ "sourceNode": "channelSplitterNode", "destinationNode": "leftVUMeterNode" },
{ "sourceNode": "channelSplitterNode", "destinationNode": "rightVUMeterNode" }
}
}
import SwitchboardSDK
...
let channelSplitterNode = SBChannelSplitterNode()
let audioGraph = SBAudioGraph()
...
audioGraph.addNode(channelSplitterNode)
audioGraph.connect(stereoInputNode, to: channelSplitterNode)
audioGraph.connect(channelSplitterNode, to: leftVUMeterNode)
audioGraph.connect(channelSplitterNode, to: rightVUMeterNode)
import com.synervoz.switchboard.sdk.audiograph.AudioGraph
import com.synervoz.switchboard.sdk.audiographnodes.ChannelSplitterNode
...
private val channelSplitterNode = ChannelSplitterNode()
private val audioGraph = AudioGraph()
...
audioGraph.addNode(channelSplitterNode)
audioGraph.connect(stereoInputNode, channelSplitterNode)
audioGraph.connect(channelSplitterNode, leftVUMeterNode)
audioGraph.connect(channelSplitterNode, rightVUMeterNode)
#include "AudioGraph.hpp"
#include "ChannelSplitterNode.hpp"
using namespace switchboard;
...
ChannelSplitterNode channelSplitterNode;
AudioGraph audioGraph;
...
audioGraph.addNode(channelSplitterNode);
audioGraph.connect(stereoInputNode, channelSplitterNode);
audioGraph.connect(channelSplitterNode, leftVUMeterNode);
audioGraph.connect(channelSplitterNode, rightVUMeterNode);
// Change the import to reflect the location of library
// relative to this publically accessible AudioWorklet
import {SwitchboardSDK} from "/libs/switchboard-sdk/index.js";
...
audioGraph.addNode(channelSplitterNode);
audioGraph.addNode(leftVUMeterNode);
audioGraph.addNode(rightVUMeterNode);
audioGraph.connect(audioGraphStereoInputNode, channelSplitterNode);
audioGraph.connect(channelSplitterNode, leftVUMeterNode);
audioGraph.connect(channelSplitterNode, rightVUMeterNode);