/* * JFugue, an Application Programming Interface (API) for Music Programming * http://www.jfugue.org * * Copyright (C) 2003-2014 David Koelle * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jfugue.player; import org.jfugue.midi.MidiParserListener; import org.jfugue.pattern.Pattern; import org.jfugue.pattern.PatternProducer; import org.staccato.StaccatoParser; import jp.kshoji.javax.sound.midi.InvalidMidiDataException; import jp.kshoji.javax.sound.midi.MidiUnavailableException; import jp.kshoji.javax.sound.midi.Sequence; /** * This is a player that is optimized for defining and playing music in a program. * It specifically parses music with a StaccatoParser and converts the music to * MIDI using a MidiParserListener. * * This Player uses a ManagedPlayer but does not expose any of the ManagedPlayer's * ability to be managed. */ public class Player { private StaccatoParser staccatoParser; private MidiParserListener midiParserListener; private ManagedPlayer managedPlayer; public Player() { managedPlayer = new ManagedPlayer(); staccatoParser = new StaccatoParser(); midiParserListener = new MidiParserListener(); staccatoParser.addParserListener(midiParserListener); } public Sequence getSequence(PatternProducer... patternProducers) { return getSequence(new Pattern(patternProducers)); } public Sequence getSequence(PatternProducer patternProducer) { return getSequence(patternProducer.getPattern().toString()); } public Sequence getSequence(String... strings) { return getSequence(new Pattern(strings)); } public Sequence getSequence(String string) { staccatoParser.parse(string); return midiParserListener.getSequence(); } public void play(PatternProducer... patternProducers) { play(new Pattern(patternProducers)); } public void play(PatternProducer patternProducer) { play(patternProducer.getPattern().toString()); } public void play(String... strings) { play(new Pattern(strings)); } public void play(String string) { play(getSequence(string)); } /** * This method plays a sequence by starting the sequence and waiting for the sequence * to finish before continuing. It also converts InvalidMidiDataException and * MidiUnavailableException to RuntimeExceptions for easier end-user programming. * If you want to create an application where you catch those exceptions, you * may want to use ManagedPlayer directly. * * @param sequence */ public void play(Sequence sequence) { try { managedPlayer.start(sequence); } catch (InvalidMidiDataException e) { throw new RuntimeException(e); } catch (MidiUnavailableException e) { throw new RuntimeException(e); } // Wait for the sequence to finish playing while (!managedPlayer.isFinished()) { try { Thread.sleep(20); // don't hog all of the CPU } catch (InterruptedException e) { // Nothing to do here } } } public void delayPlay(final long millisToDelay, final PatternProducer... patternProducers) { delayPlay(millisToDelay, new Pattern(patternProducers)); } public void delayPlay(final long millisToDelay, final PatternProducer patternProducer) { delayPlay(millisToDelay, patternProducer.getPattern().toString()); } public void delayPlay(final long millisToDelay, final String... strings) { delayPlay(millisToDelay, new Pattern(strings)); } public void delayPlay(final long millisToDelay, final String string) { delayPlay(millisToDelay, getSequence(string)); } public void delayPlay(final long millisToDelay, final Sequence sequence) { Thread thread = new Thread() { public void run() { try { Thread.sleep(millisToDelay); } catch (InterruptedException e) { // Get yourself an egg and beat it! } Player.this.play(sequence); } }; thread.start(); } /** * Returns the ManagedPlayer behind this Player. You can start, pause, stop, resume, and seek a ManagedPlayer. * @see ManagedPlayer */ public ManagedPlayer getManagedPlayer() { return this.managedPlayer; } /** * Returns the StaccatoParser used by this Player. The only thing you might want to do with this is set whether the parser * throws an exception if an unknown token is found. * @see StaccatoParser */ public StaccatoParser getStaccatoParser() { return this.staccatoParser; } /** * Returns the MidiParserListener used by this Player. * @see org.jfugue.midi.MidiParserListener */ public MidiParserListener getMidiParserListener() { return this.midiParserListener; } }