- 新增 StreamingAudioWriter 组件:持续录制 WAV 文件,VAD 检测静音段自动切换 - 静音检测:检测到 ~1s 连续静音后关闭当前文件,触发 chunkCompleted 信号 - STTTestPage 重构:移除缓冲区推理模式,改为 WAV 文件流式识别 - 每个 WAV 文件完成后在后台线程读取并推理,不阻塞继续录制 - 设置页面新增「调试音频目录」配置项 - 音频存储路径:debug 模式使用配置目录,非 debug 模式使用系统临时目录 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
71 lines
1.9 KiB
C++
71 lines
1.9 KiB
C++
#pragma once
|
|
|
|
#include <QWidget>
|
|
#include <memory>
|
|
#include "widgets/audio_waveform.h"
|
|
|
|
class QLabel;
|
|
class QPushButton;
|
|
class QComboBox;
|
|
class QTextEdit;
|
|
class QSpinBox;
|
|
|
|
namespace impress {
|
|
|
|
class ConfigManager;
|
|
class SenseVoiceEngine;
|
|
class AudioCapture;
|
|
class StreamingAudioWriter;
|
|
|
|
/**
|
|
* @brief STT 测试页面
|
|
*
|
|
* 实时麦克风采集 + 基于 VAD 的流式 WAV 文件录制 + 后台识别。
|
|
* 音频采集与推理分离,防止推理阻塞音频流。
|
|
* 使用 VAD 检测静音段自动切换 WAV 文件,每个文件完成后触发识别。
|
|
*/
|
|
class STTTestPage : public QWidget {
|
|
Q_OBJECT
|
|
public:
|
|
explicit STTTestPage(ConfigManager* configManager,
|
|
SenseVoiceEngine* sttEngine,
|
|
QWidget* parent = nullptr);
|
|
~STTTestPage() override;
|
|
|
|
private slots:
|
|
void onToggleRecording();
|
|
void onAudioDataReady(const std::vector<float>& samples, int sampleRate);
|
|
void onChunkCompleted(const QString& filePath, int durationMs);
|
|
void onRecognitionResult(const QString& text, float confidence, double latency, bool isFinal);
|
|
void onModelLoaded(const QString& modelPath);
|
|
void onModelLoadError(const QString& modelPath, const QString& error);
|
|
void onModelUnloaded();
|
|
|
|
private:
|
|
void setupUI();
|
|
void updateUIState();
|
|
void startAudioCapture();
|
|
void transcribeChunk(const QString& filePath, int durationMs);
|
|
|
|
ConfigManager* configManager_;
|
|
SenseVoiceEngine* sttEngine_;
|
|
AudioCapture* audioCapture_;
|
|
StreamingAudioWriter* streamingWriter_;
|
|
|
|
// UI 控件
|
|
QComboBox* deviceCombo_;
|
|
QPushButton* recordBtn_;
|
|
QTextEdit* textOutput_;
|
|
QLabel* latencyLabel_;
|
|
QLabel* statusLabel_;
|
|
AudioWaveform* waveform_;
|
|
|
|
bool isRecording_ = false;
|
|
bool isLoadingModel_ = false;
|
|
bool isInferencing_ = false;
|
|
int audioSampleRate_ = 16000;
|
|
int completedCount_ = 0; // 已完成文件计数
|
|
};
|
|
|
|
} // namespace impress
|