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::callbacks::ListResult;
use libpulse_binding::context::{ use libpulse_binding::context::{
flags, introspect::ServerInfo, introspect::SinkInfo, subscribe::subscription_masks, introspect::ServerInfo, introspect::SinkInfo, subscribe::Facility, subscribe::InterestMaskSet,
subscribe::Facility, subscribe::Operation as SubscribeOperation, Context, State as PulseState, subscribe::Operation as SubscribeOperation, Context, FlagSet, State as PulseState,
}; };
use libpulse_binding::mainloop::standard::IterateResult; use libpulse_binding::mainloop::standard::IterateResult;
use libpulse_binding::mainloop::standard::Mainloop; use libpulse_binding::mainloop::standard::Mainloop;
use libpulse_binding::proplist::{properties, Proplist}; use libpulse_binding::proplist::{properties, Proplist};
use libpulse_binding::volume::{ChannelVolumes, Volume, VOLUME_MAX, VOLUME_NORM}; use libpulse_binding::volume::{ChannelVolumes, Volume};
struct PulseAudioConnection { struct PulseAudioConnection {
mainloop: Rc<RefCell<Mainloop>>, mainloop: Rc<RefCell<Mainloop>>,
@@ -79,7 +79,7 @@ impl PulseAudioConnection {
context context
.borrow_mut() .borrow_mut()
.connect(None, flags::NOFLAGS, None) .connect(None, FlagSet::NOFLAGS, None)
.map_err(|_e| { .map_err(|_e| {
::std::io::Error::new( ::std::io::Error::new(
::std::io::ErrorKind::Other, ::std::io::ErrorKind::Other,
@@ -158,60 +158,75 @@ impl PulseAudioClient {
Ok(req) => { Ok(req) => {
let mut introspector = conn.context.borrow_mut().introspect(); 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) => { PulseAudioClientRequest::GetDefaultDevice(s) => {
introspector.get_server_info(move |info| { introspector.get_server_info(move |info| {
*done.lock().unwrap() = true;
PulseAudioClient::server_info_callback( PulseAudioClient::server_info_callback(
cl.clone(), cl.clone(),
l.clone(), l.clone(),
info, info,
); );
if let Some(s) = &s {
let _ = s.send(true);
}
}); });
s
} }
PulseAudioClientRequest::GetSinkInfoByIndex(s, index) => { PulseAudioClientRequest::GetSinkInfoByIndex(s, index) => {
introspector.get_sink_info_by_index(index, move |res| { introspector.get_sink_info_by_index(index, move |res| {
*done.lock().unwrap() = true;
PulseAudioClient::sink_info_callback( PulseAudioClient::sink_info_callback(
cl.clone(), cl.clone(),
l.clone(), l.clone(),
res, res,
); );
if let Some(s) = &s {
let _ = s.send(true);
}
}); });
s
} }
PulseAudioClientRequest::GetSinkInfoByName(s, name) => { PulseAudioClientRequest::GetSinkInfoByName(s, name) => {
introspector.get_sink_info_by_name(&name, move |res| { introspector.get_sink_info_by_name(&name, move |res| {
*done.lock().unwrap() = true;
PulseAudioClient::sink_info_callback( PulseAudioClient::sink_info_callback(
cl.clone(), cl.clone(),
l.clone(), l.clone(),
res, res,
); );
if let Some(s) = &s {
let _ = s.send(true);
}
}); });
s
} }
PulseAudioClientRequest::SetSinkVolumeByName(s, name, volumes) => { PulseAudioClientRequest::SetSinkVolumeByName(s, name, volumes) => {
introspector.set_sink_volume_by_name(&name, &volumes, None); introspector.set_sink_volume_by_name(
if let Some(s) = &s { &name,
let _ = s.send(true); &volumes,
} Some(Box::new(move |_| {
*done.lock().unwrap() = true;
})),
);
s
} }
PulseAudioClientRequest::SetSinkMuteByName(s, name, mute) => { PulseAudioClientRequest::SetSinkMuteByName(s, name, mute) => {
introspector.set_sink_mute_by_name(&name, mute, None); introspector.set_sink_mute_by_name(
if let Some(s) = &s { &name,
let _ = s.send(true); mute,
} Some(Box::new(move |_| {
*done.lock().unwrap() = true;
})),
);
s
} }
}; };
// send request and receive response // send request and receive response
loop {
if *done_reader.lock().unwrap() {
break;
}
conn.iterate(true).unwrap(); conn.iterate(true).unwrap();
conn.iterate(true).unwrap(); }
if let Some(s) = s {
let _ = s.send(true);
}
} }
} }
} }
@@ -241,10 +256,9 @@ impl PulseAudioClient {
.unwrap() .unwrap()
.subscribe_callback(facility, operation, index) .subscribe_callback(facility, operation, index)
}))); })));
conn.context.borrow_mut().subscribe( conn.context
subscription_masks::SERVER | subscription_masks::SINK, .borrow_mut()
|_| {}, .subscribe(InterestMaskSet::SERVER | InterestMaskSet::SINK, |_| {});
);
conn.mainloop.borrow_mut().run().unwrap(); conn.mainloop.borrow_mut().run().unwrap();
}); });
@@ -355,7 +369,7 @@ impl PulseAudioSoundDevice {
}; };
inner.volume = Some(sink_info.volume); 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; inner.muted = sink_info.mute;
listener(); listener();
@@ -407,9 +421,9 @@ impl PulseAudioSoundDevice {
}; };
// apply step to volumes // 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 { if step > 0 {
volume.inc_clamp(Volume(step as u32), VOLUME_MAX); volume.inc_clamp(Volume(step as u32), Volume::MAX);
} else { } else {
volume.decrease(Volume(-step as u32)); volume.decrease(Volume(-step as u32));
} }
@@ -421,7 +435,7 @@ impl PulseAudioSoundDevice {
// update volumes // update volumes
inner.volume = Some(volume); 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 self.client
.lock() .lock()
.unwrap() .unwrap()
@@ -444,7 +458,7 @@ impl PulseAudioSoundDevice {
}; };
// apply step to volumes // 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 let name = inner
.name .name
@@ -453,7 +467,7 @@ impl PulseAudioSoundDevice {
// update volumes // update volumes
inner.volume = Some(volume); 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 self.client
.lock() .lock()
.unwrap() .unwrap()