• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

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

 
Ranch Hand
Posts: 650
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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:
 
Sheriff
Posts: 22815
132
Eclipse IDE Spring Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Mark E Hansen
Ranch Hand
Posts: 650
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 22815
132
Eclipse IDE Spring Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 650
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 650
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 22815
132
Eclipse IDE Spring Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 650
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 22815
132
Eclipse IDE Spring Chrome Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 650
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
A lot of people cry when they cut onions. The trick is not to form an emotional bond. This tiny ad told me:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic