diff --git a/Cargo.toml b/Cargo.toml index 3afd5e8..a46dd7f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,4 @@ zbus = { git = "https://gitlab.freedesktop.org/dbus/zbus.git" } zvariant = { git = "https://gitlab.freedesktop.org/dbus/zbus.git" } #zbus = { path = "../zbus/zbus" } #zvariant = { path = "../zbus/zvariant" } +rdw4 = { path = "../rdw/rdw4" } diff --git a/qemu-display/src/audio.rs b/qemu-display/src/audio.rs index b0790b6..7975615 100644 --- a/qemu-display/src/audio.rs +++ b/qemu-display/src/audio.rs @@ -256,4 +256,27 @@ impl Audio { self.out_listener.replace(c); Ok(()) } + + pub async fn register_in_listener(&mut self, handler: H) -> Result<()> { + let (p0, p1) = UnixStream::pair()?; + self.proxy + .register_in_listener(p0.as_raw_fd().into()) + .await?; + let c = zbus::ConnectionBuilder::unix_stream(p1) + .p2p() + .build() + .await?; + { + let mut server = c.object_server_mut().await; + server + .at( + "/org/qemu/Display1/AudioInListener", + AudioInListener { handler }, + ) + .unwrap(); + server.start_dispatch(); + } + self.in_listener.replace(c); + Ok(()) + } } diff --git a/qemu-rdw/Cargo.toml b/qemu-rdw/Cargo.toml index 47eac25..9022f83 100644 --- a/qemu-rdw/Cargo.toml +++ b/qemu-rdw/Cargo.toml @@ -13,7 +13,7 @@ once_cell = "1.5" zbus = { version = "2.0.0-beta" } qemu-display = { path = "../qemu-display" } keycodemap = { path = "../keycodemap" } -rdw = { package = "rdw4", git = "https://gitlab.gnome.org/malureau/rdw.git" } +rdw = { package = "rdw4", version = "0.1.0" } futures-util = "0.3.13" futures = "0.3.13" async-trait = "0.1.48" diff --git a/qemu-rdw/src/audio.rs b/qemu-rdw/src/audio.rs index bdf0e54..2456441 100644 --- a/qemu-rdw/src/audio.rs +++ b/qemu-rdw/src/audio.rs @@ -1,6 +1,6 @@ use std::{error::Error, result::Result}; -use qemu_display::{Audio, AudioOutHandler}; +use qemu_display::{Audio, AudioInHandler, AudioOutHandler}; #[derive(Debug)] pub struct Handler { @@ -9,7 +9,7 @@ pub struct Handler { } #[derive(Debug, Default)] -pub struct OutListener { +struct OutListener { gst: rdw::GstAudio, } @@ -17,7 +17,7 @@ pub struct OutListener { impl AudioOutHandler for OutListener { async fn init(&mut self, id: u64, info: qemu_display::PCMInfo) { if let Err(e) = self.gst.init_out(id, &info.gst_caps()) { - log::warn!("Failed to initialize audio stream: {}", e); + log::warn!("Failed to initialize audio output stream: {}", e); } } @@ -27,7 +27,7 @@ impl AudioOutHandler for OutListener { async fn set_enabled(&mut self, id: u64, enabled: bool) { if let Err(e) = self.gst.set_enabled_out(id, enabled) { - log::warn!("Failed to set enabled audio stream: {}", e); + log::warn!("Failed to set enabled audio output stream: {}", e); } } @@ -37,7 +37,7 @@ impl AudioOutHandler for OutListener { volume.mute, volume.volume.first().map(|v| *v as f64 / 255f64), ) { - log::warn!("Failed to set volume: {}", e); + log::warn!("Failed to set output volume: {}", e); } } @@ -48,10 +48,56 @@ impl AudioOutHandler for OutListener { } } +#[derive(Debug, Default)] +struct InListener { + gst: rdw::GstAudio, +} + +#[async_trait::async_trait] +impl AudioInHandler for InListener { + async fn init(&mut self, id: u64, info: qemu_display::PCMInfo) { + if let Err(e) = self.gst.init_in(id, &info.gst_caps()) { + log::warn!("Failed to initialize audio input stream: {}", e); + } + } + + async fn fini(&mut self, id: u64) { + self.gst.fini_in(id); + } + + async fn set_enabled(&mut self, id: u64, enabled: bool) { + if let Err(e) = self.gst.set_enabled_in(id, enabled) { + log::warn!("Failed to set enabled audio input stream: {}", e); + } + } + + async fn set_volume(&mut self, id: u64, volume: qemu_display::Volume) { + if let Err(e) = self.gst.set_volume_in( + id, + volume.mute, + volume.volume.first().map(|v| *v as f64 / 255f64), + ) { + log::warn!("Failed to set audio input volume: {}", e); + } + } + + async fn read(&mut self, id: u64, size: u64) -> Vec { + match self.gst.read_in(id, size).await { + Ok(d) => d, + Err(e) => { + log::warn!("Failed to read from input stream: {}", e); + vec![] + } + } + } +} + impl Handler { pub async fn new(mut audio: Audio) -> Result> { let gst = rdw::GstAudio::new()?; audio.register_out_listener(OutListener { gst }).await?; + let gst = rdw::GstAudio::new()?; + audio.register_in_listener(InListener { gst }).await?; Ok(Handler { audio }) } }