Java Sound: Getting default microphone port
Asked Answered
L

1

8

Using Java, I'm trying to record sound from the default microphone and show the current volume and mute status (as set at OS level, not interested in checking bytes if possible). So far, I can get the TargetDataLine and record to it using the following code:

TargetDataLine line = (TargetDataLine) AudioSystem.getLine(new DataLine.Info(TargetDataLine.class, formato));

This works great on Windows, line being the default microphone selected using the OS.

Right now, to get volume/mute controls I have the following code:

Mixer.Info[] mixerInfos = AudioSystem.getMixerInfo();

for (Mixer.Info mixerInfo : mixerInfos) {
    Mixer mixer = AudioSystem.getMixer(mixerInfo);

    if (mixer.getMaxLines(Port.Info.MICROPHONE) > 0) {
        System.out.println("-------------");
        System.out.println(mixerInfo);
        Port line = (Port) mixer.getLine(Port.Info.MICROPHONE);
        line.open();


        Line.Info[] targets = mixer.getTargetLineInfo();

        Control[] controls = line.getControls();
        for (Control control : controls) {
            if (control instanceof CompoundControl) {
                Control[] subControls = ((CompoundControl) control).getMemberControls();
                for (Control subControl : subControls) {
                    System.out.println(subControl);
                }
            } else {
                System.out.println(control);
            }
        }
        System.out.println("-----------");
    }
}

There are 2 microphones in my setup and I haven't found a way of knowing which is the default one (right now it is the second one in the array).

Tried Line port = AudioSystem.getLine(Port.Info.MICROPHONE); and it is returning the first one available (and it is not the default in this instance).

So, any way to get the default microphone port that relates to the TargetDataLine obtained?

Thanks!

Lioness answered 19/1, 2018 at 14:11 Comment(0)
M
4

To get of all microphones installed in your system you can list them as follow :

 package testing;

import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.TargetDataLine;

public class Main {
public static void main(String[] args) {
    //Enumerates all available microphones
        Mixer.Info[] mixerInfos = AudioSystem.getMixerInfo();
        for (Mixer.Info info: mixerInfos){
            Mixer m = AudioSystem.getMixer(info);
            Line.Info[] lineInfos = m.getTargetLineInfo();
            if(lineInfos.length>=1 && lineInfos[0].getLineClass().equals(TargetDataLine.class)){//Only prints out info is it is a Microphone
                System.out.println("Line Name: " + info.getName());//The name of the AudioDevice
                System.out.println("Line Description: " + info.getDescription());//The type of audio device
                for (Line.Info lineInfo:lineInfos){
                    System.out.println ("\t"+"---"+lineInfo);
                    Line line;
                    try {
                        line = m.getLine(lineInfo);
                    } catch (LineUnavailableException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        return;
                    }
                    System.out.println("\t-----"+line);
                }
            }
        }
}
}

Starting from that you can identify the default one... For instance in my MacBook the default one has this name "Built-in Microphone"

Molten answered 19/1, 2018 at 16:58 Comment(9)
That returns the TargetDataLIne as I stated in my question and yes, I do that to record audio. I need to get the volume level and for that I need the port that belongs to that TargetDataLine so I can get its controls.Lioness
Have look here: github.com/lkuza2/java-speech-api/wiki/…Molten
Thanks but it isn't what I'm looking for. That doesn't return the OS sound level (as set in the mixer). And as stated in my question ('as set at OS level, not interested in checking bytes if possible') I can't use that answer.Lioness
I'll give it a try. It doesn't solve my problem of getting or at least knowing which one is the default microphone but I'll check what can I do with that data. Thank you!Lioness
For Mac the default one is the one with name “Built-in Microphone” on other os the name could change, I cannot test it on Windows, but once you know the correct string , you can use it to find the default one...Molten
I need to get the controls (volume / mute) and as far as I know I need the port instance for this. Can't get them from the TargetDataLine nor from the mixer named 'Default'.Lioness
I think you are make the things more complicate then they are, by default Java is using the default microphone, but for more information you can find a good explanation here: github.com/lkuza2/java-speech-api/wiki/Microphone-SelectionMolten
You can access microphones through the Sound API, but it won't give you a simple loudness level. You'll just have to capture the data and make your own decision about how loud it is. download.oracle.com/javase/tutorial/sound/capturing.html So you can start playing with volume just after starting to record...Molten
Ones you have the line you can do something like this: FloatControl volume= (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN); If you really want to...Molten

© 2022 - 2024 — McMap. All rights reserved.