【问题标题】:Detect silence getting user input via voice检测通过语音获取用户输入的静音
【发布时间】:2017-05-06 15:36:14
【问题描述】:

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

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 循环中停止录制。

【问题讨论】:

  • 也许有一段时间或者是否通过设置计时器限制来检查数据是否为空?
  • @GiaRui 时间限制作为控制相当差。我想添加一些关于声音信号的检查,但我不知道该怎么做
  • 这里有一个可能有用的链接:stackoverflow.com/questions/26574326/…
  • 谢谢。看来值得
  • 不用谢。 :-) 如果你让它工作,你可以把它贴在这里?

标签: java audio


【解决方案1】:

经过多次尝试,现在它似乎工作了。这是更新后的代码:

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();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多