7 Replies Latest reply: Aug 10, 2010 2:26 PM by captfoss RSS

    How do you adjust sound for application without changing the system volume?

    843802
      I tried finding something on these forums related to this but could not.

      I've been able to get the system volume (on Windows Vista) using:
      Port lineOut= null;
              FloatControl volCtrl;
              Mixer mixer = null;
              try {
                mixer = AudioSystem.getMixer(null);
                
                if(AudioSystem.isLineSupported(Port.Info.SPEAKER)) {
                    System.out.println("SPEAKER port is supported.");
                    lineOut = (Port) AudioSystem.getLine(Port.Info.SPEAKER);
                } else if (AudioSystem.isLineSupported(Port.Info.LINE_OUT)) {
                    System.out.println("LINE_OUT port is supported.");
                    lineOut = (Port) AudioSystem.getLine(Port.Info.LINE_OUT);
                }
                if(lineOut != null) {
                    //lineOut = (Port)mixer.getLine(Port.Info.LINE_OUT);
                    lineOut.open();
                    volCtrl = (FloatControl) lineOut.getControl(
      
                        FloatControl.Type.VOLUME);
      But, this is changing the volume across the entire system. I only want to adjust the volume for my application. Can anyone point me in the right direction?
        • 1. Re: How do you adjust sound for application without changing the system volume?
          captfoss
          sbrown99 wrote:
          But, this is changing the volume across the entire system. I only want to adjust the volume for my application. Can anyone point me in the right direction?
          Well yeah, of course it's chaging the volume across the entire system, you're adjusting the volume of the speaker ;-)

          You need to adjust the volume of the specific line you're doing your IO on...probably the SourceDataLine you're using.
          • 2. Re: How do you adjust sound for application without changing the system volume?
            843802
            Is there not a general volume control on a specific mixer that controls volume for all lines going out to the speakers?

            Right now I'm just playing sound effects using Clips. They're very short clips so I don't hold them in memory, I wanted to avoid try to apply a volume change to multiple lines if at all possible?

            I'll try what you said and see if I can get it to work though.
            • 3. Re: How do you adjust sound for application without changing the system volume?
              843802
              Perhaps if I explain a bit more about the way I'm playing sounds someone can help.

              Here is a small class I'm using to play a sound clip:

              // class to play a short sound file on another thread
              public class AudioEngine {
              
              public static boolean playClipOnceAndClose(String filePath) {
                      boolean fileFound = false;
              
                      final Clip c = AudioEngine.getClip(filePath);
                      
                      if(c != null){fileFound = true; }
                      if(c != null)
                      {
                          Thread t = new Thread(new Runnable() {
              
                              public void run() {
                                c.addLineListener(new LineListener() {
                                    public void update(LineEvent event) {
                                      if (event.getType() == LineEvent.Type.STOP) {
                                        event.getLine().close();
                                      }
              
                                    }
                                });
                                  c.start();
              
                              }
                          });
                          t.start();
              
                      }
                      return fileFound;
                  }
              
               public static Clip getClip(String filePath) {
                      Clip c = null;
                      AudioInputStream sound = null;
                      try {
              
                          // specify the sound to play
                          // (assuming the sound can be played by the audio system)
                          File soundFile = new File(filePath);
                          sound = AudioSystem.getAudioInputStream(soundFile);
                          // load the sound into memory (a Clip)
                          DataLine.Info info = new DataLine.Info(Clip.class, sound.getFormat());
                          c = (Clip) AudioSystem.getLine(info);
                          c.open(sound);
                      } catch (LineUnavailableException ex) {
                          Logger.getLogger(AudioEngine.class.getName()).log(Level.SEVERE, null, ex);
                      } catch (UnsupportedAudioFileException ex) {
                          Logger.getLogger(AudioEngine.class.getName()).log(Level.SEVERE, null, ex);
                      } catch (IOException ex) {
                          Logger.getLogger(AudioEngine.class.getName()).log(Level.SEVERE, null, ex);
                      } finally {
                          try {
                              sound.close();
                          } catch (IOException ex) {
                              Logger.getLogger(AudioEngine.class.getName()).log(Level.SEVERE, null, ex);
                          }
                      }
                      return c;
                  }
              
              }
              In this example, which mixer, line, and controls do I need to grab a hold of to effect the volume of clips played in this manner, without effecting the system mixer?
              I've been checking through the mixers and I can't seem to find one (besides the system mixer) that even has a volume control.

              Do I need to somehow create this DataLine on another mixer, and then use that mixer's volume control?

              Edited by: sbrown99 on Aug 10, 2010 11:26 AM


              Will I have to get my source lines from a Mixer, and somehow put a TargetDataLine on the mixer that handles the volume?

              Edited by: sbrown99 on Aug 10, 2010 12:00 PM
              • 4. Re: How do you adjust sound for application without changing the system volume?
                captfoss
                sbrown99 wrote:
                Is there not a general volume control on a specific mixer that controls volume for all lines going out to the speakers?
                You're acting like JavaSound is floating in its own little universe. It's not, it's interfacing with the sound hardware...

                So you can adjust the volume of the Speakers (the output of the overall computer system), or you can adjust the volume of stuff as it goes into the system...
                Right now I'm just playing sound effects using Clips. They're very short clips so I don't hold them in memory, I wanted to avoid try to apply a volume change to multiple lines if at all possible?
                Clips automatically load the entire file in memory, so, actually, no. You are holding them in memory...
                I'll try what you said and see if I can get it to work though.
                [http://www.jsresources.org/examples/AmplitudeConverter.html]

                You could also use the above method to adjust the volume of a file... it uses an "AmplitudeAudioInputStream" to play the file, and then you can adjust the amplitude (IE, volume) of the file as it flows through. This is a software-based volume control solution... but it requires you to install Tritonus, so, take whichever tradeoff works best for you.
                • 5. Re: How do you adjust sound for application without changing the system volume?
                  captfoss
                  In this example, which mixer, line, and controls do I need to grab a hold of to effect the volume of clips played in this manner, without effecting the system mixer?
                  I've been checking through the mixers and I can't seem to find one (besides the system mixer) that even has a volume control.
                  You wouldn't be looking for the volume control on a mixer, you'd be looking for the volume control on the datalines you're using. Namely, the clip objects (if they implement volume control...if not, then you can't adjust their volume).
                  • 6. Re: How do you adjust sound for application without changing the system volume?
                    843802
                    captfoss wrote:
                    In this example, which mixer, line, and controls do I need to grab a hold of to effect the volume of clips played in this manner, without effecting the system mixer?
                    I've been checking through the mixers and I can't seem to find one (besides the system mixer) that even has a volume control.
                    You wouldn't be looking for the volume control on a mixer, you'd be looking for the volume control on the datalines you're using. Namely, the clip objects (if they implement volume control...if not, then you can't adjust their volume).
                    Okay, I get what you're saying about the clips, but is the following scenario possible:

                    I create a Mixer (or find a pre-defined one that works).

                    I have all my audio go into this mixer as input.

                    The mixer has an output line (I created or can use) that I have a volume control on.

                    This way all my audio goes through a mixer giving me a central place to effect my applications' volume?

                    It's kind of hard to understand why they wouldn't build this sort of thing into the API. You ever used an application that also turned the volume down on every other application you were using...

                    Thanks for the help hoss!

                    Edited by: sbrown99 on Aug 10, 2010 12:34 PM
                    • 7. Re: How do you adjust sound for application without changing the system volume?
                      captfoss
                      This way all my audio goes through a mixer giving me a central place to effect my applications' volume?
                      Either the output of the Mixer goes to the speakers, or, it doesn't get rendered.

                      So you'd have to write everything to a Mixer, get a single output, rewrite that output to the System mixer, and adjust the volume of the input to the System mixer. (or you could adjust the volume on the output of the first mixer, but, it doesn't really matter either way).
                      It's kind of hard to understand why they wouldn't build this sort of thing into the API. You ever used an application that also turned the volume down on every other application you were using...
                      I've used a few applications that tied their volume to the overall system volume, yes... I seem to recall a few DVD-playing programs over the years doing that.

                      They did build it into the API...it's just that the default mixer doesn't support output lines, it just dumps directly to the speakers... You want to control the volume, you either have to use 2 mixers or control the volume on all of the lines manually.

                      shrug