Java 通过语音获取用户输入时检测静音

Java 通过语音获取用户输入时检测静音,java,audio,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(() -> {

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

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();
}
private byte[]record()引发LineUnavailableException{
AudioFormat=AudioUtil.getAudioFormat(audioConf);
DataLine.Info=newdataline.Info(TargetDataLine.class,格式);
//检查系统是否支持数据线
如果(!AudioSystem.isLineSupported(信息)){
返回null;
}
麦克风=(TargetDataLine)AudioSystem.getLine(信息);
麦克风。打开(格式);
麦克风。开始();
System.out.println(“监听,点击回车停止…”);
ByteArrayOutputStream ByteArrayOutputStream=新建ByteArrayOutputStream();
int numBytesRead;
byte[]data=新字节[micromic.getBufferSize()/5];
short[]shorts=新的short[data.length/2];
长启动间隔=0;
布尔暂停=假;
//开始音频捕获。
麦克风。开始();
//这里,stopped是另一个线程设置的全局布尔值。
当(!停止){
//从TargetDataLine读取下一个数据块。
numBytesRead=麦克风读取(数据,0,数据.长度);
ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
//保存这段数据。
写入(数据,0,numbytes读取);
双均方根=0;
对于(int i=0;i5000&&暂停)
打破
如果(!暂停){
startSilence=现在;
System.out.println(“监听,“+startSilence”的新静音);
}
暂停=正确;
}否则
暂停=错误;
}
返回byteArrayOutputStream.toByteArray();
}

可能需要一段时间或如果需要通过设置计时器限制来检查数据是否为空?@GiaRui时间限制作为控制非常差。我想增加一些关于声音信号的检查,但我不知道如何做。这是alink,可能会有帮助:谢谢。似乎不值得感谢。:-)如果你让它工作,你可以把它贴在这里?