[WIP] Fix: crackling sound when seeking forwars

This commit is contained in:
Alex P 2025-09-30 13:11:16 +00:00
parent e989cad633
commit 05b347fe74
1 changed files with 6 additions and 21 deletions

View File

@ -588,7 +588,6 @@ int jetkvm_audio_capture_init() {
__attribute__((hot)) int jetkvm_audio_read_encode(void * __restrict__ opus_buf) { __attribute__((hot)) int jetkvm_audio_read_encode(void * __restrict__ opus_buf) {
static short SIMD_ALIGN pcm_buffer[1920]; static short SIMD_ALIGN pcm_buffer[1920];
static short prev_max_sample = 0; // Track previous frame's peak for discontinuity detection static short prev_max_sample = 0; // Track previous frame's peak for discontinuity detection
static int silence_count = 0; // Count consecutive silent frames
unsigned char * __restrict__ out = (unsigned char*)opus_buf; unsigned char * __restrict__ out = (unsigned char*)opus_buf;
SIMD_PREFETCH(out, 1, 3); SIMD_PREFETCH(out, 1, 3);
@ -673,37 +672,23 @@ retry_read:
short max_sample = simd_find_max_abs_s16(pcm_buffer, total_samples); short max_sample = simd_find_max_abs_s16(pcm_buffer, total_samples);
if (max_sample < 50) { if (max_sample < 50) {
silence_count++; prev_max_sample = 0; // Reset on silence
if (silence_count > 2) {
prev_max_sample = 0; // Reset after extended silence
}
if (trace_logging_enabled) { if (trace_logging_enabled) {
printf("[AUDIO_OUTPUT] jetkvm_audio_read_encode: Silence detected (max=%d), skipping frame\n", max_sample); printf("[AUDIO_OUTPUT] jetkvm_audio_read_encode: Silence detected (max=%d), skipping frame\n", max_sample);
} }
return 0; return 0;
} }
// Detect audio discontinuity (video seek): sudden level change after silence // Detect discontinuity (video seek): abrupt level change >5x
// If audio level jumps >4x after 2+ silent frames, likely a seek occurred if (prev_max_sample > 0) {
if (silence_count >= 2 && prev_max_sample > 0) { int level_ratio = (max_sample > prev_max_sample * 5) || (prev_max_sample > max_sample * 5);
int level_ratio = (max_sample > prev_max_sample) ? if (level_ratio) {
(max_sample / (prev_max_sample + 1)) :
(prev_max_sample / (max_sample + 1));
if (level_ratio > 4) {
if (trace_logging_enabled) { if (trace_logging_enabled) {
printf("[AUDIO_OUTPUT] Discontinuity detected (level jump %dx: %d→%d), resetting encoder\n", printf("[AUDIO_OUTPUT] Discontinuity detected (%d→%d), resetting encoder\n", prev_max_sample, max_sample);
level_ratio, prev_max_sample, max_sample);
} }
// Reset Opus encoder state to prevent mixing old/new audio context
opus_encoder_ctl(encoder, OPUS_RESET_STATE); opus_encoder_ctl(encoder, OPUS_RESET_STATE);
// Drop and reprepare ALSA to flush any buffered old audio
snd_pcm_drop(pcm_capture_handle);
snd_pcm_prepare(pcm_capture_handle);
} }
} }
silence_count = 0;
prev_max_sample = max_sample; prev_max_sample = max_sample;
// Apply moderate 2.5x gain to prevent quantization noise on transients // Apply moderate 2.5x gain to prevent quantization noise on transients