JavaSoundEngine-声音引擎播放器源代码

2016-05-26· 3068 次浏览
JavaSoundEngine-声音引擎播放器源代码 ## 实现一 ``` import java.io.*; import javax.sound.sampled.*; /** * Class SoundEngine provides functionality to process sound files. * Sounds can be loaded, played, paused, resumed, and stopped. * * The sound engine can play multiple sounds simultaniously, but only * the last sound loaded can be controlled (pased, resumed, etc.). * * The sound engine accepts files in WAV, AIFF, and AU formats (although * not all WAV files - it depends on the encoding in the file). * * @author Michael Kolling and David J Barnes * @version 1.0 */ public class SoundEngine { // the following three fields hold information about the sound clip // currently loaded in this engine private Clip currentSoundClip = null; private int currentSoundDuration = 0; private int currentSoundFrameLength = 0; /** * Create a SoundEngine that can play sound files. */ public SoundEngine() { } /** * Load and play a specified sound file. If the file is not in a * recognised file format, false is returned. Otherwise the sound * is started and true is returned. The method returns immediately * after the sound starts (not after the sound finishes). * * @param soundFile The file to be loaded. * @return True, if the sound file could be loaded, false otherwise. */ public boolean play(File soundFile) { if(loadSound(soundFile)) { currentSoundClip.start(); return true; } else { return false; } } /** * Stop the currently playing sound (if there is one playing). If no * sound is playing, this method has no effect. */ public void stop() { if(currentSoundClip != null) { currentSoundClip.stop(); currentSoundClip = null; } } /** * Pause the currently playing sound. If no sound is currently playing, * calling this method has no effect. */ public void pause() { if(currentSoundClip != null) { currentSoundClip.stop(); } } /** * Resume the currently paused sound. If no sound is currently paused, * this method has no effect. */ public void resume() { if(currentSoundClip != null) { currentSoundClip.start(); } } /** * Set the current playing position in the currently playing sound to 'value'. * 'value' is a percentage value (0 to 100). If there is no sound currently * playing, this method has no effect. * * @param value The target position in the sound file, as a percentage. */ public void seek(int value) { if(currentSoundClip != null) { int seekPosition = currentSoundFrameLength / 100 * value; currentSoundClip.setFramePosition(seekPosition); } } /** * Set the playback volume of the current sound. If no sound is currently * loaded, this method has no effect. * * @param vol Volume level as a percentage (0..100). */ public void setVolume(int vol) { if(currentSoundClip == null) { return; } if(vol < 0 &##124;&##124; vol > 100) { vol = 100; } double val = vol / 100.0; try { FloatControl volControl = (FloatControl) currentSoundClip.getControl(FloatControl.Type.MASTER_GAIN); float dB = (float)(Math.log(val == 0.0 ? 0.0001 : val) / Math.log(10.0) * 20.0); volControl.setValue(dB); } catch (Exception ex) { System.out.println("could not set volume"); } } /** * Return the duration of the currently loaded sound clip. * * @return The duration of the current sound, or 0 if no sound has been loaded. */ public int getDuration() { return currentSoundDuration; } /** * Load the sound file supplied by the parameter into this sound engine. * * @return True if successful, false if the file could not be decoded. */ private boolean loadSound(File file) { currentSoundDuration = 0; try { AudioInputStream stream = AudioSystem.getAudioInputStream(file); AudioFormat format = stream.getFormat(); // we cannot play ALAW/ULAW, so we convert them to PCM // if ((format.getEncoding() == AudioFormat.Encoding.ULAW) &##124;&##124; (format.getEncoding() == AudioFormat.Encoding.ALAW)) { AudioFormat tmp = new AudioFormat( AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), format.getSampleSizeInBits() * 2, format.getChannels(), format.getFrameSize() * 2, format.getFrameRate(), true); stream = AudioSystem.getAudioInputStream(tmp, stream); format = tmp; } DataLine.Info info = new DataLine.Info(Clip.class, stream.getFormat(), ((int) stream.getFrameLength() * format.getFrameSize())); currentSoundClip = (Clip) AudioSystem.getLine(info); currentSoundClip.open(stream); currentSoundFrameLength = (int) stream.getFrameLength(); currentSoundDuration = (int) (currentSoundClip.getBufferSize() / (currentSoundClip.getFormat().getFrameSize() * currentSoundClip.getFormat().getFrameRate())); return true; } catch (Exception ex) { currentSoundClip = null; return false; } } } ``` ## 实现二 ``` package com.zhenzhigu.higame.audio; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.Timer; import java.util.TimerTask; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioFormat.Encoding; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.DataLine; import javax.sound.sampled.FloatControl; import javax.sound.sampled.LineEvent; import javax.sound.sampled.LineListener; import javax.sound.sampled.SourceDataLine; import com.zhenzhigu.higame.util.FileUtil; public class Sound { public static void main(String[] args) throws InterruptedException { Timer timer = new Timer(); timer.schedule(new TimerTask() { public void run() { // TODO Auto-generated method stub } }, 0,100); for(int i=1;i<=10000;i++){ Sound pl = new Sound (); pl.init(FileUtil.getAssetAsFile("music/swish-1.mp3")); pl.loop(1); Thread.sleep(100); System.out.println(i); } } private Clip clip = null; private int loops = 1; private boolean closed = false; public void init(File file){ try { AudioInputStream srcInput = AudioSystem.getAudioInputStream(file); AudioInputStream audioInput = null; if(srcInput.getFormat().getEncoding()==Encoding.PCM_SIGNED){ audioInput = srcInput; }else{ //根据原始音频流格式创建新的PCM格式 final AudioFormat outFormat = this.getOutFormat(srcInput.getFormat()); audioInput = AudioSystem.getAudioInputStream(outFormat, srcInput); } DataLine.Info clipInfo = new DataLine.Info(Clip.class, audioInput.getFormat()); this.clip = ((Clip)AudioSystem.getLine(clipInfo)); this.clip.open(audioInput); this.clip.addLineListener(new LineListener() { public void update(LineEvent event) { if(closed &##124;&##124; isDone() ){ clip.close(); } } }); } catch (Exception e) { throw new IllegalStateException(e); } } private AudioFormat getOutFormat(AudioFormat inFormat) { final int ch = inFormat.getChannels(); final float rate = inFormat.getSampleRate(); return new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, rate, 16, ch, ch * 2, rate, false); } //---------- Controller ----------- public void start(){ this.clip.start(); } public void stop() { clip.stop(); clip.setFramePosition(0); } public void pause() { clip.stop(); } public void close(){ closed = true; clip.close(); clip = null; } public boolean isDone(){ return (loops!=0 && (loops*clip.getFrameLength()==clip.getFramePosition())); } /* * 设置音量:0-200 */ public void setGain(float vol) { double value = vol / 100.0f; try { FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN); float db = (float)(Math.log(value==0.0?0.0001:value)/Math.log(10.0)*20.0); System.out.println(db); gainControl.setValue(db); } catch (Exception ex) { ex.printStackTrace(); } } /** * 循环次数:0代表无限循环,1代表播放1次 * @param i */ public void loop(int i) { clip.setLoopPoints(0, -1); clip.loop(i-1); this.loops = i; } public void setPosition(int frames){ clip.setFramePosition(frames); } public int getPosition() { return clip.getFramePosition(); } public boolean isRunning() { return clip.isRunning(); } } ```