lavalink_rs/model/
player.rs

1use crate::model::*;
2
3#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
4#[serde(rename_all = "camelCase")]
5#[cfg_attr(feature = "python", pyo3::pyclass(get_all, set_all))]
6/// Information about the player of a guild.
7pub struct Player {
8    #[serde(deserialize_with = "deserialize_number_from_string")]
9    pub guild_id: GuildId,
10    /// The currently playing track.
11    pub track: Option<track::TrackData>,
12    /// The current volume of the player.
13    pub volume: u16,
14    /// Whether the player is paused or not.
15    pub paused: bool,
16    /// The state of the player.
17    pub state: State,
18    /// The filters currently in use by the player
19    pub filters: Option<Filters>,
20    /// The voice connection information of the player.
21    pub voice: ConnectionInfo,
22}
23
24#[derive(Hash, PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Serialize, Deserialize)]
25#[serde(rename_all = "camelCase")]
26#[cfg_attr(feature = "python", pyo3::pyclass(get_all, set_all))]
27pub struct State {
28    /// Unix timestamp in milliseconds.
29    pub time: u64,
30    /// The current position of the track in milliseconds.
31    pub position: u64,
32    /// Whether Lavalink is connected to the discord voice gateway.
33    pub connected: bool,
34    #[serde(deserialize_with = "deserialize_option_number")]
35    /// The latency of the node to the Discord voice gateway in milliseconds.
36    ///
37    /// None if not connected.
38    pub ping: Option<u32>,
39}
40
41#[derive(Hash, PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Serialize, Deserialize)]
42#[serde(rename_all = "camelCase")]
43#[cfg_attr(feature = "python", pyo3::pyclass(get_all, set_all))]
44/// Discord voice websocket connection information.
45pub struct ConnectionInfo {
46    /// The Discord voice endpoint to connect to.
47    ///
48    /// Provided by `Voice Server Update`.
49    pub endpoint: String,
50    /// The Discord voice token to authenticate with.
51    ///
52    /// Provided by `Voice Server Update`.
53    pub token: String,
54    /// The Discord voice session id to authenticate with.
55    ///
56    /// Not to be confused by the Lavalink `session_id`.
57    ///
58    /// Provided by `Voice State Update`.
59    pub session_id: String,
60}
61
62impl ConnectionInfo {
63    pub fn fix(&mut self) {
64        self.endpoint = self.endpoint.replace("wss://", "");
65    }
66}
67
68#[cfg(feature = "songbird")]
69use songbird_dep::ConnectionInfo as SongbirdConnectionInfo;
70
71#[cfg(feature = "songbird")]
72impl From<SongbirdConnectionInfo> for ConnectionInfo {
73    fn from(connection_info: SongbirdConnectionInfo) -> ConnectionInfo {
74        ConnectionInfo {
75            endpoint: connection_info.endpoint,
76            token: connection_info.token,
77            session_id: connection_info.session_id,
78        }
79    }
80}
81
82#[derive(PartialEq, Debug, Clone, Serialize, Deserialize, Default)]
83#[serde(rename_all = "camelCase")]
84#[cfg_attr(feature = "python", pyo3::pyclass)]
85pub struct Filters {
86    /// Adjusts the player volume from 0.0 to 5.0, where 1.0 is 100%.
87    ///
88    /// NOTE: Values >1.0 may cause clipping
89    #[serde(skip_serializing_if = "Option::is_none")]
90    pub volume: Option<f64>,
91    /// Adjusts 15 different bands.
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub equalizer: Option<Vec<Equalizer>>,
94    /// Eliminates part of a band, usually targeting vocals.
95    #[serde(skip_serializing_if = "Option::is_none")]
96    pub karaoke: Option<Karaoke>,
97    /// Changes the speed, pitch, and rate.
98    #[serde(skip_serializing_if = "Option::is_none")]
99    pub timescale: Option<Timescale>,
100    /// Creates a shuddering effect, where the volume quickly oscillates.
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub tremolo: Option<TremoloVibrato>,
103    /// Creates a shuddering effect, where the pitch quickly oscillates.
104    #[serde(skip_serializing_if = "Option::is_none")]
105    pub vibrato: Option<TremoloVibrato>,
106    /// Rotates the audio around the stereo channels/user headphones (aka Audio Panning).
107    #[serde(skip_serializing_if = "Option::is_none")]
108    pub rotation: Option<Rotation>,
109    /// Distorts the audio.
110    #[serde(skip_serializing_if = "Option::is_none")]
111    pub distortion: Option<Distortion>,
112    /// Mixes both stereo channels (left and right).
113    #[serde(skip_serializing_if = "Option::is_none")]
114    pub channel_mix: Option<ChannelMix>,
115    /// Filters out higher frequencies.
116    #[serde(skip_serializing_if = "Option::is_none")]
117    pub low_pass: Option<LowPass>,
118    /// Filter plugin configurations.
119    #[serde(skip_serializing_if = "Option::is_none")]
120    pub plugin_filters: Option<serde_json::Value>,
121}
122
123#[derive(PartialEq, PartialOrd, Debug, Clone, Serialize, Deserialize, Default)]
124#[serde(rename_all = "camelCase")]
125#[cfg_attr(feature = "python", pyo3::pyclass(get_all, set_all))]
126/// Mixes both channels (left and right), with a configurable factor on how much each channel affects the other.
127///
128/// With the defaults, both channels are kept independent of each other.
129/// Setting all factors to 0.5 means both channels get the same audio.
130/// All values are (0.0 <= x <= 1.0)
131pub struct ChannelMix {
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub left_to_left: Option<f64>,
134    #[serde(skip_serializing_if = "Option::is_none")]
135    pub left_to_right: Option<f64>,
136    #[serde(skip_serializing_if = "Option::is_none")]
137    pub right_to_left: Option<f64>,
138    #[serde(skip_serializing_if = "Option::is_none")]
139    pub right_to_right: Option<f64>,
140}
141
142#[derive(PartialEq, PartialOrd, Debug, Clone, Serialize, Deserialize, Default)]
143#[serde(rename_all = "camelCase")]
144#[cfg_attr(feature = "python", pyo3::pyclass(get_all, set_all))]
145/// Distortion effect.
146///
147/// It can generate some pretty unique audio effects.
148pub struct Distortion {
149    #[serde(skip_serializing_if = "Option::is_none")]
150    pub sin_offset: Option<f64>,
151    #[serde(skip_serializing_if = "Option::is_none")]
152    pub sin_scale: Option<f64>,
153    #[serde(skip_serializing_if = "Option::is_none")]
154    pub cos_offset: Option<f64>,
155    #[serde(skip_serializing_if = "Option::is_none")]
156    pub cos_scale: Option<f64>,
157    #[serde(skip_serializing_if = "Option::is_none")]
158    pub tan_offset: Option<f64>,
159    #[serde(skip_serializing_if = "Option::is_none")]
160    pub tan_scale: Option<f64>,
161    #[serde(skip_serializing_if = "Option::is_none")]
162    pub offset: Option<f64>,
163    #[serde(skip_serializing_if = "Option::is_none")]
164    pub scale: Option<f64>,
165}
166
167#[derive(PartialEq, PartialOrd, Debug, Clone, Serialize, Deserialize, Default)]
168#[serde(rename_all = "camelCase")]
169#[cfg_attr(feature = "python", pyo3::pyclass(get_all, set_all))]
170/// A fixed band equalizer.
171pub struct Equalizer {
172    /// The band (0 to 14)
173    pub band: u8,
174    /// The gain (-0.25 to 1.0)
175    ///
176    /// -0.25 means the given band is completely muted, and 0.25 means it is doubled.
177    /// Modifying the gain could also change the volume of the output.
178    pub gain: f64,
179}
180
181#[derive(PartialEq, PartialOrd, Debug, Clone, Serialize, Deserialize, Default)]
182#[serde(rename_all = "camelCase")]
183#[cfg_attr(feature = "python", pyo3::pyclass(get_all, set_all))]
184/// Uses equalization to eliminate part of a band, usually targeting vocals.
185pub struct Karaoke {
186    /// The level (0 to 1.0 where 0.0 is no effect and 1.0 is full effect)
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub level: Option<f64>,
189    /// The mono level (0 to 1.0 where 0.0 is no effect and 1.0 is full effect)
190    #[serde(skip_serializing_if = "Option::is_none")]
191    pub mono_level: Option<f64>,
192    /// The filter band (in Hz)
193    #[serde(skip_serializing_if = "Option::is_none")]
194    pub filter_band: Option<f64>,
195    /// The filter width.
196    #[serde(skip_serializing_if = "Option::is_none")]
197    pub filter_width: Option<f64>,
198}
199
200#[derive(PartialEq, PartialOrd, Debug, Clone, Serialize, Deserialize, Default)]
201#[serde(rename_all = "camelCase")]
202#[cfg_attr(feature = "python", pyo3::pyclass(get_all, set_all))]
203/// Higher frequencies get suppressed, while lower frequencies pass through this filter.
204pub struct LowPass {
205    /// The smoothing factor (1.0 < x)
206    ///
207    /// Any smoothing values equal to or less than 1.0 will disable the filter.
208    #[serde(skip_serializing_if = "Option::is_none")]
209    pub smoothing: Option<f64>,
210}
211
212#[derive(PartialEq, PartialOrd, Debug, Clone, Serialize, Deserialize, Default)]
213#[serde(rename_all = "camelCase")]
214#[cfg_attr(feature = "python", pyo3::pyclass(get_all, set_all))]
215/// Rotates the sound around the stereo channels/user headphones (aka Audio Panning).
216///
217/// It can produce an effect similar to [this](https://youtu.be/QB9EB8mTKcc) without the reverb.
218pub struct Rotation {
219    /// The frequency of the audio rotating around the listener in Hz.
220    ///
221    /// 0.2 is similar to the example video above
222    #[serde(skip_serializing_if = "Option::is_none")]
223    pub rotation_hz: Option<f64>,
224}
225
226#[derive(PartialEq, PartialOrd, Debug, Clone, Serialize, Deserialize, Default)]
227#[serde(rename_all = "camelCase")]
228#[cfg_attr(feature = "python", pyo3::pyclass(get_all, set_all))]
229/// Changes the speed, pitch, and rate.
230///
231/// All default to 1.0.
232pub struct Timescale {
233    /// The playback speed (0.0 <= x)
234    #[serde(skip_serializing_if = "Option::is_none")]
235    pub speed: Option<f64>,
236    /// The pitch (0.0 <= x)
237    #[serde(skip_serializing_if = "Option::is_none")]
238    pub pitch: Option<f64>,
239    /// The rate (0.0 <= x)
240    #[serde(skip_serializing_if = "Option::is_none")]
241    pub rate: Option<f64>,
242}
243
244#[derive(PartialEq, PartialOrd, Debug, Clone, Serialize, Deserialize, Default)]
245#[serde(rename_all = "camelCase")]
246#[cfg_attr(feature = "python", pyo3::pyclass(get_all, set_all))]
247/// Tremolo uses amplification to create a shuddering effect, where the volume quickly oscillates.
248///
249/// [Demo](https://en.wikipedia.org/wiki/File:Fuse_Electronics_Tremolo_MK-III_Quick_Demo.ogv)
250///
251/// Vibrato is similar to tremolo, but rather than oscillating the volume, it oscillates the pitch.
252pub struct TremoloVibrato {
253    /// For tremolo (0.0 < x)
254    /// For vibrato (0.0 < x <= 14.0)
255    #[serde(skip_serializing_if = "Option::is_none")]
256    pub frequency: Option<f64>,
257    /// For both tremolo and vibrato (0.0 < x <= 1.0)
258    #[serde(skip_serializing_if = "Option::is_none")]
259    pub depth: Option<f64>,
260}