/* * AudioThread.java * * Created on May 28, 2007, 8:58 PM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package jblackout.util; import jblackout.exception.SegmentNotLoadedException; import com.sun.tools.javac.code.Source; import java.lang.Thread; import java.lang.*; import java.net.URL; import java.awt.Dimension; import java.io.IOException; import javax.sound.sampled.*; import javazoom.jl.player.advanced.*; import javazoom.jl.player.*; import javax.sound.sampled.*; import java.io.*; /** * Thread that plays mp3 Music. * @author Jason R. Ederle */ public class AudioThread implements Runnable { AudioInputStream in; AudioInputStream din; AudioFormat decodedFormat; AudioFormat baseFormat; SourceDataLine line; FloatControl volume; CacheManager cacheManager; ByteArrayInputStream bis; byte[] data; byte[] tempData; int mediaId; Thread thread; URL pathToSong; boolean isSongPaused = false; //set to true when caller wants song to pause. boolean songIsPlaying = false; //set true when song is actively playing audio, false when no audio is loaded, false after song ends. boolean timeToExitThread = false; //this tells the thread when to exit the play loop. /** Creates a new instance of AudioThread */ public AudioThread(int playMediaId, CacheManager cacheManagerRef) { if(thread == null){ thread = new Thread(this, "Audio Thread."); } mediaId = playMediaId; cacheManager = cacheManagerRef; thread.start(); } /** * The thread plays a song and sleeps on pause. */ public void run(){ try{ //the thread will play the song, and exit when it's finished. playSong(); } catch(Exception e){ e.printStackTrace(); } } 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); System.out.println("Audio Thread - System audio buffer granted is " + res.available() + " bytes."); return res; } public void playSong(){ try { //File file = new File(Constant.pathToAnMp3); //Get encoded input stream. in= AudioSystem.getAudioInputStream(new ByteArrayInputStream(cacheManager.getSegment(mediaId, 1))); AudioFormat baseFormat = in.getFormat(); AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16, baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false); //Get decoded input stream din = null; din = AudioSystem.getAudioInputStream(decodedFormat, in); // Start Playing Song. rawplay(decodedFormat, din); //blocks until all audio has been played, then cleans up resources. line.drain(); line.close(); in.close(); System.out.println("Audio Thread - Closing Input stream and stopping song."); } catch (Exception e) { //Handle exception. } } /** * Converts byte array into input stream. */ private AudioInputStream reloadInputStream(byte[] binArray){ try{ //File file = new File(Constant.pathToAnMp3); //return AudioSystem.getAudioInputStream( file ); return AudioSystem.getAudioInputStream( new ByteArrayInputStream( binArray ) ); } catch(Exception e){ e.printStackTrace(); } return null; } private void rawplay(AudioFormat targetFormat, AudioInputStream din) { try{ byte[] data = new byte[Constant.SEGMENT_SIZE]; SourceDataLine line = getLine(targetFormat); int nextSegment = 1; if (line != null) { // Start line.start(); int totalRead = 0, totalWritten = 0; int nBytesRead = 0, nBytesWritten = 0; int nBytesLeft = Constant.SEGMENT_SIZE; int copySize = 1024 * 4; //4K //Write All segments into the system audio buffer. while (nextSegment == 1) { //in = AudioSystem.getAudioInputStream(new ByteArrayInputStream(cacheManager.getSegment(mediaId, nextSegment))); //din = AudioSystem.getAudioInputStream(targetFormat, in); System.out.println("----------- Loading Segment " + nextSegment + " -----------"); int reqNumBytes = 0; while(nBytesLeft > 0){ //Read From buffer if(nBytesLeft <= line.available()) reqNumBytes = nBytesLeft; else reqNumBytes = line.available(); nBytesRead = din.read(data, 0, reqNumBytes); totalRead += nBytesRead; //how much data left for this segment in buffer. nBytesLeft = nBytesLeft - nBytesRead; //Wait for room in buffer while( nBytesRead > line.available() ){ System.out.println("Audio Thread - Waiting for system audio buffer room."); thread.sleep(250); } //Write to System Audio Buffer nBytesWritten = line.write(data, 0, nBytesRead); totalWritten += nBytesWritten; } System.out.println("Read " + totalRead); System.out.println("Wrote " + totalWritten); //Update trackging variables nextSegment++; totalRead = 0; totalWritten = 0; nBytesRead = 0; nBytesWritten = 0; nBytesLeft = Constant.SEGMENT_SIZE; //Exit if last segment in streaming data if(nBytesLeft == 0 ){ System.out.println("Audio Thread - Full song loaded into system audio buffer."); break; } if (nBytesRead == -1) { System.out.println("***** Error - Audio thread couldn't read from decoded input stream."); break; } /* if(cacheManager.isThisLastSegment(mediaId, nextSegment)) break; else nextSegment++; */ } // // Stop line.drain(); line.stop(); line.close(); din.close(); } } catch(Exception e){ e.printStackTrace(); } } /** * STATUS FUNCTIONS */ public boolean isSongPlaying(){ return songIsPlaying; } public boolean isSongPaused(){ return isSongPaused; } /** * CONTROL FUNCTIONS */ /** * Stops playing audio, but doesn't empty line buffer so that audio can be resumed. */ public void pauseSong(){ isSongPaused = true; } /** * Starts playing a song, IF AND ONLY IF it's been paused. */ public void playPausedSong(){ thread.interrupt(); } public void stopSong(){ songIsPlaying = false; //reset tracking data isSongPaused = false; // " " } /** * TODO */ public void setVolume(float value){ //volume.setValue(value); //System.out.printf("Volume to %f\n", value); } /** * This signals the tread to return from the run loop. */ public void killAudioThread(){ timeToExitThread = true; } } /* * * private void rawplay(AudioFormat targetFormat, AudioInputStream dinRef) throws IOException, LineUnavailableException { din = dinRef; data = new byte[4096]; line = getLine(targetFormat); if (line != null) { // Start line.start(); songIsPlaying = true; int nBytesRead = 0, nBytesWritten = 0; while (nBytesRead != -1) { nBytesRead = din.read(data, 0, data.length); if (nBytesRead != -1) nBytesWritten = line.write(data, 0, nBytesRead); //check for user clicking pause button, if true put thread to sleep. if(isSongPaused) { try{ songIsPlaying = false; line.stop(); thread.sleep(9999999); //sleep while paused. } catch(InterruptedException iex){ line.start(); isSongPaused = false; } } if(timeToExitThread){ line.stop(); stopSong(); songIsPlaying = false; return; } } //end while stopSong(); }//end if } public void configureAudioInputStream(int segNum) throws SegmentNotLoadedException { //Bitrate, channels, sample rate etc. try{ if(line != null){ line.drain(); line.close(); } //get first segment just to configure sound settings. Don't copy it's buffer into line yet. bis = new ByteArrayInputStream(cacheManager.getSegment(mediaId, 1)); in = AudioSystem.getAudioInputStream(new File(Constant.pathToAnMp3)); baseFormat = in.getFormat(); decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16, baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false); line = getLine(decodedFormat); line.start(); } catch(Exception e){ e.printStackTrace(); } } 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 playSong(URL songURL){ //Start playing the song try{ System.out.println(songURL); AudioInputStream in= AudioSystem.getAudioInputStream(songURL); AudioInputStream din = null; 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); // Play now. rawplay(decodedFormat, din); in.close(); } catch(Exception e){ System.out.println("Exception thrown while starting new player: " + e.getMessage() + "\n" ); e.printStackTrace(); } } */