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.DataLine; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; import org.ripple.power.ui.UIRes; // 非特定解码器播放用类 public class OtherSound implements Sound { private SourceDataLine clip; private boolean isRunning; private float volume; public OtherSound() { 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; } this.isRunning = true; AudioInputStream din = null; AudioInputStream in = null; try { in = AudioSystem.getAudioInputStream(is); if (in == null) { return; } AudioFormat baseFormat = in.getFormat(); AudioFormat decodedFormat = new AudioFormat( AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16, baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false); din = AudioSystem.getAudioInputStream(decodedFormat, in); rawplay(decodedFormat, din, volume); } catch (Exception e) { } finally { if (in != null) { try { in.close(); } catch (Exception e) { } } } } public void setSoundVolume(int volume) { this.volume = volume / 100F; } private void rawplay(AudioFormat trgFormat, AudioInputStream din, float volume) throws IOException, LineUnavailableException { if (volume <= 0f) { return; } if (volume >= 1.0f) { volume = 1.0f; } byte[] data = new byte[8192]; try { clip = getLine(trgFormat); if (clip == null) { return; } clip.start(); int nBytesRead = 0; while (isRunning && (nBytesRead != -1)) { nBytesRead = din.read(data, 0, data.length); for (int i = 0; i < nBytesRead; i++) { data[i] *= volume; } if (nBytesRead != -1) { clip.write(data, 0, nBytesRead); } } } finally { clip.drain(); clip.stop(); clip.close(); din.close(); } } private SourceDataLine getLine(AudioFormat audioFormat) throws LineUnavailableException { SourceDataLine res = null; DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat); res = (SourceDataLine) AudioSystem.getLine(info); res.open(audioFormat); return res; } public void stopSound() { if (clip != null) { clip.stop(); } isRunning = false; } public boolean isVolumeSupported() { return true; } }