How can I get an array of all valid system AudioFormat objects in Java

115 views Asked by At

I am creating an object that can play synthesised audio in Java but I need to be able to set it to the AudioFormat with the Operating system's highest possible audio bitrate it can play.

(Synth generates 64-bit float audio and can bit-crush it to 32-bit float or PCM, 24-bit, 16-bit and 8-bit PCM audio.)

I will need to filter all the Operating system's valid AudioFormats and pick the format with the highest bitrate the system can use.

How can I get the approtriate array of all the AudioFormats that the system can play without error?

public class AudioSettings {
    
    // instance variables
    private int sampleRate;
    private AudioFormat audioFormat;
    private SourceDataLine sourceDataLine;
    
    public AudioSettings(int sampleRate) {
        
        this.sampleRate = sampleRate;
        
        // get highest possible quality bitrate for system
        int highestBitRate = 16;
        
        AudioFormat currentFormat = new AudioFormat(new Encoding("PCM_SIGNED"), (float) sampleRate, highestBitRate,
                2, highestBitRate / 8 * 2, sampleRate, true);
        
        for (AudioFormat format : /* What goes here? */) {

            if (format.getSampleSizeInBits() > highestBitRate 
                    && format.isBigEndian()
                    && format.getChannels() == 2) {
                currentFormat = format;
                highestBitRate = format.getSampleSizeInBits();
            }
        }
        
        audioFormat = currentFormat;
    }
    
}
2

There are 2 answers

0
Phil Freihofner On

According to this document frpm the Java 8 days, Java Sound Technology, Java supports a max of 16-bit encoding, and a highest sample rate of 48 kHz.

IDK if there's been any advancement since then. There must be a specification for Java 17, for example, where the specs are listed.

As far as querying the system for supported file types, there is a mention of in the tutorial Using File and Format Converters, in the last section: Learning What Conversions Are Available.

A related AudioSystem method, getAudioFileTypes(AudioInputStream), returns the complete list of supported file types for the given stream, as an array of AudioFileFormat.Type instances.

0
Edward Eddy67716 On

Thanks to @gpasch I found my answer from his link. Although I think you only need to read one instance of the Line.Info[] array because it seems to print out three groups that are exactly the same.

public static void main(String[] args) {
        
        Line.Info desired = new Line.Info(SourceDataLine.class);
        Line.Info[] infos = AudioSystem.getSourceLineInfo(desired);

        for (Line.Info info : infos) {
            if (info instanceof DataLine.Info) {
                AudioFormat[] forms = ((DataLine.Info) info).getFormats();

                for (AudioFormat format : forms) {
                    System.out.println(format);
                }
            }
        }

    }