package com.mautini.assistant.demo.client.audio; import com.mautini.assistant.demo.config.AudioConf; import com.mautini.assistant.demo.exception.AudioException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.TargetDataLine; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStreamReader; public class AudioRecorder { private static final Logger LOGGER = LoggerFactory.getLogger(AudioRecorder.class); private TargetDataLine microphone; private boolean stopped = false; private AudioConf audioConf; public AudioRecorder(AudioConf audioConf) { this.audioConf = audioConf; } 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; LOGGER.info("End of the capture"); } catch (IOException ex) { ex.printStackTrace(); } stop(); }); // Start the thread that can stop the record stopper.start(); return record(); } catch (Exception e) { throw new AudioException("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)) { LOGGER.error("Line not supported"); System.exit(0); } microphone = (TargetDataLine) AudioSystem.getLine(info); microphone.open(format); microphone.start(); LOGGER.info("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(); } /** * Stop the capture */ private void stop() { microphone.stop(); microphone.close(); } }