lavalink-client 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -180,4 +180,26 @@ Check out the [Documentation](https://lc4.gitbook.io/lavalink-client) for **Exam
180
180
  ```
181
181
  In one of the next updates, there will be more queueWatcher options and more custom nodeevents to trace
182
182
 
183
- Most features of this update got tested, but if you encounter any bugs feel free to open an issue!
183
+ Most features of this update got tested, but if you encounter any bugs feel free to open an issue!
184
+
185
+ ## **Version 2.1.0**
186
+ - Fixed that, if you skip and have trackloop enabled, it doesn't skip the track
187
+ - I fixed that in the past, but for some reason i removed the fix on accident ig.
188
+ - Reworked the Filter Manager for custom filters via [LavalinkFilterPlugin](https://github.com/rohank05/lavalink-filter-plugin) / [LavalinkLavaDSPX-Plugin](https://github.com/devoxin/LavaDSPX-Plugin/)
189
+ - Note that the [LavalinkLavaDSPX-Plugin](https://github.com/devoxin/LavaDSPX-Plugin/) is by a Community Member of Lavalink and UNOFFICIAL
190
+ - They now have individual state-variabels (booleans): `player.filterManager.filters.lavalinkLavaDspxPlugin`
191
+ - `player.filterManager.filters.lavalinkLavaDspxPlugin.echo`
192
+ - `player.filterManager.filters.lavalinkLavaDspxPlugin.normalization`
193
+ - `player.filterManager.filters.lavalinkLavaDspxPlugin.highPass`
194
+ - `player.filterManager.filters.lavalinkLavaDspxPlugin.lowPass`
195
+ - and for: `player.filterManager.filters.lavalinkFilterPlugin` (this plugins seems to not work on v4 at the moment)
196
+ - `player.filterManager.filters.lavalinkLavaDspxPlugin.echo`
197
+ - `player.filterManager.filters.lavalinkLavaDspxPlugin.reverb`
198
+ - They also now have individual state-changing-methods: `player.filterManager.lavalinkLavaDspxPlugin`
199
+ - `player.filterManager.lavalinkLavaDspxPlugin.toggleEcho(decay:number, echoLength:number)`
200
+ - `player.filterManager.lavalinkLavaDspxPlugin.toggleNormalization(maxAmplitude:number, adaptive:boolean)`
201
+ - `player.filterManager.lavalinkLavaDspxPlugin.toggleHighPass(boostFactor:number, cutoffFrequency:number)`
202
+ - `player.filterManager.lavalinkLavaDspxPlugin.toggleLowPass(boostFactor:number, cutoffFrequency:number)`
203
+ - and for: `player.filterManager.lavalinkFilterPlugin`
204
+ - `player.filterManager.lavalinkFilterPlugin.toggleEcho(delay:number, decay:number)`
205
+ - `player.filterManager.lavalinkFilterPlugin.toggleReverb(delays:number[], gains:number[])`
@@ -86,20 +86,28 @@ export declare class FilterManager {
86
86
  * @returns
87
87
  */
88
88
  toggleLowPass(smoothing?: number): Promise<boolean>;
89
- /**
90
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
91
- * @param delay
92
- * @param decay
93
- * @returns
94
- */
95
- toggleEcho(delay?: number, decay?: number): Promise<boolean>;
96
- /**
97
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
98
- * @param delays
99
- * @param gains
100
- * @returns
101
- */
102
- toggleReverb(delays?: number[], gains?: number[]): Promise<boolean>;
89
+ lavalinkLavaDspxPlugin: {
90
+ toggleLowPass: (boostFactor?: number, cutoffFrequency?: number) => Promise<boolean>;
91
+ toggleHighPass: (boostFactor?: number, cutoffFrequency?: number) => Promise<boolean>;
92
+ toggleNormalization: (maxAmplitude?: number, adaptive?: boolean) => Promise<boolean>;
93
+ toggleEcho: (decay?: number, echoLength?: number) => Promise<boolean>;
94
+ };
95
+ lavalinkFilterPlugin: {
96
+ /**
97
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
98
+ * @param delay
99
+ * @param decay
100
+ * @returns
101
+ */
102
+ toggleEcho: (delay?: number, decay?: number) => Promise<boolean>;
103
+ /**
104
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
105
+ * @param delays
106
+ * @param gains
107
+ * @returns
108
+ */
109
+ toggleReverb: (delays?: number[], gains?: number[]) => Promise<boolean>;
110
+ };
103
111
  /**
104
112
  * Enables / Disabels a Nightcore-like filter Effect. Disables/Overwrides both: custom and Vaporwave Filter
105
113
  * @param speed
@@ -160,10 +168,23 @@ export interface PlayerFilters {
160
168
  audioOutput: AudioOutputs;
161
169
  /** Lavalink Volume FILTER (not player Volume, think of it as a gain booster) */
162
170
  volume: boolean;
163
- /** only with the custom lavalink filter plugin */
164
- echo: boolean;
165
- /** only with the custom lavalink filter plugin */
166
- reverb: boolean;
171
+ /** Filters for the Lavalink Filter Plugin */
172
+ lavalinkFilterPlugin: {
173
+ /** if echo filter is enabled / not */
174
+ echo: boolean;
175
+ /** if reverb filter is enabled / not */
176
+ reverb: boolean;
177
+ };
178
+ lavalinkLavaDspxPlugin: {
179
+ /** if lowPass filter is enabled / not */
180
+ lowPass: boolean;
181
+ /** if highPass filter is enabled / not */
182
+ highPass: boolean;
183
+ /** if normalization filter is enabled / not */
184
+ normalization: boolean;
185
+ /** if echo filter is enabled / not */
186
+ echo: boolean;
187
+ };
167
188
  }
168
189
  /**
169
190
  * There are 15 bands (0-14) that can be changed.
@@ -174,9 +195,9 @@ export interface PlayerFilters {
174
195
  */
175
196
  export interface EQBand {
176
197
  /** On what band position (0-14) it should work */
177
- band: IntegerNumber;
198
+ band: IntegerNumber | number;
178
199
  /** The gain (-0.25 to 1.0) */
179
- gain: FloatNumber;
200
+ gain: FloatNumber | number;
180
201
  }
181
202
  /**
182
203
  * Uses equalization to eliminate part of a band, usually targeting vocals.
@@ -265,20 +286,6 @@ export interface LowPassFilter {
265
286
  /** The smoothing factor (1.0 < x) */
266
287
  smoothing?: number;
267
288
  }
268
- /**
269
- * A Plugin Filter
270
- */
271
- export interface EchoFilter {
272
- delay: number;
273
- decay: number;
274
- }
275
- /**
276
- * A Plugin Filter
277
- */
278
- export interface ReverbFilter {
279
- delays: number[];
280
- gains: number[];
281
- }
282
289
  /**
283
290
  * Filter Data stored in the Client and partially sent to Lavalink
284
291
  */
@@ -292,15 +299,34 @@ export interface FilterData {
292
299
  distortion?: DistortionFilter;
293
300
  channelMix?: ChannelMixFilter;
294
301
  lowPass?: LowPassFilter;
295
- pluginFilters?: Record<PluginFiltersKey, PluginFiltersValues>;
296
- }
297
- export type PluginFiltersKey = "lavalink-filter-plugin" | string;
298
- export interface PluginFiltersValues extends LavalinkFiltersPlugin {
299
- [key: string]: string | number | string[] | number[] | EchoFilter | ReverbFilter;
300
- }
301
- export interface LavalinkFiltersPlugin {
302
- "echo": EchoFilter;
303
- "reverb": ReverbFilter;
302
+ pluginFilters?: {
303
+ "lavalink-filter-plugin"?: {
304
+ "echo"?: {
305
+ delay?: number;
306
+ decay?: number;
307
+ };
308
+ "reverb"?: {
309
+ delays?: number[];
310
+ gains?: number[];
311
+ };
312
+ };
313
+ "high-pass"?: {
314
+ cutoffFrequency?: number;
315
+ boostFactor?: number;
316
+ };
317
+ "low-pass"?: {
318
+ cutoffFrequency?: number;
319
+ boostFactor?: number;
320
+ };
321
+ normalization?: {
322
+ maxAmplitude?: number;
323
+ adaptive?: boolean;
324
+ };
325
+ echo?: {
326
+ echoLength?: number;
327
+ decay?: number;
328
+ };
329
+ };
304
330
  }
305
331
  /**
306
332
  * Actual Filter Data sent to Lavalink
@@ -15,13 +15,21 @@ class FilterManager {
15
15
  vaporwave: false,
16
16
  custom: false,
17
17
  nightcore: false,
18
- echo: false,
19
- reverb: false,
20
18
  rotation: false,
21
19
  karaoke: false,
22
20
  tremolo: false,
23
21
  vibrato: false,
24
22
  lowPass: false,
23
+ lavalinkFilterPlugin: {
24
+ echo: false,
25
+ reverb: false,
26
+ },
27
+ lavalinkLavaDspxPlugin: {
28
+ lowPass: false,
29
+ highPass: false,
30
+ normalization: false,
31
+ echo: false,
32
+ },
25
33
  audioOutput: "stereo",
26
34
  };
27
35
  /** The Filter Data sent to Lavalink, only if the filter is enabled (ofc.) */
@@ -61,7 +69,23 @@ class FilterManager {
61
69
  delays: [],
62
70
  gains: [] // [0.84, 0.83, 0.82, 0.81]
63
71
  }
64
- }
72
+ },
73
+ "high-pass": { // Cuts off frequencies lower than the specified {cutoffFrequency}.
74
+ // "cutoffFrequency": 1475, // Integer, higher than zero, in Hz.
75
+ // "boostFactor": 1.0 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
76
+ },
77
+ "low-pass": { // Cuts off frequencies higher than the specified {cutoffFrequency}.
78
+ // "cutoffFrequency": 284, // Integer, higher than zero, in Hz.
79
+ // "boostFactor": 1.24389 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
80
+ },
81
+ "normalization": { // Attenuates peaking where peaks are defined as having a higher value than {maxAmplitude}.
82
+ // "maxAmplitude": 0.6327, // Float, within the range of 0.0 - 1.0. A value of 0.0 mutes the output.
83
+ // "adaptive": true // false
84
+ },
85
+ "echo": { // Self-explanatory; provides an echo effect.
86
+ // "echoLength": 0.5649, // Float, higher than 0.0, in seconds (1.0 = 1 second).
87
+ // "decay": 0.4649 // Float, within the range of 0.0 - 1.0. A value of 1.0 means no decay, and a value of 0.0 means
88
+ },
65
89
  },
66
90
  channelMix: exports.audioOutputsData.stereo,
67
91
  /*distortion: {
@@ -94,10 +118,18 @@ class FilterManager {
94
118
  delete sendData.tremolo;
95
119
  if (!this.filters.vibrato)
96
120
  delete sendData.vibrato;
97
- if (!this.filters.echo)
121
+ if (!this.filters.lavalinkFilterPlugin.echo)
98
122
  delete sendData.pluginFilters?.["lavalink-filter-plugin"]?.echo;
99
- if (!this.filters.reverb)
123
+ if (!this.filters.lavalinkFilterPlugin.reverb)
100
124
  delete sendData.pluginFilters?.["lavalink-filter-plugin"]?.reverb;
125
+ if (!this.filters.lavalinkLavaDspxPlugin.echo)
126
+ delete sendData.pluginFilters?.echo;
127
+ if (!this.filters.lavalinkLavaDspxPlugin.normalization)
128
+ delete sendData.pluginFilters?.normalization;
129
+ if (!this.filters.lavalinkLavaDspxPlugin.highPass)
130
+ delete sendData.pluginFilters?.["high-pass"];
131
+ if (!this.filters.lavalinkLavaDspxPlugin.lowPass)
132
+ delete sendData.pluginFilters?.["low-pass"];
101
133
  if (sendData.pluginFilters?.["lavalink-filter-plugin"] && Object.values(sendData.pluginFilters?.["lavalink-filter-plugin"]).length === 0)
102
134
  delete sendData.pluginFilters["lavalink-filter-plugin"];
103
135
  if (sendData.pluginFilters && Object.values(sendData.pluginFilters).length === 0)
@@ -121,7 +153,7 @@ class FilterManager {
121
153
  // delete disabled filters
122
154
  if (key === "pluginFilters") {
123
155
  // for(const key of [...Object.keys(sendData.pluginFilters)]) {
124
- // if (this.player.node.info && !this.player.node.info?.plugins?.find?.(v => v.name === key)) delete sendData[key];
156
+ // // if (this.player.node.info && !this.player.node.info?.plugins?.find?.(v => v.name === key)) delete sendData[key];
125
157
  // }
126
158
  }
127
159
  else if (this.player.node.info && !this.player.node.info?.filters?.includes?.(key))
@@ -148,9 +180,13 @@ class FilterManager {
148
180
  this.filters.rotation = this.data.rotation.rotationHz !== 0;
149
181
  this.filters.vibrato = this.data.vibrato.frequency !== 0 || this.data.vibrato.depth !== 0;
150
182
  this.filters.tremolo = this.data.tremolo.frequency !== 0 || this.data.tremolo.depth !== 0;
151
- const lavalinkFilterData = (this.data.pluginFilters?.["lavalink-filter-plugin"] || { echo: { decay: 0, delay: 0 }, reverb: { gains: [], delays: [] } });
152
- this.filters.echo = lavalinkFilterData.echo.decay !== 0 || lavalinkFilterData.echo.delay !== 0;
153
- this.filters.reverb = lavalinkFilterData.reverb?.delays?.length !== 0 || lavalinkFilterData.reverb?.gains?.length !== 0;
183
+ const lavalinkFilterData = (this.data.pluginFilters?.["lavalink-filter-plugin"] || { echo: { decay: this.data.pluginFilters?.echo?.decay && !this.data.pluginFilters?.echo?.echoLength ? this.data.pluginFilters.echo.decay : 0, delay: this.data.pluginFilters?.echo?.delay || 0 }, reverb: { gains: [], delays: [], ...((this.data.pluginFilters.reverb) || {}) } });
184
+ this.filters.lavalinkFilterPlugin.echo = lavalinkFilterData.echo.decay !== 0 || lavalinkFilterData.echo.delay !== 0;
185
+ this.filters.lavalinkFilterPlugin.reverb = lavalinkFilterData.reverb?.delays?.length !== 0 || lavalinkFilterData.reverb?.gains?.length !== 0;
186
+ this.filters.lavalinkLavaDspxPlugin.highPass = Object.values(this.data.pluginFilters["high-pass"] || {}).length > 0;
187
+ this.filters.lavalinkLavaDspxPlugin.lowPass = Object.values(this.data.pluginFilters["low-pass"] || {}).length > 0;
188
+ this.filters.lavalinkLavaDspxPlugin.normalization = Object.values(this.data.pluginFilters.normalization || {}).length > 0;
189
+ this.filters.lavalinkLavaDspxPlugin.echo = Object.values(this.data.pluginFilters.echo || {}).length > 0 && typeof this.data.pluginFilters?.echo?.delay === "undefined";
154
190
  this.filters.lowPass = this.data.lowPass.smoothing !== 0;
155
191
  this.filters.karaoke = Object.values(this.data.karaoke).some(v => v !== 0);
156
192
  if ((this.filters.nightcore || this.filters.vaporwave) && oldFilterTimescale) {
@@ -166,8 +202,12 @@ class FilterManager {
166
202
  * Reset all Filters
167
203
  */
168
204
  async resetFilters() {
169
- this.filters.echo = false;
170
- this.filters.reverb = false;
205
+ this.filters.lavalinkLavaDspxPlugin.echo = false;
206
+ this.filters.lavalinkLavaDspxPlugin.normalization = false;
207
+ this.filters.lavalinkLavaDspxPlugin.highPass = false;
208
+ this.filters.lavalinkLavaDspxPlugin.lowPass = false;
209
+ this.filters.lavalinkFilterPlugin.echo = false;
210
+ this.filters.lavalinkFilterPlugin.reverb = false;
171
211
  this.filters.nightcore = false;
172
212
  this.filters.lowPass = false;
173
213
  this.filters.rotation = false;
@@ -197,14 +237,30 @@ class FilterManager {
197
237
  pluginFilters: {
198
238
  "lavalink-filter-plugin": {
199
239
  echo: {
200
- delay: 0,
201
- decay: 0
240
+ // delay: 0, // in seconds
241
+ // decay: 0 // 0 < 1
202
242
  },
203
243
  reverb: {
204
- delays: [],
205
- gains: []
206
- },
207
- }
244
+ // delays: [], // [0.037, 0.042, 0.048, 0.053]
245
+ // gains: [] // [0.84, 0.83, 0.82, 0.81]
246
+ }
247
+ },
248
+ "high-pass": { // Cuts off frequencies lower than the specified {cutoffFrequency}.
249
+ // "cutoffFrequency": 1475, // Integer, higher than zero, in Hz.
250
+ // "boostFactor": 1.0 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
251
+ },
252
+ "low-pass": { // Cuts off frequencies higher than the specified {cutoffFrequency}.
253
+ // "cutoffFrequency": 284, // Integer, higher than zero, in Hz.
254
+ // "boostFactor": 1.24389 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
255
+ },
256
+ "normalization": { // Attenuates peaking where peaks are defined as having a higher value than {maxAmplitude}.
257
+ // "maxAmplitude": 0.6327, // Float, within the range of 0.0 - 1.0. A value of 0.0 mutes the output.
258
+ // "adaptive": true // false
259
+ },
260
+ "echo": { // Self-explanatory; provides an echo effect.
261
+ // "echoLength": 0.5649, // Float, higher than 0.0, in seconds (1.0 = 1 second).
262
+ // "decay": 0.4649 // Float, within the range of 0.0 - 1.0. A value of 1.0 means no decay, and a value of 0.0 means
263
+ },
208
264
  },
209
265
  rotation: {
210
266
  rotationHz: 0
@@ -372,52 +428,156 @@ class FilterManager {
372
428
  await this.applyPlayerFilters();
373
429
  return this.filters.lowPass;
374
430
  }
375
- /**
376
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
377
- * @param delay
378
- * @param decay
379
- * @returns
380
- */
381
- async toggleEcho(delay = 4, decay = 0.8) {
382
- if (this.player.node.info && !this.player.node.info?.filters?.includes("echo"))
383
- throw new Error("Node#Info#filters does not include the 'echo' Filter (Node has it not enable aka not installed!)");
384
- if (!this.data)
385
- this.data = {};
386
- if (!this.data.pluginFilters)
387
- this.data.pluginFilters = {};
388
- if (!this.data.pluginFilters["lavalink-filter-plugin"])
389
- this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
390
- if (!this.data.pluginFilters["lavalink-filter-plugin"].echo)
391
- this.data.pluginFilters["lavalink-filter-plugin"].echo = { decay: 0, delay: 0 };
392
- this.data.pluginFilters["lavalink-filter-plugin"].echo.delay = this.filters.echo ? 0 : delay;
393
- this.data.pluginFilters["lavalink-filter-plugin"].echo.decay = this.filters.echo ? 0 : decay;
394
- this.filters.echo = !this.filters.echo;
395
- await this.applyPlayerFilters();
396
- return this.filters.echo;
397
- }
398
- /**
399
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
400
- * @param delays
401
- * @param gains
402
- * @returns
403
- */
404
- async toggleReverb(delays = [0.037, 0.042, 0.048, 0.053], gains = [0.84, 0.83, 0.82, 0.81]) {
405
- if (this.player.node.info && !this.player.node.info?.filters?.includes("reverb"))
406
- throw new Error("Node#Info#filters does not include the 'reverb' Filter (Node has it not enable aka not installed!)");
407
- if (!this.data)
408
- this.data = {};
409
- if (!this.data.pluginFilters)
410
- this.data.pluginFilters = {};
411
- if (!this.data.pluginFilters["lavalink-filter-plugin"])
412
- this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
413
- if (!this.data.pluginFilters["lavalink-filter-plugin"].reverb)
414
- this.data.pluginFilters["lavalink-filter-plugin"].reverb = { delays: [], gains: [] };
415
- this.data.pluginFilters["lavalink-filter-plugin"].reverb.delays = this.filters.reverb ? [] : delays;
416
- this.data.pluginFilters["lavalink-filter-plugin"].reverb.gains = this.filters.reverb ? [] : gains;
417
- this.filters.reverb = !this.filters.reverb;
418
- await this.applyPlayerFilters();
419
- return this.filters.reverb;
420
- }
431
+ lavalinkLavaDspxPlugin = {
432
+ toggleLowPass: async (boostFactor = 1.0, cutoffFrequency = 80) => {
433
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
434
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
435
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("low-pass"))
436
+ throw new Error("Node#Info#filters does not include the 'low-pass' Filter (Node has it not enable)");
437
+ if (!this.data)
438
+ this.data = {};
439
+ if (!this.data.pluginFilters)
440
+ this.data.pluginFilters = {};
441
+ if (!this.data.pluginFilters["low-pass"])
442
+ this.data.pluginFilters["low-pass"] = {};
443
+ if (this.filters.lavalinkLavaDspxPlugin.lowPass) {
444
+ delete this.data.pluginFilters["low-pass"];
445
+ }
446
+ else {
447
+ this.data.pluginFilters["low-pass"] = {
448
+ boostFactor: boostFactor,
449
+ cutoffFrequency: cutoffFrequency
450
+ };
451
+ }
452
+ this.filters.lavalinkLavaDspxPlugin.lowPass = !this.filters.lavalinkLavaDspxPlugin.lowPass;
453
+ await this.applyPlayerFilters();
454
+ return this.filters.lavalinkLavaDspxPlugin.lowPass;
455
+ },
456
+ toggleHighPass: async (boostFactor = 1.0, cutoffFrequency = 80) => {
457
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
458
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
459
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("high-pass"))
460
+ throw new Error("Node#Info#filters does not include the 'high-pass' Filter (Node has it not enable)");
461
+ if (!this.data)
462
+ this.data = {};
463
+ if (!this.data.pluginFilters)
464
+ this.data.pluginFilters = {};
465
+ if (!this.data.pluginFilters["high-pass"])
466
+ this.data.pluginFilters["high-pass"] = {};
467
+ if (this.filters.lavalinkLavaDspxPlugin.highPass) {
468
+ delete this.data.pluginFilters["high-pass"];
469
+ }
470
+ else {
471
+ this.data.pluginFilters["high-pass"] = {
472
+ boostFactor: boostFactor,
473
+ cutoffFrequency: cutoffFrequency
474
+ };
475
+ }
476
+ this.filters.lavalinkLavaDspxPlugin.highPass = !this.filters.lavalinkLavaDspxPlugin.highPass;
477
+ await this.applyPlayerFilters();
478
+ return this.filters.lavalinkLavaDspxPlugin.highPass;
479
+ },
480
+ toggleNormalization: async (maxAmplitude = 0.75, adaptive = true) => {
481
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
482
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
483
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("normalization"))
484
+ throw new Error("Node#Info#filters does not include the 'normalization' Filter (Node has it not enable)");
485
+ if (!this.data)
486
+ this.data = {};
487
+ if (!this.data.pluginFilters)
488
+ this.data.pluginFilters = {};
489
+ if (!this.data.pluginFilters.normalization)
490
+ this.data.pluginFilters.normalization = {};
491
+ if (this.filters.lavalinkLavaDspxPlugin.normalization) {
492
+ delete this.data.pluginFilters.normalization;
493
+ }
494
+ else {
495
+ this.data.pluginFilters.normalization = {
496
+ adaptive: adaptive,
497
+ maxAmplitude: maxAmplitude
498
+ };
499
+ }
500
+ this.filters.lavalinkLavaDspxPlugin.normalization = !this.filters.lavalinkLavaDspxPlugin.normalization;
501
+ await this.applyPlayerFilters();
502
+ return this.filters.lavalinkLavaDspxPlugin.normalization;
503
+ },
504
+ toggleEcho: async (decay = 0.5, echoLength = 0.5) => {
505
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
506
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
507
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("echo"))
508
+ throw new Error("Node#Info#filters does not include the 'echo' Filter (Node has it not enable)");
509
+ if (!this.data)
510
+ this.data = {};
511
+ if (!this.data.pluginFilters)
512
+ this.data.pluginFilters = {};
513
+ if (!this.data.pluginFilters.echo)
514
+ this.data.pluginFilters.echo = {};
515
+ if (this.filters.lavalinkLavaDspxPlugin.echo) {
516
+ delete this.data.pluginFilters.echo;
517
+ }
518
+ else {
519
+ this.data.pluginFilters.echo = {
520
+ decay: decay,
521
+ echoLength: echoLength
522
+ };
523
+ }
524
+ this.filters.lavalinkLavaDspxPlugin.echo = !this.filters.lavalinkLavaDspxPlugin.echo;
525
+ await this.applyPlayerFilters();
526
+ return this.filters.lavalinkLavaDspxPlugin.echo;
527
+ }
528
+ };
529
+ lavalinkFilterPlugin = {
530
+ /**
531
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
532
+ * @param delay
533
+ * @param decay
534
+ * @returns
535
+ */
536
+ toggleEcho: async (delay = 4, decay = 0.8) => {
537
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavalink-filter-plugin"))
538
+ throw new Error("Node#Info#plugins does not include the lavalink-filter-plugin plugin");
539
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("echo"))
540
+ throw new Error("Node#Info#filters does not include the 'echo' Filter (Node has it not enable aka not installed!)");
541
+ if (!this.data)
542
+ this.data = {};
543
+ if (!this.data.pluginFilters)
544
+ this.data.pluginFilters = {};
545
+ if (!this.data.pluginFilters["lavalink-filter-plugin"])
546
+ this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
547
+ if (!this.data.pluginFilters["lavalink-filter-plugin"].echo)
548
+ this.data.pluginFilters["lavalink-filter-plugin"].echo = { decay: 0, delay: 0 };
549
+ this.data.pluginFilters["lavalink-filter-plugin"].echo.delay = this.filters.lavalinkFilterPlugin.echo ? 0 : delay;
550
+ this.data.pluginFilters["lavalink-filter-plugin"].echo.decay = this.filters.lavalinkFilterPlugin.echo ? 0 : decay;
551
+ this.filters.lavalinkFilterPlugin.echo = !this.filters.lavalinkFilterPlugin.echo;
552
+ await this.applyPlayerFilters();
553
+ return this.filters.lavalinkFilterPlugin.echo;
554
+ },
555
+ /**
556
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
557
+ * @param delays
558
+ * @param gains
559
+ * @returns
560
+ */
561
+ toggleReverb: async (delays = [0.037, 0.042, 0.048, 0.053], gains = [0.84, 0.83, 0.82, 0.81]) => {
562
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavalink-filter-plugin"))
563
+ throw new Error("Node#Info#plugins does not include the lavalink-filter-plugin plugin");
564
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("reverb"))
565
+ throw new Error("Node#Info#filters does not include the 'reverb' Filter (Node has it not enable aka not installed!)");
566
+ if (!this.data)
567
+ this.data = {};
568
+ if (!this.data.pluginFilters)
569
+ this.data.pluginFilters = {};
570
+ if (!this.data.pluginFilters["lavalink-filter-plugin"])
571
+ this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
572
+ if (!this.data.pluginFilters["lavalink-filter-plugin"].reverb)
573
+ this.data.pluginFilters["lavalink-filter-plugin"].reverb = { delays: [], gains: [] };
574
+ this.data.pluginFilters["lavalink-filter-plugin"].reverb.delays = this.filters.lavalinkFilterPlugin.reverb ? [] : delays;
575
+ this.data.pluginFilters["lavalink-filter-plugin"].reverb.gains = this.filters.lavalinkFilterPlugin.reverb ? [] : gains;
576
+ this.filters.lavalinkFilterPlugin.reverb = !this.filters.lavalinkFilterPlugin.reverb;
577
+ await this.applyPlayerFilters();
578
+ return this.filters.lavalinkFilterPlugin.reverb;
579
+ }
580
+ };
421
581
  /**
422
582
  * Enables / Disabels a Nightcore-like filter Effect. Disables/Overwrides both: custom and Vaporwave Filter
423
583
  * @param speed
@@ -663,7 +663,7 @@ class LavalinkNode {
663
663
  return this.NodeManager.LavalinkManager.options.autoSkip && player.play({ noReplace: true });
664
664
  }
665
665
  // remove tracks from the queue
666
- if (player.repeatMode !== "track")
666
+ if (player.repeatMode !== "track" || player.get("internal_skipped"))
667
667
  await (0, Utils_1.queueTrackEnd)(player);
668
668
  else if (player.queue.current) { // If there was a current Track already and repeatmode === true, add it to the queue.
669
669
  player.queue.previous.unshift(player.queue.current);
@@ -671,6 +671,7 @@ class LavalinkNode {
671
671
  player.queue.previous.splice(player.queue.options.maxPreviousTracks, player.queue.previous.length);
672
672
  await player.queue.utils.save();
673
673
  }
674
+ player.set("internal_skipped", false);
674
675
  // if no track available, end queue
675
676
  if (!player.queue.current)
676
677
  return this.queueEnd(player, track, payload);
@@ -333,6 +333,7 @@ class Player {
333
333
  if (!this.playing)
334
334
  return await this.play();
335
335
  const now = performance.now();
336
+ this.set("internal_skipped", true);
336
337
  await this.node.updatePlayer({ guildId: this.guildId, playerOptions: { track: { encoded: null } } });
337
338
  this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
338
339
  return this;
@@ -86,20 +86,28 @@ export declare class FilterManager {
86
86
  * @returns
87
87
  */
88
88
  toggleLowPass(smoothing?: number): Promise<boolean>;
89
- /**
90
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
91
- * @param delay
92
- * @param decay
93
- * @returns
94
- */
95
- toggleEcho(delay?: number, decay?: number): Promise<boolean>;
96
- /**
97
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
98
- * @param delays
99
- * @param gains
100
- * @returns
101
- */
102
- toggleReverb(delays?: number[], gains?: number[]): Promise<boolean>;
89
+ lavalinkLavaDspxPlugin: {
90
+ toggleLowPass: (boostFactor?: number, cutoffFrequency?: number) => Promise<boolean>;
91
+ toggleHighPass: (boostFactor?: number, cutoffFrequency?: number) => Promise<boolean>;
92
+ toggleNormalization: (maxAmplitude?: number, adaptive?: boolean) => Promise<boolean>;
93
+ toggleEcho: (decay?: number, echoLength?: number) => Promise<boolean>;
94
+ };
95
+ lavalinkFilterPlugin: {
96
+ /**
97
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
98
+ * @param delay
99
+ * @param decay
100
+ * @returns
101
+ */
102
+ toggleEcho: (delay?: number, decay?: number) => Promise<boolean>;
103
+ /**
104
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
105
+ * @param delays
106
+ * @param gains
107
+ * @returns
108
+ */
109
+ toggleReverb: (delays?: number[], gains?: number[]) => Promise<boolean>;
110
+ };
103
111
  /**
104
112
  * Enables / Disabels a Nightcore-like filter Effect. Disables/Overwrides both: custom and Vaporwave Filter
105
113
  * @param speed
@@ -160,10 +168,23 @@ export interface PlayerFilters {
160
168
  audioOutput: AudioOutputs;
161
169
  /** Lavalink Volume FILTER (not player Volume, think of it as a gain booster) */
162
170
  volume: boolean;
163
- /** only with the custom lavalink filter plugin */
164
- echo: boolean;
165
- /** only with the custom lavalink filter plugin */
166
- reverb: boolean;
171
+ /** Filters for the Lavalink Filter Plugin */
172
+ lavalinkFilterPlugin: {
173
+ /** if echo filter is enabled / not */
174
+ echo: boolean;
175
+ /** if reverb filter is enabled / not */
176
+ reverb: boolean;
177
+ };
178
+ lavalinkLavaDspxPlugin: {
179
+ /** if lowPass filter is enabled / not */
180
+ lowPass: boolean;
181
+ /** if highPass filter is enabled / not */
182
+ highPass: boolean;
183
+ /** if normalization filter is enabled / not */
184
+ normalization: boolean;
185
+ /** if echo filter is enabled / not */
186
+ echo: boolean;
187
+ };
167
188
  }
168
189
  /**
169
190
  * There are 15 bands (0-14) that can be changed.
@@ -174,9 +195,9 @@ export interface PlayerFilters {
174
195
  */
175
196
  export interface EQBand {
176
197
  /** On what band position (0-14) it should work */
177
- band: IntegerNumber;
198
+ band: IntegerNumber | number;
178
199
  /** The gain (-0.25 to 1.0) */
179
- gain: FloatNumber;
200
+ gain: FloatNumber | number;
180
201
  }
181
202
  /**
182
203
  * Uses equalization to eliminate part of a band, usually targeting vocals.
@@ -265,20 +286,6 @@ export interface LowPassFilter {
265
286
  /** The smoothing factor (1.0 < x) */
266
287
  smoothing?: number;
267
288
  }
268
- /**
269
- * A Plugin Filter
270
- */
271
- export interface EchoFilter {
272
- delay: number;
273
- decay: number;
274
- }
275
- /**
276
- * A Plugin Filter
277
- */
278
- export interface ReverbFilter {
279
- delays: number[];
280
- gains: number[];
281
- }
282
289
  /**
283
290
  * Filter Data stored in the Client and partially sent to Lavalink
284
291
  */
@@ -292,15 +299,34 @@ export interface FilterData {
292
299
  distortion?: DistortionFilter;
293
300
  channelMix?: ChannelMixFilter;
294
301
  lowPass?: LowPassFilter;
295
- pluginFilters?: Record<PluginFiltersKey, PluginFiltersValues>;
296
- }
297
- export type PluginFiltersKey = "lavalink-filter-plugin" | string;
298
- export interface PluginFiltersValues extends LavalinkFiltersPlugin {
299
- [key: string]: string | number | string[] | number[] | EchoFilter | ReverbFilter;
300
- }
301
- export interface LavalinkFiltersPlugin {
302
- "echo": EchoFilter;
303
- "reverb": ReverbFilter;
302
+ pluginFilters?: {
303
+ "lavalink-filter-plugin"?: {
304
+ "echo"?: {
305
+ delay?: number;
306
+ decay?: number;
307
+ };
308
+ "reverb"?: {
309
+ delays?: number[];
310
+ gains?: number[];
311
+ };
312
+ };
313
+ "high-pass"?: {
314
+ cutoffFrequency?: number;
315
+ boostFactor?: number;
316
+ };
317
+ "low-pass"?: {
318
+ cutoffFrequency?: number;
319
+ boostFactor?: number;
320
+ };
321
+ normalization?: {
322
+ maxAmplitude?: number;
323
+ adaptive?: boolean;
324
+ };
325
+ echo?: {
326
+ echoLength?: number;
327
+ decay?: number;
328
+ };
329
+ };
304
330
  }
305
331
  /**
306
332
  * Actual Filter Data sent to Lavalink
@@ -12,13 +12,21 @@ export class FilterManager {
12
12
  vaporwave: false,
13
13
  custom: false,
14
14
  nightcore: false,
15
- echo: false,
16
- reverb: false,
17
15
  rotation: false,
18
16
  karaoke: false,
19
17
  tremolo: false,
20
18
  vibrato: false,
21
19
  lowPass: false,
20
+ lavalinkFilterPlugin: {
21
+ echo: false,
22
+ reverb: false,
23
+ },
24
+ lavalinkLavaDspxPlugin: {
25
+ lowPass: false,
26
+ highPass: false,
27
+ normalization: false,
28
+ echo: false,
29
+ },
22
30
  audioOutput: "stereo",
23
31
  };
24
32
  /** The Filter Data sent to Lavalink, only if the filter is enabled (ofc.) */
@@ -58,7 +66,23 @@ export class FilterManager {
58
66
  delays: [],
59
67
  gains: [] // [0.84, 0.83, 0.82, 0.81]
60
68
  }
61
- }
69
+ },
70
+ "high-pass": { // Cuts off frequencies lower than the specified {cutoffFrequency}.
71
+ // "cutoffFrequency": 1475, // Integer, higher than zero, in Hz.
72
+ // "boostFactor": 1.0 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
73
+ },
74
+ "low-pass": { // Cuts off frequencies higher than the specified {cutoffFrequency}.
75
+ // "cutoffFrequency": 284, // Integer, higher than zero, in Hz.
76
+ // "boostFactor": 1.24389 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
77
+ },
78
+ "normalization": { // Attenuates peaking where peaks are defined as having a higher value than {maxAmplitude}.
79
+ // "maxAmplitude": 0.6327, // Float, within the range of 0.0 - 1.0. A value of 0.0 mutes the output.
80
+ // "adaptive": true // false
81
+ },
82
+ "echo": { // Self-explanatory; provides an echo effect.
83
+ // "echoLength": 0.5649, // Float, higher than 0.0, in seconds (1.0 = 1 second).
84
+ // "decay": 0.4649 // Float, within the range of 0.0 - 1.0. A value of 1.0 means no decay, and a value of 0.0 means
85
+ },
62
86
  },
63
87
  channelMix: audioOutputsData.stereo,
64
88
  /*distortion: {
@@ -91,10 +115,18 @@ export class FilterManager {
91
115
  delete sendData.tremolo;
92
116
  if (!this.filters.vibrato)
93
117
  delete sendData.vibrato;
94
- if (!this.filters.echo)
118
+ if (!this.filters.lavalinkFilterPlugin.echo)
95
119
  delete sendData.pluginFilters?.["lavalink-filter-plugin"]?.echo;
96
- if (!this.filters.reverb)
120
+ if (!this.filters.lavalinkFilterPlugin.reverb)
97
121
  delete sendData.pluginFilters?.["lavalink-filter-plugin"]?.reverb;
122
+ if (!this.filters.lavalinkLavaDspxPlugin.echo)
123
+ delete sendData.pluginFilters?.echo;
124
+ if (!this.filters.lavalinkLavaDspxPlugin.normalization)
125
+ delete sendData.pluginFilters?.normalization;
126
+ if (!this.filters.lavalinkLavaDspxPlugin.highPass)
127
+ delete sendData.pluginFilters?.["high-pass"];
128
+ if (!this.filters.lavalinkLavaDspxPlugin.lowPass)
129
+ delete sendData.pluginFilters?.["low-pass"];
98
130
  if (sendData.pluginFilters?.["lavalink-filter-plugin"] && Object.values(sendData.pluginFilters?.["lavalink-filter-plugin"]).length === 0)
99
131
  delete sendData.pluginFilters["lavalink-filter-plugin"];
100
132
  if (sendData.pluginFilters && Object.values(sendData.pluginFilters).length === 0)
@@ -118,7 +150,7 @@ export class FilterManager {
118
150
  // delete disabled filters
119
151
  if (key === "pluginFilters") {
120
152
  // for(const key of [...Object.keys(sendData.pluginFilters)]) {
121
- // if (this.player.node.info && !this.player.node.info?.plugins?.find?.(v => v.name === key)) delete sendData[key];
153
+ // // if (this.player.node.info && !this.player.node.info?.plugins?.find?.(v => v.name === key)) delete sendData[key];
122
154
  // }
123
155
  }
124
156
  else if (this.player.node.info && !this.player.node.info?.filters?.includes?.(key))
@@ -145,9 +177,13 @@ export class FilterManager {
145
177
  this.filters.rotation = this.data.rotation.rotationHz !== 0;
146
178
  this.filters.vibrato = this.data.vibrato.frequency !== 0 || this.data.vibrato.depth !== 0;
147
179
  this.filters.tremolo = this.data.tremolo.frequency !== 0 || this.data.tremolo.depth !== 0;
148
- const lavalinkFilterData = (this.data.pluginFilters?.["lavalink-filter-plugin"] || { echo: { decay: 0, delay: 0 }, reverb: { gains: [], delays: [] } });
149
- this.filters.echo = lavalinkFilterData.echo.decay !== 0 || lavalinkFilterData.echo.delay !== 0;
150
- this.filters.reverb = lavalinkFilterData.reverb?.delays?.length !== 0 || lavalinkFilterData.reverb?.gains?.length !== 0;
180
+ const lavalinkFilterData = (this.data.pluginFilters?.["lavalink-filter-plugin"] || { echo: { decay: this.data.pluginFilters?.echo?.decay && !this.data.pluginFilters?.echo?.echoLength ? this.data.pluginFilters.echo.decay : 0, delay: this.data.pluginFilters?.echo?.delay || 0 }, reverb: { gains: [], delays: [], ...((this.data.pluginFilters.reverb) || {}) } });
181
+ this.filters.lavalinkFilterPlugin.echo = lavalinkFilterData.echo.decay !== 0 || lavalinkFilterData.echo.delay !== 0;
182
+ this.filters.lavalinkFilterPlugin.reverb = lavalinkFilterData.reverb?.delays?.length !== 0 || lavalinkFilterData.reverb?.gains?.length !== 0;
183
+ this.filters.lavalinkLavaDspxPlugin.highPass = Object.values(this.data.pluginFilters["high-pass"] || {}).length > 0;
184
+ this.filters.lavalinkLavaDspxPlugin.lowPass = Object.values(this.data.pluginFilters["low-pass"] || {}).length > 0;
185
+ this.filters.lavalinkLavaDspxPlugin.normalization = Object.values(this.data.pluginFilters.normalization || {}).length > 0;
186
+ this.filters.lavalinkLavaDspxPlugin.echo = Object.values(this.data.pluginFilters.echo || {}).length > 0 && typeof this.data.pluginFilters?.echo?.delay === "undefined";
151
187
  this.filters.lowPass = this.data.lowPass.smoothing !== 0;
152
188
  this.filters.karaoke = Object.values(this.data.karaoke).some(v => v !== 0);
153
189
  if ((this.filters.nightcore || this.filters.vaporwave) && oldFilterTimescale) {
@@ -163,8 +199,12 @@ export class FilterManager {
163
199
  * Reset all Filters
164
200
  */
165
201
  async resetFilters() {
166
- this.filters.echo = false;
167
- this.filters.reverb = false;
202
+ this.filters.lavalinkLavaDspxPlugin.echo = false;
203
+ this.filters.lavalinkLavaDspxPlugin.normalization = false;
204
+ this.filters.lavalinkLavaDspxPlugin.highPass = false;
205
+ this.filters.lavalinkLavaDspxPlugin.lowPass = false;
206
+ this.filters.lavalinkFilterPlugin.echo = false;
207
+ this.filters.lavalinkFilterPlugin.reverb = false;
168
208
  this.filters.nightcore = false;
169
209
  this.filters.lowPass = false;
170
210
  this.filters.rotation = false;
@@ -194,14 +234,30 @@ export class FilterManager {
194
234
  pluginFilters: {
195
235
  "lavalink-filter-plugin": {
196
236
  echo: {
197
- delay: 0,
198
- decay: 0
237
+ // delay: 0, // in seconds
238
+ // decay: 0 // 0 < 1
199
239
  },
200
240
  reverb: {
201
- delays: [],
202
- gains: []
203
- },
204
- }
241
+ // delays: [], // [0.037, 0.042, 0.048, 0.053]
242
+ // gains: [] // [0.84, 0.83, 0.82, 0.81]
243
+ }
244
+ },
245
+ "high-pass": { // Cuts off frequencies lower than the specified {cutoffFrequency}.
246
+ // "cutoffFrequency": 1475, // Integer, higher than zero, in Hz.
247
+ // "boostFactor": 1.0 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
248
+ },
249
+ "low-pass": { // Cuts off frequencies higher than the specified {cutoffFrequency}.
250
+ // "cutoffFrequency": 284, // Integer, higher than zero, in Hz.
251
+ // "boostFactor": 1.24389 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
252
+ },
253
+ "normalization": { // Attenuates peaking where peaks are defined as having a higher value than {maxAmplitude}.
254
+ // "maxAmplitude": 0.6327, // Float, within the range of 0.0 - 1.0. A value of 0.0 mutes the output.
255
+ // "adaptive": true // false
256
+ },
257
+ "echo": { // Self-explanatory; provides an echo effect.
258
+ // "echoLength": 0.5649, // Float, higher than 0.0, in seconds (1.0 = 1 second).
259
+ // "decay": 0.4649 // Float, within the range of 0.0 - 1.0. A value of 1.0 means no decay, and a value of 0.0 means
260
+ },
205
261
  },
206
262
  rotation: {
207
263
  rotationHz: 0
@@ -369,52 +425,156 @@ export class FilterManager {
369
425
  await this.applyPlayerFilters();
370
426
  return this.filters.lowPass;
371
427
  }
372
- /**
373
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
374
- * @param delay
375
- * @param decay
376
- * @returns
377
- */
378
- async toggleEcho(delay = 4, decay = 0.8) {
379
- if (this.player.node.info && !this.player.node.info?.filters?.includes("echo"))
380
- throw new Error("Node#Info#filters does not include the 'echo' Filter (Node has it not enable aka not installed!)");
381
- if (!this.data)
382
- this.data = {};
383
- if (!this.data.pluginFilters)
384
- this.data.pluginFilters = {};
385
- if (!this.data.pluginFilters["lavalink-filter-plugin"])
386
- this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
387
- if (!this.data.pluginFilters["lavalink-filter-plugin"].echo)
388
- this.data.pluginFilters["lavalink-filter-plugin"].echo = { decay: 0, delay: 0 };
389
- this.data.pluginFilters["lavalink-filter-plugin"].echo.delay = this.filters.echo ? 0 : delay;
390
- this.data.pluginFilters["lavalink-filter-plugin"].echo.decay = this.filters.echo ? 0 : decay;
391
- this.filters.echo = !this.filters.echo;
392
- await this.applyPlayerFilters();
393
- return this.filters.echo;
394
- }
395
- /**
396
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
397
- * @param delays
398
- * @param gains
399
- * @returns
400
- */
401
- async toggleReverb(delays = [0.037, 0.042, 0.048, 0.053], gains = [0.84, 0.83, 0.82, 0.81]) {
402
- if (this.player.node.info && !this.player.node.info?.filters?.includes("reverb"))
403
- throw new Error("Node#Info#filters does not include the 'reverb' Filter (Node has it not enable aka not installed!)");
404
- if (!this.data)
405
- this.data = {};
406
- if (!this.data.pluginFilters)
407
- this.data.pluginFilters = {};
408
- if (!this.data.pluginFilters["lavalink-filter-plugin"])
409
- this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
410
- if (!this.data.pluginFilters["lavalink-filter-plugin"].reverb)
411
- this.data.pluginFilters["lavalink-filter-plugin"].reverb = { delays: [], gains: [] };
412
- this.data.pluginFilters["lavalink-filter-plugin"].reverb.delays = this.filters.reverb ? [] : delays;
413
- this.data.pluginFilters["lavalink-filter-plugin"].reverb.gains = this.filters.reverb ? [] : gains;
414
- this.filters.reverb = !this.filters.reverb;
415
- await this.applyPlayerFilters();
416
- return this.filters.reverb;
417
- }
428
+ lavalinkLavaDspxPlugin = {
429
+ toggleLowPass: async (boostFactor = 1.0, cutoffFrequency = 80) => {
430
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
431
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
432
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("low-pass"))
433
+ throw new Error("Node#Info#filters does not include the 'low-pass' Filter (Node has it not enable)");
434
+ if (!this.data)
435
+ this.data = {};
436
+ if (!this.data.pluginFilters)
437
+ this.data.pluginFilters = {};
438
+ if (!this.data.pluginFilters["low-pass"])
439
+ this.data.pluginFilters["low-pass"] = {};
440
+ if (this.filters.lavalinkLavaDspxPlugin.lowPass) {
441
+ delete this.data.pluginFilters["low-pass"];
442
+ }
443
+ else {
444
+ this.data.pluginFilters["low-pass"] = {
445
+ boostFactor: boostFactor,
446
+ cutoffFrequency: cutoffFrequency
447
+ };
448
+ }
449
+ this.filters.lavalinkLavaDspxPlugin.lowPass = !this.filters.lavalinkLavaDspxPlugin.lowPass;
450
+ await this.applyPlayerFilters();
451
+ return this.filters.lavalinkLavaDspxPlugin.lowPass;
452
+ },
453
+ toggleHighPass: async (boostFactor = 1.0, cutoffFrequency = 80) => {
454
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
455
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
456
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("high-pass"))
457
+ throw new Error("Node#Info#filters does not include the 'high-pass' Filter (Node has it not enable)");
458
+ if (!this.data)
459
+ this.data = {};
460
+ if (!this.data.pluginFilters)
461
+ this.data.pluginFilters = {};
462
+ if (!this.data.pluginFilters["high-pass"])
463
+ this.data.pluginFilters["high-pass"] = {};
464
+ if (this.filters.lavalinkLavaDspxPlugin.highPass) {
465
+ delete this.data.pluginFilters["high-pass"];
466
+ }
467
+ else {
468
+ this.data.pluginFilters["high-pass"] = {
469
+ boostFactor: boostFactor,
470
+ cutoffFrequency: cutoffFrequency
471
+ };
472
+ }
473
+ this.filters.lavalinkLavaDspxPlugin.highPass = !this.filters.lavalinkLavaDspxPlugin.highPass;
474
+ await this.applyPlayerFilters();
475
+ return this.filters.lavalinkLavaDspxPlugin.highPass;
476
+ },
477
+ toggleNormalization: async (maxAmplitude = 0.75, adaptive = true) => {
478
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
479
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
480
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("normalization"))
481
+ throw new Error("Node#Info#filters does not include the 'normalization' Filter (Node has it not enable)");
482
+ if (!this.data)
483
+ this.data = {};
484
+ if (!this.data.pluginFilters)
485
+ this.data.pluginFilters = {};
486
+ if (!this.data.pluginFilters.normalization)
487
+ this.data.pluginFilters.normalization = {};
488
+ if (this.filters.lavalinkLavaDspxPlugin.normalization) {
489
+ delete this.data.pluginFilters.normalization;
490
+ }
491
+ else {
492
+ this.data.pluginFilters.normalization = {
493
+ adaptive: adaptive,
494
+ maxAmplitude: maxAmplitude
495
+ };
496
+ }
497
+ this.filters.lavalinkLavaDspxPlugin.normalization = !this.filters.lavalinkLavaDspxPlugin.normalization;
498
+ await this.applyPlayerFilters();
499
+ return this.filters.lavalinkLavaDspxPlugin.normalization;
500
+ },
501
+ toggleEcho: async (decay = 0.5, echoLength = 0.5) => {
502
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
503
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
504
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("echo"))
505
+ throw new Error("Node#Info#filters does not include the 'echo' Filter (Node has it not enable)");
506
+ if (!this.data)
507
+ this.data = {};
508
+ if (!this.data.pluginFilters)
509
+ this.data.pluginFilters = {};
510
+ if (!this.data.pluginFilters.echo)
511
+ this.data.pluginFilters.echo = {};
512
+ if (this.filters.lavalinkLavaDspxPlugin.echo) {
513
+ delete this.data.pluginFilters.echo;
514
+ }
515
+ else {
516
+ this.data.pluginFilters.echo = {
517
+ decay: decay,
518
+ echoLength: echoLength
519
+ };
520
+ }
521
+ this.filters.lavalinkLavaDspxPlugin.echo = !this.filters.lavalinkLavaDspxPlugin.echo;
522
+ await this.applyPlayerFilters();
523
+ return this.filters.lavalinkLavaDspxPlugin.echo;
524
+ }
525
+ };
526
+ lavalinkFilterPlugin = {
527
+ /**
528
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
529
+ * @param delay
530
+ * @param decay
531
+ * @returns
532
+ */
533
+ toggleEcho: async (delay = 4, decay = 0.8) => {
534
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavalink-filter-plugin"))
535
+ throw new Error("Node#Info#plugins does not include the lavalink-filter-plugin plugin");
536
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("echo"))
537
+ throw new Error("Node#Info#filters does not include the 'echo' Filter (Node has it not enable aka not installed!)");
538
+ if (!this.data)
539
+ this.data = {};
540
+ if (!this.data.pluginFilters)
541
+ this.data.pluginFilters = {};
542
+ if (!this.data.pluginFilters["lavalink-filter-plugin"])
543
+ this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
544
+ if (!this.data.pluginFilters["lavalink-filter-plugin"].echo)
545
+ this.data.pluginFilters["lavalink-filter-plugin"].echo = { decay: 0, delay: 0 };
546
+ this.data.pluginFilters["lavalink-filter-plugin"].echo.delay = this.filters.lavalinkFilterPlugin.echo ? 0 : delay;
547
+ this.data.pluginFilters["lavalink-filter-plugin"].echo.decay = this.filters.lavalinkFilterPlugin.echo ? 0 : decay;
548
+ this.filters.lavalinkFilterPlugin.echo = !this.filters.lavalinkFilterPlugin.echo;
549
+ await this.applyPlayerFilters();
550
+ return this.filters.lavalinkFilterPlugin.echo;
551
+ },
552
+ /**
553
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
554
+ * @param delays
555
+ * @param gains
556
+ * @returns
557
+ */
558
+ toggleReverb: async (delays = [0.037, 0.042, 0.048, 0.053], gains = [0.84, 0.83, 0.82, 0.81]) => {
559
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavalink-filter-plugin"))
560
+ throw new Error("Node#Info#plugins does not include the lavalink-filter-plugin plugin");
561
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("reverb"))
562
+ throw new Error("Node#Info#filters does not include the 'reverb' Filter (Node has it not enable aka not installed!)");
563
+ if (!this.data)
564
+ this.data = {};
565
+ if (!this.data.pluginFilters)
566
+ this.data.pluginFilters = {};
567
+ if (!this.data.pluginFilters["lavalink-filter-plugin"])
568
+ this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
569
+ if (!this.data.pluginFilters["lavalink-filter-plugin"].reverb)
570
+ this.data.pluginFilters["lavalink-filter-plugin"].reverb = { delays: [], gains: [] };
571
+ this.data.pluginFilters["lavalink-filter-plugin"].reverb.delays = this.filters.lavalinkFilterPlugin.reverb ? [] : delays;
572
+ this.data.pluginFilters["lavalink-filter-plugin"].reverb.gains = this.filters.lavalinkFilterPlugin.reverb ? [] : gains;
573
+ this.filters.lavalinkFilterPlugin.reverb = !this.filters.lavalinkFilterPlugin.reverb;
574
+ await this.applyPlayerFilters();
575
+ return this.filters.lavalinkFilterPlugin.reverb;
576
+ }
577
+ };
418
578
  /**
419
579
  * Enables / Disabels a Nightcore-like filter Effect. Disables/Overwrides both: custom and Vaporwave Filter
420
580
  * @param speed
@@ -659,7 +659,7 @@ export class LavalinkNode {
659
659
  return this.NodeManager.LavalinkManager.options.autoSkip && player.play({ noReplace: true });
660
660
  }
661
661
  // remove tracks from the queue
662
- if (player.repeatMode !== "track")
662
+ if (player.repeatMode !== "track" || player.get("internal_skipped"))
663
663
  await queueTrackEnd(player);
664
664
  else if (player.queue.current) { // If there was a current Track already and repeatmode === true, add it to the queue.
665
665
  player.queue.previous.unshift(player.queue.current);
@@ -667,6 +667,7 @@ export class LavalinkNode {
667
667
  player.queue.previous.splice(player.queue.options.maxPreviousTracks, player.queue.previous.length);
668
668
  await player.queue.utils.save();
669
669
  }
670
+ player.set("internal_skipped", false);
670
671
  // if no track available, end queue
671
672
  if (!player.queue.current)
672
673
  return this.queueEnd(player, track, payload);
@@ -330,6 +330,7 @@ export class Player {
330
330
  if (!this.playing)
331
331
  return await this.play();
332
332
  const now = performance.now();
333
+ this.set("internal_skipped", true);
333
334
  await this.node.updatePlayer({ guildId: this.guildId, playerOptions: { track: { encoded: null } } });
334
335
  this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
335
336
  return this;
@@ -86,20 +86,28 @@ export declare class FilterManager {
86
86
  * @returns
87
87
  */
88
88
  toggleLowPass(smoothing?: number): Promise<boolean>;
89
- /**
90
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
91
- * @param delay
92
- * @param decay
93
- * @returns
94
- */
95
- toggleEcho(delay?: number, decay?: number): Promise<boolean>;
96
- /**
97
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
98
- * @param delays
99
- * @param gains
100
- * @returns
101
- */
102
- toggleReverb(delays?: number[], gains?: number[]): Promise<boolean>;
89
+ lavalinkLavaDspxPlugin: {
90
+ toggleLowPass: (boostFactor?: number, cutoffFrequency?: number) => Promise<boolean>;
91
+ toggleHighPass: (boostFactor?: number, cutoffFrequency?: number) => Promise<boolean>;
92
+ toggleNormalization: (maxAmplitude?: number, adaptive?: boolean) => Promise<boolean>;
93
+ toggleEcho: (decay?: number, echoLength?: number) => Promise<boolean>;
94
+ };
95
+ lavalinkFilterPlugin: {
96
+ /**
97
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
98
+ * @param delay
99
+ * @param decay
100
+ * @returns
101
+ */
102
+ toggleEcho: (delay?: number, decay?: number) => Promise<boolean>;
103
+ /**
104
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
105
+ * @param delays
106
+ * @param gains
107
+ * @returns
108
+ */
109
+ toggleReverb: (delays?: number[], gains?: number[]) => Promise<boolean>;
110
+ };
103
111
  /**
104
112
  * Enables / Disabels a Nightcore-like filter Effect. Disables/Overwrides both: custom and Vaporwave Filter
105
113
  * @param speed
@@ -160,10 +168,23 @@ export interface PlayerFilters {
160
168
  audioOutput: AudioOutputs;
161
169
  /** Lavalink Volume FILTER (not player Volume, think of it as a gain booster) */
162
170
  volume: boolean;
163
- /** only with the custom lavalink filter plugin */
164
- echo: boolean;
165
- /** only with the custom lavalink filter plugin */
166
- reverb: boolean;
171
+ /** Filters for the Lavalink Filter Plugin */
172
+ lavalinkFilterPlugin: {
173
+ /** if echo filter is enabled / not */
174
+ echo: boolean;
175
+ /** if reverb filter is enabled / not */
176
+ reverb: boolean;
177
+ };
178
+ lavalinkLavaDspxPlugin: {
179
+ /** if lowPass filter is enabled / not */
180
+ lowPass: boolean;
181
+ /** if highPass filter is enabled / not */
182
+ highPass: boolean;
183
+ /** if normalization filter is enabled / not */
184
+ normalization: boolean;
185
+ /** if echo filter is enabled / not */
186
+ echo: boolean;
187
+ };
167
188
  }
168
189
  /**
169
190
  * There are 15 bands (0-14) that can be changed.
@@ -174,9 +195,9 @@ export interface PlayerFilters {
174
195
  */
175
196
  export interface EQBand {
176
197
  /** On what band position (0-14) it should work */
177
- band: IntegerNumber;
198
+ band: IntegerNumber | number;
178
199
  /** The gain (-0.25 to 1.0) */
179
- gain: FloatNumber;
200
+ gain: FloatNumber | number;
180
201
  }
181
202
  /**
182
203
  * Uses equalization to eliminate part of a band, usually targeting vocals.
@@ -265,20 +286,6 @@ export interface LowPassFilter {
265
286
  /** The smoothing factor (1.0 < x) */
266
287
  smoothing?: number;
267
288
  }
268
- /**
269
- * A Plugin Filter
270
- */
271
- export interface EchoFilter {
272
- delay: number;
273
- decay: number;
274
- }
275
- /**
276
- * A Plugin Filter
277
- */
278
- export interface ReverbFilter {
279
- delays: number[];
280
- gains: number[];
281
- }
282
289
  /**
283
290
  * Filter Data stored in the Client and partially sent to Lavalink
284
291
  */
@@ -292,15 +299,34 @@ export interface FilterData {
292
299
  distortion?: DistortionFilter;
293
300
  channelMix?: ChannelMixFilter;
294
301
  lowPass?: LowPassFilter;
295
- pluginFilters?: Record<PluginFiltersKey, PluginFiltersValues>;
296
- }
297
- export type PluginFiltersKey = "lavalink-filter-plugin" | string;
298
- export interface PluginFiltersValues extends LavalinkFiltersPlugin {
299
- [key: string]: string | number | string[] | number[] | EchoFilter | ReverbFilter;
300
- }
301
- export interface LavalinkFiltersPlugin {
302
- "echo": EchoFilter;
303
- "reverb": ReverbFilter;
302
+ pluginFilters?: {
303
+ "lavalink-filter-plugin"?: {
304
+ "echo"?: {
305
+ delay?: number;
306
+ decay?: number;
307
+ };
308
+ "reverb"?: {
309
+ delays?: number[];
310
+ gains?: number[];
311
+ };
312
+ };
313
+ "high-pass"?: {
314
+ cutoffFrequency?: number;
315
+ boostFactor?: number;
316
+ };
317
+ "low-pass"?: {
318
+ cutoffFrequency?: number;
319
+ boostFactor?: number;
320
+ };
321
+ normalization?: {
322
+ maxAmplitude?: number;
323
+ adaptive?: boolean;
324
+ };
325
+ echo?: {
326
+ echoLength?: number;
327
+ decay?: number;
328
+ };
329
+ };
304
330
  }
305
331
  /**
306
332
  * Actual Filter Data sent to Lavalink
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lavalink-client",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "Easy, flexible and feature-rich lavalink@v4 Client. Both for Beginners and Proficients.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",