wayle_audio/core/device/input/
mod.rs1pub(crate) mod controls;
2pub(crate) mod monitoring;
3pub(crate) mod types;
4
5use std::{collections::HashMap, sync::Arc};
6
7use controls::InputDeviceController;
8use derive_more::Debug;
9use libpulse_binding::time::MicroSeconds;
10use tokio::sync::oneshot;
11use tokio_util::sync::CancellationToken;
12pub(crate) use types::{InputDeviceParams, LiveInputDeviceParams};
13use wayle_core::Property;
14use wayle_traits::{ModelMonitoring, Reactive};
15
16use crate::{
17 backend::{
18 commands::Command,
19 types::{CommandSender, EventSender},
20 },
21 error::Error,
22 types::{
23 device::{Device, DeviceKey, DevicePort, DeviceState, DeviceType, SourceInfo},
24 format::{AudioFormat, ChannelMap, SampleSpec},
25 },
26 volume::types::Volume,
27};
28
29#[derive(Clone, Debug)]
44pub struct InputDevice {
45 #[debug(skip)]
47 command_tx: CommandSender,
48
49 #[debug(skip)]
51 event_tx: Option<EventSender>,
52
53 #[debug(skip)]
55 cancellation_token: Option<CancellationToken>,
56
57 pub key: DeviceKey,
59
60 pub name: Property<String>,
62
63 pub description: Property<String>,
65
66 pub card_index: Property<Option<u32>>,
68
69 pub owner_module: Property<Option<u32>>,
71
72 pub driver: Property<String>,
74
75 pub state: Property<DeviceState>,
77
78 pub volume: Property<Volume>,
80
81 pub base_volume: Property<Volume>,
83
84 pub n_volume_steps: Property<u32>,
86
87 pub muted: Property<bool>,
89
90 pub properties: Property<HashMap<String, String>>,
92
93 pub ports: Property<Vec<DevicePort>>,
95
96 pub active_port: Property<Option<String>>,
98
99 pub formats: Property<Vec<AudioFormat>>,
101
102 pub sample_spec: Property<SampleSpec>,
104
105 pub channel_map: Property<ChannelMap>,
107
108 pub monitor_of_sink: Property<Option<u32>>,
110
111 pub monitor_of_sink_name: Property<Option<String>>,
113
114 pub is_monitor: Property<bool>,
116
117 pub latency: Property<MicroSeconds>,
119
120 pub configured_latency: Property<MicroSeconds>,
122
123 pub flags: Property<u32>,
125}
126
127impl PartialEq for InputDevice {
128 fn eq(&self, other: &Self) -> bool {
129 self.key == other.key
130 }
131}
132
133impl Reactive for InputDevice {
134 type Context<'a> = InputDeviceParams<'a>;
135 type LiveContext<'a> = LiveInputDeviceParams<'a>;
136 type Error = Error;
137
138 async fn get(params: Self::Context<'_>) -> Result<Self, Self::Error> {
139 let (tx, rx) = oneshot::channel();
140 params
141 .command_tx
142 .send(Command::GetDevice {
143 device_key: params.device_key,
144 responder: tx,
145 })
146 .map_err(|_| Error::CommandChannelDisconnected)?;
147
148 let device = rx.await.map_err(|_| Error::CommandChannelDisconnected)??;
149
150 match device {
151 Device::Source(source) => Ok(Self::from_source(
152 &source,
153 params.command_tx.clone(),
154 None,
155 None,
156 )),
157 Device::Sink(_) => Err(Error::DeviceNotFound {
158 index: params.device_key.index,
159 device_type: DeviceType::Input,
160 }),
161 }
162 }
163
164 async fn get_live(params: Self::LiveContext<'_>) -> Result<Arc<Self>, Self::Error> {
165 let (tx, rx) = oneshot::channel();
166 params
167 .command_tx
168 .send(Command::GetDevice {
169 device_key: params.device_key,
170 responder: tx,
171 })
172 .map_err(|_| Error::CommandChannelDisconnected)?;
173
174 let device = rx.await.map_err(|_| Error::CommandChannelDisconnected)??;
175
176 let device = match device {
177 Device::Source(source) => Arc::new(Self::from_source(
178 &source,
179 params.command_tx.clone(),
180 Some(params.event_tx.clone()),
181 Some(params.cancellation_token.child_token()),
182 )),
183 Device::Sink(_) => {
184 return Err(Error::DeviceNotFound {
185 index: params.device_key.index,
186 device_type: DeviceType::Input,
187 });
188 }
189 };
190
191 device.clone().start_monitoring().await?;
192
193 Ok(device)
194 }
195}
196
197impl InputDevice {
198 pub(crate) fn from_source(
199 source: &SourceInfo,
200 command_tx: CommandSender,
201 event_tx: Option<EventSender>,
202 cancellation_token: Option<CancellationToken>,
203 ) -> Self {
204 Self {
205 command_tx,
206 event_tx,
207 cancellation_token,
208 key: source.key(),
209 name: Property::new(source.device.name.clone()),
210 description: Property::new(source.device.description.clone()),
211 card_index: Property::new(source.device.card_index),
212 owner_module: Property::new(source.device.owner_module),
213 driver: Property::new(source.device.driver.clone()),
214 state: Property::new(source.device.state),
215 volume: Property::new(source.device.volume.clone()),
216 base_volume: Property::new(source.device.base_volume.clone()),
217 n_volume_steps: Property::new(source.device.n_volume_steps),
218 muted: Property::new(source.device.muted),
219 properties: Property::new(source.device.properties.clone()),
220 ports: Property::new(source.device.ports.clone()),
221 active_port: Property::new(source.device.active_port.clone()),
222 formats: Property::new(source.device.formats.clone()),
223 sample_spec: Property::new(source.device.sample_spec.clone()),
224 channel_map: Property::new(source.device.channel_map.clone()),
225 monitor_of_sink: Property::new(source.monitor_of_sink),
226 monitor_of_sink_name: Property::new(source.monitor_of_sink_name.clone()),
227 is_monitor: Property::new(source.is_monitor),
228 latency: Property::new(source.device.latency),
229 configured_latency: Property::new(source.device.configured_latency),
230 flags: Property::new(source.device.flags),
231 }
232 }
233
234 pub(crate) fn update_from_source(&self, source: &SourceInfo) {
235 self.name.set(source.device.name.clone());
236 self.description.set(source.device.description.clone());
237 self.card_index.set(source.device.card_index);
238 self.owner_module.set(source.device.owner_module);
239 self.driver.set(source.device.driver.clone());
240 self.state.set(source.device.state);
241 self.volume.set(source.device.volume.clone());
242 self.base_volume.set(source.device.base_volume.clone());
243 self.n_volume_steps.set(source.device.n_volume_steps);
244 self.muted.set(source.device.muted);
245 self.properties.set(source.device.properties.clone());
246 self.ports.set(source.device.ports.clone());
247 self.active_port.set(source.device.active_port.clone());
248 self.formats.set(source.device.formats.clone());
249 self.sample_spec.set(source.device.sample_spec.clone());
250 self.channel_map.set(source.device.channel_map.clone());
251 self.monitor_of_sink.set(source.monitor_of_sink);
252 self.monitor_of_sink_name
253 .set(source.monitor_of_sink_name.clone());
254 self.is_monitor.set(source.is_monitor);
255 self.latency.set(source.device.latency);
256 self.configured_latency
257 .set(source.device.configured_latency);
258 self.flags.set(source.device.flags);
259 }
260
261 pub async fn set_volume(&self, volume: Volume) -> Result<(), Error> {
266 InputDeviceController::set_volume(&self.command_tx, self.key, volume).await
267 }
268
269 pub async fn set_mute(&self, muted: bool) -> Result<(), Error> {
274 InputDeviceController::set_mute(&self.command_tx, self.key, muted).await
275 }
276
277 pub async fn set_port(&self, port: String) -> Result<(), Error> {
282 InputDeviceController::set_port(&self.command_tx, self.key, port).await
283 }
284
285 pub async fn set_as_default(&self) -> Result<(), Error> {
290 InputDeviceController::set_as_default(&self.command_tx, self.key).await
291 }
292}