Skip to content

Commit 4424f12

Browse files
ZhaoChaoqunclaude
andcommitted
Simplify Streaming Paraformer with silence padding approach
- Remove isStopping flag and complex async synchronization - Use 0.3s silence padding to trigger remaining frame decoding - Replace inputFinished()/recreateStream() with simpler reset() - Fix both crash and trailing audio loss issues Co-Authored-By: Claude <noreply@anthropic.com>
1 parent b7fbfcc commit 4424f12

2 files changed

Lines changed: 25 additions & 40 deletions

File tree

Sources/RecordingManager.swift

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ class RecordingManager {
152152
case .funasrNano:
153153
vad?.reset()
154154
case .streamingParaformer:
155-
// 确保使用新的 stream(防止上次 inputFinished 后状态异常)
156-
onlineRecognizer?.recreateStream()
155+
// reset() 已在 stopRecording 中调用,无需额外操作
156+
break
157157
}
158158

159159
// 创建音频引擎
@@ -256,17 +256,10 @@ class RecordingManager {
256256
let text = recognizer.getResult()
257257
if !text.isEmpty {
258258
DispatchQueue.main.async { [weak self] in
259-
guard let self = self else { return }
260-
self.accumulatedText = text
261-
self.onPartialResult?(text)
259+
self?.accumulatedText = text
260+
self?.onPartialResult?(text)
262261
}
263262
}
264-
265-
// 检查端点(句子结束)
266-
if recognizer.isEndpoint() {
267-
print(">>> 检测到端点")
268-
// 可以在这里添加标点逻辑
269-
}
270263
}
271264

272265
private func transcribeSegment(_ segment: SpeechSegment) {
@@ -398,40 +391,32 @@ class RecordingManager {
398391

399392
/// 停止 Streaming Paraformer 录音
400393
private func stopRecordingStreaming(completion: @escaping (String?) -> Void) {
401-
// 处理剩余的解码
402-
recognitionQueue.async { [weak self] in
403-
guard let self = self,
404-
let recognizer = self.onlineRecognizer else {
405-
DispatchQueue.main.async { completion(nil) }
406-
return
407-
}
394+
guard let recognizer = onlineRecognizer else {
395+
completion(nil)
396+
return
397+
}
408398

409-
// 通知输入结束(必须在 recognitionQueue 中调用,确保之前的音频都已送入)
410-
recognizer.inputFinished()
399+
// 注入 0.3 秒静音(4800 samples @ 16kHz)触发剩余帧解码
400+
let silencePadding = [Float](repeating: 0.0, count: 4800)
401+
recognizer.acceptWaveform(samples: silencePadding)
411402

412-
// 继续解码直到完成
413-
while recognizer.isReady() {
414-
recognizer.decode()
415-
}
416-
417-
// 再次尝试解码(inputFinished 后可能产生新的可解码帧)
403+
// 解码所有剩余帧
404+
while recognizer.isReady() {
418405
recognizer.decode()
406+
}
419407

420-
// 获取最终结果
421-
let text = recognizer.getResult()
408+
// 获取最终结果
409+
let text = recognizer.getResult()
422410

423-
// 重新创建流(inputFinished 后必须创建新流才能继续使用
424-
recognizer.recreateStream()
411+
// 重置流状态(为下次录音准备
412+
recognizer.reset()
425413

426-
DispatchQueue.main.async {
427-
var finalText: String? = nil
428-
if !text.isEmpty {
429-
finalText = self.addFinalPunctuation(text)
430-
}
431-
print(">>> 最终识别结果: \(finalText ?? "(无)")")
432-
completion(finalText)
433-
}
414+
var finalText: String? = nil
415+
if !text.isEmpty {
416+
finalText = addFinalPunctuation(text)
434417
}
418+
print(">>> 最终识别结果: \(finalText ?? "(无)")")
419+
completion(finalText)
435420
}
436421

437422
var isInitialized: Bool {

Typeless.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@
361361
"$(inherited)",
362362
"$(SRCROOT)/Frameworks/sherpa-onnx/lib",
363363
);
364-
MARKETING_VERSION = 1.2.9;
364+
MARKETING_VERSION = 1.2.10;
365365
PRODUCT_BUNDLE_IDENTIFIER = com.typeless.app;
366366
PRODUCT_NAME = "Nano Typeless";
367367
SWIFT_EMIT_LOC_STRINGS = YES;
@@ -397,7 +397,7 @@
397397
"$(inherited)",
398398
"$(SRCROOT)/Frameworks/sherpa-onnx/lib",
399399
);
400-
MARKETING_VERSION = 1.2.9;
400+
MARKETING_VERSION = 1.2.10;
401401
PRODUCT_BUNDLE_IDENTIFIER = com.typeless.app;
402402
PRODUCT_NAME = "Nano Typeless";
403403
SWIFT_EMIT_LOC_STRINGS = YES;

0 commit comments

Comments
 (0)