123 lines
2.8 KiB
Java
123 lines
2.8 KiB
Java
package envoy.client.data.audio;
|
|
|
|
import java.io.IOException;
|
|
import java.nio.file.*;
|
|
|
|
import javax.sound.sampled.*;
|
|
|
|
import envoy.exception.EnvoyException;
|
|
|
|
/**
|
|
* Records audio and exports it as a byte array.
|
|
*
|
|
* @author Kai S. K. Engelbart
|
|
* @since Envoy Client v0.1-beta
|
|
*/
|
|
public final class AudioRecorder {
|
|
|
|
/**
|
|
* The default audio format used for recording and play back.
|
|
*
|
|
* @since Envoy Client v0.1-beta
|
|
*/
|
|
public static final AudioFormat DEFAULT_AUDIO_FORMAT = new AudioFormat(16000, 16, 1, true, false);
|
|
|
|
/**
|
|
* The format in which audio files will be saved.
|
|
*/
|
|
public static final String FILE_FORMAT = "wav";
|
|
|
|
private final AudioFormat format;
|
|
private final DataLine.Info info;
|
|
|
|
private TargetDataLine line;
|
|
private Path tempFile;
|
|
|
|
/**
|
|
* Initializes the recorder with the default audio format.
|
|
*
|
|
* @since Envoy Client v0.1-beta
|
|
*/
|
|
public AudioRecorder() { this(DEFAULT_AUDIO_FORMAT); }
|
|
|
|
/**
|
|
* Initializes the recorder with a given audio format.
|
|
*
|
|
* @param format the audio format to use
|
|
* @since Envoy Client v0.1-beta
|
|
*/
|
|
public AudioRecorder(AudioFormat format) {
|
|
this.format = format;
|
|
info = new DataLine.Info(TargetDataLine.class, format);
|
|
}
|
|
|
|
/**
|
|
* @return {@code true} if audio recording is supported
|
|
* @since Envoy Client v0.1-beta
|
|
*/
|
|
public boolean isSupported() { return AudioSystem.isLineSupported(info); }
|
|
|
|
/**
|
|
* @return {@code true} if the recorder is active
|
|
* @since Envoy Client v0.1-beta
|
|
*/
|
|
public boolean isRecording() { return line != null && line.isActive(); }
|
|
|
|
/**
|
|
* Starts the audio recording.
|
|
*
|
|
* @throws EnvoyException if starting the recording failed
|
|
* @since Envoy Client v0.1-beta
|
|
*/
|
|
public void start() throws EnvoyException {
|
|
try {
|
|
|
|
// Open the line
|
|
line = (TargetDataLine) AudioSystem.getLine(info);
|
|
line.open(format);
|
|
line.start();
|
|
|
|
// Prepare temp file
|
|
tempFile = Files.createTempFile("recording", FILE_FORMAT);
|
|
|
|
// Start the recording
|
|
final var ais = new AudioInputStream(line);
|
|
AudioSystem.write(ais, AudioFileFormat.Type.WAVE, tempFile.toFile());
|
|
} catch (IOException | LineUnavailableException e) {
|
|
throw new EnvoyException("Cannot record voice", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stops the recording.
|
|
*
|
|
* @return the finished recording
|
|
* @throws EnvoyException if finishing the recording failed
|
|
* @since Envoy Client v0.1-beta
|
|
*/
|
|
public byte[] finish() throws EnvoyException {
|
|
try {
|
|
line.stop();
|
|
line.close();
|
|
final byte[] data = Files.readAllBytes(tempFile);
|
|
Files.delete(tempFile);
|
|
return data;
|
|
} catch (final IOException e) {
|
|
throw new EnvoyException("Cannot save voice recording", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Cancels the active recording.
|
|
*
|
|
* @since Envoy Client v0.1-beta
|
|
*/
|
|
public void cancel() {
|
|
line.stop();
|
|
line.close();
|
|
try {
|
|
Files.deleteIfExists(tempFile);
|
|
} catch (final IOException e) {}
|
|
}
|
|
}
|