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:
37
src/state.rs
37
src/state.rs
@@ -29,6 +29,11 @@ pub struct VmicState {
|
||||
// pitfalls here, unlike PipeWire's JSON dump (see pw::text).
|
||||
pub mic_source: Option<String>,
|
||||
pub mic_volume_pct: Option<u8>,
|
||||
|
||||
// Opt-in: keep the 2-node topology even when a source is mixed in while
|
||||
// the self-monitor loopback is on, accepting that the mix becomes
|
||||
// audible in the loopback instead of paying for a 4-node split.
|
||||
pub loopback_no_mix: bool,
|
||||
}
|
||||
|
||||
fn db_path() -> PathBuf {
|
||||
@@ -90,12 +95,33 @@ pub fn open_db() -> Result<Connection> {
|
||||
loopback_id INTEGER,
|
||||
volume_pct INTEGER,
|
||||
mic_source TEXT,
|
||||
mic_volume_pct INTEGER
|
||||
mic_volume_pct INTEGER,
|
||||
loopback_no_mix INTEGER NOT NULL DEFAULT 0
|
||||
);",
|
||||
)?;
|
||||
migrate_add_loopback_no_mix(&conn)?;
|
||||
Ok(conn)
|
||||
}
|
||||
|
||||
/// `CREATE TABLE IF NOT EXISTS` above only covers fresh databases; an
|
||||
/// existing `vmic.db` from before `loopback_no_mix` existed needs the column
|
||||
/// added explicitly. Safe to call unconditionally - a no-op once the column
|
||||
/// is present either way.
|
||||
fn migrate_add_loopback_no_mix(conn: &Connection) -> Result<()> {
|
||||
let has_column = conn
|
||||
.prepare("PRAGMA table_info(vmics)")?
|
||||
.query_map([], |row| row.get::<_, String>(1))?
|
||||
.filter_map(std::result::Result::ok)
|
||||
.any(|c| c == "loopback_no_mix");
|
||||
if !has_column {
|
||||
conn.execute(
|
||||
"ALTER TABLE vmics ADD COLUMN loopback_no_mix INTEGER NOT NULL DEFAULT 0",
|
||||
[],
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl VmicState {
|
||||
fn from_row(row: &rusqlite::Row) -> rusqlite::Result<Self> {
|
||||
Ok(Self {
|
||||
@@ -112,6 +138,7 @@ impl VmicState {
|
||||
volume_pct: row.get("volume_pct")?,
|
||||
mic_source: row.get("mic_source")?,
|
||||
mic_volume_pct: row.get("mic_volume_pct")?,
|
||||
loopback_no_mix: row.get("loopback_no_mix")?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -135,8 +162,8 @@ impl VmicState {
|
||||
"INSERT INTO vmics (
|
||||
name, sink_name, mid_name, mix_name, source_name,
|
||||
sink_node_id, mix_node_id, sink_pid, mix_pid, loopback_id, volume_pct,
|
||||
mic_source, mic_volume_pct
|
||||
) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)
|
||||
mic_source, mic_volume_pct, loopback_no_mix
|
||||
) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14)
|
||||
ON CONFLICT(name) DO UPDATE SET
|
||||
sink_name = excluded.sink_name,
|
||||
mid_name = excluded.mid_name,
|
||||
@@ -149,7 +176,8 @@ impl VmicState {
|
||||
loopback_id = excluded.loopback_id,
|
||||
volume_pct = excluded.volume_pct,
|
||||
mic_source = excluded.mic_source,
|
||||
mic_volume_pct = excluded.mic_volume_pct",
|
||||
mic_volume_pct = excluded.mic_volume_pct,
|
||||
loopback_no_mix = excluded.loopback_no_mix",
|
||||
params![
|
||||
self.name,
|
||||
self.sink_name,
|
||||
@@ -164,6 +192,7 @@ impl VmicState {
|
||||
self.volume_pct,
|
||||
self.mic_source,
|
||||
self.mic_volume_pct,
|
||||
self.loopback_no_mix,
|
||||
],
|
||||
)?;
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user