diff --git a/app/src/main/assets/3dspeaker_speech_eres2net_base_sv_zh-cn_3dspeaker_16k.onnx b/app/src/main/assets/3dspeaker_speech_eres2net_base_sv_zh-cn_3dspeaker_16k.onnx index 65ad555..dd917a2 100644 Binary files a/app/src/main/assets/3dspeaker_speech_eres2net_base_sv_zh-cn_3dspeaker_16k.onnx and b/app/src/main/assets/3dspeaker_speech_eres2net_base_sv_zh-cn_3dspeaker_16k.onnx differ diff --git a/app/src/main/java/com/zs/smarthuman/sherpa/VadManager.kt b/app/src/main/java/com/zs/smarthuman/sherpa/VadManager.kt index ff86af4..61115c7 100644 --- a/app/src/main/java/com/zs/smarthuman/sherpa/VadManager.kt +++ b/app/src/main/java/com/zs/smarthuman/sherpa/VadManager.kt @@ -28,7 +28,7 @@ class VadManager( sileroVadModelConfig = SileroVadModelConfig( model = "silero_vad.onnx", threshold = 0.5F, - minSilenceDuration = 0.25F, + minSilenceDuration = 0.1F, minSpeechDuration = 0.25F, windowSize = 512, ), diff --git a/app/src/main/java/com/zs/smarthuman/sherpa/VoiceController.kt b/app/src/main/java/com/zs/smarthuman/sherpa/VoiceController.kt index c3a6287..39b3ec8 100644 --- a/app/src/main/java/com/zs/smarthuman/sherpa/VoiceController.kt +++ b/app/src/main/java/com/zs/smarthuman/sherpa/VoiceController.kt @@ -25,12 +25,15 @@ class VoiceController( companion object { // 日志标签 private const val TAG = "VoiceController" + // 采样率 private const val SAMPLE_RATE = 16000 + // 预缓存大小(2秒) private const val PRE_BUFFER_SIZE = SAMPLE_RATE * 2 private const val INVALID_RESET_DEBOUNCE_MS = 1500L + // 最小语音时长 private const val MIN_SPEECH_MS = 600L @@ -78,6 +81,7 @@ class VoiceController( // 声纹验证相关 private val CURRENT_USER_ID = "current_wakeup_user" private val ENABLE_STRICT_SPEAKER_VERIFY = true + private val preBufferLock = Any() init { try { @@ -163,7 +167,10 @@ class VoiceController( } else { TimeoutType.IDLE_TIMEOUT } - LogUtils.d(TAG, "⏱ WAIT_SPEECH timeout → WAIT_WAKEUP | 超时类型: $currentTimeoutType") + LogUtils.d( + TAG, + "⏱ WAIT_SPEECH timeout → WAIT_WAKEUP | 超时类型: $currentTimeoutType" + ) onTimeoutTip?.invoke(currentTimeoutType) resetAll() return @@ -273,7 +280,9 @@ class VoiceController( speechEnableAtMs = System.currentTimeMillis() + SPEECH_COOLDOWN_MS LogUtils.d(TAG, "🎵 提示音结束") if (!preBuffer.isEmpty()) { - preBuffer.clear() + synchronized(preBufferLock){ + preBuffer.clear() + } } state = VoiceState.WAIT_SPEECH_COOLDOWN } @@ -322,7 +331,9 @@ class VoiceController( LogUtils.d(TAG, "🔄 重置所有状态 | 本次超时类型: $currentTimeoutType") audioBuffer.clear() if (!preBuffer.isEmpty()) { - preBuffer.clear() + synchronized(preBufferLock){ + preBuffer.clear() + } } vadManager.reset() wakeupManager.reset() @@ -363,22 +374,20 @@ class VoiceController( private fun cachePreBuffer(samples: FloatArray) { // 空数据快速返回,避免无效循环 if (samples.isEmpty()) return - - for (s in samples) { - preBuffer.addLast(s) - // 关键修复:移除前先检查队列是否非空 -// if (preBuffer.size > PRE_BUFFER_SIZE && !preBuffer.isEmpty()) { -// preBuffer.removeFirst() -// } - if (preBuffer.size > PRE_BUFFER_SIZE) { - if (preBuffer.isEmpty()) { - LogUtils.w(TAG, "❌ preBuffer is empty when trying to remove first element") - } else { - preBuffer.removeFirst() + synchronized(preBufferLock) { + for (s in samples) { + preBuffer.addLast(s) + if (preBuffer.size > PRE_BUFFER_SIZE) { + if (preBuffer.isEmpty()) { + LogUtils.w(TAG, "❌ preBuffer is empty when trying to remove first element") + } else { + preBuffer.removeFirst() + } } - } + } } + } private fun verifySpeaker(audio: FloatArray): Boolean { @@ -426,7 +435,10 @@ class VoiceController( // 3. 计算真实处理耗时(结束时间 - 开始时间) val verifyCostMs = System.currentTimeMillis() - verifyStartMs // 日志区分:音频时长 vs 处理耗时 - LogUtils.d(TAG, "📊 声纹验证 | 统一阈值: $SPEAKER_THRESHOLD | 通过: $verifyPass | 音频时长: $audioDurationMs ms | 处理耗时: $verifyCostMs ms") + LogUtils.d( + TAG, + "📊 声纹验证 | 统一阈值: $SPEAKER_THRESHOLD | 通过: $verifyPass | 音频时长: $audioDurationMs ms | 处理耗时: $verifyCostMs ms" + ) verifyPass } }.onFailure { e -> diff --git a/app/src/main/java/com/zs/smarthuman/ui/MainActivity.kt b/app/src/main/java/com/zs/smarthuman/ui/MainActivity.kt index 0aa0a5c..ed2ace4 100644 --- a/app/src/main/java/com/zs/smarthuman/ui/MainActivity.kt +++ b/app/src/main/java/com/zs/smarthuman/ui/MainActivity.kt @@ -504,24 +504,24 @@ class MainActivity : BaseViewModelActivity() } - private fun loadLocalJsonAndPlay() { - lifecycleScope.launch(Dispatchers.IO) { - try { - val jsonStr = assets - .open("readEnd.json") - .bufferedReader() - .use { it.readText() } - - UnityPlayerHolder - .getInstance() - .startTalking(jsonStr) - - } catch (e: Exception) { - e.printStackTrace() - LogUtils.eTag("lrs", "loadLocalJsonAndPlay error: ${e.message}") - } - } - } +// private fun loadLocalJsonAndPlay() { +// lifecycleScope.launch(Dispatchers.IO) { +// try { +// val jsonStr = assets +// .open("readEnd.json") +// .bufferedReader() +// .use { it.readText() } +// +// UnityPlayerHolder +// .getInstance() +// .startTalking(jsonStr) +// +// } catch (e: Exception) { +// e.printStackTrace() +// LogUtils.eTag("lrs", "loadLocalJsonAndPlay error: ${e.message}") +// } +// } +// } /** * 下载并且安装