1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
use delegate::delegate;
use kithara_bufpool::HasPool;
use kithara_events::EventBus;
use kithara_play::{CrossfadeSettings, EngineLoadSnapshot, EqBandConfig, PlayError, PlayerStatus};
use super::QueueControl;
use crate::event::QueueEvent;
impl<S> QueueControl<S>
where
S: HasPool<u8> + HasPool<f32> + Send + Sync + 'static,
{
/// Underlying event bus used by queue and player events.
#[must_use]
pub fn bus(&self) -> &EventBus {
&self.bus
}
#[must_use]
pub fn crossfade_settings(&self) -> CrossfadeSettings {
*self
.crossfade_settings
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
}
/// Drain pending player-side notifications. Called by FFI tick
/// loops after [`Self::tick`].
pub fn process_notifications(&self) {
self.command(|queue| queue.player.process_notifications());
}
/// Reset all EQ bands to 0 dB.
///
/// # Errors
/// Forwards `PlayError` from the underlying player.
pub fn reset_eq(&self) -> Result<(), PlayError> {
self.with_open_result(|queue| queue.player.reset_eq())
}
/// Update the profile captured by future transitions.
///
/// # Errors
/// Returns an error when any profile value is invalid.
pub fn set_crossfade_settings(&self, settings: CrossfadeSettings) -> Result<(), PlayError> {
let settings = settings.validate()?;
self.with_open_result(|queue| {
*queue
.crossfade_settings
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner) = settings;
queue.player.set_crossfade_duration(settings.duration);
queue
.bus
.publish(QueueEvent::CrossfadeSettingsChanged { settings });
Ok(())
})
}
/// Set the default playback rate.
pub fn set_default_rate(&self, rate: f32) {
self.command(|queue| queue.player.set_default_rate(rate));
}
/// Set gain for an EQ band.
///
/// # Errors
/// Forwards `PlayError` from the underlying player.
pub fn set_eq_gain(&self, band: usize, gain_db: f32) -> Result<(), PlayError> {
self.with_open_result(|queue| queue.player.set_eq_gain(band, gain_db))
}
/// Replace the live player's EQ band layout.
///
/// # Errors
/// Forwards `PlayError` from the underlying player.
pub fn set_eq_layout(&self, layout: Vec<EqBandConfig>) -> Result<(), PlayError> {
self.with_open_result(|queue| queue.player.set_eq_layout(layout))
}
/// Set the mute flag.
pub fn set_muted(&self, muted: bool) {
self.command(|queue| queue.player.set_muted(muted));
}
/// Set the live playback rate (mirrors into the tempo-mode sibling
/// so a running key-locked stretch tracks the move).
pub fn set_rate(&self, rate: f32) {
self.command(|queue| queue.player.set_rate(rate));
}
/// Set the volume (0.0..=1.0).
pub fn set_volume(&self, volume: f32) {
self.command(|queue| queue.player.set_volume(volume));
}
delegate! {
to self.player {
/// Whether playback is active.
#[must_use]
pub fn is_playing(&self) -> bool;
/// Live engine playback rate (player-reported, 0.0 when paused).
#[must_use]
pub fn rate(&self) -> f32;
/// Default playback rate.
#[must_use]
pub fn default_rate(&self) -> f32;
/// Current volume (0.0..=1.0).
#[must_use]
pub fn volume(&self) -> f32;
/// Whether output is muted.
#[must_use]
pub fn is_muted(&self) -> bool;
/// Live engine playback status.
#[must_use]
pub fn status(&self) -> PlayerStatus;
/// Live audio-engine cost (realtime factor / load / ms).
#[must_use]
pub fn engine_load(&self) -> EngineLoadSnapshot;
/// Number of EQ bands.
#[must_use]
pub fn eq_band_count(&self) -> usize;
/// Current gain for an EQ band.
#[must_use]
pub fn eq_gain(&self, band: usize) -> Option<f32>;
/// Current track duration in seconds.
#[must_use]
pub fn duration_seconds(&self) -> Option<f64>;
}
}
}