package org.example;

import javax.sound.sampled.*;
import org.vosk.LogLevel;
import org.vosk.Recognizer;
import org.vosk.LibVosk;
import org.vosk.Model;
import java.io.IOException;

public class demo3 {

    private static volatile boolean recording = false; // 控制录音的标志
    private static final String START_KEYWORD = "开始"; // 启动录音的关键词
    private static final String STOP_KEYWORD = "停止"; // 停止录音的关键词
    private static final long PAUSE_DURATION_MS = 3000; // 停顿时间：3秒
    private static final float VOLUME_THRESHOLD = 0.01f; // 音量阈值

    public static void main(String[] args) throws IOException {
        LibVosk.setLogLevel(LogLevel.DEBUG);

        // 设置音频格式
        AudioFormat format = new AudioFormat(16000, 16, 1, true, false);
        DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);

        // 检查是否支持该音频格式
        if (!AudioSystem.isLineSupported(info)) {
            System.out.println("不支持的音频格式");
            System.exit(0);
        }

        // 获取并打开音频输入线
        TargetDataLine microphone;
        try {
            microphone = (TargetDataLine) AudioSystem.getLine(info);
            microphone.open(format);
        } catch (LineUnavailableException e) {
            e.printStackTrace();
            return;
        }

        // 创建Vosk识别器用于检测关键词
        try (Model model = new Model("src\\main\\resources\\model\\vosk-model-cn-0.22");
             Recognizer recognizer = new Recognizer(model, 16000)) {

            microphone.start();
            System.out.println("语言识别模型载入完成...");
            System.out.println("开始监听...");

            byte[] buffer = new byte[4096];
            int bytesRead;

            while (true) {
                bytesRead = microphone.read(buffer, 0, buffer.length);
                if (bytesRead > 0) {
                    recognizer.acceptWaveForm(buffer, bytesRead);
                    String result = recognizer.getPartialResult(); // 获取部分识别结果

                    if (result.contains(START_KEYWORD)) {
                        System.out.println("检测到开始字样，启动录音...");
                        recording = true;
                        startRecording(microphone, model);
                        break; // 退出循环，开始录音
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭麦克风
            if (microphone != null && microphone.isOpen()) {
                microphone.stop();
                microphone.close();
            }
        }
    }

    private static void startRecording(TargetDataLine microphone, Model model) {
        try (Recognizer recognizer = new Recognizer(model, 16000)) {
            System.out.println("开始录音...");

            byte[] buffer = new byte[4096];
            int bytesRead;
            long lastActivityTime = System.currentTimeMillis();
            StringBuilder resultBuilder = new StringBuilder();

            while (recording) { // 进行实际的语音识别
                bytesRead = microphone.read(buffer, 0, buffer.length);
                if (bytesRead > 0) {
                    recognizer.acceptWaveForm(buffer, bytesRead);
                    String result = recognizer.getPartialResult(); // 获取部分识别结果
                    System.out.println(result);

                    // 计算音量
                    float volume = calculateVolume(buffer, bytesRead);

                    // 更新最后活动时间
                    if (volume > VOLUME_THRESHOLD) {
                        lastActivityTime = System.currentTimeMillis();
                    }

                    // 检查是否有3秒钟的停顿
                    if (System.currentTimeMillis() - lastActivityTime > PAUSE_DURATION_MS) {
                        System.out.println("检测到停顿超过3秒，清空识别内容...");
                        recognizer.reset(); // 清空识别器内容
                        resultBuilder.append("\n[停顿]");
                    }

                    // 检测停止关键词
                    if (result.contains(STOP_KEYWORD)) {
                        System.out.println("检测到停止字样，停止录音...");
                        recording = false; // 设置标志，停止录音
                        resultBuilder.append("\n[停止]");
                    }

                    // 将当前识别结果添加到结果构建器中
                    resultBuilder.append(result);
                }
            }

            // 输出最终识别结果
            System.out.println("最终识别结果: " + resultBuilder.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static float calculateVolume(byte[] buffer, int bytesRead) {
        long sum = 0;
        for (int i = 0; i < bytesRead; i += 2) {
            // 读取每个样本的短整数值
            int sample = (buffer[i] & 0xFF) | (buffer[i + 1] << 8);
            sum += Math.abs(sample);
        }
        float average = (float) sum / (bytesRead / 2);
        return average / Short.MAX_VALUE; // 归一化
    }
}
