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