views:

14

answers:

1

I want to smoothly transition between two audio clips that are loaded into an array of javax.sound.sampled.Clips in my Java applet. At the moment I stop one clip and start the next but this produces audible clicking noises due to the audio stopping and starting abruptly. I need to use the Clip interface so that I can do looping and transition between clips keeping the same track position.

I have tried turning the gain down before stopping one clip and then ramping the gain back up when I start the next using the FloatControl.Type.MASTER_GAIN. This requires flushing the buffer if I want to change the gain quickly and even then I get clicking and stuttering if I try to change the gain too quickly. Plus flushing the buffer requires that I stop and restart the clip to get back the buffer that was flushed (so I don't jump forward over the flushed portion) and this introduces the same clicking that I am trying to get rid of.

Anyone have experience changing gain quickly (within 200ms) say from 0dB to -60dB. I'm thinking I may have to get down to the buffer level and start manipulating the bits directly but I don't know how to get to this from the Clip interface.

Any suggestions?

A: 

Found an awesome extension to the Clip class that lets you create a single Clip object with multiple streams and then use custom transitions, such as fade in and out, to switch between streams. This gets rid of the annoying clicking!

I found it on the HydrogenAudio forums, written by an awesome guy who goes by the handle googlebot. It's open source under the GNU licence.

Here's a link to the forum posts describing the program the class was created for: hydrogenaudio.org/forums/index.php?showtopic=80673 (spam bot says I can only post one link :P)

Here's a link to the Google code page where you can grab the Java class files: http://code.google.com/p/advancedabx/source/browse/#hg/AdvancedABX/src/de/uebber/sound/lib

If you end up using these classes you might find some array bounding errors in the open and addstream functions in the SwitchableArrayClip.java class.

You will need to change:

// Fill it
    int numRead = 0;
    int offset = 0;
    while (numRead != -1) {
        numRead = stream.read(audioData[0], offset - numRead, len - numRead);
    }

to:

// Fill it
    int numRead = 0;
    int offset = 0;
    while (numRead != -1) {
        numRead = stream.read(audioData[0], offset, len - offset);
        offset += numRead;
    }

There are some other issues, such as using setFramePosition, due to the fact that the player is threaded. But I will let you figure those out or you can ask here and I will show you what I did to fix them.

Hope this helps someone!

Hiyooo