Build audio apps effortlessly
A cross-platform SDK that simplifies audio app development and saves time.
Customers and Partners
What is the Switchboard SDK?
We built the Switchboard SDK to make it easier to develop audio features and apps without needing to be a specialist in audio programming or C++.
Switchboard saves you time from prototype through production, and starts to pay dividends for products that are cross platform and have multiple audio features.
- Music and social app developers
- R&D / ML / AI teams looking to commercialize
- Hardware projects like headphones, speakers, wearables, etc.
- Pro audio industry - hardware and software
- Apps & SDKs with audio features
Audio Graph Examples
- Karaoke & Remix Apps
- Watch / Listen Parties & Live Events
- Hardware Device / Companion App
Why use it?
Easy-To-Use
Put together complex audio pipelines without the need for C++ or real-time audio programming.
Cross-Platform
Make an audio engine that sounds the same on iOS, Android, macOS and Linux. Share the same audio code between these platforms.
High-Performance
Our audio processing algorithms are highly optimized so you don't need to worry about audio glitches.
Extensible
Get access to and seamlessly integrate a wide variety of audio nodes that our partners provide.
Time Saver
Save months or more, especially for complex audio pipelines.
Robust
Avoid writing glue code and validating 3rd party apps. We integrated and tested third party SDKs so you don't have to.
Flexible
Quickly test new audio features, rearrange effects chains, or compare third party extensions.
Customizable
Custom builds and licensing options available—tailored to your needs.
Listen Party Demo
Plug in headphones or turn on speakers. Unmute to begin.
How does the above example work?
- JSON
- Swift
- Kotlin
- C++
- JavaScript
{
"nodes": {
{ "id": "noisySpeakerPlayerNode", "type": "AudioPlayerNode" },
{ "id": "noiseFilter", "type": "RNNoise.NoiseFilterNode" },
{ "id": "compressor", "type": "Superpowered.CompressorNode" },
{ "id": "cleanSpeakerPlayerNode", "type": "AudioPlayerNode" },
{ "id": "voiceEffect", "type": "AudioEffects.PingPongDelayNode" },
{ "id": "mixer", "type": "MixerNode" },
{ "id": "musicPlayer", "type": "AudioPlayerNode" },
{ "id": "ducking", "type": "MusicDuckingNode" },
},
"connections": {
{ "sourceNode": "noisySpeakerPlayerNode", "destinationNode": "noiseFilter" },
{ "sourceNode": "noiseFilter", "destinationNode": "compressor" },
{ "sourceNode": "compressor", "destinationNode": "mixer" },
{ "sourceNode": "cleanSpeakerPlayerNode", "destinationNode": "voiceEffect" },
{ "sourceNode": "voiceEffect", "destinationNode": "mixer" },
{ "sourceNode": "musicPlayer", "destinationNode": "ducking" },
{ "sourceNode": "mixer", "destinationNode": "ducking" },
{ "sourceNode": "ducking", "destinationNode": "OutputNode" }
},
"tracks": {
"noisySpeakerPlayerNode": "conversation-noise-male-stereo.mp3",
"cleanSpeakerPlayerNode": "conversation-clean-female-stereo.mp3",
"musicPlayer": "elevator-music-stereo.mp3"
}
}
import SwitchboardAudioEffects
import SwitchboardRNNoise
import SwitchboardSDK
import SwitchboardSuperpowered
class HeroExample {
var audioEngine = SBAudioEngine()
let audioGraph = SBAudioGraph()
let noisySpeakerPlayerNode = SBAudioPlayerNode()
let cleanSpeakerPlayerNode = SBAudioPlayerNode()
let musicPlayerNode = SBAudioPlayerNode()
let noiseFilterNode = SBRNNoiseFilterNode()
let noiseFilterMonoToMultiChannelNode = SBMonoToMultiChannelNode()
let compressorNode = SBCompressorNode()
let effectNode = SBPingPongDelayNode()
let speechMixerNode = SBMixerNode()
let speechSplitterNode = SBBusSplitterNode()
let multiChannelToMonoNode = SBMultiChannelToMonoNode()
let duckingNode = SBMusicDuckingNode()
let mixerNode = SBMixerNode()
init() {
noisySpeakerPlayerNode.name = "Frank"
cleanSpeakerPlayerNode.name = "Alice"
musicPlayerNode.name = "Music"
audioGraph.addNode(noisySpeakerPlayerNode)
audioGraph.addNode(cleanSpeakerPlayerNode)
audioGraph.addNode(musicPlayerNode)
audioGraph.addNode(noiseFilterNode)
audioGraph.addNode(noiseFilterMonoToMultiChannelNode)
audioGraph.addNode(compressorNode)
audioGraph.addNode(effectNode)
audioGraph.addNode(multiChannelToMonoNode)
audioGraph.addNode(speechMixerNode)
audioGraph.addNode(speechSplitterNode)
audioGraph.addNode(mixerNode)
audioGraph.addNode(duckingNode)
audioGraph.connect(noisySpeakerPlayerNode, to: noiseFilterNode)
audioGraph.connect(noiseFilterNode, to: noiseFilterMonoToMultiChannelNode)
audioGraph.connect(noiseFilterMonoToMultiChannelNode, to: compressorNode)
audioGraph.connect(compressorNode, to: speechMixerNode)
audioGraph.connect(cleanSpeakerPlayerNode, to: effectNode)
audioGraph.connect(effectNode, to: speechMixerNode)
audioGraph.connect(speechMixerNode, to: speechSplitterNode)
audioGraph.connect(speechSplitterNode, to: multiChannelToMonoNode)
audioGraph.connect(musicPlayerNode, to: duckingNode)
audioGraph.connect(multiChannelToMonoNode, to: duckingNode)
audioGraph.connect(speechSplitterNode, to: mixerNode)
audioGraph.connect(duckingNode, to: mixerNode)
audioGraph.connect(mixerNode, to: audioGraph.outputNode)
noisySpeakerPlayerNode.load(Bundle.main.url(forResource: "conversation-noise-male-stereo", withExtension: "mp3")!.absoluteString)
noisySpeakerPlayerNode.isLoopingEnabled = true
noisySpeakerPlayerNode.numberOfChannels = 1
cleanSpeakerPlayerNode.load(Bundle.main.url(forResource: "conversation-clean-female-stereo", withExtension: "mp3")!.absoluteString)
cleanSpeakerPlayerNode.isLoopingEnabled = true
musicPlayerNode.load(Bundle.main.url(forResource: "elevator-music-stereo", withExtension: "mp3")!.absoluteString)
musicPlayerNode.isLoopingEnabled = true
}
func startEngine() {
noisySpeakerPlayerNode.play()
cleanSpeakerPlayerNode.play()
musicPlayerNode.play()
audioEngine.start(audioGraph)
}
func stopEngine() {
noisySpeakerPlayerNode.stop()
cleanSpeakerPlayerNode.stop()
musicPlayerNode.stop()
audioEngine.stop()
}
}
import com.synervoz.switchboard.sdk.audioengine.AudioEngine
import com.synervoz.switchboard.sdk.audiograph.AudioGraph
import com.synervoz.switchboard.sdk.audiographnodes.AudioPlayerNode
import com.synervoz.switchboard.sdk.audiographnodes.MixerNode
import com.synervoz.switchboard.sdk.audiographnodes.MonoToMultiChannelNode
import com.synervoz.switchboard.sdk.audiographnodes.MultiChannelToMonoNode
import com.synervoz.switchboard.sdk.audiographnodes.MusicDuckingNode
import com.synervoz.switchboard.sdk.audiographnodes.BusSplitterNode
import com.synervoz.switchboardaudioeffects.audiographnodes.PingPongDelayNode
import com.synervoz.switchboardrnnoise.audiographnodes.RNNoiseFilterNode
import com.synervoz.switchboardsuperpowered.audiographnodes.CompressorNode
class HeroExample(context: Context) {
val audioEngine = AudioEngine(context)
val audioGraph = AudioGraph()
val noisySpeakerPlayerNode = AudioPlayerNode()
val cleanSpeakerPlayerNode = AudioPlayerNode()
val musicPlayerNode = AudioPlayerNode()
val noiseFilterNode = RNNoiseFilterNode()
val noiseFilterMonoToMultiChannelNode = MonoToMultiChannelNode()
val compressorNode = CompressorNode()
val effectNode = PingPongDelayNode()
val speechMixerNode = MixerNode()
val speechSplitterNode = BusSplitterNode()
val multiChannelToMonoNode = MultiChannelToMonoNode()
val duckingNode = MusicDuckingNode()
val mixerNode = MixerNode()
init {
noisySpeakerPlayerNode.name = "Frank"
cleanSpeakerPlayerNode.name = "Alice"
musicPlayerNode.name = "Music"
audioGraph.addNode(noisySpeakerPlayerNode)
audioGraph.addNode(cleanSpeakerPlayerNode)
audioGraph.addNode(musicPlayerNode)
audioGraph.addNode(noiseFilterNode)
audioGraph.addNode(noiseFilterMonoToMultiChannelNode)
audioGraph.addNode(compressorNode)
audioGraph.addNode(effectNode)
audioGraph.addNode(multiChannelToMonoNode)
audioGraph.addNode(speechMixerNode)
audioGraph.addNode(speechSplitterNode)
audioGraph.addNode(mixerNode)
audioGraph.addNode(duckingNode)
audioGraph.connect(noisySpeakerPlayerNode, noiseFilterNode)
audioGraph.connect(noiseFilterNode, noiseFilterMonoToMultiChannelNode)
audioGraph.connect(noiseFilterMonoToMultiChannelNode, compressorNode)
audioGraph.connect(compressorNode, speechMixerNode)
audioGraph.connect(cleanSpeakerPlayerNode, effectNode)
audioGraph.connect(effectNode, speechMixerNode)
audioGraph.connect(speechMixerNode, speechSplitterNode)
audioGraph.connect(speechSplitterNode, multiChannelToMonoNode)
audioGraph.connect(musicPlayerNode, duckingNode)
audioGraph.connect(multiChannelToMonoNode, duckingNode)
audioGraph.connect(speechSplitterNode, mixerNode)
audioGraph.connect(duckingNode, mixerNode)
audioGraph.connect(mixerNode, audioGraph.outputNode)
noisySpeakerPlayerNode.isLoopingEnabled = true
noisySpeakerPlayerNode.numberOfChannels = 1
cleanSpeakerPlayerNode.isLoopingEnabled = true
musicPlayerNode.isLoopingEnabled = true
}
fun startEngine() {
noisySpeakerPlayerNode.play()
cleanSpeakerPlayerNode.play()
musicPlayerNode.play()
audioEngine.start(audioGraph)
}
fun stopEngine() {
noisySpeakerPlayerNode.stop()
cleanSpeakerPlayerNode.stop()
musicPlayerNode.stop()
audioEngine.stop()
}
fun close() {
audioEngine.close()
audioGraph.close()
noisySpeakerPlayerNode.close()
cleanSpeakerPlayerNode.close()
musicPlayerNode.close()
noiseFilterNode.close()
noiseFilterMonoToMultiChannelNode.close()
compressorNode.close()
effectNode.close()
multiChannelToMonoNode.close()
speechMixerNode.close()
speechSplitterNode.close()
mixerNode.close()
duckingNode.close()
}
}
#include "AudioGraph.hpp"
#include "AudioPlayerNode.hpp"
#include "MonoToMultiChannelNode.hpp"
#include "NoiseFilterNode.hpp"
#include "CompressorNode.hpp"
#include "PingPongDelayNode.hpp"
#include "MixerNode.hpp"
#include "BusSplitterNode.hpp"
#include "MultiChannelToMonoNode.hpp"
#include "MusicDuckingNode.hpp"
using namespace switchboard;
class HeroAudioGraph {
public:
HeroAudioGraph() {
noisySpeakerPlayerNode.name = "Frank";
cleanSpeakerPlayerNode.name = "Alice";
musicPlayerNode.name = "Music";
// Adding nodes to audio graph
audioGraph.addNode(noisySpeakerPlayerNode);
audioGraph.addNode(cleanSpeakerPlayerNode);
audioGraph.addNode(musicPlayerNode);
audioGraph.addNode(noiseFilterNode);
audioGraph.addNode(noiseFilterMonoToMultiChannelNode);
audioGraph.addNode(compressorNode);
audioGraph.addNode(effectNode);
audioGraph.addNode(multiChannelToMonoNode);
audioGraph.addNode(speechMixerNode);
audioGraph.addNode(speechSplitterNode);
audioGraph.addNode(mixerNode);
audioGraph.addNode(duckingNode);
// Connecting audio nodes
audioGraph.connect(noisySpeakerPlayerNode, noiseFilterNode);
audioGraph.connect(noiseFilterNode, noiseFilterMonoToMultiChannelNode);
audioGraph.connect(noiseFilterMonoToMultiChannelNode, compressorNode);
audioGraph.connect(compressorNode, speechMixerNode);
audioGraph.connect(cleanSpeakerPlayerNode, effectNode);
audioGraph.connect(effectNode, speechMixerNode);
audioGraph.connect(speechMixerNode, speechSplitterNode);
audioGraph.connect(speechSplitterNode, multiChannelToMonoNode);
audioGraph.connect(musicPlayerNode, duckingNode);
audioGraph.connect(multiChannelToMonoNode, duckingNode);
audioGraph.connect(speechSplitterNode, mixerNode);
audioGraph.connect(duckingNode, mixerNode);
audioGraph.connect(mixerNode, audioGraph.getOutputNode());
// Starting players
noisySpeakerPlayerNode.load("conversation-noise-male-stereo.mp3", ::Mp3);
noisySpeakerPlayerNode.setNumberOfChannels(1);
noisySpeakerPlayerNode.play();
cleanSpeakerPlayerNode.load("conversation-clean-female-stereo.mp3", ::Mp3);
cleanSpeakerPlayerNode.play();
musicPlayerNode.load("elevator-music-stereo.mp3", ::Mp3);
musicPlayerNode.play();
}
private:
AudioGraph audioGraph;
AudioPlayerNode noisySpeakerPlayerNode;
AudioPlayerNode cleanSpeakerPlayerNode;
AudioPlayerNode musicPlayerNode;
extensions::rnnoise::NoiseFilterNode noiseFilterNode;
MonoToMultiChannelNode noiseFilterMonoToMultiChannelNode;
extensions::superpowered::CompressorNode compressorNode;
extensions::audioeffects::PingPongDelayNode effectNode;
MixerNode speechMixerNode;
BusSplitterNode speechSplitterNode;
MultiChannelToMonoNode multiChannelToMonoNode;
MusicDuckingNode duckingNode;
MixerNode mixerNode;
};
Coming soon...
Check out our sample app projects on GitHub

Vocal FX Chains App
Make vocal performances more interesting by applying various effects.

Karaoke App
Simplify the process of creating a karaoke app.

Guitar Effect
Guitar effect app showcasing Switchboard SDK functionality.

Voice Communication
Real-time voice chat app emulating a seamless in-person experience.

Ducking And Sound Effects
Ducking music during voice chat, sound effects that enhance user interactions.

Online Radio App
Implement the audio pipeline of a simple online radio app, with easy integration.

DJ App
Mix tracks, apply effects and sync beats in real-time.