Fix call gap tone to follow 500ms of missing jitter PCM
This commit is contained in:
1 parent
9e3a417059
commit
1c51df039f
2 files changed
+68
-36
No files matched your search
+32
-20
@@ -25,7 +25,7 @@
|
||||
|
||||
#define CALL_AUDIO_ID "call_audio"
|
||||
#define CALL_AUDIO_BITRATE 32000
|
||||
#define CALL_STALL_TB 5000 /* 500мс без медиа и недобор PCM → глитч-тон */
|
||||
#define CALL_STALL_SAMPLES (CALL_AUDIO_SAMPLE_RATE / 2) /* 500мс без PCM из jitter → глитч-тон */
|
||||
#define CALL_AEC_FILTER_SAMPLES 14400 /* хвост эха 300мс @48кГц */
|
||||
#define CALL_AEC_DELAY_FRAMES 2 /* desktop: минимальная задержка duplex */
|
||||
|
||||
@@ -36,7 +36,7 @@ static int g_ending = 0;
|
||||
static int g_glitch_started = 0; /* только аудиопоток */
|
||||
static int g_ended_started = 0; /* только аудио-поток: тон завершения запущен */
|
||||
static uint64_t g_call_id = 0;
|
||||
static uint64_t g_last_media_tb = 0;
|
||||
static int g_gap_samples = 0; /* только аудиопоток; насыщение на пороге */
|
||||
static opus_codec_encoder_t* g_encoder = NULL;
|
||||
static opus_codec_decoder_t* g_decoder = NULL;
|
||||
static struct call_jitter* g_vj = NULL;
|
||||
@@ -85,7 +85,6 @@ void call_audio_on_media(struct UTUN_INSTANCE* inst, uint64_t call_id,
|
||||
pthread_mutex_lock(&g_mtx);
|
||||
if (g_active && call_id == g_call_id && g_vj && opus && len > 0) {
|
||||
call_jitter_push(g_vj, opus, len);
|
||||
g_last_media_tb = get_time_tb();
|
||||
}
|
||||
pthread_mutex_unlock(&g_mtx);
|
||||
}
|
||||
@@ -185,7 +184,7 @@ int call_audio_start(uint64_t call_id) {
|
||||
g_ending = 0;
|
||||
g_ended_started = 0;
|
||||
g_glitch_started = 0;
|
||||
g_last_media_tb = 0;
|
||||
g_gap_samples = 0;
|
||||
pthread_mutex_unlock(&g_mtx);
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CALL, "%s: started call=0x%016llx aec=%d delay=%d compressor=%s gain=%d", CALL_AUDIO_ID,
|
||||
@@ -220,7 +219,7 @@ void call_audio_release(uint64_t call_id) {
|
||||
g_ending = 0;
|
||||
g_ended_started = 0;
|
||||
g_call_id = 0;
|
||||
g_last_media_tb = 0;
|
||||
g_gap_samples = 0;
|
||||
enc = g_encoder; g_encoder = NULL;
|
||||
dec = g_decoder; g_decoder = NULL;
|
||||
j = g_vj; g_vj = NULL;
|
||||
@@ -347,7 +346,6 @@ int call_audio_pull_pcm(uint64_t call_id, int16_t* out, int max_samples) {
|
||||
int active = 0, ending = 0;
|
||||
struct call_jitter* j = NULL;
|
||||
struct call_tones* tones = NULL;
|
||||
uint64_t last_media = 0;
|
||||
|
||||
pthread_mutex_lock(&g_mtx);
|
||||
if (g_active && call_id == g_call_id) {
|
||||
@@ -355,7 +353,6 @@ int call_audio_pull_pcm(uint64_t call_id, int16_t* out, int max_samples) {
|
||||
ending = g_ending;
|
||||
j = g_vj;
|
||||
tones = g_tones;
|
||||
last_media = g_last_media_tb;
|
||||
}
|
||||
pthread_mutex_unlock(&g_mtx);
|
||||
|
||||
@@ -375,21 +372,36 @@ int call_audio_pull_pcm(uint64_t call_id, int16_t* out, int max_samples) {
|
||||
n = call_tones_render(tones, out, max_samples);
|
||||
} else {
|
||||
n = call_jitter_pull(j, out, max_samples);
|
||||
uint64_t now = get_time_tb();
|
||||
int stalled = n < max_samples && last_media != 0 && now - last_media >= CALL_STALL_TB;
|
||||
if (stalled != g_glitch_started) {
|
||||
g_glitch_started = stalled;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CALL, "%s: gap tone %s call=%016llx media_gap=%llums pcm=%d/%d",
|
||||
CALL_AUDIO_ID, stalled ? "started" : "stopped", (unsigned long long)call_id,
|
||||
(unsigned long long)((now - last_media) / 10), n, max_samples);
|
||||
}
|
||||
if (stalled) {
|
||||
call_tones_glitch_start(tones);
|
||||
n += call_tones_render(tones, out + n, max_samples - n);
|
||||
} else {
|
||||
int previous_gap = g_gap_samples;
|
||||
if (n > 0) g_gap_samples = 0;
|
||||
int missing = max_samples - n;
|
||||
int quiet = CALL_STALL_SAMPLES - g_gap_samples;
|
||||
if (quiet > missing) quiet = missing;
|
||||
int tone_samples = missing - quiet;
|
||||
if (n > 0 && previous_gap > 0)
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CALL, "%s: PCM resumed call=%016llx gap=%dms pcm=%d/%d", CALL_AUDIO_ID,
|
||||
(unsigned long long)call_id, previous_gap * 1000 / CALL_AUDIO_SAMPLE_RATE, n, max_samples);
|
||||
if (missing > 0 && g_gap_samples == 0)
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CALL, "%s: PCM gap started call=%016llx pcm=%d/%d", CALL_AUDIO_ID,
|
||||
(unsigned long long)call_id, n, max_samples);
|
||||
g_gap_samples += quiet;
|
||||
/* Новый PCM прерывает предыдущий цикл тона, даже если хвост блока снова пуст. */
|
||||
if (g_glitch_started && (n > 0 || tone_samples == 0)) {
|
||||
g_glitch_started = 0;
|
||||
call_tones_glitch_stop(tones);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CALL, "%s: gap tone stopped call=%016llx pcm=%d/%d", CALL_AUDIO_ID,
|
||||
(unsigned long long)call_id, n, max_samples);
|
||||
}
|
||||
memset(out + n, 0, (size_t)quiet * sizeof(*out));
|
||||
if (tone_samples > 0) {
|
||||
if (!g_glitch_started) {
|
||||
g_glitch_started = 1;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CALL, "%s: gap tone started call=%016llx pcm_gap=500ms pcm=%d/%d", CALL_AUDIO_ID,
|
||||
(unsigned long long)call_id, n, max_samples);
|
||||
}
|
||||
call_tones_glitch_start(tones);
|
||||
call_tones_render(tones, out + n + quiet, tone_samples);
|
||||
}
|
||||
for (int i = n; i < max_samples; i++) out[i] = 0;
|
||||
n = max_samples;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user