# How Voicebox Post-Processing Effects (Pedalboard) Work

> Discover how Voicebox leverages the pedalboard library for real-time DSP effects on TTS audio. Learn about its declarative JSON chain and server-side validation for powerful audio processing.

- Repository: [Jamie Pine/voicebox](https://github.com/jamiepine/voicebox)
- Tags: internals
- Published: 2026-04-14

---

**Voicebox applies real-time DSP effects to TTS-generated audio using a declarative JSON chain processed through Spotify's `pedalboard` library, validating parameters server-side before constructing and executing a `Pedalboard` instance on NumPy audio arrays.**

Voicebox is an open-source text-to-speech platform that provides a studio-grade post-processing pipeline for audio manipulation. The Voicebox post-processing effects system wraps Spotify's `pedalboard` library to transform raw generated speech through configurable chains of DSP effects like reverb, chorus, and distortion. This architecture separates effect definition, validation, and execution into discrete stages that ensure type safety while maintaining real-time processing capabilities.

## Effect Registry and Built-in Presets

The foundation of Voicebox's audio processing resides in [`backend/utils/effects.py`](https://github.com/jamiepine/voicebox/blob/main/backend/utils/effects.py), which maintains a declarative registry of every supported DSP effect. Lines 38-47 define the **effect registry**, cataloging each effect's Python class, UI label, and parameter ranges with default values.

The system includes **built-in presets** for common audio transformations. Located at lines 50-85 of [`backend/utils/effects.py`](https://github.com/jamiepine/voicebox/blob/main/backend/utils/effects.py), these pre-defined chains provide immediate access to characteristic sounds such as robotic voice modulation, radio static, echo chamber ambience, and deep voice filtering. The `get_available_effects` function (lines 58-73) exposes this registry to the frontend, enabling the React-based UI to render an interactive chain editor with appropriate parameter controls.

## Validation and Pedalboard Construction

Before processing audio, Voicebox validates all incoming effect chains through a strict server-side pipeline. The `validate_effects_chain` function in [`backend/utils/effects.py`](https://github.com/jamiepine/voicebox/blob/main/backend/utils/effects.py) (lines 81-115) performs three critical checks:

1. Verifies that each effect `type` exists in the registry
2. Validates that provided parameters match known fields for that effect
3. Ensures numeric values fall within acceptable bounds

After validation, `build_pedalboard` (lines 118-140) transforms the JSON chain into a concrete `pedalboard.Pedalboard` object. This function merges user-provided parameters with defaults, instantiates the specific plugin classes from the `pedalboard` library, and filters out any disabled entries before returning a configured board ready for audio processing.

## Executing Effects on Audio

The core processing happens in `apply_effects` ([`backend/utils/effects.py`](https://github.com/jamiepine/voicebox/blob/main/backend/utils/effects.py), lines 142-174), which executes the constructed `Pedalboard` on NumPy audio arrays. This function handles both mono and multichannel audio, preserving original dimensionality while applying the full effect chain in a single pass.

When TTS generation completes, the generation service in [`backend/services/generation.py`](https://github.com/jamiepine/voicebox/blob/main/backend/services/generation.py) (lines 74-90) optionally invokes `apply_effects` if a post-processing chain was specified during the request. The service loads the raw audio via `backend.utils.audio.load_audio`, processes it through the pedalboard, and stores the result as a new generation version while preserving the original.

## API Endpoints for Effect Management

Voicebox exposes effect functionality through dedicated REST endpoints in [`backend/routes/effects.py`](https://github.com/jamiepine/voicebox/blob/main/backend/routes/effects.py). The **preview endpoint** (`/effects/preview/{generation_id}`, lines 35-49) streams a temporary WAV file processed with the supplied chain without persisting a new version, allowing users to audition settings before committing.

For permanent application, the **apply-effects endpoint** (`/generations/{generation_id}/versions/apply-effects`, lines 65-84) creates a durable new version by running the same validation and processing pipeline, then saving the output to disk. Both endpoints share the identical validation and construction logic, ensuring consistent behavior between preview and production modes.

## Practical Implementation Example

To process audio programmatically using Voicebox's effect system:

```python
import numpy as np
from voicebox.backend.utils.effects import (
    get_available_effects,
    validate_effects_chain,
    apply_effects,
)
from voicebox.backend.utils.audio import load_audio, save_audio

# Load mono or multichannel audio

audio, sr = load_audio("generation_123.wav")

# Define a DSP effect chain

chain = [
    {
        "type": "reverb",
        "enabled": True,
        "params": {
            "room_size": 0.8,
            "wet_level": 0.6,
            "dry_level": 0.4
        }
    },
    {
        "type": "chorus",
        "enabled": True,
        "params": {
            "rate_hz": 0.2,
            "depth": 1.0,
            "mix": 0.5
        }
    }
]

# Validate parameter types and ranges

error = validate_effects_chain(chain)
if error:
    raise ValueError(f"Invalid effects chain: {error}")

# Apply effects and save

processed = apply_effects(audio, sr, chain)
save_audio(processed, "generation_123_processed.wav", sr)

```

To preview effects via the HTTP API:

```bash
curl -X POST "https://voicebox.example.com/effects/preview/12345" \
     -H "Content-Type: application/json" \
     -d '{
           "effects_chain": [
               {"type":"distortion","enabled":true,
                "params":{"drive_db":25.0}}
           ]
         }' --output preview.wav

```

## Summary

- **Voicebox post-processing effects** leverage Spotify's `pedalboard` library to apply DSP chains to generated audio through a declarative JSON interface.
- The **effect registry** in [`backend/utils/effects.py`](https://github.com/jamiepine/voicebox/blob/main/backend/utils/effects.py) (lines 38-47) defines available effects, while **built-in presets** (lines 50-85) provide ready-made configurations for common transformations.
- **Server-side validation** via `validate_effects_chain` (lines 81-115) ensures type safety and parameter bounds before construction.
- The `build_pedalboard` function (lines 118-140) instantiates concrete `pedalboard` plugin classes from validated JSON chains.
- **Audio processing** occurs in `apply_effects` (lines 142-174), which handles mono/multichannel arrays and preserves dimensional integrity.
- Integration points include the **generation service** ([`backend/services/generation.py`](https://github.com/jamiepine/voicebox/blob/main/backend/services/generation.py), lines 74-90) for automatic post-processing and **REST endpoints** ([`backend/routes/effects.py`](https://github.com/jamiepine/voicebox/blob/main/backend/routes/effects.py)) for preview and permanent application.

## Frequently Asked Questions

### What audio formats does Voicebox's pedalboard processing support?

Voicebox processes audio as NumPy arrays internally, supporting any format that converts to floating-point PCM. The `load_audio` utility typically handles WAV files, and `apply_effects` accepts both mono (1D) and multichannel (2D) arrays, returning processed audio with identical dimensionality. The output is generally encoded as WAV via `soundfile` before streaming or storage.

### How does Voicebox validate effect parameters before processing?

The `validate_effects_chain` function in [`backend/utils/effects.py`](https://github.com/jamiepine/voicebox/blob/main/backend/utils/effects.py) (lines 81-115) performs strict server-side validation by checking that each effect type exists in the registry, that provided parameters match the effect's known fields, and that numeric values fall within defined bounds. Any validation failure returns a descriptive error string that prevents the `build_pedalboard` function from executing.

### Can I create custom effect chains beyond the built-in presets?

Yes. While Voicebox provides built-in presets such as robotic and radio effects defined in [`backend/utils/effects.py`](https://github.com/jamiepine/voicebox/blob/main/backend/utils/effects.py) (lines 50-85), you can construct arbitrary chains by specifying any combination of registered effect types with custom parameters. The frontend's EffectsEditor component builds these declarative JSON chains, which are then validated and processed by the backend regardless of whether they match a preset.

### What is the difference between the preview and apply-effects endpoints?

The preview endpoint (`/effects/preview/{generation_id}`) in [`backend/routes/effects.py`](https://github.com/jamiepine/voicebox/blob/main/backend/routes/effects.py) (lines 35-49) processes audio and streams a temporary WAV response without persisting data, ideal for real-time auditioning. The apply-effects endpoint (`/generations/{generation_id}/versions/apply-effects`, lines 65-84) performs identical processing but saves the result as a permanent new generation version in the database and file system. Both use the same validation and `apply_effects` pipeline.