feat: add Request::SetRoute
This commit is contained in:
parent
9795cf9c31
commit
a5366a5cb8
1 changed files with 62 additions and 7 deletions
|
|
@ -46,6 +46,7 @@ pub fn run(on_event: impl FnMut(Event) + Send + 'static) -> Sender {
|
||||||
let (request_tx, request_rx) = pipewire::channel::channel();
|
let (request_tx, request_rx) = pipewire::channel::channel();
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
|
let on_event = Box::new(on_event);
|
||||||
if let Err(why) = run_service(request_rx, on_event) {
|
if let Err(why) = run_service(request_rx, on_event) {
|
||||||
tracing::error!(?why, "failed to run pipewire thread");
|
tracing::error!(?why, "failed to run pipewire thread");
|
||||||
}
|
}
|
||||||
|
|
@ -57,7 +58,7 @@ pub fn run(on_event: impl FnMut(Event) + Send + 'static) -> Sender {
|
||||||
/// Monitor pipewire activity and
|
/// Monitor pipewire activity and
|
||||||
fn run_service(
|
fn run_service(
|
||||||
rx: pipewire::channel::Receiver<Request>,
|
rx: pipewire::channel::Receiver<Request>,
|
||||||
on_event: impl FnMut(Event) + Send + 'static,
|
on_event: Box<dyn FnMut(Event)>,
|
||||||
) -> Result<(), pipewire::Error> {
|
) -> Result<(), pipewire::Error> {
|
||||||
let main_loop = pipewire::main_loop::MainLoopRc::new(None)?;
|
let main_loop = pipewire::main_loop::MainLoopRc::new(None)?;
|
||||||
let context = pipewire::context::ContextRc::new(&main_loop, None)?;
|
let context = pipewire::context::ContextRc::new(&main_loop, None)?;
|
||||||
|
|
@ -76,7 +77,7 @@ fn run_service(
|
||||||
node_card_profile_device: IntMap::new(),
|
node_card_profile_device: IntMap::new(),
|
||||||
node_props: IntMap::new(),
|
node_props: IntMap::new(),
|
||||||
main_loop: main_loop.downgrade(),
|
main_loop: main_loop.downgrade(),
|
||||||
on_event: Box::new(on_event),
|
on_event,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let _request_handler = rx.attach(main_loop.loop_(), {
|
let _request_handler = rx.attach(main_loop.loop_(), {
|
||||||
|
|
@ -88,6 +89,14 @@ fn run_service(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Request::SetRoute(id, card_profile_device, route) => {
|
||||||
|
if let Some(state) = state.upgrade() {
|
||||||
|
state
|
||||||
|
.borrow_mut()
|
||||||
|
.set_route(id, card_profile_device as i32, route as i32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Request::SetNodeVolume(id, volume, balance) => {
|
Request::SetNodeVolume(id, volume, balance) => {
|
||||||
if let Some(state) = state.upgrade() {
|
if let Some(state) = state.upgrade() {
|
||||||
state.borrow_mut().set_node_volume(id, volume, balance);
|
state.borrow_mut().set_node_volume(id, volume, balance);
|
||||||
|
|
@ -439,6 +448,8 @@ pub enum Request {
|
||||||
SetProfile(DeviceId, u32, bool),
|
SetProfile(DeviceId, u32, bool),
|
||||||
/// Set a new volume
|
/// Set a new volume
|
||||||
SetNodeVolume(DeviceId, f32, Option<f32>),
|
SetNodeVolume(DeviceId, f32, Option<f32>),
|
||||||
|
/// Change route of a device
|
||||||
|
SetRoute(DeviceId, u32, u32),
|
||||||
/// Stop the main loop and exit the thread.
|
/// Stop the main loop and exit the thread.
|
||||||
Quit,
|
Quit,
|
||||||
}
|
}
|
||||||
|
|
@ -519,6 +530,10 @@ impl State {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_node(&mut self, id: PipewireId, node: Node) {
|
fn add_node(&mut self, id: PipewireId, node: Node) {
|
||||||
|
eprintln!(
|
||||||
|
"adding node {} with card.profile.device {:?}",
|
||||||
|
node.object_id, node.card_profile_device
|
||||||
|
);
|
||||||
// Map the device's pipewire ID to its device ID
|
// Map the device's pipewire ID to its device ID
|
||||||
if let Some(entry) = self.proxies.nodes.get_mut(id) {
|
if let Some(entry) = self.proxies.nodes.get_mut(id) {
|
||||||
entry.0 = node.object_id;
|
entry.0 = node.object_id;
|
||||||
|
|
@ -558,6 +573,7 @@ impl State {
|
||||||
}
|
}
|
||||||
routes[index as usize] = route.clone();
|
routes[index as usize] = route.clone();
|
||||||
|
|
||||||
|
eprintln!("add route on device {id}[{index}]: {}", route.name);
|
||||||
self.on_event(Event::AddRoute(id, index, route));
|
self.on_event(Event::AddRoute(id, index, route));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -574,13 +590,22 @@ impl State {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_sink(&mut self, name: String) {
|
fn default_sink(&mut self, name: String) {
|
||||||
|
eprintln!("default sink set to {name}");
|
||||||
self.on_event(Event::DefaultSink(name));
|
self.on_event(Event::DefaultSink(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_source(&mut self, name: String) {
|
fn default_source(&mut self, name: String) {
|
||||||
|
eprintln!("default source set to {name}");
|
||||||
self.on_event(Event::DefaultSource(name));
|
self.on_event(Event::DefaultSource(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn node_route(&self, device_id: DeviceId, route_device: i32) -> Option<&Route> {
|
||||||
|
self.routes
|
||||||
|
.get(device_id)?
|
||||||
|
.iter()
|
||||||
|
.find(|r| r.devices.contains(&route_device))
|
||||||
|
}
|
||||||
|
|
||||||
fn on_event(&mut self, event: Event) {
|
fn on_event(&mut self, event: Event) {
|
||||||
(self.on_event)(event);
|
(self.on_event)(event);
|
||||||
}
|
}
|
||||||
|
|
@ -698,11 +723,39 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_route(&self, device_id: DeviceId, route_device: i32) -> Option<&Route> {
|
fn set_route(&self, device_id: DeviceId, card_profile_device: i32, route_index: i32) {
|
||||||
self.routes
|
let Some(device) = self.device(device_id) else {
|
||||||
.get(device_id)?
|
return;
|
||||||
.iter()
|
};
|
||||||
.find(|r| r.devices.contains(&route_device))
|
|
||||||
|
tracing::debug!(target: "sound", "set_route device_id {device_id}, route_index {route_index}");
|
||||||
|
|
||||||
|
let buffer = std::io::Cursor::new(Vec::new());
|
||||||
|
let Ok(serialized) = PodSerializer::serialize(
|
||||||
|
buffer,
|
||||||
|
&pod::Value::Object(pod::object!(
|
||||||
|
SpaTypes::ObjectParamRoute,
|
||||||
|
ParamType::Route,
|
||||||
|
pod::property!(
|
||||||
|
FormatProperties(libspa_sys::SPA_PARAM_ROUTE_index),
|
||||||
|
Int,
|
||||||
|
route_index
|
||||||
|
),
|
||||||
|
pod::property!(
|
||||||
|
FormatProperties(libspa_sys::SPA_PARAM_ROUTE_device),
|
||||||
|
Int,
|
||||||
|
card_profile_device
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.map(|(cursor, _)| cursor.into_inner()) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(param) = Pod::from_bytes(&serialized) {
|
||||||
|
device.set_param(ParamType::Route, 0, param);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_node_props(&mut self, id: NodeId, props: NodeProps) {
|
fn set_node_props(&mut self, id: NodeId, props: NodeProps) {
|
||||||
|
|
@ -760,6 +813,7 @@ impl State {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_profile(&mut self, id: DeviceId, index: u32, save: bool) {
|
fn set_profile(&mut self, id: DeviceId, index: u32, save: bool) {
|
||||||
|
eprintln!("set profile {id}[{index}]: {save}");
|
||||||
let Some(device) = self.device(id) else {
|
let Some(device) = self.device(id) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
@ -800,6 +854,7 @@ impl State {
|
||||||
volume: f32,
|
volume: f32,
|
||||||
balance: Option<f32>,
|
balance: Option<f32>,
|
||||||
) {
|
) {
|
||||||
|
eprintln!("set volume on {id} route device {route_device}");
|
||||||
let Some(device) = self.device(id) else {
|
let Some(device) = self.device(id) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue