I have a simple capture/playback Swing app that has to detect if there is no appropriate microphone attached to the computer and warn the user. After a lot of fiddling around I have found the only solution that allowed me to detect the newly attached or removed microphone:
com.sun.media.sound.JDK13Services.setCachingPeriod(0);
private static boolean isMicrophoneAvailable() {
try {
if (!AudioSystem.isLineSupported(Port.Info.MICROPHONE)) {
log.debug("NO MICROPHONE FOUND");
return false;
} else {
log.debug("MICROPHONE FOUND");
return true;
}
} catch (IllegalArgumentException e) {
log.debug("INCONSISTENT");
}
return false;
}
called in the background thread like this:
new Thread() {
public void run() {
while(!thisFrame.isClosed()){
if(isMicrophoneAvailable() == true){
//OK
}else{
//WARN
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
The problem is that although the device is being detected correctly using the described method, the list of underlying Lines is not refreshed. That is, when the program is started, and the device is attached later, the following exception is thrown when trying to record sound:
java.lang.IllegalArgumentException: No line matching interface TargetDataLine supporting format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, big-endian is supported.
Is there any way to get the lines list of AudioSystem refreshed? Maybe something similar to the JDK13Services
workaround used at the very beginning to avoid caching?
UPDATE: Code that throws an exception:
AudioFormat format = formatControls.getDefaultFormat();
DataLine.Info info = new DataLine.Info(TargetDataLine.class,format);
try {
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format, line.getBufferSize());
} catch (LineUnavailableException ex) {
shutDown("No audio input device available. Please make sure that a microphone is attached to your computer");
return;
} catch (Exception ex) {
log.error(ex.toString());
shutDown(ex.toString());
return;
}
and the Exception itself:
java.lang.IllegalArgumentException: No line matching interface TargetDataLine supporting format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, big-endian is supported.