How to Bypass an Effect in Tone.js

In Tone.js, bypassing an effect without disconnecting it from the audio graph is essential for maintaining a continuous signal flow and preventing audio glitches. This article explains how to temporarily disable or bypass any effect node in Tone.js using the wet property, allowing you to toggle effects on and off seamlessly during playback.


The Standard Method: Utilizing the wet Control

The most efficient way to bypass an effect in Tone.js is by manipulating its wet parameter. Almost all effect nodes in Tone.js (such as Distortion, Reverb, Delay, and Chorus) inherit from the base Tone.Effect class. This class includes a wet signal that controls the ratio of the wet (effected) signal to the dry (unaffected) signal.

Code Example:

// Create a synth and an effect
const synth = new Tone.PolySynth().toDestination();
const feedbackDelay = new Tone.FeedbackDelay("8n", 0.5).toDestination();

// Connect the synth to the effect
synth.connect(feedbackDelay);

// Bypass the effect (Dry signal only)
feedbackDelay.wet.value = 0;

// Enable the effect (Fully wet signal)
feedbackDelay.wet.value = 1;

Preventing Audio Pops with Smooth Transitions

Directly changing wet.value = 0 can sometimes cause abrupt volume changes or minor clicks in the audio. Because wet is a Tone.Signal object, you can schedule smooth transitions to bypass or enable the effect over time using rampTo().

// Smoothly bypass the effect over 0.5 seconds
feedbackDelay.wet.rampTo(0, 0.5);

// Smoothly re-enable the effect over 0.3 seconds
feedbackDelay.wet.rampTo(1, 0.3);

Custom Bypass with Tone.CrossFade

If you are using a custom utility node or a raw Web Audio API node that does not have a native wet property, you can build a bypass chain using Tone.CrossFade. This splits the signal into a wet path and a dry path, allowing you to fade between them.

const source = new Tone.Oscillator().start();
const crossFade = new Tone.CrossFade().toDestination();

// Create the effect node
const effect = new Tone.BitCrusher(4);

// Connect Dry signal to input 0
source.connect(crossFade.a);

// Connect Wet signal (through effect) to input 1
source.connect(effect);
effect.connect(crossFade.b);

// Bypass effect (100% dry signal)
crossFade.fade.value = 0;

// Enable effect (100% wet signal)
crossFade.fade.value = 1;