UNPKG

magmastream

Version:

A user-friendly Lavalink client designed for NodeJS.

600 lines (599 loc) 29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AvailableFilters = exports.Filters = void 0; const filtersEqualizers_1 = require("../utils/filtersEqualizers"); class Filters { distortion; equalizer; karaoke; player; rotation; timescale; vibrato; reverb; volume; bassBoostlevel; filtersStatus; constructor(player) { this.distortion = null; this.equalizer = []; this.karaoke = null; this.player = player; this.rotation = null; this.timescale = null; this.vibrato = null; this.volume = 1.0; this.bassBoostlevel = 0; // Initialize filter status this.filtersStatus = Object.values(AvailableFilters).reduce((acc, filter) => { acc[filter] = false; return acc; }, {}); } /** * Updates the player's audio filters. * * This method sends a request to the player's node to update the filter settings * based on the current properties of the `Filters` instance. The filters include * distortion, equalizer, karaoke, rotation, timescale, vibrato, and volume. Once * the request is sent, it ensures that the player's audio output reflects the * changes in filter settings. * * @returns {Promise<this>} - Returns a promise that resolves to the current instance * of the Filters class for method chaining. */ async updateFilters() { const { distortion, equalizer, karaoke, rotation, timescale, vibrato, volume } = this; await this.player.node.rest.updatePlayer({ data: { filters: { distortion, equalizer, karaoke, rotation, timescale, vibrato, volume, }, }, guildId: this.player.guildId, }); return this; } /** * Applies a specific filter to the player. * * This method allows you to set the value of a specific filter property. * The filter property must be a valid key of the Filters object. * * @param {{ property: T; value: Filters[T] }} filter - An object containing the filter property and value. * @param {boolean} [updateFilters=true] - Whether to update the filters after applying the filter. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async applyFilter(filter, updateFilters = true) { this[filter.property] = filter.value; if (updateFilters) { await this.updateFilters(); } return this; } /** * Sets the status of a specific filter. * * This method updates the filter status to either true or false, indicating whether * the filter is applied or not. This helps track which filters are active. * * @param {AvailableFilters} filter - The filter to update. * @param {boolean} status - The status to set (true for active, false for inactive). * @returns {this} - Returns the current instance of the Filters class for method chaining. */ setFilterStatus(filter, status) { this.filtersStatus[filter] = status; return this; } /** * Retrieves the status of a specific filter. * * This method returns whether a specific filter is currently applied or not. * * @param {AvailableFilters} filter - The filter to check. * @returns {boolean} - Returns true if the filter is active, false otherwise. */ getFilterStatus(filter) { return this.filtersStatus[filter]; } /** * Clears all filters applied to the audio. * * This method resets all filter settings to their default values and removes any * active filters from the player. * * @returns {this} - Returns the current instance of the Filters class for method chaining. */ async clearFilters() { this.filtersStatus = Object.values(AvailableFilters).reduce((acc, filter) => { acc[filter] = false; return acc; }, {}); this.player.filters = new Filters(this.player); await this.setEqualizer([]); await this.setDistortion(null); await this.setKaraoke(null); await this.setRotation(null); await this.setTimescale(null); await this.setVibrato(null); await this.updateFilters(); return this; } /** * Sets the own equalizer bands on the audio. * * This method adjusts the equalization curve of the player's audio output, * allowing you to control the frequency response. * * @param {Band[]} [bands] - The equalizer bands to apply (band, gain). * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async setEqualizer(bands) { return await this.applyFilter({ property: "equalizer", value: bands }); } /** * Sets the own karaoke options to the audio. * * This method adjusts the audio so that it sounds like a karaoke song, with the * original vocals removed. Note that not all songs can be successfully made into * karaoke tracks, and some tracks may not sound as good. * * @param {karaokeOptions} [karaoke] - The karaoke settings to apply (level, monoLevel, filterBand, filterWidth). * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async setKaraoke(karaoke) { const result = await this.applyFilter({ property: "karaoke", value: karaoke ?? null }); return karaoke ? result.setFilterStatus(AvailableFilters.SetKaraoke, true) : (await this.applyFilter({ property: "karaoke", value: null })).setFilterStatus(AvailableFilters.SetKaraoke, false); } /** * Sets the own timescale options to the audio. * * This method adjusts the speed and pitch of the audio, allowing you to control the playback speed. * * @param {timescaleOptions} [timescale] - The timescale settings to apply (speed and pitch). * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async setTimescale(timescale) { const result = await this.applyFilter({ property: "timescale", value: timescale ?? null }); return timescale ? result.setFilterStatus(AvailableFilters.SetTimescale, true) : (await this.applyFilter({ property: "timescale", value: null })).setFilterStatus(AvailableFilters.SetTimescale, false); } /** * Sets the own vibrato options to the audio. * * This method applies a vibrato effect to the audio, which adds a wavering, * pulsing quality to the sound. The effect is created by rapidly varying the * pitch of the audio. * * @param {vibratoOptions} [vibrato] - The vibrato settings to apply (frequency, depth). * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async setVibrato(vibrato) { const result = await this.applyFilter({ property: "vibrato", value: vibrato ?? null }); return vibrato ? result.setFilterStatus(AvailableFilters.Vibrato, true) : (await this.applyFilter({ property: "vibrato", value: null })).setFilterStatus(AvailableFilters.Vibrato, false); } /** * Sets the own rotation options effect to the audio. * * This method applies a rotation effect to the audio, which simulates the sound * moving around the listener's head. This effect can create a dynamic and immersive * audio experience by altering the directionality of the sound. * * @param {rotationOptions} [rotation] - The rotation settings to apply (rotationHz). * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async setRotation(rotation) { const result = await this.applyFilter({ property: "rotation", value: rotation ?? null }); return rotation ? result.setFilterStatus(AvailableFilters.SetRotation, true) : (await this.applyFilter({ property: "rotation", value: null })).setFilterStatus(AvailableFilters.SetRotation, false); } /** * Sets the own distortion options effect to the audio. * * This method applies a distortion effect to the audio, which adds a rougher, * more intense quality to the sound. The effect is created by altering the * audio signal to create a more jagged, irregular waveform. * * @param {distortionOptions} [distortion] - The distortion settings to apply (sinOffset, sinScale, cosOffset, cosScale, tanOffset, tanScale, offset, scale). * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async setDistortion(distortion) { const result = await this.applyFilter({ property: "distortion", value: distortion ?? null }); return distortion ? result.setFilterStatus(AvailableFilters.SetDistortion, true) : (await this.applyFilter({ property: "distortion", value: null })).setFilterStatus(AvailableFilters.SetDistortion, false); } /** * Sets the bass boost level on the audio. * * This method scales the gain of a predefined equalizer curve to the specified level. * The curve is designed to emphasize or reduce low frequencies, creating a bass-heavy * or bass-reduced effect. * * @param {number} level - The level of bass boost to apply. The value ranges from -3 to 3, * where negative values reduce bass, 0 disables the effect, * and positive values increase bass. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. * * @example * // Apply different levels of bass boost or reduction: * await player.bassBoost(3); // Maximum Bass Boost * await player.bassBoost(2); // Medium Bass Boost * await player.bassBoost(1); // Mild Bass Boost * await player.bassBoost(0); // No Effect (Disabled) * await player.bassBoost(-1); // Mild Bass Reduction * await player.bassBoost(-2); // Medium Bass Reduction * await player.bassBoost(-3); // Maximum Bass Removal */ async bassBoost(stage) { // Ensure stage is between -3 and 3 stage = Math.max(-3, Math.min(3, stage)); // Map stage (-3 to 3) to range (-1.0 to 1.0) const level = stage / 3; // Converts -3 to 3 → -1.0 to 1.0 // Generate a dynamic equalizer by scaling bassBoostEqualizer const equalizer = filtersEqualizers_1.bassBoostEqualizer.map((band) => ({ band: band.band, gain: band.gain * level, // Scale the gain dynamically })); await this.applyFilter({ property: "equalizer", value: equalizer }); this.setFilterStatus(AvailableFilters.BassBoost, stage !== 0); // Active if stage is not 0 this.bassBoostlevel = stage; return this; } /** * Toggles the chipmunk effect on the audio. * * This method applies or removes a chipmunk effect by adjusting the timescale settings. * When enabled, it increases the speed, pitch, and rate of the audio, resulting in a high-pitched, fast playback * similar to the sound of a chipmunk. * * @param {boolean} status - Whether to enable or disable the chipmunk effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async chipmunk(status) { const result = await this.applyFilter({ property: "timescale", value: status ? { speed: 1.5, pitch: 1.5, rate: 1.5 } : null }); return status ? result.setFilterStatus(AvailableFilters.Chipmunk, true) : (await this.applyFilter({ property: "timescale", value: null })).setFilterStatus(AvailableFilters.Chipmunk, false); } /** * Toggles the "China" effect on the audio. * * This method applies or removes a filter that reduces the pitch of the audio by half, * without changing the speed or rate. This creates a "hollow" or "echoey" sound. * * @param {boolean} status - Whether to enable or disable the "China" effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async china(status) { const result = await this.applyFilter({ property: "timescale", value: status ? { speed: 1.0, pitch: 0.5, rate: 1.0 } : null }); return status ? result.setFilterStatus(AvailableFilters.China, true) : (await this.applyFilter({ property: "timescale", value: null })).setFilterStatus(AvailableFilters.China, false); } /** * Toggles the 8D audio effect on the audio. * * This method applies or removes an 8D audio effect by adjusting the rotation settings. * When enabled, it creates a sensation of the audio moving around the listener's head, * providing an immersive audio experience. * * @param {boolean} status - Whether to enable or disable the 8D effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async eightD(status) { const result = await this.applyFilter({ property: "rotation", value: status ? { rotationHz: 0.2 } : null }); return status ? result.setFilterStatus(AvailableFilters.EightD, true) : (await this.applyFilter({ property: "rotation", value: null })).setFilterStatus(AvailableFilters.EightD, false); } /** * Toggles the nightcore effect on the audio. * * This method applies or removes a nightcore effect by adjusting the timescale settings. * When enabled, it increases the speed and pitch of the audio, giving it a more * upbeat and energetic feel. * * @param {boolean} status - Whether to enable or disable the nightcore effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async nightcore(status) { const result = await this.applyFilter({ property: "timescale", value: status ? { speed: 1.1, pitch: 1.125, rate: 1.05 } : null }); return status ? result.setFilterStatus(AvailableFilters.Nightcore, true) : (await this.applyFilter({ property: "timescale", value: null })).setFilterStatus(AvailableFilters.Nightcore, false); } /** * Toggles the slowmo effect on the audio. * * This method applies or removes a slowmo effect by adjusting the timescale settings. * When enabled, it slows down the audio while keeping the pitch the same, giving it * a more relaxed and calming feel. * * @param {boolean} status - Whether to enable or disable the slowmo effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async slowmo(status) { const result = await this.applyFilter({ property: "timescale", value: status ? { speed: 0.7, pitch: 1.0, rate: 0.8 } : null }); return status ? result.setFilterStatus(AvailableFilters.Slowmo, true) : (await this.applyFilter({ property: "timescale", value: null })).setFilterStatus(AvailableFilters.Slowmo, false); } /** * Toggles a soft equalizer effect to the audio. * * This method applies or removes a soft equalizer effect by adjusting the equalizer settings. * When enabled, it reduces the bass and treble frequencies, giving the audio a softer and more * mellow sound. * * @param {boolean} status - Whether to enable or disable the soft equalizer effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async soft(status) { const result = await this.applyFilter({ property: "equalizer", value: status ? filtersEqualizers_1.softEqualizer : [] }); return status ? result.setFilterStatus(AvailableFilters.Soft, true) : (await this.applyFilter({ property: "equalizer", value: [] })).setFilterStatus(AvailableFilters.Soft, false); } /** * Toggles the TV equalizer effect on the audio. * * This method applies or removes a TV equalizer effect by adjusting the equalizer settings. * When enabled, it enhances specific frequency bands to mimic the audio characteristics * typically found in television audio outputs. * * @param {boolean} status - Whether to enable or disable the TV equalizer effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async tv(status) { const result = await this.applyFilter({ property: "equalizer", value: status ? filtersEqualizers_1.tvEqualizer : [] }); return status ? result.setFilterStatus(AvailableFilters.TV, true) : (await this.applyFilter({ property: "equalizer", value: [] })).setFilterStatus(AvailableFilters.TV, false); } /** * Toggles the treble/bass equalizer effect on the audio. * * This method applies or removes a treble/bass equalizer effect by adjusting the equalizer settings. * When enabled, it enhances the treble and bass frequencies, giving the audio a more balanced sound. * * @param {boolean} status - Whether to enable or disable the treble/bass equalizer effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async trebleBass(status) { const result = await this.applyFilter({ property: "equalizer", value: status ? filtersEqualizers_1.trebleBassEqualizer : [] }); return status ? result.setFilterStatus(AvailableFilters.TrebleBass, true) : (await this.applyFilter({ property: "equalizer", value: [] })).setFilterStatus(AvailableFilters.TrebleBass, false); } /** * Toggles the vaporwave effect on the audio. * * This method applies or removes a vaporwave effect by adjusting the equalizer settings. * When enabled, it gives the audio a dreamy and nostalgic feel, characteristic of the vaporwave genre. * * @param {boolean} status - Whether to enable or disable the vaporwave effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async vaporwave(status) { const result = await this.applyFilter({ property: "equalizer", value: status ? filtersEqualizers_1.vaporwaveEqualizer : [] }); return status ? result.setFilterStatus(AvailableFilters.Vaporwave, true) : (await this.applyFilter({ property: "equalizer", value: [] })).setFilterStatus(AvailableFilters.Vaporwave, false); } /** * Toggles the distortion effect on the audio. * * This method applies or removes a distortion effect by adjusting the distortion settings. * When enabled, it adds a rougher, more intense quality to the sound by altering the * audio signal to create a more jagged, irregular waveform. * * @param {boolean} status - Whether to enable or disable the distortion effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async distort(status) { return status ? this.setDistortion({ sinOffset: 0, sinScale: 0.2, cosOffset: 0, cosScale: 0.2, tanOffset: 0, tanScale: 0.2, offset: 0, scale: 1.2, }).then((result) => result.setFilterStatus(AvailableFilters.Distort, true)) : this.setDistortion().then((result) => result.setFilterStatus(AvailableFilters.Distort, false)); } /** * Toggles the party effect on the audio. * * This method applies or removes a party effect by adjusting the equalizer settings. * When enabled, it enhances the bass and treble frequencies, providing a more energetic and lively sound. * * @param {boolean} status - Whether to enable or disable the party effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async pop(status) { const result = await this.applyFilter({ property: "equalizer", value: status ? filtersEqualizers_1.popEqualizer : [] }); return status ? result.setFilterStatus(AvailableFilters.Pop, true) : (await this.applyFilter({ property: "equalizer", value: [] })).setFilterStatus(AvailableFilters.Pop, false); } /** * Toggles a party effect on the audio. * * This method applies a party effect to audio. * @param {boolean} status - Whether to enable or disable the party effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async party(status) { const result = await this.applyFilter({ property: "equalizer", value: status ? filtersEqualizers_1.popEqualizer : [] }); return status ? result.setFilterStatus(AvailableFilters.Party, true) : (await this.applyFilter({ property: "equalizer", value: [] })).setFilterStatus(AvailableFilters.Party, false); } /** * Toggles earrape effect on the audio. * * This method applies earrape effect to audio. * @param {boolean} status - Whether to enable or disable the earrape effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async earrape(status) { if (status) { await this.player.setVolume(200); return this.setFilterStatus(AvailableFilters.Earrape, true); } else { await this.player.setVolume(100); return this.setFilterStatus(AvailableFilters.Earrape, false); } } /** * Toggles electronic effect on the audio. * * This method applies electronic effect to audio. * @param {boolean} status - Whether to enable or disable the electronic effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async electronic(status) { const result = await this.applyFilter({ property: "equalizer", value: status ? filtersEqualizers_1.electronicEqualizer : [] }); return status ? result.setFilterStatus(AvailableFilters.Electronic, true) : (await this.applyFilter({ property: "equalizer", value: [] })).setFilterStatus(AvailableFilters.Electronic, false); } /** * Toggles radio effect on the audio. * * This method applies radio effect to audio. * @param {boolean} status - Whether to enable or disable the radio effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async radio(status) { const result = await this.applyFilter({ property: "equalizer", value: status ? filtersEqualizers_1.radioEqualizer : [] }); return status ? result.setFilterStatus(AvailableFilters.Radio, true) : (await this.applyFilter({ property: "equalizer", value: [] })).setFilterStatus(AvailableFilters.Radio, false); } /** * Toggles a tremolo effect on the audio. * * This method applies a tremolo effect to audio. * @param {boolean} status - Whether to enable or disable the tremolo effect. * @returns {this} - Returns the current instance of the Filters class for method chaining. */ async tremolo(status) { const result = await this.applyFilter({ property: "vibrato", value: status ? { frequency: 5, depth: 0.5 } : null }); return status ? result.setFilterStatus(AvailableFilters.Tremolo, true) : (await this.applyFilter({ property: "vibrato", value: null })).setFilterStatus(AvailableFilters.Tremolo, false); } /** * Toggless a darthvader effect on the audio. * * This method applies a darthvader effect to audio. * @param {boolean} status - Whether to enable or disable the darthvader effect. * @returns {this} - Returns the current instance of the Filters class for method chaining. */ async darthvader(status) { const result = await this.applyFilter({ property: "timescale", value: status ? { speed: 1.0, pitch: 0.5, rate: 1.0 } : null }); return status ? result.setFilterStatus(AvailableFilters.Darthvader, true) : (await this.applyFilter({ property: "timescale", value: null })).setFilterStatus(AvailableFilters.Darthvader, false); } /** * Toggles a daycore effect on the audio. * * This method applies a daycore effect to audio. * @param {boolean} status - Whether to enable or disable the daycore effect. * @returns {this} - Returns the current instance of the Filters class for method chaining. */ async daycore(status) { const result = await this.applyFilter({ property: "timescale", value: status ? { speed: 0.7, pitch: 0.8, rate: 0.8 } : null }); return status ? result.setFilterStatus(AvailableFilters.Daycore, true) : (await this.applyFilter({ property: "timescale", value: null })).setFilterStatus(AvailableFilters.Daycore, false); } /** * Toggles a doubletime effect on the audio. * * This method applies a doubletime effect to audio. * @param {boolean} status - Whether to enable or disable the doubletime effect. * @returns {this} - Returns the current instance of the Filters class for method chaining */ async doubletime(status) { const result = await this.applyFilter({ property: "timescale", value: status ? { speed: 2.0, pitch: 1.0, rate: 2.0 } : null }); return status ? result.setFilterStatus(AvailableFilters.Doubletime, true) : (await this.applyFilter({ property: "timescale", value: null })).setFilterStatus(AvailableFilters.Doubletime, false); } /** * Toggles the demon effect on the audio. * * This method applies or removes a demon effect by adjusting the equalizer, * timescale, and reverb settings. When enabled, it creates a deeper and more * intense sound by lowering the pitch and adding reverb to the audio. * * @param {boolean} status - Whether to enable or disable the demon effect. * @returns {Promise<this>} - Returns the current instance of the Filters class for method chaining. */ async demon(status) { const filters = status ? { equalizer: filtersEqualizers_1.demonEqualizer, timescale: { pitch: 0.8 }, reverb: { wet: 0.7, dry: 0.3, roomSize: 0.8, damping: 0.5 }, } : { equalizer: [], timescale: null, reverb: null, }; await Promise.all(Object.entries(filters).map(([property, value]) => this.applyFilter({ property: property, value }))); this.setFilterStatus(AvailableFilters.Demon, status); return this; } } exports.Filters = Filters; var AvailableFilters; (function (AvailableFilters) { AvailableFilters["BassBoost"] = "bassboost"; AvailableFilters["Distort"] = "distort"; AvailableFilters["SetDistortion"] = "setDistortion"; AvailableFilters["EightD"] = "eightD"; AvailableFilters["SetKaraoke"] = "setKaraoke"; AvailableFilters["Nightcore"] = "nightcore"; AvailableFilters["Slowmo"] = "slowmo"; AvailableFilters["Soft"] = "soft"; AvailableFilters["TrebleBass"] = "trebleBass"; AvailableFilters["SetTimescale"] = "setTimescale"; AvailableFilters["TV"] = "tv"; AvailableFilters["Vibrato"] = "vibrato"; AvailableFilters["Vaporwave"] = "vaporwave"; AvailableFilters["Pop"] = "pop"; AvailableFilters["Party"] = "party"; AvailableFilters["Earrape"] = "earrape"; AvailableFilters["Electronic"] = "electronic"; AvailableFilters["Radio"] = "radio"; AvailableFilters["SetRotation"] = "setRotation"; AvailableFilters["Tremolo"] = "tremolo"; AvailableFilters["China"] = "china"; AvailableFilters["Chipmunk"] = "chipmunk"; AvailableFilters["Darthvader"] = "darthvader"; AvailableFilters["Daycore"] = "daycore"; AvailableFilters["Doubletime"] = "doubletime"; AvailableFilters["Demon"] = "demon"; })(AvailableFilters || (exports.AvailableFilters = AvailableFilters = {}));