feat: Add PTT, Volume Sliders, and Device Node Selection
This commit is contained in:
+2
-2
@@ -18,11 +18,11 @@ pub enum AudioError {
|
||||
pub trait AudioBackend: Send + Sync {
|
||||
/// Starts capturing raw PCM audio from the input device (microphone),
|
||||
/// sending chunks of samples (e.g. `Vec<i16>`) to the provided Sender.
|
||||
fn start_capture(&self, tx: Sender<Vec<i16>>) -> Result<(), AudioError>;
|
||||
fn start_capture(&self, tx: Sender<Vec<i16>>, target_node: Option<String>) -> Result<(), AudioError>;
|
||||
|
||||
/// Starts playing back raw PCM audio to the output device (speaker),
|
||||
/// reading mixed/incoming chunks of samples from the provided Receiver.
|
||||
fn start_playback(&self, rx: Receiver<Vec<i16>>) -> Result<(), AudioError>;
|
||||
fn start_playback(&self, rx: Receiver<Vec<i16>>, target_node: Option<String>) -> Result<(), AudioError>;
|
||||
|
||||
/// Stops both capture and playback streams.
|
||||
fn stop(&self) -> Result<(), AudioError>;
|
||||
|
||||
@@ -35,7 +35,7 @@ impl PipeWireBackend {
|
||||
}
|
||||
|
||||
impl AudioBackend for PipeWireBackend {
|
||||
fn start_capture(&self, tx: Sender<Vec<i16>>) -> Result<(), AudioError> {
|
||||
fn start_capture(&self, tx: Sender<Vec<i16>>, target_node: Option<String>) -> Result<(), AudioError> {
|
||||
let mut capture_guard = self.capture_state.lock().unwrap();
|
||||
if capture_guard.is_some() {
|
||||
return Err(AudioError::Stream("Capture already started".to_string()));
|
||||
@@ -47,7 +47,7 @@ impl AudioBackend for PipeWireBackend {
|
||||
let thread = thread::Builder::new()
|
||||
.name("peerspeak-capture".to_string())
|
||||
.spawn(move || {
|
||||
if let Err(e) = run_capture(cmd_rx, tx_clone) {
|
||||
if let Err(e) = run_capture(cmd_rx, tx_clone, target_node) {
|
||||
eprintln!("Capture thread error: {:?}", e);
|
||||
}
|
||||
})
|
||||
@@ -57,7 +57,7 @@ impl AudioBackend for PipeWireBackend {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn start_playback(&self, rx: Receiver<Vec<i16>>) -> Result<(), AudioError> {
|
||||
fn start_playback(&self, rx: Receiver<Vec<i16>>, target_node: Option<String>) -> Result<(), AudioError> {
|
||||
let mut playback_guard = self.playback_state.lock().unwrap();
|
||||
if playback_guard.is_some() {
|
||||
return Err(AudioError::Stream("Playback already started".to_string()));
|
||||
@@ -68,7 +68,7 @@ impl AudioBackend for PipeWireBackend {
|
||||
let thread = thread::Builder::new()
|
||||
.name("peerspeak-playback".to_string())
|
||||
.spawn(move || {
|
||||
if let Err(e) = run_playback(cmd_rx, rx) {
|
||||
if let Err(e) = run_playback(cmd_rx, rx, target_node) {
|
||||
eprintln!("Playback thread error: {:?}", e);
|
||||
}
|
||||
})
|
||||
@@ -97,7 +97,7 @@ impl AudioBackend for PipeWireBackend {
|
||||
}
|
||||
}
|
||||
|
||||
fn run_capture(cmd_rx: pw::channel::Receiver<()>, tx: Sender<Vec<i16>>) -> Result<(), AudioError> {
|
||||
fn run_capture(cmd_rx: pw::channel::Receiver<()>, tx: Sender<Vec<i16>>, target_node: Option<String>) -> Result<(), AudioError> {
|
||||
let mainloop = pw::main_loop::MainLoopRc::new(None)
|
||||
.map_err(|e| AudioError::Init(e.to_string()))?;
|
||||
let context = pw::context::ContextRc::new(&mainloop, None)
|
||||
@@ -115,11 +115,14 @@ fn run_capture(cmd_rx: pw::channel::Receiver<()>, tx: Sender<Vec<i16>>) -> Resul
|
||||
mainloop_clone.quit();
|
||||
});
|
||||
|
||||
let props = properties! {
|
||||
let mut props = properties! {
|
||||
*pw::keys::MEDIA_TYPE => "Audio",
|
||||
*pw::keys::MEDIA_CATEGORY => "Capture",
|
||||
*pw::keys::MEDIA_ROLE => "Communication",
|
||||
};
|
||||
if let Some(target) = target_node {
|
||||
props.insert("node.target", target);
|
||||
}
|
||||
|
||||
let stream = pw::stream::StreamBox::new(&core, "peerspeak-capture-stream", props)
|
||||
.map_err(|e| AudioError::Init(e.to_string()))?;
|
||||
@@ -210,7 +213,7 @@ fn run_capture(cmd_rx: pw::channel::Receiver<()>, tx: Sender<Vec<i16>>) -> Resul
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_playback(cmd_rx: pw::channel::Receiver<()>, rx: Receiver<Vec<i16>>) -> Result<(), AudioError> {
|
||||
fn run_playback(cmd_rx: pw::channel::Receiver<()>, rx: Receiver<Vec<i16>>, target_node: Option<String>) -> Result<(), AudioError> {
|
||||
let mainloop = pw::main_loop::MainLoopRc::new(None)
|
||||
.map_err(|e| AudioError::Init(e.to_string()))?;
|
||||
let context = pw::context::ContextRc::new(&mainloop, None)
|
||||
@@ -228,11 +231,14 @@ fn run_playback(cmd_rx: pw::channel::Receiver<()>, rx: Receiver<Vec<i16>>) -> Re
|
||||
mainloop_clone.quit();
|
||||
});
|
||||
|
||||
let props = properties! {
|
||||
let mut props = properties! {
|
||||
*pw::keys::MEDIA_TYPE => "Audio",
|
||||
*pw::keys::MEDIA_CATEGORY => "Playback",
|
||||
*pw::keys::MEDIA_ROLE => "Communication",
|
||||
};
|
||||
if let Some(target) = target_node {
|
||||
props.insert("node.target", target);
|
||||
}
|
||||
|
||||
let stream = pw::stream::StreamBox::new(&core, "peerspeak-playback-stream", props)
|
||||
.map_err(|e| AudioError::Init(e.to_string()))?;
|
||||
|
||||
Reference in New Issue
Block a user