4

How does one get the master volume in Java? I want to make a program that displays (NOT CHANGE) this value (probably on a JProgressBar or something similar) as a percentage of the maximum setting. I might also want to display the current sound level as a percentage of highest possible sound level, but this is not needed.

Ky -
  • 30,724
  • 51
  • 192
  • 308
  • 1
    As a side note, don't use a progress bar for that. The master sound level is not a measure of progress, and some OSes will draw an animating bar that will not be appropriate for measuring the sound level. – cdhowie Nov 18 '10 at 03:41
  • As what is it measured, then? – Ky - Nov 18 '10 at 04:35
  • A progress bar is a bar that shows the progress of a long-lived task (eg copying files) – Jean Hominal Nov 18 '10 at 05:15
  • No. A progress bar shows a bar that is a certain percentage of the length of the whole object. One must not think that it can only grow. – Ky - Nov 18 '10 at 05:37
  • I didn't say that it can only grow… But read http://download.oracle.com/javase/6/docs/api/javax/swing/JProgressBar.html - "A component that visually displays the progress of some task." That component is not made to display a value that can be modified by the user. (While `JSlider` is) – Jean Hominal Nov 21 '10 at 04:52
  • I do not want the user to modify it. I just want the user to see the volume Note that in my question I said "displays". I did not mention being able to modify it. – Ky - Nov 21 '10 at 05:07

4 Answers4

3

I am not entirely sure, but you could have a look at the (Java Media Framework - JMF). You are able to control the sound via that library, so I would assume you can get the details about it too. It might just be the application's sound level, so I might be wrong.

Nico Huysamen
  • 10,217
  • 9
  • 62
  • 88
2

Although JProgressBar is not used for this
This might Help

package test;

import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;

public class SoundMeter {

JFrame j;

public SoundMeter() {
    j = new JFrame("SoundMeter");
    j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    j.setLayout(new BoxLayout(j.getContentPane(), BoxLayout.Y_AXIS));
    printMixersDetails();
    j.setVisible(true);
}
public void printMixersDetails(){
    javax.sound.sampled.Mixer.Info[] mixers = AudioSystem.getMixerInfo();
    System.out.println("There are " + mixers.length + " mixer info objects");  
    for(int i=0;i<mixers.length;i++){
        Mixer.Info mixerInfo = mixers[i];
        System.out.println("Mixer Name:"+mixerInfo.getName());
        Mixer mixer = AudioSystem.getMixer(mixerInfo);
        Line.Info[] lineinfos = mixer.getTargetLineInfo();
        for(Line.Info lineinfo : lineinfos){
            System.out.println("line:" + lineinfo);
            try {
                Line line = mixer.getLine(lineinfo);
                line.open();
                if(line.isControlSupported(FloatControl.Type.VOLUME)){
                    FloatControl control = (FloatControl) line.getControl(FloatControl.Type.VOLUME);
                    System.out.println("Volume:"+control.getValue());   
                    JProgressBar pb = new JProgressBar();
                    // if you want to set the value for the volume 0.5 will be 50%
                    // 0.0 being 0%
                    // 1.0 being 100%
                    //control.setValue((float) 0.5);
                    int value = (int) (control.getValue()*100);
                    pb.setValue(value);
                    j.add(new JLabel(lineinfo.toString()));
                    j.add(pb);
                    j.pack();
                }
            } catch (LineUnavailableException e) {
                e.printStackTrace();
            }
        }
    }
}
public static void main(String[] args) {
    new SoundMeter();
}
}
Jaguar
  • 159
  • 2
  • 3
  • 9
0

Nico is right. Here is an article and example that might help you.

http://onjava.com/pub/a/onjava/excerpt/jenut3_ch17/index.html
http://onjava.com/onjava/excerpt/jenut3_ch17/examples/SoundPlayer.java

Gary
  • 13,303
  • 18
  • 49
  • 71
AlexR
  • 114,158
  • 16
  • 130
  • 208
0

You could be a little less abrasive rather than say "Does not help me".

Otherwise, here is the big picture, using the Sound API mentioned by AlexR's example: (there are a lot of practical details on that forum thread, and there is some Oracle documentation for Processing Audio with Controls)

  • Once you get a Line object that represents the sound output line that you wish to control, it is rather trivial to get the volume control:

    line.open(); // May be necessary if the line is not already opened.
    FloatControl volumeControl = (FloatControl) masterLine.getControl(FloatControl.Type.VOLUME);
    
  • Getting the "Master Line" object is, at best, platform-dependant. You will have to list the Mixers and the Lines at runtime using the AudioSystem static methods in order to determine which line you want. It can also happen that the master line will not support the volume control directly, but only through a CompoundControl. (through a hierarchy that is, you guessed it, platform-dependant).

Jean Hominal
  • 16,518
  • 5
  • 56
  • 90
  • using `line = (Port)AudioSystem.getMixer(null).getLine(Port.Info.LINE_IN);`, I get `java.lang.IllegalArgumentException: Line unsupported: LINE_IN source port` – Ky - Nov 22 '10 at 16:12
  • @Supuhstar: 1. I suspect you meant to write `((Port) AudioSystem.getMixer(null)).getLine(Port.Info.LINE_IN);` - which would have thrown a `ClassCastException`. 2. There is no guarantee that invoking `AudioSystem.getMixer(null)` will yield the `Port` that you want to get - the computer cannot guess what you want. 3. I believe the only reliable way is by enumerating some subset of the system's `Line`s or the `Mixer`s by using the `AudioSystem.getMixerInfo()` and similar other methods, and checking each one. 4. If you had read the linked forum thread, I would not have had to write points 2 and 3. – Jean Hominal Nov 22 '10 at 19:14