2017-05-06 62 views
2

我試圖檢測到沉默,以停止錄製麥克風的音頻。我目前的代碼是:檢測靜音獲取用戶輸入通過語音

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循環中停止它。

+0

也許有些時候或者如果通過檢查數據是空的還是不通過設置計時器限制? –

+0

@GiaRui時間限制作爲控制很差。我想添加一些關於聲音信號的檢查,但我不知道該怎麼做 – greywolf82

+0

這裏是可能有用的鏈接:https://stackoverflow.com/questions/26574326/how-to-calculate-the-level -amplitude-db-of-audio-signal-in-java –

回答

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