Java - recording from mixer

前端 未结 2 644
抹茶落季
抹茶落季 2020-12-14 20:18

I have a problem connected with my previous question. I want to record audio from mixer (speakers), I\'m using javax.sound. I have to set up audioFormat and I don\'t know wh

2条回答
  •  时光取名叫无心
    2020-12-14 20:57

    You're getting a TargetDataLine using an AudioFormat you've created. This isn't guaranteed to work. You must first query the Mixer to check if it supports your desired AudioFormat using the AudioSystem.isLineSupported(Info info) method.

    Personally, I find this quite cumbersome. You need to query the Mixers on the system to determine if they support the AudioFormat you want.

    The function below will get a Vector of supported formats for a data line class. Call it using

    Vector formats = getSupportedFormats(TargetDataLine.class);
    

    or

    Vector formats = getSupportedFormats(SourceDataLine.class);
    

    This code might need a bit of debugging; I had to remove some of my app-specific stuff to make it self contained...

    public Vector getSupportedFormats(Class dataLineClass) {
        /*
         * These define our criteria when searching for formats supported
         * by Mixers on the system.
         */
        float sampleRates[] = { (float) 8000.0, (float) 16000.0, (float) 44100.0 };
        int channels[] = { 1, 2 };
        int bytesPerSample[] = { 2 };
    
        AudioFormat format;
        DataLine.Info lineInfo;
    
        SystemAudioProfile profile = new SystemAudioProfile(); // Used for allocating MixerDetails below.
        Vector formats = new Vector();
    
        for (Mixer.Info mixerInfo : AudioSystem.getMixerInfo()) {
            for (int a = 0; a < sampleRates.length; a++) {
                for (int b = 0; b < channels.length; b++) {
                    for (int c = 0; c < bytesPerSample.length; c++) {
                        format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
                                sampleRates[a], 8 * bytesPerSample[c], channels[b], bytesPerSample[c],
                                sampleRates[a], false);
                        lineInfo = new DataLine.Info(dataLineClass, format);
                        if (AudioSystem.isLineSupported(lineInfo)) {
                            /*
                             * TODO: To perform an exhaustive search on supported lines, we should open
                             * TODO: each Mixer and get the supported lines. Do this if this approach
                             * TODO: doesn't give decent results. For the moment, we just work with whatever
                             * TODO: the unopened mixers tell us.
                             */
                            if (AudioSystem.getMixer(mixerInfo).isLineSupported(lineInfo)) {
                                formats.add(format);
                            }
                        }
                    }
                }
            }
        }
        return formats;
    }
    

提交回复
热议问题