wood burning stoves 2.0*
The moose likes Other JSE/JEE APIs and the fly likes Adjusting the master volume on the Windows/XP machine using JavaSound? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Java » Other JSE/JEE APIs
Bookmark "Adjusting the master volume on the Windows/XP machine using JavaSound?" Watch "Adjusting the master volume on the Windows/XP machine using JavaSound?" New topic
Author

Adjusting the master volume on the Windows/XP machine using JavaSound?

Mark E Hansen
Ranch Hand

Joined: Apr 01, 2009
Posts: 643
I have a Java (1.6) application which plays Wave files using the JavaSound API.

The problem I'm having is that after each reboot of the machine, the master volume control on the machine is set to zero (I think it's the motherboard monitor software doing this, but haven't been able to get anywhere with the manufacturer).

What I would like to do is to have my Java application just adjust the volume to 100% each time it begins to play the Wave file (note: The application sends the sound to a home theater system, where the user controls the volume. The application (machine's) volume should always be 100%).

I've been going through the JavaSound documentation, and can't find a way to do this.

I've written a simple test program to play with this. This program calls AudioSystem.getMixerInfo() to get a list of Mixer.Info objects.
My machine has 8 Mixer.Info objects.
I then call mixer.getSourceLineInfo() to get a list of Line.Info objects.
I then call mixer.getLine(lineInfo) to get a line.
I then call line.getControl(FloatControl.Type.MASTER_GAIN) on the line to get the volume control.

No matter what I set the master volume to on the machine, the volume control's getValue() returns 0.0
No matter what I pass to the volume control's setValue(), the master volume doesn't change.

Is it possible to adjust the volume control on the PC from within a Java application?

Can anyone point me to a tutorial/sample which shows how to do it?

Thanks,

Here is the code from my sample application, if it helps:
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19684
    
  20

Mark E Hansen wrote:Is it possible to adjust the volume control on the PC from within a Java application?

It sure is.

Can anyone point me to a tutorial/sample which shows how to do it?

You're already going into the right direction. All you forgot is to open the line first. That and you probably need FloatControl.Type.VOLUME instead of MASTER_GAIN.

The following (adapted from your code) gives me two volumes, one of 0.11 for my actual sound card and one of 1.0 for the not-used on-board sound card. I've checked Window's settings to confirm.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Mark E Hansen
Ranch Hand

Joined: Apr 01, 2009
Posts: 643
Thanks for your quick help, Rob.

When I run your code, I only have one mixer which has a Line.Info which supports the Volume control type.
However, getValue() on it still returns 1.0 no matter what the PC's volume is set to.

Here is the output when I run the code:
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19684
    
  20

Your desired volume or master gain control may be embedded into another control. What happens if you print out all controls?
By the way, instead of trying to retrieve the control and catching an exception, use isControlSupported to check.
Mark E Hansen
Ranch Hand

Joined: Apr 01, 2009
Posts: 643
Thanks, Rob. Now I'm seeing lots of controls, and one of them includes a volume setting which appears to be tracking what I set the PC's volume control to. It's under a mixer named "Port SoundMAX HD Audio" -> Line.Info: "SPEAKER target port", then under a Control named "Wave Control", sub control named "Volume".

I will start playing with this and see if I can set the volume next.

Thanks!
Mark E Hansen
Ranch Hand

Joined: Apr 01, 2009
Posts: 643
Thanks so much for your help. I finally got it working. It seem really complicated the way they lay out the controls in such a hierarchical manner, but I have it adjusting both the Master controls as well as the controls which belong to the Wave Controls, and it's doing what I want.

Thanks again.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19684
    
  20

The control layout is not determined by Java but by the operating system. I've written a volume control-like program in Java that just uses this grouping. The only custom grouping I'm doing is take all non-compound controls of the line and group them in the user interface under the "master" group. So if I would have this structure
then I have two panes: one called master with the first three controls and one called wave control.

And you're welcome.
Mark E Hansen
Ranch Hand

Joined: Apr 01, 2009
Posts: 643
Thanks again, Rob. I guess I have mine set up the same way. The thing I don't like is that it seems like magic to locate the proper controls. For example, when looking for the correct line, I'm using lineInfo.toString().contains("SPEAKER"). This seems a little fragile - will the line I want always include the word "SPEAKER", or is that just the word used by the particular sound driver used by the O/S on my machine?

I have a similar concern when locating the Wave controls. I'm using control.toString().contains("Wave Control")

Finally, when identifying the specific controls, some of them are not too hard. For example, the Volume control can be identified this way: if (controlType.equals(FloatControl.Type.VOLUME)), but there are others which aren't so easy. For example there's one which disables digital output. I'm guessing this is particular to my sound card/drivers. I have to identify it this way: if ("Disable digital output".equals(controlType.toString())).

Is this just the way it goes?
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19684
    
  20

The speaker can be retrieved using Port.Info.SPEAKER with Mixer.getLine (after of course checking the return value of Mixer.isLineSupported). For controls it is possible to use the same technique, but only for a few controls and it probably doesn't work if the volume is stored in a compound control.

The following prints out all mixers with their SPEAKER port and their volume control - if they have them:
Mark E Hansen
Ranch Hand

Joined: Apr 01, 2009
Posts: 643
Oh, great! I'll give that a go. That'll just leave me with string comparisons to locate the Wave controls and driver-specific features.

Thanks again.
Jeffrey Goldberg
Greenhorn

Joined: Aug 12, 2010
Posts: 1
Does anyone know if this same code will work on Mac OS X? I'm not able to get it to. . . this is what I get when I run the above code:

There are 3 mixer info objects
mixer name: Java Sound Audio Engine
mixer name: Built-in Microphone
Line.Info: interface TargetDataLine supporting 64 audio formats
java.lang.IllegalArgumentException: Unsupported control type: Volume
java(19564,0x100501000) malloc: *** error for object 0x4000000000004: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

Thanks!
Jeffrey
Roger Pack
Greenhorn

Joined: Aug 24, 2011
Posts: 4
Rob Spoor wrote:
Mark E Hansen wrote:Is it possible to adjust the volume control on the PC from within a Java application?

It sure is.


Anybody able to get this to work with Windows 7? (the OP was asking about XP). I haven't had much luck with it.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Adjusting the master volume on the Windows/XP machine using JavaSound?