java - 检测静音通过语音获取用户输入

标签 java audio

我正在尝试检测静音以停止从麦克风录制音频。我当前的代码是:

public byte[] getRecord() throws AudioException {
    try {
        // Reset the flag
        stopped = false;

        // Start a new thread to wait during listening
        Thread stopper = new Thread(() -> {
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                br.readLine();
                stopped = true;
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            stop();
        });

        // Start the thread that can stop the record
        stopper.start();

        return record();
    } catch (Exception e) {
        throw new LineUnavailableException("Unable to record your voice", e);
    }
}

private byte[] record() throws LineUnavailableException {
    AudioFormat format = AudioUtil.getAudioFormat(audioConf);
    DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);

    // Checks if system supports the data line
    if (!AudioSystem.isLineSupported(info)) {
        return null;
    }

    microphone = (TargetDataLine) AudioSystem.getLine(info);
    microphone.open(format);
    microphone.start();

    System.out.println("Listening, tap enter to stop ...");

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    int numBytesRead;
    byte[] data = new byte[microphone.getBufferSize() / 5];

    // Begin audio capture.
    microphone.start();

    // Here, stopped is a global boolean set by another thread.
    while (!stopped) {
        // Read the next chunk of data from the TargetDataLine.
        numBytesRead = microphone.read(data, 0, data.length);
        // Save this chunk of data.
        byteArrayOutputStream.write(data, 0, numBytesRead);
    }

    return byteArrayOutputStream.toByteArray();
}

目前我使用 shell 停止录制,但我想知道如何在 while 循环中停止它。

最佳答案

经过多次尝试,现在看来是可行的。这是更新后的代码:

private byte[] record() throws LineUnavailableException {
    AudioFormat format = AudioUtil.getAudioFormat(audioConf);
    DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);

    // Checks if system supports the data line
    if (!AudioSystem.isLineSupported(info)) {
        return null;
    }

    microphone = (TargetDataLine) AudioSystem.getLine(info);
    microphone.open(format);
    microphone.start();

    System.out.println("Listening, tap enter to stop ...");

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    int numBytesRead;
    byte[] data = new byte[microphone.getBufferSize() / 5];
    short[] shorts = new short[data.length / 2];
    long startSilence = 0;
    boolean pause = false;

    // Begin audio capture.
    microphone.start();

    // Here, stopped is a global boolean set by another thread.
    while (!stopped) {
        // Read the next chunk of data from the TargetDataLine.
        numBytesRead = microphone.read(data, 0, data.length);
        ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);

        // Save this chunk of data.
        byteArrayOutputStream.write(data, 0, numBytesRead);

        double rms = 0;
        for (int i = 0; i < shorts.length; i++) {
            double normal = shorts[i] / 32768f;
            rms += normal * normal;
        }
        rms = Math.sqrt(rms / shorts.length);
        System.out.println("Listening, rms is " + rms);
        if (rms < 0.1) {
            long now = System.currentTimeMillis();
            if (now - startSilence > 5000 && pause)
                break;
            if (!pause) {
                startSilence = now;
                System.out.println("Listening, new silence at " + startSilence);
            }
            pause = true;
        } else
            pause = false;
    }

    return byteArrayOutputStream.toByteArray();
}

关于java - 检测静音通过语音获取用户输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43822266/

相关文章:

java - 领英 API。如何获得一个弹出窗口,要求用户单击“允许”并自动获取代码,而不是在 Linkedin 中复制和粘贴

java - 使用java实现屏幕共享

Javadocs - @param 名称未找到

android - 按下特定按钮时播放特定声音

javascript - 如何将 blob url 数据保存在目录中

ios - AVAudioPlayer 对象声音未播放 - Swift

javascript - 音频上下播放和 .currentTime HTML5/Javascript

javascript - 是否可以使用 JavaScript 在浏览器中播放合成声音?

java - 显示从 1 到 100 的数字,没有循环或条件

java - 如何使用 javax.xml.xpath 对 XML 文件运行 XQuery?