or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

audio-filters.mdevents-exceptions.mdindex.mdnode-management.mdplayer-control.mdqueue-system.mdtrack-search.md

audio-filters.mddocs/

0

# Audio Filters

1

2

Comprehensive audio filter system including equalizer, distortion, karaoke, timescale, and plugin filters for advanced audio processing and effects. The filter system allows real-time audio manipulation to enhance playback quality and create creative audio effects.

3

4

## Capabilities

5

6

### Filter Container

7

8

The main Filters class that manages all individual filter types and applies them to players.

9

10

```python { .api }

11

class Filters:

12

def __init__(self, *, data: dict | None = None):

13

"""

14

Initialize a new Filters container.

15

16

Parameters:

17

- data: Optional filter data to initialize from

18

"""

19

20

@property

21

def volume(self) -> float | None:

22

"""

23

Player volume multiplier (0.0-5.0, where 1.0 is 100%).

24

Values >1.0 may cause clipping.

25

"""

26

27

@volume.setter

28

def volume(self, value: float) -> None:

29

"""Set the volume multiplier."""

30

31

@property

32

def equalizer(self) -> Equalizer:

33

"""15-band equalizer filter."""

34

35

@property

36

def karaoke(self) -> Karaoke:

37

"""Karaoke filter for vocal elimination."""

38

39

@property

40

def timescale(self) -> Timescale:

41

"""Timescale filter for speed/pitch/rate adjustment."""

42

43

@property

44

def tremolo(self) -> Tremolo:

45

"""Tremolo filter for volume oscillation."""

46

47

@property

48

def vibrato(self) -> Vibrato:

49

"""Vibrato filter for pitch oscillation."""

50

51

@property

52

def rotation(self) -> Rotation:

53

"""Rotation filter for audio panning effects."""

54

55

@property

56

def distortion(self) -> Distortion:

57

"""Distortion filter for audio distortion effects."""

58

59

@property

60

def channel_mix(self) -> ChannelMix:

61

"""Channel mix filter for stereo channel manipulation."""

62

63

@property

64

def low_pass(self) -> LowPass:

65

"""Low pass filter for high frequency suppression."""

66

67

@property

68

def plugin_filters(self) -> PluginFilters:

69

"""Custom plugin filters for Lavalink plugins."""

70

71

def set_filters(self, **filters) -> None:

72

"""

73

Set multiple filters at once.

74

75

Parameters:

76

- volume: float - Volume multiplier

77

- equalizer: Equalizer - Equalizer filter

78

- karaoke: Karaoke - Karaoke filter

79

- timescale: Timescale - Timescale filter

80

- tremolo: Tremolo - Tremolo filter

81

- vibrato: Vibrato - Vibrato filter

82

- rotation: Rotation - Rotation filter

83

- distortion: Distortion - Distortion filter

84

- channel_mix: ChannelMix - Channel mix filter

85

- low_pass: LowPass - Low pass filter

86

- plugin_filters: PluginFilters - Plugin filters

87

- reset: bool - Whether to reset unspecified filters

88

"""

89

90

def reset(self) -> None:

91

"""Reset all filters to their default states."""

92

93

@classmethod

94

def from_filters(cls, **filters) -> Self:

95

"""

96

Create a new Filters instance with specified filters.

97

98

Parameters:

99

- **filters: Filter parameters (same as set_filters)

100

101

Returns:

102

Filters: New Filters instance

103

"""

104

105

def __call__(self) -> dict:

106

"""

107

Get the raw filter payload for Lavalink.

108

109

Returns:

110

dict: Filter payload data

111

"""

112

```

113

114

### Equalizer Filter

115

116

15-band equalizer for frequency-specific volume adjustment.

117

118

```python { .api }

119

class Equalizer:

120

def __init__(self, payload: list[dict] | None = None):

121

"""

122

Initialize equalizer with optional band data.

123

124

Parameters:

125

- payload: List of band configurations

126

"""

127

128

def set(self, *, bands: list[dict] | None = None) -> Self:

129

"""

130

Set equalizer bands.

131

132

Parameters:

133

- bands: List of dicts with 'band' (0-14) and 'gain' (-0.25 to 1.0) keys

134

135

Returns:

136

Self: This equalizer instance for chaining

137

138

Note:

139

- Band 0-14 represent different frequency ranges

140

- Gain -0.25 = muted, 0.0 = unchanged, 1.0 = doubled

141

- This method resets ALL bands, use payload property for selective changes

142

"""

143

144

def reset(self) -> Self:

145

"""

146

Reset all bands to 0.0 gain.

147

148

Returns:

149

Self: This equalizer instance for chaining

150

"""

151

152

@property

153

def payload(self) -> dict[int, dict]:

154

"""

155

Raw equalizer band data (copy).

156

157

Returns:

158

dict: Band data keyed by band number (0-14)

159

"""

160

```

161

162

### Karaoke Filter

163

164

Vocal elimination filter using equalization techniques.

165

166

```python { .api }

167

class Karaoke:

168

def __init__(self, payload: dict):

169

"""

170

Initialize karaoke filter.

171

172

Parameters:

173

- payload: Karaoke configuration data

174

"""

175

176

def set(

177

self,

178

*,

179

level: float | None = None,

180

mono_level: float | None = None,

181

filter_band: float | None = None,

182

filter_width: float | None = None

183

) -> Self:

184

"""

185

Configure karaoke filter parameters.

186

187

Parameters:

188

- level: Effect level (0.0-1.0)

189

- mono_level: Mono level (0.0-1.0)

190

- filter_band: Filter band frequency in Hz

191

- filter_width: Filter width

192

193

Returns:

194

Self: This karaoke instance for chaining

195

"""

196

197

def reset(self) -> Self:

198

"""

199

Reset karaoke filter to defaults.

200

201

Returns:

202

Self: This karaoke instance for chaining

203

"""

204

205

@property

206

def payload(self) -> dict:

207

"""Raw karaoke filter data (copy)."""

208

```

209

210

### Timescale Filter

211

212

Speed, pitch, and rate modification filter.

213

214

```python { .api }

215

class Timescale:

216

def __init__(self, payload: dict):

217

"""

218

Initialize timescale filter.

219

220

Parameters:

221

- payload: Timescale configuration data

222

"""

223

224

def set(

225

self,

226

*,

227

speed: float | None = None,

228

pitch: float | None = None,

229

rate: float | None = None

230

) -> Self:

231

"""

232

Configure timescale parameters.

233

234

Parameters:

235

- speed: Playback speed multiplier

236

- pitch: Pitch adjustment multiplier

237

- rate: Rate adjustment multiplier

238

239

Returns:

240

Self: This timescale instance for chaining

241

"""

242

243

def reset(self) -> Self:

244

"""

245

Reset timescale filter to defaults.

246

247

Returns:

248

Self: This timescale instance for chaining

249

"""

250

251

@property

252

def payload(self) -> dict:

253

"""Raw timescale filter data (copy)."""

254

```

255

256

### Tremolo Filter

257

258

Volume oscillation effect filter.

259

260

```python { .api }

261

class Tremolo:

262

def __init__(self, payload: dict):

263

"""

264

Initialize tremolo filter.

265

266

Parameters:

267

- payload: Tremolo configuration data

268

"""

269

270

def set(

271

self,

272

*,

273

frequency: float | None = None,

274

depth: float | None = None

275

) -> Self:

276

"""

277

Configure tremolo parameters.

278

279

Parameters:

280

- frequency: Oscillation frequency in Hz

281

- depth: Effect depth (0.0-1.0)

282

283

Returns:

284

Self: This tremolo instance for chaining

285

"""

286

287

def reset(self) -> Self:

288

"""

289

Reset tremolo filter to defaults.

290

291

Returns:

292

Self: This tremolo instance for chaining

293

"""

294

295

@property

296

def payload(self) -> dict:

297

"""Raw tremolo filter data (copy)."""

298

```

299

300

### Vibrato Filter

301

302

Pitch oscillation effect filter.

303

304

```python { .api }

305

class Vibrato:

306

def __init__(self, payload: dict):

307

"""

308

Initialize vibrato filter.

309

310

Parameters:

311

- payload: Vibrato configuration data

312

"""

313

314

def set(

315

self,

316

*,

317

frequency: float | None = None,

318

depth: float | None = None

319

) -> Self:

320

"""

321

Configure vibrato parameters.

322

323

Parameters:

324

- frequency: Oscillation frequency in Hz

325

- depth: Effect depth (0.0-1.0)

326

327

Returns:

328

Self: This vibrato instance for chaining

329

"""

330

331

def reset(self) -> Self:

332

"""

333

Reset vibrato filter to defaults.

334

335

Returns:

336

Self: This vibrato instance for chaining

337

"""

338

339

@property

340

def payload(self) -> dict:

341

"""Raw vibrato filter data (copy)."""

342

```

343

344

### Rotation Filter

345

346

Audio panning and stereo rotation effects.

347

348

```python { .api }

349

class Rotation:

350

def __init__(self, payload: dict):

351

"""

352

Initialize rotation filter.

353

354

Parameters:

355

- payload: Rotation configuration data

356

"""

357

358

def set(self, *, rotation_hz: float | None = None) -> Self:

359

"""

360

Configure rotation frequency.

361

362

Parameters:

363

- rotation_hz: Rotation frequency in Hz (0.2 is similar to example effects)

364

365

Returns:

366

Self: This rotation instance for chaining

367

"""

368

369

def reset(self) -> Self:

370

"""

371

Reset rotation filter to defaults.

372

373

Returns:

374

Self: This rotation instance for chaining

375

"""

376

377

@property

378

def payload(self) -> dict:

379

"""Raw rotation filter data (copy)."""

380

```

381

382

### Distortion Filter

383

384

Audio distortion effects filter.

385

386

```python { .api }

387

class Distortion:

388

def __init__(self, payload: dict):

389

"""

390

Initialize distortion filter.

391

392

Parameters:

393

- payload: Distortion configuration data

394

"""

395

396

def set(

397

self,

398

*,

399

sin_offset: float | None = None,

400

sin_scale: float | None = None,

401

cos_offset: float | None = None,

402

cos_scale: float | None = None,

403

tan_offset: float | None = None,

404

tan_scale: float | None = None,

405

offset: float | None = None,

406

scale: float | None = None

407

) -> Self:

408

"""

409

Configure distortion parameters.

410

411

Parameters:

412

- sin_offset: Sine offset value

413

- sin_scale: Sine scale multiplier

414

- cos_offset: Cosine offset value

415

- cos_scale: Cosine scale multiplier

416

- tan_offset: Tangent offset value

417

- tan_scale: Tangent scale multiplier

418

- offset: General offset value

419

- scale: General scale multiplier

420

421

Returns:

422

Self: This distortion instance for chaining

423

"""

424

425

def reset(self) -> Self:

426

"""

427

Reset distortion filter to defaults.

428

429

Returns:

430

Self: This distortion instance for chaining

431

"""

432

433

@property

434

def payload(self) -> dict:

435

"""Raw distortion filter data (copy)."""

436

```

437

438

### Channel Mix Filter

439

440

Left/right channel mixing and manipulation.

441

442

```python { .api }

443

class ChannelMix:

444

def __init__(self, payload: dict):

445

"""

446

Initialize channel mix filter.

447

448

Parameters:

449

- payload: Channel mix configuration data

450

"""

451

452

def set(

453

self,

454

*,

455

left_to_left: float | None = None,

456

left_to_right: float | None = None,

457

right_to_left: float | None = None,

458

right_to_right: float | None = None

459

) -> Self:

460

"""

461

Configure channel mixing factors.

462

463

Parameters:

464

- left_to_left: Left channel to left output (0.0-1.0)

465

- left_to_right: Left channel to right output (0.0-1.0)

466

- right_to_left: Right channel to left output (0.0-1.0)

467

- right_to_right: Right channel to right output (0.0-1.0)

468

469

Returns:

470

Self: This channel mix instance for chaining

471

472

Note:

473

- Default values keep channels independent

474

- Setting all to 0.5 creates mono output

475

"""

476

477

def reset(self) -> Self:

478

"""

479

Reset channel mix filter to defaults.

480

481

Returns:

482

Self: This channel mix instance for chaining

483

"""

484

485

@property

486

def payload(self) -> dict:

487

"""Raw channel mix filter data (copy)."""

488

```

489

490

### Low Pass Filter

491

492

High frequency suppression filter.

493

494

```python { .api }

495

class LowPass:

496

def __init__(self, payload: dict):

497

"""

498

Initialize low pass filter.

499

500

Parameters:

501

- payload: Low pass configuration data

502

"""

503

504

def set(self, *, smoothing: float | None = None) -> Self:

505

"""

506

Configure low pass smoothing.

507

508

Parameters:

509

- smoothing: Smoothing factor (>1.0 to enable, <=1.0 disables)

510

511

Returns:

512

Self: This low pass instance for chaining

513

"""

514

515

def reset(self) -> Self:

516

"""

517

Reset low pass filter to defaults.

518

519

Returns:

520

Self: This low pass instance for chaining

521

"""

522

523

@property

524

def payload(self) -> dict:

525

"""Raw low pass filter data (copy)."""

526

```

527

528

### Plugin Filters

529

530

Custom filters for Lavalink plugins.

531

532

```python { .api }

533

class PluginFilters:

534

def __init__(self, payload: dict[str, Any]):

535

"""

536

Initialize plugin filters.

537

538

Parameters:

539

- payload: Plugin filter configuration data

540

"""

541

542

def set(self, **options: dict[str, Any]) -> Self:

543

"""

544

Set plugin-specific filter values.

545

546

Parameters:

547

- **options: Plugin filter options in format:

548

pluginName={"filterKey": "filterValue", ...}

549

550

Returns:

551

Self: This plugin filters instance for chaining

552

553

Example:

554

plugin_filters.set(pluginName={"filterKey": "filterValue"})

555

"""

556

557

def reset(self) -> Self:

558

"""

559

Reset all plugin filters to defaults.

560

561

Returns:

562

Self: This plugin filters instance for chaining

563

"""

564

565

@property

566

def payload(self) -> dict[str, Any]:

567

"""Raw plugin filter data (copy)."""

568

```

569

570

## Usage Examples

571

572

### Basic Filter Application

573

574

```python

575

import wavelink

576

577

@bot.command()

578

async def bass_boost(ctx, level: int = 3):

579

"""Apply bass boost using equalizer."""

580

player = ctx.voice_client

581

if not player:

582

return await ctx.send("Not connected to a voice channel!")

583

584

# Get current filters

585

filters = player.filters

586

587

# Configure bass boost (boost low frequencies)

588

bass_bands = [

589

{"band": 0, "gain": level * 0.05}, # 25Hz

590

{"band": 1, "gain": level * 0.04}, # 40Hz

591

{"band": 2, "gain": level * 0.03}, # 63Hz

592

{"band": 3, "gain": level * 0.02}, # 100Hz

593

{"band": 4, "gain": level * 0.01}, # 160Hz

594

]

595

596

filters.equalizer.set(bands=bass_bands)

597

await player.set_filters(filters)

598

599

await ctx.send(f"Applied bass boost level {level}")

600

601

@bot.command()

602

async def nightcore(ctx):

603

"""Apply nightcore effect (higher pitch and speed)."""

604

player = ctx.voice_client

605

if not player:

606

return await ctx.send("Not connected to a voice channel!")

607

608

# Get current filters

609

filters = player.filters

610

611

# Configure nightcore timescale

612

filters.timescale.set(speed=1.3, pitch=1.3, rate=1.0)

613

614

await player.set_filters(filters)

615

await ctx.send("Applied nightcore effect!")

616

617

@bot.command()

618

async def vaporwave(ctx):

619

"""Apply vaporwave effect (lower pitch and speed)."""

620

player = ctx.voice_client

621

if not player:

622

return await ctx.send("Not connected to a voice channel!")

623

624

filters = player.filters

625

626

# Configure vaporwave timescale

627

filters.timescale.set(speed=0.8, pitch=0.8, rate=1.0)

628

629

await player.set_filters(filters)

630

await ctx.send("Applied vaporwave effect!")

631

```

632

633

### Advanced Filter Combinations

634

635

```python

636

@bot.command()

637

async def party_mode(ctx):

638

"""Apply multiple filters for party effect."""

639

player = ctx.voice_client

640

if not player:

641

return await ctx.send("Not connected to a voice channel!")

642

643

filters = player.filters

644

645

# Bass boost with equalizer

646

bass_bands = [

647

{"band": 0, "gain": 0.15},

648

{"band": 1, "gain": 0.12},

649

{"band": 2, "gain": 0.09},

650

{"band": 3, "gain": 0.06},

651

]

652

filters.equalizer.set(bands=bass_bands)

653

654

# Add tremolo for volume oscillation

655

filters.tremolo.set(frequency=2.0, depth=0.3)

656

657

# Add rotation for stereo effects

658

filters.rotation.set(rotation_hz=0.1)

659

660

# Slight volume boost

661

filters.volume = 1.2

662

663

await player.set_filters(filters)

664

await ctx.send("πŸŽ‰ Party mode activated!")

665

666

@bot.command()

667

async def robot_voice(ctx):

668

"""Apply robot voice effect."""

669

player = ctx.voice_client

670

if not player:

671

return await ctx.send("Not connected to a voice channel!")

672

673

filters = player.filters

674

675

# Distortion for robotic sound

676

filters.distortion.set(

677

sin_offset=0.0,

678

sin_scale=1.0,

679

cos_offset=0.0,

680

cos_scale=1.0,

681

tan_offset=0.0,

682

tan_scale=1.0,

683

offset=0.0,

684

scale=1.0

685

)

686

687

# Channel mix for stereo effect

688

filters.channel_mix.set(

689

left_to_left=0.8,

690

left_to_right=0.2,

691

right_to_left=0.2,

692

right_to_right=0.8

693

)

694

695

await player.set_filters(filters)

696

await ctx.send("πŸ€– Robot voice effect applied!")

697

```

698

699

### Filter Management Commands

700

701

```python

702

@bot.command()

703

async def filters(ctx):

704

"""Show current filter status."""

705

player = ctx.voice_client

706

if not player:

707

return await ctx.send("Not connected to a voice channel!")

708

709

filters = player.filters

710

embed = discord.Embed(title="Current Filters", color=discord.Color.blue())

711

712

# Volume

713

if filters.volume is not None:

714

embed.add_field(name="Volume", value=f"{filters.volume:.2f}x", inline=True)

715

716

# Check each filter type

717

filter_info = []

718

719

# Equalizer

720

eq_active = any(band["gain"] != 0.0 for band in filters.equalizer.payload.values())

721

if eq_active:

722

filter_info.append("Equalizer")

723

724

# Timescale

725

ts_payload = filters.timescale.payload

726

if ts_payload.get("speed") or ts_payload.get("pitch") or ts_payload.get("rate"):

727

speed = ts_payload.get("speed", 1.0)

728

pitch = ts_payload.get("pitch", 1.0)

729

filter_info.append(f"Timescale (Speed: {speed:.2f}, Pitch: {pitch:.2f})")

730

731

# Other filters

732

if filters.karaoke.payload:

733

filter_info.append("Karaoke")

734

if filters.tremolo.payload:

735

filter_info.append("Tremolo")

736

if filters.vibrato.payload:

737

filter_info.append("Vibrato")

738

if filters.rotation.payload:

739

filter_info.append("Rotation")

740

if filters.distortion.payload:

741

filter_info.append("Distortion")

742

if filters.channel_mix.payload:

743

filter_info.append("Channel Mix")

744

if filters.low_pass.payload:

745

filter_info.append("Low Pass")

746

if filters.plugin_filters.payload:

747

filter_info.append("Plugin Filters")

748

749

if filter_info:

750

embed.add_field(

751

name="Active Filters",

752

value="\n".join(filter_info),

753

inline=False

754

)

755

else:

756

embed.add_field(name="Status", value="No filters active", inline=False)

757

758

await ctx.send(embed=embed)

759

760

@bot.command()

761

async def reset_filters(ctx):

762

"""Reset all filters to default."""

763

player = ctx.voice_client

764

if not player:

765

return await ctx.send("Not connected to a voice channel!")

766

767

# Reset all filters

768

await player.set_filters() # Passing None resets all filters

769

await ctx.send("βœ… All filters reset to default!")

770

771

@bot.command()

772

async def save_filters(ctx, name: str):

773

"""Save current filter preset."""

774

player = ctx.voice_client

775

if not player:

776

return await ctx.send("Not connected to a voice channel!")

777

778

# In a real bot, you'd save this to a database

779

# This is a simple example using a dict

780

if not hasattr(bot, 'filter_presets'):

781

bot.filter_presets = {}

782

783

# Get current filter payload

784

filter_data = player.filters()

785

bot.filter_presets[name.lower()] = filter_data

786

787

await ctx.send(f"πŸ’Ύ Saved current filters as preset '{name}'")

788

789

@bot.command()

790

async def load_filters(ctx, name: str):

791

"""Load a saved filter preset."""

792

player = ctx.voice_client

793

if not player:

794

return await ctx.send("Not connected to a voice channel!")

795

796

if not hasattr(bot, 'filter_presets'):

797

return await ctx.send("No filter presets saved!")

798

799

preset_name = name.lower()

800

if preset_name not in bot.filter_presets:

801

available = ", ".join(bot.filter_presets.keys())

802

return await ctx.send(f"Preset '{name}' not found! Available: {available}")

803

804

# Create filters from saved data

805

filter_data = bot.filter_presets[preset_name]

806

filters = wavelink.Filters(data=filter_data)

807

808

await player.set_filters(filters)

809

await ctx.send(f"πŸ“‚ Loaded filter preset '{name}'")

810

```

811

812

### Custom Equalizer Presets

813

814

```python

815

# Predefined EQ presets

816

EQ_PRESETS = {

817

'flat': [], # No changes

818

'bass_boost': [

819

{"band": 0, "gain": 0.2},

820

{"band": 1, "gain": 0.15},

821

{"band": 2, "gain": 0.1},

822

{"band": 3, "gain": 0.05},

823

],

824

'treble_boost': [

825

{"band": 11, "gain": 0.1},

826

{"band": 12, "gain": 0.15},

827

{"band": 13, "gain": 0.2},

828

{"band": 14, "gain": 0.25},

829

],

830

'vocal_boost': [

831

{"band": 6, "gain": 0.1},

832

{"band": 7, "gain": 0.15},

833

{"band": 8, "gain": 0.2},

834

{"band": 9, "gain": 0.15},

835

{"band": 10, "gain": 0.1},

836

],

837

'pop': [

838

{"band": 0, "gain": 0.1},

839

{"band": 1, "gain": 0.05},

840

{"band": 7, "gain": 0.1},

841

{"band": 8, "gain": 0.15},

842

{"band": 9, "gain": 0.1},

843

{"band": 13, "gain": 0.1},

844

{"band": 14, "gain": 0.15},

845

]

846

}

847

848

@bot.command()

849

async def eq_preset(ctx, preset: str = None):

850

"""Apply or list equalizer presets."""

851

player = ctx.voice_client

852

if not player:

853

return await ctx.send("Not connected to a voice channel!")

854

855

if preset is None:

856

available = ", ".join(EQ_PRESETS.keys())

857

return await ctx.send(f"Available EQ presets: {available}")

858

859

preset_name = preset.lower()

860

if preset_name not in EQ_PRESETS:

861

available = ", ".join(EQ_PRESETS.keys())

862

return await ctx.send(f"Unknown preset! Available: {available}")

863

864

filters = player.filters

865

filters.equalizer.set(bands=EQ_PRESETS[preset_name])

866

867

await player.set_filters(filters)

868

await ctx.send(f"🎡 Applied '{preset}' EQ preset")

869

870

@bot.command()

871

async def custom_eq(ctx, *band_gains):

872

"""Set custom equalizer bands. Usage: !custom_eq 0.1 0.2 0.0 ..."""

873

player = ctx.voice_client

874

if not player:

875

return await ctx.send("Not connected to a voice channel!")

876

877

if len(band_gains) > 15:

878

return await ctx.send("Maximum 15 bands (0-14)!")

879

880

try:

881

# Parse gain values

882

gains = [float(gain) for gain in band_gains]

883

884

# Validate gain range

885

for gain in gains:

886

if not -0.25 <= gain <= 1.0:

887

return await ctx.send("Gain values must be between -0.25 and 1.0!")

888

889

# Create band configuration

890

bands = [{"band": i, "gain": gain} for i, gain in enumerate(gains)]

891

892

filters = player.filters

893

filters.equalizer.set(bands=bands)

894

await player.set_filters(filters)

895

896

await ctx.send(f"πŸŽ›οΈ Applied custom EQ with {len(bands)} bands")

897

898

except ValueError:

899

await ctx.send("Invalid gain values! Use numbers between -0.25 and 1.0")

900

```