/* AudioPlayerSample.java -- Simple Java Audio Player Copyright (C) 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. GNU Classpath is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Classpath is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Classpath; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU General Public License cover the whole combination. As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ package gnu.classpath.examples.sound; import java.io.File; import java.io.IOException; import java.util.Map; 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 javax.sound.sampled.UnsupportedAudioFileException; /** * A simple demo to show the use of the Java Sound API. * It plays the given file (up to the end, so don't pass the 26 minutes long * Pink Floyd's Echoes unless you really want!!). * * See: http://jsresources.org/examples/SimpleAudioPlayer.java.html * * @author Mario Torre <neugens@limasoftware.net> */ public class AudioPlayerSample { private static final int EXTERNAL_BUFFER_SIZE = 128000; /** * @param args */ public static void main(String[] args) { if (args.length < 1) { System.out.println("Radio Classpath -: Usage: " + "AudioPlayerSample [file]"); return; } String file = args[0]; System.out.println("Welcome to Radio Classpath, only great music for you!"); System.out.println("Today's DJ Tap The WaterDroplet"); // now create the AudioInputStream AudioInputStream audioInputStream = null; try { audioInputStream = AudioSystem.getAudioInputStream(new File(file)); } catch (UnsupportedAudioFileException e) { // This happen when the subsystem is unable to parse the kind of // audio file we are submitting // See the README for supported audio file types under Classpath // for the version you are using. e.printStackTrace(); return; } catch (IOException e) { e.printStackTrace(); return; } // get informations about the kind of file we are about to play AudioFormat audioFormat = audioInputStream.getFormat(); System.out.println("Playing file: " + file); System.out.println("format: " + audioFormat.toString()); System.out.print("Additional properties: "); // now, we try to get all the properties we have in this AudioFormat // and display them Map<String, Object> properties = audioFormat.properties(); if (properties.size() < 0) { System.out.println("none"); } else { System.out.println("found #" + properties.size() + " properties"); for (String key : properties.keySet()) { System.out.println(key + ": " + properties.get(key)); } } // let's setup things for playing // first, we require a Line. As we are doing playing, we will ask for a // SourceDataLine SourceDataLine line = null; // To get the source line, we first need to build an Info object // this is done in one line: DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat); System.out.println("searching line..."); // usually, if a backend can parse a file type, it can also // create a line to handle it, but that's not guaranteed // so we need to take care and to handle a possible // LineUnavailableException try { line = (SourceDataLine) AudioSystem.getLine(info); System.out.println("line found, opening..."); // once created, a line must be opened to let data flow // though it. line.open(audioFormat); } catch (LineUnavailableException e) { // in a real application you should signal that in a kindly way to // your users e.printStackTrace(); return; } catch (Exception e) { e.printStackTrace(); return; } // an open line pass data to the backend only when it is in // a state called "started" ("playing" or "play" in some other // framework) System.out.print("starting line... "); line.start(); System.out.println("done"); // now we can start reading data from the AudioStream and writing // data to the pipeline. The Java Sound API is rather low level // so let you pass up to one byte of data at a time // (with some constraints, refer to the API documentation to know more) // We will do some buffering. You may want to check the frame size // to allow a better buffering, also. System.out.println("now playing..."); int nBytesRead = 0; byte[] abData = new byte[EXTERNAL_BUFFER_SIZE]; while (nBytesRead != - 1) { try { nBytesRead = audioInputStream.read(abData, 0, abData.length); } catch (IOException e) { e.printStackTrace(); } if (nBytesRead >= 0) { // this method returns the number of bytes actuall written // to the line. You may want to use this number to check // for events, display the current position (give also a // look to the API for other ways of doing that) etc.. line.write(abData, 0, nBytesRead); } } System.out.print("stream finished, draining line... "); // call this method to ensure that all the data in the internal buffer // reach the audio backend, otherwise your application will // cut the last frames of audio data (and users will not enjoy the last // seconds of their precious music) line.drain(); // Once done, we can close the line. Note that a line, once closed // may not be reopened (depends on the backend, in some cases a "reopen", // if allowed, really opens a new line, reallocating all the resources) System.out.println("line drained, now exiting"); line.close(); System.out.println("We hope you enjoyed Radio Classpath!"); } }