Skip to content
This repository was archived by the owner on Apr 5, 2025. It is now read-only.

Commit 4adb979

Browse files
authored
Fix/filter values (#326)
* Add baseFilter class and remove None values from filter payloads. * Bump version
1 parent 7a67075 commit 4adb979

File tree

3 files changed

+58
-33
lines changed

3 files changed

+58
-33
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "wavelink"
7-
version = "3.4.1"
7+
version = "3.4.2"
88
authors = [
99
{ name="PythonistaGuild, EvieePy", email="[email protected]" },
1010
]

wavelink/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
__author__ = "PythonistaGuild, EvieePy"
2727
__license__ = "MIT"
2828
__copyright__ = "Copyright 2019-Present (c) PythonistaGuild, EvieePy"
29-
__version__ = "3.4.1"
29+
__version__ = "3.4.2"
3030

3131

3232
from .enums import *

wavelink/filters.py

Lines changed: 56 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,27 @@
2424

2525
from __future__ import annotations
2626

27-
from typing import TYPE_CHECKING, Any, TypedDict
27+
from typing import TYPE_CHECKING, Any, Generic, TypedDict, TypeVar
28+
29+
from .types.filters import (
30+
ChannelMix as ChannelMixPayload,
31+
Distortion as DistortionPayload,
32+
Equalizer as EqualizerPayload,
33+
FilterPayload,
34+
Karaoke as KaraokePayload,
35+
LowPass as LowPassPayload,
36+
Rotation as RotationPayload,
37+
Timescale as TimescalePayload,
38+
Tremolo as TremoloPayload,
39+
Vibrato as VibratoPayload,
40+
)
2841

2942

3043
if TYPE_CHECKING:
3144
from typing_extensions import Self, Unpack
3245

33-
from .types.filters import (
34-
ChannelMix as ChannelMixPayload,
35-
Distortion as DistortionPayload,
36-
Equalizer as EqualizerPayload,
37-
FilterPayload,
38-
Karaoke as KaraokePayload,
39-
LowPass as LowPassPayload,
40-
Rotation as RotationPayload,
41-
Timescale as TimescalePayload,
42-
Tremolo as TremoloPayload,
43-
Vibrato as VibratoPayload,
44-
)
46+
47+
FT = TypeVar("FT")
4548

4649

4750
__all__ = (
@@ -108,6 +111,19 @@ class ChannelMixOptions(TypedDict):
108111
right_to_right: float | None
109112

110113

114+
class _BaseFilter(Generic[FT]):
115+
_payload: FT
116+
117+
def __init__(self, payload: FT) -> None:
118+
self._payload = payload
119+
self._remove_none()
120+
121+
def _remove_none(self) -> None:
122+
# Lavalink doesn't allow nullable types in any filters, but they are still not required...
123+
# Passing None makes it easier for the user to remove a field...
124+
self._payload = {k: v for k, v in self._payload.items() if v is not None} # type: ignore
125+
126+
111127
class Equalizer:
112128
"""Equalizer Filter Class.
113129
@@ -182,14 +198,14 @@ def __repr__(self) -> str:
182198
return f"<Equalizer: {self._payload}>"
183199

184200

185-
class Karaoke:
201+
class Karaoke(_BaseFilter[KaraokePayload]):
186202
"""Karaoke Filter class.
187203
188204
Uses equalization to eliminate part of a band, usually targeting vocals.
189205
"""
190206

191207
def __init__(self, payload: KaraokePayload) -> None:
192-
self._payload = payload
208+
super().__init__(payload=payload)
193209

194210
def set(self, **options: Unpack[KaraokeOptions]) -> Self:
195211
"""Set the properties of the this filter.
@@ -214,6 +230,7 @@ def set(self, **options: Unpack[KaraokeOptions]) -> Self:
214230
"filterBand": options.get("filter_band", self._payload.get("filterBand")),
215231
"filterWidth": options.get("filter_width", self._payload.get("filterWidth")),
216232
}
233+
self._remove_none()
217234
return self
218235

219236
def reset(self) -> Self:
@@ -236,14 +253,14 @@ def __repr__(self) -> str:
236253
return f"<Karaoke: {self._payload}>"
237254

238255

239-
class Timescale:
256+
class Timescale(_BaseFilter[TimescalePayload]):
240257
"""Timescale Filter class.
241258
242259
Changes the speed, pitch, and rate.
243260
"""
244261

245262
def __init__(self, payload: TimescalePayload) -> None:
246-
self._payload = payload
263+
super().__init__(payload=payload)
247264

248265
def set(self, **options: Unpack[TimescalePayload]) -> Self:
249266
"""Set the properties of the this filter.
@@ -261,6 +278,7 @@ def set(self, **options: Unpack[TimescalePayload]) -> Self:
261278
The rate.
262279
"""
263280
self._payload.update(options)
281+
self._remove_none()
264282
return self
265283

266284
def reset(self) -> Self:
@@ -283,15 +301,15 @@ def __repr__(self) -> str:
283301
return f"<Timescale: {self._payload}>"
284302

285303

286-
class Tremolo:
304+
class Tremolo(_BaseFilter[TremoloPayload]):
287305
"""The Tremolo Filter class.
288306
289307
Uses amplification to create a shuddering effect, where the volume quickly oscillates.
290308
Demo: https://en.wikipedia.org/wiki/File:Fuse_Electronics_Tremolo_MK-III_Quick_Demo.ogv
291309
"""
292310

293311
def __init__(self, payload: TremoloPayload) -> None:
294-
self._payload = payload
312+
super().__init__(payload=payload)
295313

296314
def set(self, **options: Unpack[TremoloPayload]) -> Self:
297315
"""Set the properties of the this filter.
@@ -307,6 +325,7 @@ def set(self, **options: Unpack[TremoloPayload]) -> Self:
307325
The tremolo depth.
308326
"""
309327
self._payload.update(options)
328+
self._remove_none()
310329
return self
311330

312331
def reset(self) -> Self:
@@ -329,14 +348,14 @@ def __repr__(self) -> str:
329348
return f"<Tremolo: {self._payload}>"
330349

331350

332-
class Vibrato:
351+
class Vibrato(_BaseFilter[VibratoPayload]):
333352
"""The Vibrato Filter class.
334353
335354
Similar to tremolo. While tremolo oscillates the volume, vibrato oscillates the pitch.
336355
"""
337356

338357
def __init__(self, payload: VibratoPayload) -> None:
339-
self._payload = payload
358+
super().__init__(payload=payload)
340359

341360
def set(self, **options: Unpack[VibratoPayload]) -> Self:
342361
"""Set the properties of the this filter.
@@ -352,6 +371,7 @@ def set(self, **options: Unpack[VibratoPayload]) -> Self:
352371
The vibrato depth.
353372
"""
354373
self._payload.update(options)
374+
self._remove_none()
355375
return self
356376

357377
def reset(self) -> Self:
@@ -374,15 +394,15 @@ def __repr__(self) -> str:
374394
return f"<Vibrato: {self._payload}>"
375395

376396

377-
class Rotation:
397+
class Rotation(_BaseFilter[RotationPayload]):
378398
"""The Rotation Filter class.
379399
380400
Rotates the sound around the stereo channels/user headphones (aka Audio Panning).
381401
It can produce an effect similar to https://youtu.be/QB9EB8mTKcc (without the reverb).
382402
"""
383403

384404
def __init__(self, payload: RotationPayload) -> None:
385-
self._payload = payload
405+
super().__init__(payload=payload)
386406

387407
def set(self, **options: Unpack[RotationOptions]) -> Self:
388408
"""Set the properties of the this filter.
@@ -396,6 +416,7 @@ def set(self, **options: Unpack[RotationOptions]) -> Self:
396416
The frequency of the audio rotating around the listener in Hz. ``0.2`` is similar to the example video.
397417
"""
398418
self._payload: RotationPayload = {"rotationHz": options.get("rotation_hz", self._payload.get("rotationHz"))}
419+
self._remove_none()
399420
return self
400421

401422
def reset(self) -> Self:
@@ -418,14 +439,14 @@ def __repr__(self) -> str:
418439
return f"<Rotation: {self._payload}>"
419440

420441

421-
class Distortion:
442+
class Distortion(_BaseFilter[DistortionPayload]):
422443
"""The Distortion Filter class.
423444
424445
According to Lavalink "It can generate some pretty unique audio effects."
425446
"""
426447

427448
def __init__(self, payload: DistortionPayload) -> None:
428-
self._payload = payload
449+
super().__init__(payload=payload)
429450

430451
def set(self, **options: Unpack[DistortionOptions]) -> Self:
431452
"""Set the properties of the this filter.
@@ -462,6 +483,7 @@ def set(self, **options: Unpack[DistortionOptions]) -> Self:
462483
"offset": options.get("offset", self._payload.get("offset")),
463484
"scale": options.get("scale", self._payload.get("scale")),
464485
}
486+
self._remove_none()
465487
return self
466488

467489
def reset(self) -> Self:
@@ -484,7 +506,7 @@ def __repr__(self) -> str:
484506
return f"<Distortion: {self._payload}>"
485507

486508

487-
class ChannelMix:
509+
class ChannelMix(_BaseFilter[ChannelMixPayload]):
488510
"""The ChannelMix Filter class.
489511
490512
Mixes both channels (left and right), with a configurable factor on how much each channel affects the other.
@@ -494,7 +516,7 @@ class ChannelMix:
494516
"""
495517

496518
def __init__(self, payload: ChannelMixPayload) -> None:
497-
self._payload = payload
519+
super().__init__(payload=payload)
498520

499521
def set(self, **options: Unpack[ChannelMixOptions]) -> Self:
500522
"""Set the properties of the this filter.
@@ -519,6 +541,7 @@ def set(self, **options: Unpack[ChannelMixOptions]) -> Self:
519541
"rightToLeft": options.get("right_to_left", self._payload.get("rightToLeft")),
520542
"rightToRight": options.get("right_to_right", self._payload.get("rightToRight")),
521543
}
544+
self._remove_none()
522545
return self
523546

524547
def reset(self) -> Self:
@@ -541,15 +564,15 @@ def __repr__(self) -> str:
541564
return f"<ChannelMix: {self._payload}>"
542565

543566

544-
class LowPass:
567+
class LowPass(_BaseFilter[LowPassPayload]):
545568
"""The LowPass Filter class.
546569
547570
Higher frequencies get suppressed, while lower frequencies pass through this filter, thus the name low pass.
548571
Any smoothing values equal to or less than ``1.0`` will disable the filter.
549572
"""
550573

551574
def __init__(self, payload: LowPassPayload) -> None:
552-
self._payload = payload
575+
super().__init__(payload=payload)
553576

554577
def set(self, **options: Unpack[LowPassPayload]) -> Self:
555578
"""Set the properties of the this filter.
@@ -563,6 +586,7 @@ def set(self, **options: Unpack[LowPassPayload]) -> Self:
563586
The smoothing factor.
564587
"""
565588
self._payload.update(options)
589+
self._remove_none()
566590
return self
567591

568592
def reset(self) -> Self:
@@ -585,7 +609,7 @@ def __repr__(self) -> str:
585609
return f"<LowPass: {self._payload}>"
586610

587611

588-
class PluginFilters:
612+
class PluginFilters(_BaseFilter[dict[str, Any]]):
589613
"""The PluginFilters class.
590614
591615
This class handles setting filters on plugins that support setting filter values.
@@ -604,7 +628,7 @@ class PluginFilters:
604628
"""
605629

606630
def __init__(self, payload: dict[str, Any]) -> None:
607-
self._payload = payload
631+
super().__init__(payload=payload)
608632

609633
def set(self, **options: dict[str, Any]) -> Self:
610634
"""Set the properties of this filter.
@@ -625,6 +649,7 @@ def set(self, **options: dict[str, Any]) -> Self:
625649
plugin_filters.set(**{"pluginName": {"filterKey": "filterValue", ...}})
626650
"""
627651
self._payload.update(options)
652+
self._remove_none()
628653
return self
629654

630655
def reset(self) -> Self:

0 commit comments

Comments
 (0)