|
|
|
|
@ -1579,8 +1579,8 @@ int utun_bridge_call_audio_start(uint64_t call_id) {
|
|
|
|
|
return call_audio_start(call_id); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int utun_bridge_call_audio_feed(uint64_t call_id, const int16_t* pcm, int count) { |
|
|
|
|
return call_audio_feed_pcm(call_id, pcm, count); |
|
|
|
|
int utun_bridge_call_audio_feed(uint64_t call_id, const int16_t* pcm, int count, int64_t capture_pts_us) { |
|
|
|
|
return call_audio_feed_pcm(call_id, pcm, count, capture_pts_us); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void utun_bridge_call_audio_stop(void) { |
|
|
|
|
@ -2664,12 +2664,19 @@ JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeCallAudioStar
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeCallAudioFeed( |
|
|
|
|
JNIEnv* env, jobject thiz, jlong callId, jshortArray samples) { |
|
|
|
|
(void)env; (void)thiz; |
|
|
|
|
if (!samples) return JNI_FALSE; |
|
|
|
|
JNIEnv* env, jobject thiz, jlong callId, jshortArray samples, jlong capturePtsUs) { |
|
|
|
|
(void)thiz; |
|
|
|
|
if (!samples) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "call capture: null PCM"); |
|
|
|
|
return JNI_FALSE; |
|
|
|
|
} |
|
|
|
|
jsize len = (*env)->GetArrayLength(env, samples); |
|
|
|
|
jshort* data = (*env)->GetShortArrayElements(env, samples, NULL); |
|
|
|
|
int rc = utun_bridge_call_audio_feed((uint64_t)callId, (const int16_t*)data, (int)len); |
|
|
|
|
if (!data) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "call capture: JNI PCM access failed"); |
|
|
|
|
return JNI_FALSE; |
|
|
|
|
} |
|
|
|
|
int rc = utun_bridge_call_audio_feed((uint64_t)callId, (const int16_t*)data, (int)len, capturePtsUs); |
|
|
|
|
(*env)->ReleaseShortArrayElements(env, samples, data, JNI_ABORT); |
|
|
|
|
return (rc == 0) ? JNI_TRUE : JNI_FALSE; |
|
|
|
|
} |
|
|
|
|
@ -2680,6 +2687,32 @@ JNIEXPORT void JNICALL Java_com_utun_chat_data_NativeLib_nativeCallAudioStop(
|
|
|
|
|
utun_bridge_call_audio_stop(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
JNIEXPORT void JNICALL Java_com_utun_chat_data_NativeLib_nativeCallAudioProgress( |
|
|
|
|
JNIEnv* env, jobject thiz, jlong callId, jlong epoch, jlong position, jlong nowUs) { |
|
|
|
|
(void)env; (void)thiz; |
|
|
|
|
call_audio_playback_progress(callId, epoch, position, nowUs, nowUs, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Предвыделенный снимок: epoch, source_epoch, played, written, pts, valid, measured, held_back_us. */ |
|
|
|
|
JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeCallAudioClock( |
|
|
|
|
JNIEnv* env, jobject thiz, jlong callId, jlong nowUs, jlongArray out) { |
|
|
|
|
(void)thiz; |
|
|
|
|
if (!out || (*env)->GetArrayLength(env, out) != 8) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "call clock: expected LongArray(8)"); |
|
|
|
|
return JNI_FALSE; |
|
|
|
|
} |
|
|
|
|
struct call_clock_snapshot s; |
|
|
|
|
if (call_audio_get_clock(callId, nowUs, &s) != 0) return JNI_FALSE; |
|
|
|
|
jlong values[8] = {s.epoch, s.source_epoch, s.played_samples, s.written_samples, |
|
|
|
|
s.pts_us, s.valid, s.measured, s.held_back_us}; |
|
|
|
|
(*env)->SetLongArrayRegion(env, out, 0, 8, values); |
|
|
|
|
if ((*env)->ExceptionCheck(env)) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "call clock: 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( |
|
|
|
|
|