Allows multiple instance of the same clip to be played simultaneously.

This might fix some issues with some sounds not being played sometimes.

Also might require more memory since more clips are created.
This commit is contained in:
fd
2015-02-26 23:37:30 -05:00
parent ad5277882e
commit fbce0391a8
4 changed files with 119 additions and 37 deletions

View File

@@ -0,0 +1,95 @@
package itdelatrisu.opsu.audio;
import itdelatrisu.opsu.ErrorHandler;
import java.io.IOException;
import java.util.LinkedList;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
//http://stackoverflow.com/questions/1854616/in-java-how-can-i-play-the-same-audio-clip-multiple-times-simultaneously
public class MultiClip {
/** A list of clips used for this audio sample */
LinkedList<Clip> clips = new LinkedList<Clip>();
/** The format of this audio sample */
AudioFormat format;
/** The data for this audio sample */
byte[] buffer;
/** The name given to this clip */
String name;
/** Constructor
* @param name
* @throws LineUnavailableException */
public MultiClip(String name, AudioInputStream audioIn) throws IOException, LineUnavailableException {
this.name = name;
if(audioIn != null){
buffer = new byte[audioIn.available()];
int readed= 0;
while(readed < buffer.length) {
int read = audioIn.read(buffer, readed, buffer.length-readed);
if(read < 0 )
break;
readed += read;
}
format = audioIn.getFormat();
} else {
System.out.println("Null multiclip");
}
getClip();
}
/**
* Returns the name of the clip
* @return the name
*/
public String getName() {
return name;
}
/**
* Plays the clip with the specified volume.
* @param volume the volume the play at
* @throws IOException
* @throws LineUnavailableException
*/
public void start(float volume) throws LineUnavailableException, IOException {
Clip clip = getClip();
// PulseAudio does not support Master Gain
if (clip.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
// set volume
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
float dB = (float) (Math.log(volume) / Math.log(10.0) * 20.0);
gainControl.setValue(dB);
}
clip.setFramePosition(0);
clip.start();
}
/**
* Returns a Clip that is not playing from the list
* if one is not available a new one is created
* @return the Clip
*/
private Clip getClip() throws LineUnavailableException, IOException{
for(Clip c : clips){
if(!c.isRunning()){
return c;
}
}
Clip t = AudioSystem.getClip();
if (format != null)
t.open(format, buffer, 0, buffer.length);
clips.add(t);
return t;
}
}