> ## Documentation Index
> Fetch the complete documentation index at: https://salad-ffed6391.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Audio Filters

> Apply audio filters and effects to enhance your music playback experience

## 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

```python theme={null}
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

```python theme={null}
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

```python theme={null}
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

```python theme={null}
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

```python theme={null}
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

```python theme={null}
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

```python theme={null}
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

```python theme={null}
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

```python theme={null}
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

```python theme={null}
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
```

<Tip>
  Filters are applied to the currently playing track and will persist for subsequent tracks until cleared or changed.
</Tip>

<Warning>
  Heavy filter combinations may increase CPU usage on your Lavalink server. Monitor performance when using multiple filters simultaneously.
</Warning>
