fix(audio): add uac clock alignment override
This commit is contained in:
parent
a009f1b8e6
commit
cb408ebd9a
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -1642,7 +1642,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lesavka_client"
|
name = "lesavka_client"
|
||||||
version = "0.13.5"
|
version = "0.13.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-stream",
|
"async-stream",
|
||||||
@ -1676,7 +1676,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lesavka_common"
|
name = "lesavka_common"
|
||||||
version = "0.13.5"
|
version = "0.13.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
@ -1688,7 +1688,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lesavka_server"
|
name = "lesavka_server"
|
||||||
version = "0.13.5"
|
version = "0.13.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
|
|||||||
@ -4,7 +4,7 @@ path = "src/main.rs"
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "lesavka_client"
|
name = "lesavka_client"
|
||||||
version = "0.13.5"
|
version = "0.13.6"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "lesavka_common"
|
name = "lesavka_common"
|
||||||
version = "0.13.5"
|
version = "0.13.6"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
|
|||||||
@ -187,6 +187,7 @@ Hardware-facing assumptions belong near the code that uses them; this file is th
|
|||||||
| `LESAVKA_UAC_DEV` | server hardware/device override |
|
| `LESAVKA_UAC_DEV` | server hardware/device override |
|
||||||
| `LESAVKA_UAC_HDMI_COMPENSATION_US` | server HDMI audio sink latency override |
|
| `LESAVKA_UAC_HDMI_COMPENSATION_US` | server HDMI audio sink latency override |
|
||||||
| `LESAVKA_UAC_LATENCY_TIME_US` | server audio sink latency override |
|
| `LESAVKA_UAC_LATENCY_TIME_US` | server audio sink latency override |
|
||||||
|
| `LESAVKA_UAC_SESSION_CLOCK_ALIGN` | server audio sink clock-alignment override |
|
||||||
| `LESAVKA_TEST_CAM_U32` | test/build contract variable; not runtime operator config |
|
| `LESAVKA_TEST_CAM_U32` | test/build contract variable; not runtime operator config |
|
||||||
| `LESAVKA_TEST_CAP_CAMERA` | test/build contract variable; not runtime operator config |
|
| `LESAVKA_TEST_CAP_CAMERA` | test/build contract variable; not runtime operator config |
|
||||||
| `LESAVKA_TEST_CAP_MIC` | test/build contract variable; not runtime operator config |
|
| `LESAVKA_TEST_CAP_MIC` | test/build contract variable; not runtime operator config |
|
||||||
@ -211,6 +212,7 @@ Hardware-facing assumptions belong near the code that uses them; this file is th
|
|||||||
| `LESAVKA_TEST_VIDEO_SOURCE` | test/build contract variable; not runtime operator config |
|
| `LESAVKA_TEST_VIDEO_SOURCE` | test/build contract variable; not runtime operator config |
|
||||||
| `LESAVKA_TOUCHPAD_SCALE` | input routing/clipboard override |
|
| `LESAVKA_TOUCHPAD_SCALE` | input routing/clipboard override |
|
||||||
| `LESAVKA_UAC_DEV` | server hardware/device override |
|
| `LESAVKA_UAC_DEV` | server hardware/device override |
|
||||||
|
| `LESAVKA_UAC_SESSION_CLOCK_ALIGN` | disable only for A/B diagnosing UAC sink timing vs silence |
|
||||||
| `LESAVKA_UPLINK_CAMERA_PREVIEW` | client media capture/playback override |
|
| `LESAVKA_UPLINK_CAMERA_PREVIEW` | client media capture/playback override |
|
||||||
| `LESAVKA_UPLINK_MIC_LEVEL` | client media capture/playback override |
|
| `LESAVKA_UPLINK_MIC_LEVEL` | client media capture/playback override |
|
||||||
| `LESAVKA_USB_RECOVERY_` | USB recovery timing override |
|
| `LESAVKA_USB_RECOVERY_` | USB recovery timing override |
|
||||||
|
|||||||
@ -437,6 +437,7 @@ fi
|
|||||||
printf 'LESAVKA_UAC_DEV=%s\n' "${LESAVKA_UAC_DEV:-hw:UAC2Gadget,0}"
|
printf 'LESAVKA_UAC_DEV=%s\n' "${LESAVKA_UAC_DEV:-hw:UAC2Gadget,0}"
|
||||||
printf 'LESAVKA_ALSA_DEV=%s\n' "${LESAVKA_ALSA_DEV:-hw:UAC2Gadget,0}"
|
printf 'LESAVKA_ALSA_DEV=%s\n' "${LESAVKA_ALSA_DEV:-hw:UAC2Gadget,0}"
|
||||||
printf 'LESAVKA_UAC_HDMI_COMPENSATION_US=%s\n' "${LESAVKA_UAC_HDMI_COMPENSATION_US:-0}"
|
printf 'LESAVKA_UAC_HDMI_COMPENSATION_US=%s\n' "${LESAVKA_UAC_HDMI_COMPENSATION_US:-0}"
|
||||||
|
printf 'LESAVKA_UAC_SESSION_CLOCK_ALIGN=%s\n' "${LESAVKA_UAC_SESSION_CLOCK_ALIGN:-1}"
|
||||||
} | sudo tee /etc/lesavka/server.env >/dev/null
|
} | sudo tee /etc/lesavka/server.env >/dev/null
|
||||||
|
|
||||||
echo "==> 6a. Systemd units - lesavka-core"
|
echo "==> 6a. Systemd units - lesavka-core"
|
||||||
|
|||||||
@ -10,7 +10,7 @@ bench = false
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "lesavka_server"
|
name = "lesavka_server"
|
||||||
version = "0.13.5"
|
version = "0.13.6"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
autobins = false
|
autobins = false
|
||||||
|
|
||||||
|
|||||||
@ -106,6 +106,19 @@ fn non_negative_voice_sink_timing_env(name: &str, default: i64) -> i64 {
|
|||||||
.unwrap_or(default)
|
.unwrap_or(default)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn voice_sink_session_clock_align_enabled() -> bool {
|
||||||
|
std::env::var("LESAVKA_UAC_SESSION_CLOCK_ALIGN")
|
||||||
|
.ok()
|
||||||
|
.map(|value| {
|
||||||
|
let trimmed = value.trim();
|
||||||
|
!(trimmed.eq_ignore_ascii_case("0")
|
||||||
|
|| trimmed.eq_ignore_ascii_case("false")
|
||||||
|
|| trimmed.eq_ignore_ascii_case("no")
|
||||||
|
|| trimmed.eq_ignore_ascii_case("off"))
|
||||||
|
})
|
||||||
|
.unwrap_or(true)
|
||||||
|
}
|
||||||
|
|
||||||
impl Voice {
|
impl Voice {
|
||||||
#[cfg(coverage)]
|
#[cfg(coverage)]
|
||||||
pub async fn new(_alsa_dev: &str) -> anyhow::Result<Self> {
|
pub async fn new(_alsa_dev: &str) -> anyhow::Result<Self> {
|
||||||
@ -196,10 +209,11 @@ impl Voice {
|
|||||||
let buffer_time_us = voice_sink_buffer_time_us();
|
let buffer_time_us = voice_sink_buffer_time_us();
|
||||||
let latency_time_us = voice_sink_latency_time_us();
|
let latency_time_us = voice_sink_latency_time_us();
|
||||||
let compensation_us = voice_sink_compensation_us();
|
let compensation_us = voice_sink_compensation_us();
|
||||||
|
let clock_align_enabled = voice_sink_session_clock_align_enabled();
|
||||||
|
|
||||||
alsa_sink.set_property("device", alsa_dev);
|
alsa_sink.set_property("device", alsa_dev);
|
||||||
alsa_sink.set_property("sync", true);
|
alsa_sink.set_property("sync", clock_align_enabled);
|
||||||
alsa_sink.set_property("async", true);
|
alsa_sink.set_property("async", clock_align_enabled);
|
||||||
alsa_sink.set_property("enable-last-sample", false);
|
alsa_sink.set_property("enable-last-sample", false);
|
||||||
alsa_sink.set_property("provide-clock", false);
|
alsa_sink.set_property("provide-clock", false);
|
||||||
alsa_sink.set_property("buffer-time", buffer_time_us);
|
alsa_sink.set_property("buffer-time", buffer_time_us);
|
||||||
@ -214,9 +228,12 @@ impl Voice {
|
|||||||
buffer_time_us,
|
buffer_time_us,
|
||||||
latency_time_us,
|
latency_time_us,
|
||||||
compensation_us,
|
compensation_us,
|
||||||
|
clock_align_enabled,
|
||||||
"🎤 UAC sink low-latency timing armed"
|
"🎤 UAC sink low-latency timing armed"
|
||||||
);
|
);
|
||||||
crate::media_timing::prepare_pipeline_clock_sync(&pipeline);
|
if clock_align_enabled {
|
||||||
|
crate::media_timing::prepare_pipeline_clock_sync(&pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
pipeline.add_many([
|
pipeline.add_many([
|
||||||
appsrc.upcast_ref(),
|
appsrc.upcast_ref(),
|
||||||
@ -273,7 +290,7 @@ impl Voice {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
appsrc,
|
appsrc,
|
||||||
_pipe: pipeline,
|
_pipe: pipeline,
|
||||||
clock_aligned: false,
|
clock_aligned: !clock_align_enabled,
|
||||||
tap: ClipTap::new("voice", Duration::from_secs(60)),
|
tap: ClipTap::new("voice", Duration::from_secs(60)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -389,4 +406,21 @@ mod voice_sink_timing_tests {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn session_clock_alignment_defaults_on_and_accepts_disable_overrides() {
|
||||||
|
temp_env::with_var_unset("LESAVKA_UAC_SESSION_CLOCK_ALIGN", || {
|
||||||
|
assert!(super::voice_sink_session_clock_align_enabled());
|
||||||
|
});
|
||||||
|
|
||||||
|
for disabled in ["0", "false", "no", "off"] {
|
||||||
|
temp_env::with_var("LESAVKA_UAC_SESSION_CLOCK_ALIGN", Some(disabled), || {
|
||||||
|
assert!(!super::voice_sink_session_clock_align_enabled());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_env::with_var("LESAVKA_UAC_SESSION_CLOCK_ALIGN", Some("1"), || {
|
||||||
|
assert!(super::voice_sink_session_clock_align_enabled());
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user