A wee bit more if Jack
Some checks failed
ci/woodpecker/push/code_tests Pipeline failed
ci/woodpecker/push/pre_commit_test Pipeline failed

This commit is contained in:
2025-12-17 08:39:26 +01:00
parent ce5669636a
commit 2ce3d028c6
5 changed files with 51 additions and 31 deletions

View File

@@ -9,6 +9,10 @@ impl AudioBackend for CoreAudioBackend {
fn start_client(&mut self) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
fn describe_backend() -> Result<super::BackendDescription, Box<dyn std::error::Error>> {
todo!()
}
}
#[cfg(not(feature = "coreaudio"))]
@@ -16,4 +20,7 @@ impl AudioBackend for CoreAudioBackend {
fn start_client(&mut self) -> Result<(), Box<dyn std::error::Error>> {
todo!()
}
fn describe_backend() -> Result<super::BackendDescription, Box<dyn std::error::Error>> {
todo!()
}
}

View File

@@ -12,4 +12,8 @@ impl AudioBackend for DummyAudioBackend {
fn start_client(&mut self) -> Result<(), Box<dyn std::error::Error>> {
todo!()
}
fn describe_backend() -> Result<super::BackendDescription, Box<dyn std::error::Error>> {
todo!()
}
}

View File

@@ -5,6 +5,8 @@ use std::error::Error;
#[cfg(feature = "jack")]
use jack;
#[cfg(feature = "jack")]
use jack::ClientOptions;
pub(crate) struct JackAudioBackend {
pub(crate) feature_jack: bool,
@@ -38,40 +40,25 @@ impl AudioBackend for JackAudioBackend {
fn start_client(&mut self) -> Result<(), Box<dyn Error>> {
Ok(())
}
}
#[cfg(feature = "jack")]
#[cfg(test)]
mod tests {
use jack::ClientOptions;
// Get the possible input and output ports to use them for the session initialization
fn describe_backend() -> Result<super::BackendDescription, Box<dyn Error>> {
use jack::{Client, PortFlags};
use crate::audio_engine::BackendDescription;
use super::*;
#[test]
fn start_jack_client() {
let (client, _status) =
jack::Client::new("list_clients_example", ClientOptions::NO_START_SERVER)
.expect("Failed to create JACK client");
// Get all ports, then extract the unique client names
let ports = client.ports(None, None, jack::PortFlags::empty());
let mut clients: Vec<String> = ports
.iter()
.filter_map(|port| port.split(':').next().map(|s| s.to_string()))
.collect();
clients.sort();
clients.dedup();
println!("JACK clients:");
for c in clients {
assert_eq!(c, "test");
println!(" - {}", c);
}
let (client, _) = Client::new("list_ports", ClientOptions::empty())?;
let ports_in = client.ports(None, None, PortFlags::IS_INPUT);
let ports_out = client.ports(None, None, PortFlags::IS_OUTPUT);
let output = BackendDescription {
audio_devices_out: ports_out,
audio_devices_in: ports_in,
};
Ok(output)
}
}
#[cfg(not(feature = "jack"))]
#[derive(Default)]
pub(crate) struct JackStatus {}
@@ -82,4 +69,7 @@ impl AudioBackend for JackAudioBackend {
warn!("jack support is not enabled");
Ok(())
}
fn describe_backend() -> Result<super::BackendDescription, Box<dyn Error>> {
unimplemented!("jack is disabled")
}
}

View File

@@ -4,9 +4,14 @@ pub(crate) mod coreaudio_ab;
pub(crate) mod dummy_ab;
pub(crate) mod jack_ab;
pub(crate) struct BackendDescription {
pub(crate) audio_devices_out: Vec<String>,
pub(crate) audio_devices_in: Vec<String>,
}
pub(crate) trait AudioBackend {
// Start a audio backend client
// It should be executed either on the startup,
// or when the audio backend is switched
fn start_client(&mut self) -> Result<(), Box<dyn Error>>;
fn describe_backend() -> Result<BackendDescription, Box<dyn Error>>;
}

View File

@@ -9,7 +9,7 @@ use lib::termix::{
},
};
use log::info;
use tonic::{Response, transport::Server};
use tonic::{Response, Status, transport::Server};
use tonic_reflection::server;
use crate::{
@@ -83,7 +83,21 @@ impl AudioBackendRpc for TermixAudioBackend {
request: tonic::Request<DesiredAudioBacked>,
) -> Result<tonic::Response<AudioBackendDescription>, tonic::Status> {
info!("Describing the audio backend");
todo!();
match request.get_ref().backend() {
SupportedAudioBackends::AbUnspecified => return Err(Status::not_found("backend os not specified")),
SupportedAudioBackends::AbCoreaudio => todo!(),
SupportedAudioBackends::AbJack => {
let backend_desc= match jack_ab::JackAudioBackend::describe_backend(){
Ok(desc) => desc,
Err(err) => return Err(Status::internal(err.to_string())),
};
Ok(Response::new(AudioBackendDescription{
core_audio_description: None,
input_devices: backend_desc.audio_devices_in,
output_devices: backend_desc.audio_devices_out
}))
}
}
}
async fn init_connection(
&self,