pulseaudio: Iterate until callback is received

Pipewire's pulseaudio server requires a different number of iterations
to get the callback through properly.

Set a flag from the callbacks, and iterate until the flag is set to
ensure that the right number of iterations are made.
This commit is contained in:
Kenny Levinsen
2021-01-28 00:56:53 +01:00
parent 89eafe5bc7
commit ee2646f091
+47 -33
View File
@@ -16,13 +16,13 @@ use std::thread;
use libpulse_binding::callbacks::ListResult;
use libpulse_binding::context::{
flags, introspect::ServerInfo, introspect::SinkInfo, subscribe::subscription_masks,
subscribe::Facility, subscribe::Operation as SubscribeOperation, Context, State as PulseState,
introspect::ServerInfo, introspect::SinkInfo, subscribe::Facility, subscribe::InterestMaskSet,
subscribe::Operation as SubscribeOperation, Context, FlagSet, State as PulseState,
};
use libpulse_binding::mainloop::standard::IterateResult;
use libpulse_binding::mainloop::standard::Mainloop;
use libpulse_binding::proplist::{properties, Proplist};
use libpulse_binding::volume::{ChannelVolumes, Volume, VOLUME_MAX, VOLUME_NORM};
use libpulse_binding::volume::{ChannelVolumes, Volume};
struct PulseAudioConnection {
mainloop: Rc<RefCell<Mainloop>>,
@@ -79,7 +79,7 @@ impl PulseAudioConnection {
context
.borrow_mut()
.connect(None, flags::NOFLAGS, None)
.connect(None, FlagSet::NOFLAGS, None)
.map_err(|_e| {
::std::io::Error::new(
::std::io::ErrorKind::Other,
@@ -158,60 +158,75 @@ impl PulseAudioClient {
Ok(req) => {
let mut introspector = conn.context.borrow_mut().introspect();
match req {
let done = Arc::new(Mutex::new(false));
let done_reader = done.clone();
let s = match req {
PulseAudioClientRequest::GetDefaultDevice(s) => {
introspector.get_server_info(move |info| {
*done.lock().unwrap() = true;
PulseAudioClient::server_info_callback(
cl.clone(),
l.clone(),
info,
);
if let Some(s) = &s {
let _ = s.send(true);
}
});
s
}
PulseAudioClientRequest::GetSinkInfoByIndex(s, index) => {
introspector.get_sink_info_by_index(index, move |res| {
*done.lock().unwrap() = true;
PulseAudioClient::sink_info_callback(
cl.clone(),
l.clone(),
res,
);
if let Some(s) = &s {
let _ = s.send(true);
}
});
s
}
PulseAudioClientRequest::GetSinkInfoByName(s, name) => {
introspector.get_sink_info_by_name(&name, move |res| {
*done.lock().unwrap() = true;
PulseAudioClient::sink_info_callback(
cl.clone(),
l.clone(),
res,
);
if let Some(s) = &s {
let _ = s.send(true);
}
});
s
}
PulseAudioClientRequest::SetSinkVolumeByName(s, name, volumes) => {
introspector.set_sink_volume_by_name(&name, &volumes, None);
if let Some(s) = &s {
let _ = s.send(true);
}
introspector.set_sink_volume_by_name(
&name,
&volumes,
Some(Box::new(move |_| {
*done.lock().unwrap() = true;
})),
);
s
}
PulseAudioClientRequest::SetSinkMuteByName(s, name, mute) => {
introspector.set_sink_mute_by_name(&name, mute, None);
if let Some(s) = &s {
let _ = s.send(true);
}
introspector.set_sink_mute_by_name(
&name,
mute,
Some(Box::new(move |_| {
*done.lock().unwrap() = true;
})),
);
s
}
};
// send request and receive response
loop {
if *done_reader.lock().unwrap() {
break;
}
conn.iterate(true).unwrap();
conn.iterate(true).unwrap();
}
if let Some(s) = s {
let _ = s.send(true);
}
}
}
}
@@ -241,10 +256,9 @@ impl PulseAudioClient {
.unwrap()
.subscribe_callback(facility, operation, index)
})));
conn.context.borrow_mut().subscribe(
subscription_masks::SERVER | subscription_masks::SINK,
|_| {},
);
conn.context
.borrow_mut()
.subscribe(InterestMaskSet::SERVER | InterestMaskSet::SINK, |_| {});
conn.mainloop.borrow_mut().run().unwrap();
});
@@ -355,7 +369,7 @@ impl PulseAudioSoundDevice {
};
inner.volume = Some(sink_info.volume);
inner.volume_avg = sink_info.volume.avg().0 as f32 / VOLUME_NORM.0 as f32;
inner.volume_avg = sink_info.volume.avg().0 as f32 / Volume::NORMAL.0 as f32;
inner.muted = sink_info.mute;
listener();
@@ -407,9 +421,9 @@ impl PulseAudioSoundDevice {
};
// apply step to volumes
let step = (step * VOLUME_NORM.0 as f32).round() as i32;
let step = (step * Volume::NORMAL.0 as f32).round() as i32;
if step > 0 {
volume.inc_clamp(Volume(step as u32), VOLUME_MAX);
volume.inc_clamp(Volume(step as u32), Volume::MAX);
} else {
volume.decrease(Volume(-step as u32));
}
@@ -421,7 +435,7 @@ impl PulseAudioSoundDevice {
// update volumes
inner.volume = Some(volume);
inner.volume_avg = volume.avg().0 as f32 / VOLUME_NORM.0 as f32;
inner.volume_avg = volume.avg().0 as f32 / Volume::NORMAL.0 as f32;
self.client
.lock()
.unwrap()
@@ -444,7 +458,7 @@ impl PulseAudioSoundDevice {
};
// apply step to volumes
volume.scale(Volume((val * VOLUME_NORM.0 as f32).round() as u32));
volume.scale(Volume((val * Volume::NORMAL.0 as f32).round() as u32));
let name = inner
.name
@@ -453,7 +467,7 @@ impl PulseAudioSoundDevice {
// update volumes
inner.volume = Some(volume);
inner.volume_avg = volume.avg().0 as f32 / VOLUME_NORM.0 as f32;
inner.volume_avg = volume.avg().0 as f32 / Volume::NORMAL.0 as f32;
self.client
.lock()
.unwrap()