package ddf.minim; import javax.sound.sampled.AudioFormat; /** * An <code>AudioSource</code> is a kind of wrapper around an * <code>AudioStream</code>. In Minim, the classes that implement * <code>AudioStream</code> are <code>Thread</code>s and handle all of the * actual work of reading from files and writing to <code>DataLine</code>s. * An <code>AudioSource</code> will add its <code>AudioBuffer</code>s as * listeners on the stream so that you can access the stream's samples without * having to implement <code>AudioListener</code> yourself. It also provides * the same <code>Effectable</code> and <code>Recordable</code> interface * that the stream has so that you can treat an <code>AudioSource</code> as if * it was the stream itself. Because an <code>AudioStream</code> must be * closed when you are finished with it, you must remember to call * {@link #close()} on any <code>AudioSource</code>s you obtain from Minim, * such as <code>AudioInput</code>s, <code>AudioOutput</code>s, and * <code>AudioPlayer</code>s. * * @author Damien Di Fede * */ public class AudioSource extends Controller implements Effectable, Recordable { private AudioStream stream; // the StereoBuffer that will subscribe to synth private StereoBuffer buffer; /** * The buffer containing the left channel samples. If this is a mono * <code>AudioSource</code>, it contains the single channel of audio. */ public final AudioBuffer left; /** * The buffer containing the right channel samples. If this is a mono * <code>AudioSource</code>, <code>right</code> contains the same samples * as <code>left</code>. */ public final AudioBuffer right; /** * The buffer containing the mix of the left and right channels. If this is a * mono <code>AudioSource</code>, <code>mix</code> contains the same * samples as <code>left</code>. */ public final AudioBuffer mix; /** * Constructs an <code>AudioSource</code> that will subscribe to the samples * in <code>stream</code>. It is expected that the stream is using a * <code>DataLine</code> for playback. If it is not, calls to * <code>Controller</code>'s methods will result in a * <code>NullPointerException</code>. * * @param stream * the <code>AudioStream</code> to subscribe to and wrap */ public AudioSource(AudioStream stream) { super(stream.getDataLine()); this.stream = stream; this.stream.open(); buffer = new StereoBuffer(type(), bufferSize(), this); this.stream.addListener(buffer); left = buffer.left; right = buffer.right; mix = buffer.mix; } /** * Closes the <code>AudioStream</code> this was constructed with. * */ public void close() { stream.close(); } public void addEffect(AudioEffect effect) { stream.addEffect(effect); } public void clearEffects() { stream.clearEffects(); } public void disableEffect(int i) { stream.disableEffect(i); } public void disableEffect(AudioEffect effect) { stream.disableEffect(effect); } public int effectCount() { return stream.effectCount(); } public void effects() { stream.effects(); } public boolean hasEffect(AudioEffect e) { return stream.hasEffect(e); } public void enableEffect(int i) { stream.enableEffect(i); } public void enableEffect(AudioEffect effect) { stream.enableEffect(effect); } public AudioEffect getEffect(int i) { return stream.getEffect(i); } public boolean isEffected() { return stream.isEffected(); } public boolean isEnabled(AudioEffect effect) { return stream.isEnabled(effect); } public void noEffects() { stream.noEffects(); } public void removeEffect(AudioEffect effect) { stream.removeEffect(effect); } public AudioEffect removeEffect(int i) { return stream.removeEffect(i); } public void addListener(AudioListener listener) { stream.addListener(listener); } public int bufferSize() { return stream.bufferSize(); } public AudioFormat getFormat() { return stream.getFormat(); } public void removeListener(AudioListener listener) { stream.removeListener(listener); } public int type() { return stream.type(); } public float sampleRate() { return stream.getFormat().getSampleRate(); } }