As I've recently solved a similar problem, I can tell you exactly what's wrong and how to fix it.
The problem is with AudioSystem.getLine. It returns the first line(in any mixer) that
reports it can support your format. Unfortunately, a line may report as supporting a format, but still fail to open, giving LineUnavailableException, roughly saying the format is unsupported.
The only solution is to enumerate matching lines from all mixers, and try opening them. The following code may be useful to that effect:
private SourceDataLine getSourceDataLine(AudioFormat format) {
try {
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
for (Mixer.Info mi : AudioSystem.getMixerInfo()) {
SourceDataLine dataline = null;
try {
Mixer mixer = AudioSystem.getMixer(mi);
dataline = (SourceDataLine)mixer.getLine(info);
dataline.open(format);
dataline.start();
return dataline;
}
catch (Exception e) {}
if (dataline != null)
try {
dataline.close();
}
catch (Exception e) {}
}
}
catch (Exception e) {}
return null;
}
The above function iterates the available mixers, trying to open and start each individual line returned by each mixer. If no mixer supports the format, it returns null.
Common pitfall: I also tried enumerating mixer lines, and using AudioSystem.getLine with the detailed info object. This did return a working line, but one which was skippy, probably due to real-time format conversion. Using mixer.getLine with the generic info works best.