Skip to main content

Audio Filters

Apply audio filters and effects to enhance your music playback experience with Salada’s built-in filter system.

Basic Filter Usage

Using the Filters Class

from Salad import Filters

filters = Filters()

filters.set_timescale(speed=1.2, pitch=1.2)
filters.set_tremolo(frequency=4.0, depth=0.5)
filters.set_vibrato(frequency=4.0, depth=0.5)

payload = filters.to_payload()

await player.setFilters(payload)

Pre-built Filter Presets

Complete Filter Preset Function

from Salad import Filters

async def apply_filter_preset(player, preset: str):
    filters = Filters()
    preset_name = None
    
    if preset == "8d":
        filters.set_rotation(rotation_hz=0.2)
        preset_name = '8D Audio'
        
    elif preset == "karaoke":
        filters.set_karaoke()
        preset_name = 'Karaoke'
        
    elif preset == "timescale":
        filters.set_timescale(speed=1.2, pitch=1.2, rate=1.0)
        preset_name = 'Timescale'
        
    elif preset == "tremolo":
        filters.set_tremolo(depth=0.5, frequency=4.0)
        preset_name = 'Tremolo'
        
    elif preset == "vibrato":
        filters.set_vibrato(depth=0.5, frequency=4.0)
        preset_name = 'Vibrato'
        
    elif preset == "rotation":
        filters.set_rotation(rotation_hz=0.2)
        preset_name = 'Rotation'
        
    elif preset == "distortion":
        filters.set_distortion(shift=0.5)
        preset_name = 'Distortion'
        
    elif preset in ("channelmix", "channelMix"):
        filters.set_channel_mix(
            left_to_left=0.5,
            left_to_right=0.5,
            right_to_left=0.5,
            right_to_right=0.5
        )
        preset_name = 'Channel Mix'
        
    elif preset in ("lowpass", "lowPass"):
        filters.set_low_pass(smoothing=20.0)
        preset_name = 'Low Pass'
        
    elif preset == "bassboost":
        filters.set_equalizer([
            (0, 0.6), (1, 0.67), (2, 0.67), (3, 0.4),
            (4, -0.5), (5, 0.15), (6, -0.45), (7, 0.23),
            (8, 0.35), (9, 0.45), (10, 0.55), (11, 0.6),
            (12, 0.55), (13, 0.0), (14, 0.0)
        ])
        preset_name = 'Bass Boost'
        
    elif preset == "nightcore":
        filters.set_timescale(speed=1.3, pitch=1.3, rate=1.0)
        preset_name = 'Nightcore'
        
    elif preset == "vaporwave":
        filters.set_timescale(speed=0.8, pitch=0.8, rate=1.0)
        filters.set_equalizer([(0, 0.3), (1, 0.3)])
        preset_name = 'Vaporwave'
        
    elif preset == "slowmode":
        filters.set_timescale(speed=0.7, pitch=0.7, rate=1.0)
        preset_name = 'Slow Mode'
        
    elif preset in ("clear", "off", "reset"):
        await player.clearFilters()
        return 'Clear (No Filters)'
        
    else:
        return None
    
    if filters.to_payload():
        await player.setFilters(filters.to_payload())
    
    return preset_name

applied = await apply_filter_preset(player, 'nightcore')
if applied:
    print(f'✅ Applied {applied} filter')
else:
    print('❌ Unknown filter preset')

Individual Filter Methods

Audio Enhancement Filters

from Salad import Filters

filters = Filters()

filters.set_equalizer([
    (0, 0.6), (1, 0.67), (2, 0.67), (3, 0.4)
])

filters.set_timescale(speed=1.3, pitch=1.3, rate=1.0)

filters.set_timescale(speed=0.8, pitch=0.8, rate=1.0)

filters.set_timescale(speed=0.7, pitch=0.7, rate=1.0)

await player.setFilters(filters.to_payload())

Spatial Audio Effects

from Salad import Filters

filters = Filters()

filters.set_rotation(rotation_hz=0.2)

filters.set_channel_mix(
    left_to_left=1.0,
    left_to_right=0.0,
    right_to_left=0.0,
    right_to_right=1.0
)

await player.setFilters(filters.to_payload())

Modulation Effects

from Salad import Filters

filters = Filters()

filters.set_tremolo(
    depth=0.5,
    frequency=4.0
)

filters.set_vibrato(
    depth=0.5,
    frequency=4.0
)

await player.setFilters(filters.to_payload())

Advanced Audio Processing

from Salad import Filters

filters = Filters()

filters.set_distortion(
    shift=0.5,
    sin_offset=0.0,
    cos_offset=0.0,
    tan_offset=0.0,
    offset=0.0,
    gain=1.0
)

filters.set_low_pass(smoothing=20.0)

filters.set_karaoke(
    level=1.0,
    mono_level=1.0,
    filter_band=220.0,
    filter_width=100.0
)

filters.set_timescale(
    speed=1.2,
    pitch=1.2,
    rate=1.0
)

await player.setFilters(filters.to_payload())

Filter Combinations

Combining Multiple Filters

from Salad import Filters

async def apply_custom_preset(player, preset_name: str):
    filters = Filters()
    
    if preset_name == 'party':
        filters.set_equalizer([
            (0, 0.6), (1, 0.67), (2, 0.67)
        ])
        filters.set_rotation(rotation_hz=0.2)
        filters.set_tremolo(depth=0.3, frequency=2.0)
        
    elif preset_name == 'chill':
        filters.set_timescale(speed=0.8, pitch=0.8)
        filters.set_low_pass(smoothing=15.0)
        
    elif preset_name == 'intense':
        filters.set_equalizer([(0, 0.6), (1, 0.6)])
        filters.set_distortion(shift=0.3)
        filters.set_timescale(speed=1.1, pitch=1.1, rate=1.0)
        
    elif preset_name == 'vocal-focus':
        filters.set_channel_mix(
            left_to_left=0.7,
            left_to_right=0.3,
            right_to_left=0.3,
            right_to_right=0.7
        )
    
    await player.setFilters(filters.to_payload())

await apply_custom_preset(player, 'party')

Command Implementation Example

Complete Filter Command

from discord import app_commands
import discord

@bot.tree.command(name='filter')
@app_commands.describe(filter_type='The filter to apply')
async def filter_command(interaction: discord.Interaction, filter_type: str):
    await interaction.response.defer()
    
    player = bot.salad.getPlayer(interaction.guild.id)
    if not player:
        await interaction.followup.send('❌ No active music player found!')
        return
    
    preset_name = await apply_filter_preset(player, filter_type)
    
    if preset_name:
        embed = discord.Embed(
            title='🎛️ Filter Applied',
            description=f'Applied **{preset_name}** filter to the current track.',
            color=discord.Color.purple()
        )
        embed.set_footer(text='Use /filter clear to remove all filters')
        
        await interaction.followup.send(embed=embed)
    else:
        available_filters = [
            '8d', 'karaoke', 'timescale', 'tremolo', 'vibrato',
            'rotation', 'distortion', 'channelmix', 'lowpass',
            'bassboost', 'slowmode', 'nightcore', 'vaporwave', 'clear'
        ]
        
        await interaction.followup.send(
            f'❌ Unknown filter! Available filters:\n`{", ".join(available_filters)}`'
        )

Filter Persistence

Saving Filter Settings

import json
from typing import Dict, Any

filter_states: Dict[int, Dict[str, Any]] = {}

def save_filter_state(player, guild_id: int):
    filter_state = {
        'guildId': guild_id,
        'filters': player._current_filters if hasattr(player, '_current_filters') else {},
        'timestamp': asyncio.get_event_loop().time()
    }
    
    filter_states[guild_id] = filter_state
    print(f'Saved filter state: {filter_state}')

async def restore_filter_state(player, guild_id: int):
    saved_state = filter_states.get(guild_id)
    
    if saved_state and saved_state.get('filters'):
        filters = Filters()
        
        payload = saved_state['filters']
        
        if 'equalizer' in payload:
            bands = [(eq['band'], eq['gain']) for eq in payload['equalizer']]
            filters.set_equalizer(bands)
        
        if 'timescale' in payload:
            ts = payload['timescale']
            filters.set_timescale(
                speed=ts.get('speed'),
                pitch=ts.get('pitch'),
                rate=ts.get('rate')
            )
        
        if 'tremolo' in payload:
            tr = payload['tremolo']
            filters.set_tremolo(
                frequency=tr.get('frequency', 2.0),
                depth=tr.get('depth', 0.5)
            )
        
        if 'vibrato' in payload:
            vib = payload['vibrato']
            filters.set_vibrato(
                frequency=vib.get('frequency', 2.0),
                depth=vib.get('depth', 0.5)
            )
        
        if 'rotation' in payload:
            rot = payload['rotation']
            filters.set_rotation(rotation_hz=rot.get('rotationHz', 0.2))
        
        if 'distortion' in payload:
            filters.distortion = payload['distortion']
        
        if 'channelMix' in payload:
            cm = payload['channelMix']
            filters.set_channel_mix(
                left_to_left=cm.get('leftToLeft', 1.0),
                left_to_right=cm.get('leftToRight', 0.0),
                right_to_left=cm.get('rightToLeft', 0.0),
                right_to_right=cm.get('rightToRight', 1.0)
            )
        
        if 'lowPass' in payload:
            lp = payload['lowPass']
            filters.set_low_pass(smoothing=lp.get('smoothing', 20.0))
        
        if 'karaoke' in payload:
            filters.karaoke = payload['karaoke']
        
        await player.setFilters(filters.to_payload())
        print(f'Restored filter state for guild {guild_id}')

Equalizer Presets

Common Equalizer Settings

from Salad import Filters

EQUALIZER_PRESETS = {
    'bass_boost': [
        (0, 0.6), (1, 0.67), (2, 0.67), (3, 0.4),
        (4, -0.5), (5, 0.15), (6, -0.45), (7, 0.23),
        (8, 0.35), (9, 0.45), (10, 0.55), (11, 0.6),
        (12, 0.55), (13, 0.0), (14, 0.0)
    ],
    'treble_boost': [
        (0, -0.3), (1, -0.3), (2, -0.2), (3, -0.1),
        (4, 0.0), (5, 0.1), (6, 0.2), (7, 0.3),
        (8, 0.4), (9, 0.5), (10, 0.6), (11, 0.7),
        (12, 0.7), (13, 0.7), (14, 0.7)
    ],
    'soft': [
        (0, 0.0), (1, 0.0), (2, 0.0), (3, 0.0),
        (4, 0.0), (5, 0.0), (6, -0.25), (7, -0.25),
        (8, -0.25), (9, -0.25), (10, -0.25), (11, -0.25),
        (12, -0.25), (13, -0.25), (14, -0.25)
    ],
    'pop': [
        (0, 0.0), (1, 0.0), (2, 0.0), (3, 0.0),
        (4, 0.0), (5, 0.0), (6, 0.0), (7, 0.0),
        (8, 0.15), (9, 0.15), (10, 0.15), (11, 0.15),
        (12, 0.15), (13, 0.15), (14, 0.15)
    ]
}

async def apply_equalizer_preset(player, preset_name: str):
    if preset_name not in EQUALIZER_PRESETS:
        return False
    
    filters = Filters()
    filters.set_equalizer(EQUALIZER_PRESETS[preset_name])
    await player.setFilters(filters.to_payload())
    return True
Filters are applied to the currently playing track and will persist for subsequent tracks until cleared or changed.
Heavy filter combinations may increase CPU usage on your Lavalink server. Monitor performance when using multiple filters simultaneously.