0

I am currently learning how to build a simple MP3 player with jlgui (using swt to control it). While i am getting along nicely there is one thing which is really throwing me and that is controlling the volume and pan of the sound coming out of the computer.

I have a class which creates a BasicPlayer object and a BasicController to go with it. I have tried to use the BasicController.setGain method but all it does if I put any value in it is set the volume to be muted, and I cant seem to change this value during the playback of the song. Id be really grateful if anyone could give me some help on this as its driving me nuts :-(

Also considered trying the following suggestion

AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File("C:\\Kasabian.mp3"));
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);

But not really sure how to combine it with jlgui.

Reimeus
  • 158,255
  • 15
  • 216
  • 276
Robert Flook
  • 307
  • 6
  • 12
  • See 1) [Can Java Sound be used to control the system volume?](http://stackoverflow.com/q/14301618/418556) to which the answer is 'no' and I suspect that would also apply to 'JLGui' (which I've never heard of, before now). 2) [This answer](http://stackoverflow.com/a/14511710/418556) for using a `Clip` with a volume control. – Andrew Thompson Feb 03 '13 at 03:33

1 Answers1

0

"ROLL YOUR OWN" solution:

The Java Sound Tutorial has a very scant section called "Manipulating the Audio Data Directly" at the end of the page on "Processing Audio with Controls". http://docs.oracle.com/javase/tutorial/sound/controls.html

I gave up on "Controls" and just do it myself. If someone has a working solution that makes use of Java Controls for volume and pan, I'll be glad to hear about it.

To control volume yourself, you will need to get into the "buffer" of data that is read from your AudioInputLine, convert the data to PCM frames, multiply the PCM values by a fraction of 1 (where 1.0 is full volume, and 0 is silence), convert back to bytes, and then, finally, writing to your SourceDataLine.

Also, (if you are not discouraged yet), it helps if the volume variable is a loosely coupled and volatile, and helps even more if the volume you specify is a "target" and the variable inside the buffer loop incrementally approaches the target on a per frame basis. This is to avoid jumps in volume that might create clicks.

And (if that is not enough) it is helpful to map the range from 0 to 1.0 to an equation (e.g., exponential or logarithmic) that better matches levels of audibility.

Phil Freihofner
  • 7,645
  • 1
  • 20
  • 41