diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/NativeLib.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/NativeLib.kt index b94dd939..cc217013 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/NativeLib.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/NativeLib.kt @@ -271,6 +271,8 @@ object NativeLib { fun callAudioProgress(callId: Long, epoch: Long, position: Long, nowUs: Long) = nativeCallAudioProgress(callId, epoch, position, nowUs) /** out: epoch, source_epoch, played, written, pts_us, valid, measured, held_back_us. */ fun callAudioClock(callId: Long, nowUs: Long, out: LongArray): Boolean = nativeCallAudioClock(callId, nowUs, out) + /** call=debug: encoded_ms, processing_ms, reserve_ms, spread_ms, pcm_samples, tempo_x100, underruns, waiting. */ + fun callAudioDiagnostics(callId: Long, out: LongArray): Boolean = nativeCallAudioDiagnostics(callId, out) fun callAudioStop() { nativeCallAudioStop() } /* AEC (эхоподавление): включается по спикерфону; delay — измеренная задержка в кадрах. */ @@ -404,6 +406,7 @@ object NativeLib { private external fun nativeCallAudioPull(callId: Long, out: ShortArray): Int private external fun nativeCallAudioProgress(callId: Long, epoch: Long, position: Long, nowUs: Long) private external fun nativeCallAudioClock(callId: Long, nowUs: Long, out: LongArray): Boolean + private external fun nativeCallAudioDiagnostics(callId: Long, out: LongArray): Boolean private external fun nativeCallAudioStop() private external fun nativeCallAudioSetAec(enabled: Boolean) private external fun nativeCallAudioSetAecDelay(frames: Int) diff --git a/tools/chatgui-android/jni_bridge/android_jni_bridge.c b/tools/chatgui-android/jni_bridge/android_jni_bridge.c index 4548088d..abb009a5 100644 --- a/tools/chatgui-android/jni_bridge/android_jni_bridge.c +++ b/tools/chatgui-android/jni_bridge/android_jni_bridge.c @@ -2713,6 +2713,27 @@ JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeCallAudioCloc return JNI_TRUE; } +/* Диагностика включается тем же фильтром call=debug, что и нативные сводки. */ +JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeCallAudioDiagnostics( + JNIEnv* env, jobject thiz, jlong callId, jlongArray out) { + (void)thiz; + if (!debug_should_output(DEBUG_LEVEL_DEBUG, DEBUG_CATEGORY_CALL)) return JNI_FALSE; + if (!out || (*env)->GetArrayLength(env, out) != 8) { + DEBUG_ERROR(DEBUG_CATEGORY_CALL, "call diagnostics: expected LongArray(8)"); + return JNI_FALSE; + } + struct call_jitter_diagnostics d; + if (call_audio_get_diagnostics(callId, &d) != 0) return JNI_FALSE; + jlong values[8] = {d.encoded_ms, d.processing_ms, d.reserve_ms, d.arrival_spread_ms, + d.pcm_samples, d.tempo_x100, d.underruns, d.waiting}; + (*env)->SetLongArrayRegion(env, out, 0, 8, values); + if ((*env)->ExceptionCheck(env)) { + DEBUG_ERROR(DEBUG_CATEGORY_CALL, "call diagnostics: JNI snapshot copy failed"); + return JNI_FALSE; + } + return JNI_TRUE; +} + /* ── nativeCallAudioPull(callId, out) → возвращает число сэмплов ── * out — предвыделенный ShortArray (960), заполняется из аудио-потока Kotlin. */ JNIEXPORT jint JNICALL Java_com_utun_chat_data_NativeLib_nativeCallAudioPull(