Add support for --loopback-no-mix flag and topology synchronization

- Introduced the `--loopback-no-mix` flag to control 2-node vs 4-node loopback topologies.
- Updated topology handling logic to recompute and migrate as needed based on loopback flags.
- Enhanced database schema to include `loopback_no_mix` with automatic migration for backward compatibility.
- Refactored `create`, `edit`, and `route` commands to integrate new topology management capabilities.
- Improved `list` command output to include architecture details.
This commit is contained in:
2026-08-11 15:33:36 +02:00
parent be70c55728
commit 493f91bc28
10 changed files with 308 additions and 42 deletions

View File

@@ -1,3 +1,4 @@
use crate::commands::topology;
use crate::error::Result;
use crate::pw::PwGraph;
use crate::state::{self, VmicState};
@@ -21,6 +22,7 @@ pub fn run() -> Result<()> {
println!(" output device: {}", state.sink_name);
println!(" mic device: {}", state.source_name);
println!(" status: {status_colored}");
println!(" architecture: {}", topology::architecture_label(state));
println!(
" self-monitor loopback: {}",
state
@@ -46,12 +48,20 @@ pub fn run() -> Result<()> {
}
/// Checks `sink_node_id`/`mix_node_id` against the live graph snapshot.
/// `mix_node_id` is only expected to be alive when this vmic is currently
/// running as `Pure4Node` (`mix_pid.is_some()`) - a `Simple2Node` vmic never
/// has one, and that's not a problem.
fn liveness(graph: Option<&PwGraph>, state: &VmicState) -> String {
let Some(graph) = graph else {
return "unknown (could not connect to PipeWire)".to_string();
};
let nodes = graph.nodes();
let sink_alive = state.sink_node_id.is_some_and(|id| nodes.iter().any(|n| n.id == id));
if topology::current_topology(state) == topology::Topology::Simple2Node {
return if sink_alive { "active".to_string() } else { "stale (matching pw-loopback process not found)".to_string() };
}
let mix_alive = state.mix_node_id.is_some_and(|id| nodes.iter().any(|n| n.id == id));
match (sink_alive, mix_alive) {
(true, true) => "active".to_string(),