gt: 		return loadFile( filename, 1024 );
context: /*
   *  Copyright (c) 2007 - 2008 by Damien Di Fede <ddf@compartmental.net>
   *
   *   This program is free software; you can redistribute it and/or modify
   *   it under the terms of the GNU Library General Public License as published
   *   by the Free Software Foundation; either version 2 of the License, or
   *   (at your option) any later version.
   *
   *   This program 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 Library General Public License for more details.
   *
   *   You should have received a copy of the GNU Library General Public
   *   License along with this program; if not, write to the Free Software
   *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   */
  
  package ddf.minim;
  
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.util.ArrayList;
  
  import javax.sound.sampled.AudioFileFormat;
  import javax.sound.sampled.AudioFormat;
  import javax.sound.sampled.Mixer;
  
  import org.tritonus.share.sampled.AudioUtils;
  
  import ddf.minim.javasound.JSMinim;
  import ddf.minim.spi.AudioOut;
  import ddf.minim.spi.AudioRecording;
  import ddf.minim.spi.AudioRecordingStream;
  import ddf.minim.spi.AudioStream;
  import ddf.minim.spi.MinimServiceProvider;
  import ddf.minim.spi.SampleRecorder;
  
  /**
   * The <code>Minim</code> class is the starting point for most everything
   * you will do with this library. There are methods for obtaining objects for playing audio files:
   * AudioSample and AudioPlayer. There are methods for obtaining an AudioRecorder, 
   * which is how you record audio to disk. There are methods for obtaining an AudioInput, 
   * which is how you can monitor the computer's line-in or microphone, depending on what the
   * user has set as the record source. Finally there are methods for obtaining an AudioOutput, 
   * which is how you can play audio generated by your program, typically by connecting classes 
   * found in the ugens package. 
   * <p>
   * Minim keeps references to all of the resources that are 
   * returned from these various methods so that you don't have to worry about closing them.
   * Instead, when your application ends you can simply call the stop method of your Minim instance.
   * Processing users <em>do not</em> need to do this because Minim detects when a PApplet is passed 
   * to the contructor and registers for a notification of application shutdown.
   * <p>
   * Minim requires an Object that can handle two important
   * file system operations so that it doesn't have to worry about details of 
   * the current environment. These two methods are:
   * <p>
   * <code>
   * String sketchPath( String fileName )<br/>
   * InputStream createInput( String fileName )<br/>
   * </code>
   * </p>
   * These are methods that are defined in Processing, which Minim was originally 
   * designed to cleanly interface with. The <code>sketchPath</code> method is 
   * expected to transform a filename into an absolute path and is used when 
   * attempting to create an AudioRecorder. The <code>createInput</code> method 
   * is used when loading files and is expected to take a filename, which is 
   * not necessarily an absolute path, and return an <code>InputStream</code> 
   * that can be used to read the file. For example, in Processing, the <code>createInput</code>
   * method will search in the data folder, the sketch folder, handle URLs, and absolute paths.
   * If you are using Minim outside of Processing, you can handle whatever cases are 
   * appropriate for your project.
   * 
   * @example Basics/PlayAFile
   * 
   * @author Damien Di Fede
   */
  
  public class Minim
  {
  	/** Specifies that you want a MONO AudioInput or AudioOutput */
  	public static final int				MONO				= 1;
  	/** Specifies that you want a STEREO AudioInput or AudioOutput */
  	public static final int				STEREO				= 2;
  
  	public static final int				LOOP_CONTINUOUSLY	= -1;
  
  	/** The .wav file format. */
  	public static AudioFileFormat.Type	WAV					= AudioFileFormat.Type.WAVE;
  	/** The .aiff file format. */
  	public static AudioFileFormat.Type	AIFF				= AudioFileFormat.Type.AIFF;
  	/** The .aifc file format. */
  	public static AudioFileFormat.Type	AIFC				= AudioFileFormat.Type.AIFC;
  	/** The .au file format. */
  	public static AudioFileFormat.Type	AU					= AudioFileFormat.Type.AU;
  	/** The .snd file format. */
  	public static AudioFileFormat.Type	SND					= AudioFileFormat.Type.SND;
  
  	private static boolean				DEBUG				= false;
  
  	private MinimServiceProvider		mimp				= null;
  	
  	// we keep track of all the resources we are asked to create
  	// so that when shutting down the library, users can simply call stop(),
  	// and don't have to call close() on all of the things they've created.
  	// in the event that they *do* call close() on resource we've created,
  	// it will be removed from this list.
  	private ArrayList<AudioSource> 		sources				= new ArrayList<AudioSource>();
  	// and unfortunately we have to track stream separately
  	private ArrayList<AudioStream>		streams				= new ArrayList<AudioStream>();
  
  	/**
  	 * Creates an instance of Minim.
  	 * <p>
  	 * Minim requires an Object that can handle two important
  	 * file system operations so that it doesn't have to worry about details of 
  	 * the current environment. These two methods are:
  	 * <p>
  	 * <code>
  	 * String sketchPath( String fileName )<br/>
  	 * InputStream createInput( String fileName )<br/>
  	 * </code>
  	 * </p>
  	 * These are methods that are defined in Processing, which Minim was originally 
  	 * designed to cleanly interface with. The <code>sketchPath</code> method is 
  	 * expected to transform a filename into an absolute path and is used when 
  	 * attempting to create an AudioRecorder. The <code>createInput</code> method 
  	 * is used when loading files and is expected to take a filename, which is 
  	 * not necessarily an absolute path, and return an <code>InputStream</code> 
  	 * that can be used to read the file. For example, in Processing, the <code>createInput</code>
  	 * method will search in the data folder, the sketch folder, handle URLs, and absolute paths.
  	 * If you are using Minim outside of Processing, you can handle whatever cases are 
  	 * appropriate for your project.
  	 * 
  	 * @param fileSystemHandler
  	 *            The Object that will be used for file operations.
  	 *            When using Processing, simply pass <strong>this</strong> to Minim's constructor.
  	 */
  	public Minim( Object fileSystemHandler )
  	{
  		this( new JSMinim(fileSystemHandler) );
  		
  		// see if we're dealing with Processing and register for a dispose call if we are
  		Class<?> superClass = fileSystemHandler.getClass().getSuperclass();
  		if( superClass.getName() == "processing.core.PApplet" )
  		{
  			try
  			{
  				Method registerDispose = superClass.getMethod( "registerMethod", String.class, Object.class );
  				registerDispose.invoke( fileSystemHandler, "dispose", this );
  			}
  			catch ( SecurityException e )
  			{
  				e.printStackTrace();
  			}
  			catch ( NoSuchMethodException e )
  			{
  				e.printStackTrace();
  			}
  			catch ( IllegalArgumentException e )
  			{
  				e.printStackTrace();
  			}
  			catch ( IllegalAccessException e )
  			{
  				e.printStackTrace();
  			}
  			catch ( InvocationTargetException e )
  			{
  				e.printStackTrace();
  			}
  		}
  	}
  
  	/** @invisible
  	 * 
  	 * Creates an instance of Minim that will use the provided implementation
  	 * for audio.
  	 * 
  	 * @param implementation
  	 *            the MinimServiceProvider that will be used for returning audio
  	 *            resources
  	 */
  	public Minim( MinimServiceProvider implementation )
  	{
  		mimp = implementation;
  		mimp.start();
  	}
  
  	/** @invisible
  	 * 
  	 * Used internally to report error messages. These error messages will
  	 * appear in the console area of the PDE if you are running a sketch from
  	 * the PDE, otherwise they will appear in the Java Console.
  	 * 
  	 * @param message
  	 *            the error message to report
  	 */
  	public static void error(String message)
  	{
  		System.out.println( "=== Minim Error ===" );
  		System.out.println( "=== " + message );
  		System.out.println();
  	}
  
  	/** @invisible
  	 * 
  	 * Displays a debug message, but only if {@link #debugOn()} has been called.
  	 * The message will be displayed in the console area of the PDE, if you are
  	 * running your sketch from the PDE. Otherwise, it will be displayed in the
  	 * Java Console.
  	 * 
  	 * @param message
  	 *            the message to display
  	 * @see #debugOn()
  	 */
  	public static void debug(String message)
  	{
  		if ( DEBUG )
  		{
  			String[] lines = message.split( "\n" );
  			System.out.println( "=== Minim Debug ===" );
  			for ( int i = 0; i < lines.length; i++ )
  			{
  				System.out.println( "=== " + lines[i] );
  			}
  			System.out.println();
  		}
  	}
  
  	/**
  	 * Turns on debug messages.
  	 */
  	public void debugOn()
  	{
  		DEBUG = true;
  		if ( mimp != null )
  		{
  			mimp.debugOn();
  		}
  	}
  
  	/**
  	 * Turns off debug messages.
  	 * 
  	 */
  	public void debugOff()
  	{
  		DEBUG = false;
  		if ( mimp != null )
  		{
  			mimp.debugOff();
  		}
  	}
  	
  	/** @invisible
  	 *  
  	 * Library callback used by Processing when a sketch is being shutdown. 
  	 * It is not necessary to call this directly. It simply calls stop().
  	 * 
  	 * 
  	 */
  	public void dispose()
  	{
  		stop();
  	}
  
  	/**
  	 * 
  	 * Stops Minim and releases all audio resources.
  	 * <p>
  	 * If using Minim outside of Processing, you must call this to 
  	 * release all of the audio resources that Minim has generated.
  	 * It will call close() on all of them for you.
  	 * 
  	 */
  	public void stop()
  	{
  		debug( "Stopping Minim..." );
  		
  		// close all sources and release them
  		for( AudioSource s : sources )
  		{
  			// null the parent so the AudioSource doesn't try to call removeSource
  			s.parent = null;
  			s.close();
  		}
  		sources.clear();
  		
  		for( AudioStream s : streams )
  		{
  			s.close();
  		}
  		
  		// stop the implementation
  		mimp.stop();
  	}
  	
  	void addSource( AudioSource s )
  	{
  		sources.add( s );
  		s.parent = this;
  	}
  	
  	void removeSource( AudioSource s )
  	{
  		sources.remove( s );
  	}
  
  	/**
  	 * When using the JavaSound implementation of Minim, this sets the JavaSound Mixer 
  	 * that will be used for obtaining input sources such as AudioInputs.
  	 * THIS METHOD WILL BE REPLACED IN A FUTURE VERSION.
  	 * 
  	 * @param mixer
  	 *            The Mixer we should try to acquire inputs from.
  	 */
  	@Deprecated
  	public void setInputMixer(Mixer mixer)
  	{
  		if ( mimp instanceof JSMinim )
  		{
  			( (JSMinim)mimp ).setInputMixer( mixer );
  		}
  	}
  
  	/**
  	 * When using the JavaSound implementation of Minim, this sets the JavaSound Mixer 
  	 * that will be used for obtain output destinations such as those required by AudioOuput, 
  	 * AudioPlayer, AudioSample, and so forth. 
  	 * THIS METHOD WILL BE REPLACED IN A FUTURE VERSION.
  	 * 
  	 * @param mixer
  	 *            The Mixer we should try to acquire outputs from.
  	 */
  	@Deprecated
  	public void setOutputMixer(Mixer mixer)
  	{
  		if ( mimp instanceof JSMinim )
  		{
  			( (JSMinim)mimp ).setOutputMixer( mixer );
  		}
  	}
  
  	/**
  	 * Creates an AudioSample using the provided sample data and AudioFormat. 
  	 * When a buffer size is not provided, it defaults to 1024. The buffer size 
  	 * of a sample controls the size of the left, right, and mix AudioBuffer 
  	 * fields of the returned AudioSample.
  	 * 
  	 * @shortdesc Creates an AudioSample using the provided sample data and AudioFormat.
  	 * 
  	 * @param sampleData
  	 *            float[]: the single channel of sample data
  	 * @param format
  	 *            the AudioFormat describing the sample data
  	 *            
  	 * @return an AudioSample that can be triggered to make sound
  	 * 
  	 * @example Advanced/CreateAudioSample
  	 * 
  	 * @related AudioSample
  	 */
  	public AudioSample createSample(float[] sampleData, AudioFormat format)
  	{
  		return createSample( sampleData, format, 1024 );
  	}
  
  	/**
  	 * Creates an AudioSample using the provided sample data and
  	 * AudioFormat, with the desired output buffer size.
  	 * 
  	 * @param sampleData
  	 *            float[]: the single channel of sample data
  	 * @param format
  	 *            the AudioFormat describing the sample data
  	 * @param bufferSize
  	 *            int: the output buffer size to use,
  	 *            which controls the size of the left, right, and mix AudioBuffer
  	 *            fields of the returned AudioSample.
  	 *            
  	 * @return an AudioSample that can be triggered to make sound
  	 */
  	public AudioSample createSample( float[] sampleData, AudioFormat format, int bufferSize )
  	{
  		AudioSample sample = mimp.getAudioSample( sampleData, format, bufferSize );
  		addSource( sample );
  		return sample;
  	}
  
  	/**
  	 * Creates an AudioSample using the provided left and right channel
  	 * sample data with an output buffer size of 1024.
  	 * 
  	 * @param leftSampleData
  	 *            float[]: the left channel of the sample data
  	 * @param rightSampleData
  	 *            float[]: the right channel of the sample data
  	 * @param format
  	 *            the AudioFormat describing the sample data
  	 *            
  	 * @return an AudioSample that can be triggered to make sound            
  	 */
  	public AudioSample createSample( float[] leftSampleData, float[] rightSampleData, AudioFormat format )
  	{
  		return createSample( leftSampleData, rightSampleData, format, 1024 );
  	}
  
  	/**
  	 * Creates an AudioSample using the provided left and right channel
  	 * sample data.
  	 * 
  	 * @param leftSampleData
  	 *            float[]: the left channel of the sample data
  	 * @param rightSampleData
  	 *            float[]: the right channel of the sample data
  	 * @param format
  	 *            the AudioFormat describing the sample data
  	 * @param bufferSize
  	 *            int: the output buffer size to use,
  	 *            which controls the size of the left, right, and mix AudioBuffer
  	 *            fields of the returned AudioSample.
  	 *            
  	 * @return an AudioSample that can be triggered to make sound
  	 */
  	public AudioSample createSample(float[] leftSampleData, float[] rightSampleData, AudioFormat format, int bufferSize)
  	{
  		AudioSample sample = mimp.getAudioSample( leftSampleData, rightSampleData, format, bufferSize );
  		addSource( sample );
  		return sample;
  	}
  
  	/**
  	 * Loads the requested file into an AudioSample.
  	 * By default, the buffer size used is 1024.
  	 * 
  	 * @shortdesc Loads the requested file into an AudioSample.
  	 * 
  	 * @param filename
  	 *            the file or URL that you want to load
  	 *            
  	 * @return an AudioSample that can be triggered to make sound
  	 * 
  	 * @example Basics/TriggerASample
  	 * 
  	 * @see #loadSample(String, int)
  	 * @see AudioSample
  	 * @related AudioSample
  	 */
  	public AudioSample loadSample(String filename)
  	{
  		return loadSample( filename, 1024 );
  	}
  
  	/**
  	 * Loads the requested file into an AudioSample.
  	 * 
  	 * @param filename
  	 *            the file or URL that you want to load
  	 * @param bufferSize
  	 *            int: The sample buffer size you want.
  	 *            This controls the size of the left, right, and mix
  	 *            AudioBuffer fields of the returned AudioSample.
  	 *            
  	 * @return an AudioSample that can be triggered to make sound
  	 */
  	public AudioSample loadSample(String filename, int bufferSize)
  	{
  		AudioSample sample = mimp.getAudioSample( filename, bufferSize );
  		addSource( sample );
  		return sample;
  	}
  
  	/** @invisible 
  	 * Loads the requested file into an {@link AudioSnippet}
  	 * 
  	 * @param filename
  	 *            the file or URL you want to load
  	 * @return an <code>AudioSnippet</code> of the requested file or URL
  	 */
  	@Deprecated
  	public AudioSnippet loadSnippet(String filename)
  	{
  		AudioRecording c = mimp.getAudioRecording( filename );
  		if ( c != null )
  		{
  			return new AudioSnippet( c );
  		}
  		else
  		{
  			Minim.error( "Couldn't load the file " + filename );
  		}
  		return null;
  	}
  
  	/**
  	 * Loads the requested file into an AudioPlayer.
  	 * The default buffer size is 1024 samples and the 
  	 * buffer size determines the size of the left, right, 
  	 * and mix AudioBuffer fields on the returned AudioPlayer.
  	 * 
  	 * @shortdesc Loads the requested file into an AudioPlayer.
  	 * 
  	 * @example Basics/PlayAFile
  	 * 
  	 * @param filename
  	 *            the file or URL you want to load
  	 * @return an <code>AudioPlayer</code> that plays the file
  	 * 
  	 * @related AudioPlayer
  	 * 
  	 * @see #loadFile(String, int)
  	 */
  	public AudioPlayer loadFile(String filename)
  	{
  