0

I'm new to using the javax.sound.sampled package, the reason I chose to to use the package was to have more control over the audio I was using than some simpler sound solutions such as AudioClip.

I've read through: Oracle's Sound Tutorial (or at least as much as I could grasp) but I don't see a method of modulating the level/volume of playback on a Line using the Clip interface they seemed to give these kinds of options in the portions of the package that allow you to create sound, but I can't find any way of making these adjustments be it through my Line, or my AudioInputStream.

I found [this] page with the text,

Float controls, on the other hand, are well suited to represent continuously variable controls, such as pan, balance, or volume.

but no Lines on my computer return any Controls (using Line.getControls())

(I tried to force the line to accept the FloatControl.Type.VOLUME similar to this but I get an "unsupported control type exception")

Is the only way to modify the volume/level on a Line (using the Clip interface) through use of the Line's controls? Or is it possible to modify the volume of an AudioInputStream?

Alternatively is there a method of adding Controls to an existing Line?

Community
  • 1
  • 1

2 Answers2

1

Instead of using FloatControl.Type.VOLUME use FloatControl.Type.MASTER_GAIN.

0

There is at least one other way, besides using lines. (I was also having trouble getting a control line, and found that a Master line worked, as recommended by Travis Meyers. I'm giving him a + vote.) Not sure if you want to go there, but it is possible to multiply EVERY frame's audio values by a volume factor. The Java Tutorial makes a passing reference to this technique, but like much else in that document, they don't provide explicit examples.

Thus, when you acquire a buffer of bytes, you have to loop through the buffer, assembling the bytes to get the audio values. Then, multiply by your volume factor (often a float from 0 to 1.0), then dissassemble the audio value back into bytes.

It works. I do it in a crude Java Theremin you can try out. I also manipulate my pitches on a per frame basis in that program. But there are still issues with the program! I'm working right now on improving the way I pipe GUI event data to the audio loop. Also, I'm responding to changes on a per-frame basis rather than via per-buffer basis. But for most uses, per-buffer is fine.

That said, something to listen for is to take care about sending in changes in volume that cause discontinuities, which can cause loud clicks. The amount that causes the click can vary in the different volume ranges. Also, volume doesn't exactly drop off in a linear fashion, as you go from 0 to 1.0 with your volume factor.

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