package org.ripple.power.sound; import java.io.IOException; import java.io.InputStream; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Control; import javax.sound.sampled.DataLine; import javax.sound.sampled.FloatControl; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; import org.ripple.power.ui.UIRes; public class LWaveSound implements Sound { private SourceDataLine clip; private boolean isRunning; private float volume; public LWaveSound() { setSoundVolume(Sound.defaultMaxVolume); } public void playSound(String fileName) { try { playSound(UIRes.getStream(fileName)); } catch (IOException e) { e.printStackTrace(); } } public void playSound(InputStream is) { if (is == null) { return; } isRunning = true; AudioInputStream ain = null; try { ain = AudioSystem.getAudioInputStream(is); if (ain == null) { return; } AudioFormat format = ain.getFormat(); if ((format.getEncoding() == AudioFormat.Encoding.ULAW) || (format.getEncoding() == AudioFormat.Encoding.ALAW)) { AudioFormat temp = new AudioFormat( AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), format.getSampleSizeInBits() * 2, format.getChannels(), format.getFrameSize() * 2, format.getFrameRate(), true); if (ain != null) { ain.close(); } ain = AudioSystem.getAudioInputStream(temp, ain); format = temp; } rawplay(format, ain, volume); } catch (Exception e) { } finally { if (ain != null) { try { ain.close(); } catch (Exception e) { } } } } public void setSoundVolume(int volume) { this.volume = volume; } private void rawplay(AudioFormat trgFormat, AudioInputStream ain, float volume) throws IOException, LineUnavailableException { byte[] data = new byte[8192]; try { clip = getLine(ain, trgFormat); if (clip == null) { return; } Control.Type vol1 = FloatControl.Type.VOLUME, vol2 = FloatControl.Type.MASTER_GAIN; FloatControl c = (FloatControl) clip .getControl(FloatControl.Type.MASTER_GAIN); float min = c.getMinimum(); float v = volume * (c.getMaximum() - min) / 100f + min; if (this.clip.isControlSupported(vol1)) { FloatControl volumeControl = (FloatControl) this.clip .getControl(vol1); volumeControl.setValue(v); } else if (this.clip.isControlSupported(vol2)) { FloatControl gainControl = (FloatControl) this.clip .getControl(vol2); gainControl.setValue(v); } clip.start(); int nBytesRead = 0; while (isRunning && (nBytesRead != -1)) { nBytesRead = ain.read(data, 0, data.length); if (nBytesRead != -1) { clip.write(data, 0, nBytesRead); } } } finally { clip.drain(); clip.stop(); clip.close(); ain.close(); } } private SourceDataLine getLine(AudioInputStream ain, AudioFormat audioFormat) throws LineUnavailableException { DataLine.Info info = new DataLine.Info(SourceDataLine.class, ain.getFormat(), ((int) ain.getFrameLength() * audioFormat.getFrameSize())); clip = (SourceDataLine) AudioSystem.getLine(info); clip.open(audioFormat); return clip; } public void stopSound() { if (clip != null) { clip.stop(); } isRunning = false; } public boolean isVolumeSupported() { return true; } }