Lavalink

Lavalink Audio Filters: Bass Boost, Nightcore, 8D and More

How Lavalink v4 audio filters work — equalizer, timescale, rotation, karaoke, tremolo and more — with ready-to-use presets and code for Shoukaku and Wavelink.

On this page
  1. How filters work
  2. The filters
  3. Ready-to-use presets
  4. Applying filters with Shoukaku (discord.js)
  5. Applying filters with Wavelink (discord.py)
  6. Filters cost CPU
  7. Troubleshooting
  8. Summary

Filters are one of the features users love most in music bots: bass boost, nightcore, 8D audio, vaporwave. Lavalink applies them in real time on the node, so your bot just sends a description of the effect. This article explains each filter, gives working presets, and shows how to apply them from your bot.

How filters work

Filters are part of a player’s state. Your bot sends a filters object to Lavalink (a PATCH to the player in the v4 REST API, wrapped by your client library), and Lavalink processes the audio before encoding it for Discord.

Two rules to remember:

  1. Sending filters replaces the whole filter set. If you set an equalizer and then send only a timescale, the equalizer is removed. To combine effects, send them together.
  2. Changes take effect after a short delay — roughly the length of Lavalink’s audio buffer — because already-processed audio is still playing.

The filters

Volume

{ "volume": 1.0 }

A multiplier from 0.0 to 5.0. This is separate from the player’s normal volume (0–1000); use the player volume for everyday control and the filter only if you need it as part of a preset. Values above 1.0 can clip and distort.

Equalizer

Fifteen bands, from 25 Hz to 16 kHz, each with a gain from −0.25 (cut) to 1.0 (boost). A gain of 0 leaves a band unchanged.

Band 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Hz 25 40 63 100 160 250 400 630 1k 1.6k 2.5k 4k 6.3k 10k 16k
{ "equalizer": [ { "band": 0, "gain": 0.2 }, { "band": 1, "gain": 0.15 } ] }

You only need to list bands you’re changing.

Timescale

Changes speed, pitch and rate:

{ "timescale": { "speed": 1.2, "pitch": 1.2, "rate": 1.0 } }
  • speed — playback speed without changing pitch.
  • pitch — pitch without changing speed.
  • rate — both together, like speeding up a record.

Timescale powers nightcore, vaporwave and daycore effects.

Rotation (8D audio)

{ "rotation": { "rotationHz": 0.2 } }

Pans audio around the listener’s head. 0.2 Hz (one rotation every five seconds) is the classic “8D” effect; it’s best with headphones.

Karaoke

{ "karaoke": { "level": 1.0, "monoLevel": 1.0, "filterBand": 220.0, "filterWidth": 100.0 } }

Attempts to remove vocals by cancelling audio centred in the stereo mix. Results depend heavily on how the track was mixed.

Tremolo and vibrato

{ "tremolo": { "frequency": 2.0, "depth": 0.5 } }
{ "vibrato": { "frequency": 2.0, "depth": 0.5 } }

Tremolo oscillates volume; vibrato oscillates pitch. depth ranges from 0 to 1.

Low pass

{ "lowPass": { "smoothing": 20.0 } }

Suppresses higher frequencies for a muffled, “soft” or “underwater” sound. Higher smoothing means more muffled.

Channel mix

{ "channelMix": { "leftToLeft": 0.5, "leftToRight": 0.5, "rightToLeft": 0.5, "rightToRight": 0.5 } }

Mixes left and right channels. The values above produce mono; swapping produces reversed stereo.

Distortion

A set of parameters (sinOffset, sinScale, cosOffset, tanScale and others) for distortion effects. Easy to make harsh — test carefully.

Plugins can also add their own filters through a pluginFilters field.

Ready-to-use presets

Preset Filters
Bass boost equalizer bands 0–3 at 0.20, 0.15, 0.10, 0.05
Nightcore timescale speed 1.2, pitch 1.2, rate 1.0
Vaporwave timescale speed 0.85, pitch 0.8; optional equalizer lift on bands 1–2
8D rotation 0.2 Hz
Soft lowPass smoothing 20
Karaoke karaoke defaults above
Tremolo tremolo frequency 4, depth 0.3
Reset an empty filters object

A gentle bass boost sounds better than an extreme one; large gains on low bands overload quickly and distort.

Applying filters with Shoukaku (discord.js)

const presets = {
  bassboost: { equalizer: [0.2, 0.15, 0.1, 0.05].map((gain, band) => ({ band, gain })) },
  nightcore: { timescale: { speed: 1.2, pitch: 1.2, rate: 1.0 } },
  vaporwave: { timescale: { speed: 0.85, pitch: 0.8, rate: 1.0 } },
  eightd: { rotation: { rotationHz: 0.2 } },
  soft: { lowPass: { smoothing: 20 } },
  reset: {},
};

const player = shoukaku.players.get(interaction.guildId);
await player.setFilters(presets[interaction.options.getString('preset', true)]);

To combine presets, merge the objects: { ...presets.bassboost, ...presets.eightd }.

@bot.tree.command(description="Apply an audio filter.")
@app_commands.choices(preset=[
    app_commands.Choice(name=n, value=n) for n in ("bassboost", "nightcore", "vaporwave", "8d", "reset")
])
async def filter(interaction: discord.Interaction, preset: app_commands.Choice[str]):
    player: wavelink.Player = interaction.guild.voice_client
    filters: wavelink.Filters = player.filters
    filters.reset()

    if preset.value == "bassboost":
        filters.equalizer.set(bands=[{"band": i, "gain": g} for i, g in enumerate([0.2, 0.15, 0.1, 0.05])])
    elif preset.value == "nightcore":
        filters.timescale.set(speed=1.2, pitch=1.2, rate=1.0)
    elif preset.value == "vaporwave":
        filters.timescale.set(speed=0.85, pitch=0.8, rate=1.0)
    elif preset.value == "8d":
        filters.rotation.set(rotation_hz=0.2)

    await player.set_filters(filters, seek=True)
    await interaction.response.send_message(f"Filter: {preset.name}")

seek=True asks Wavelink to seek to the current position so the change is heard almost immediately instead of after the buffer drains.

Filters cost CPU

Every filter adds processing for every audio frame of that player. One player with a bass boost is trivial; hundreds of players with timescale and rotation filters add up. Timescale in particular involves resampling work. If your node’s CPU climbs as filters become popular:

Kerit Cloud’s managed Lavalink plans scale CPU from 100% on Starter to 500% on Enterprise, so filter-heavy bots can move up as they grow.

Troubleshooting

The filter doesn’t seem to apply — wait a second or two for the buffer, or seek to apply immediately.

Applying one filter removed another — filters replace the whole set. Send combined filters together.

Audio distorts — gains or volume are too high. Reduce equalizer gains and keep the volume filter at or below 1.0.

Karaoke barely changes anything — the vocals aren’t centred in the mix. It’s a limitation of the technique, not a bug.

Summary

Lavalink filters — equalizer, timescale, rotation, karaoke, tremolo, vibrato, low-pass, channel mix and distortion — are applied on the node in real time. Sending filters replaces the whole set, so combine effects in one update. Use gentle presets like a small low-band boost for bass, speed and pitch 1.2 for nightcore, and 0.2 Hz rotation for 8D, and remember that popular filters add CPU load to your node.