0

I am currently writing a test program in Java that I want to be able to control my computer's main SPEAKER with a JSlider on a GUI application. I have read through this page on the AudioSystem class and this page on Controls. It is my understanding that I need to get a Port or line through a mixer and then institute a Control on that line or port. Since I am controlling volume I need to implement a FloatControl. My program compiles with no problem, however when I run it and adjust the JSlider I get sent the error message under the catch clause.

This is my test program:

import java.awt.BorderLayout;
import java.io.IOException;

import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.Port;
import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class speakerWork2
{
    public static void main(String [] args)throws IOException
    {
        Frame speaker = new Frame();
    }
}

class Frame extends JFrame
{
    JSlider mainVolume = new JSlider(JSlider.VERTICAL,0,100,50);

    public Frame()
    {
        super();
        setVisible(true);
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        setSize(100, 450);
        setLocation(300,200);

        add(mainVolume);

        mainVolume.addChangeListener(new mainVolumeHandler());
    }

    public class mainVolumeHandler implements ChangeListener
    {
        int sliderVal = mainVolume.getValue();

        public void setValue(FloatControl sliderVal) 
        {
        }

        public void stateChanged(ChangeEvent f)
        {
            Port SPEAKER;  
            FloatControl volCtrl;  
            try 
            {  
                Mixer mixer = AudioSystem.getMixer(null);  
                SPEAKER = (Port)mixer.getLine(Port.Info.SPEAKER);  
                SPEAKER.open();  
                volCtrl = (FloatControl) SPEAKER.getControl(  
                        FloatControl.Type.VOLUME);  
            } 
            catch (Exception e) 
            {  
                System.out.println("Failed trying to find SPEAKER"  
                        + " VOLUME control: exception = " + e);  
            }
        }
    }
}

When I run the above program, exception e prints:

java.lang.IllegalArgumentException: Line unsupported: SPEAKER target port

When I query my computer for mixers, lines and ports I get the following result for my Speakers...

mixer name: Port Speakers / Headphones (IDT High Definition Audio CODEC)
Line.Info: SPEAKER target port
volCtrl.getValue() = 1.0

What am I doing wrong, and what do I need to do to correct myself?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Eric after dark
  • 1,768
  • 4
  • 31
  • 79
  • Please learn how to use code formatting. :( – Andrew Thompson Jun 01 '12 at 04:10
  • Thanks for editing that post Andrew. I was using the "enter code here" function but whenever I pasted in my code it didn't come out right. I did the best I could. If you have any tips I'd love to hear them. – Eric after dark Jun 01 '12 at 15:29
  • 1
    For code blocks, I would generally 1) Paste the code. 2) Select the code block. 3) Click the code button. *** The selected block should then be indented by 4 spaces on each line to produce the 'code' effect. There has to be an entire blank line before code blocks. Sometimes they do not format correctly if at the end of a list, but that can be fixed by inserting `---` for a horizontal line. I don't have much experience with clicking the button first that puts `enter code here`, possibly because my first attempts were as unsuccessful as yours & I found the more reliable way to do it. ;) – Andrew Thompson Jun 01 '12 at 15:56
  • Okay, thanks a lot =). I will be referring back to this comment next time I post code! – Eric after dark Jun 01 '12 at 16:32

1 Answers1

1

I can think of two plausible issues to investigate:

(1) If your target speaker port appears on a specific mixer, you have to explicitly open that mixer if it is not the default mixer. You are currently opening the "default" mixer.

(2) If the audio resource is being used by another program, it may not be available. I've heard of this happening more with Linux than other systems.

Phil Freihofner
  • 7,645
  • 1
  • 20
  • 41
  • So you're saying if the Speaker is already being used by iTunes, there is no way to control it with my Java application? – Eric after dark Jun 01 '12 at 15:27
  • No. I'm just saying this is a possibility to investigate. Does your code work if iTunes is NOT being used? I've heard of different things happening with different operating systems and applications. I recall a case on JGO (java-gaming.org) where a fellow was having problems and had a Linux system, and it turned out to be due to another application not releasing the sound card or something. I will take the time to track down that thread if you think it might be helpful, just leave a note here. – Phil Freihofner Jun 01 '12 at 20:36
  • My code still receives the same error even if iTunes isn't up. How do I edit my code to allow it to open the corresponding mixer? – Eric after dark Jun 03 '12 at 04:38
  • There is an explanation here: http://docs.oracle.com/javase/tutorial/sound/accessing.html Mainly, you specify the mixer you want in AudioSystem.getMixer(mixer) instead of using null as you have in your code. Fingers crossed, I hope this works for you! – Phil Freihofner Jun 03 '12 at 18:00
  • So I can specify my mixer by putting `Port Speakers / Headphones (IDT High Definition Audio CODEC)` instead of `null`? – Eric after dark Jun 12 '12 at 17:36
  • Not exactly. You need to create a Mixer object and put the mixer in where you have the null. On the link I provided above, see the section "Getting a Mixer". They use AudioSystem.getMixerInfo() to get an array of Mixer.Info's that are available on your system. You can inspect this array and pick the one you want to use, and then make a Mixer object via AudioSystem.getMixer(Mixer.Info info) – Phil Freihofner Jun 12 '12 at 20:50