/* -*- c-basic-offset: 2; indent-tabs-mode: nil; -*- */ /* * FreeDots -- MusicXML to braille music transcription * * Copyright 2008-2010 Mario Lang All Rights Reserved. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as * published by the Free Software Foundation. * * This code 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 (a copy is included in the LICENSE.txt file that * accompanied this code). * * You should have received a copy of the GNU General Public License * along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * This file is maintained by Mario Lang <mlang@delysid.org>. */ package freedots.playback; import java.io.Closeable; import java.io.File; import javax.sound.midi.InvalidMidiDataException; import javax.sound.midi.MidiSystem; import javax.sound.midi.MidiUnavailableException; import javax.sound.midi.Sequence; import javax.sound.midi.Sequencer; import javax.sound.midi.Soundbank; import javax.sound.midi.Synthesizer; /** * Class {@code MIDIPlayer} is a composite that coordinates * {@link javax.sound.midi.Sequencer} and * {@link javax.sound.midi.Synthesizer} to provide MIDI playback. * * Optionally it can use {@link MetaEventRelay} to resolve object * references embedded in {@link freedots.musicxml.MIDISequence} * and cause {@link PlaybackObserver} clients to be notified when a * certain object is played. */ public final class MIDIPlayer implements Closeable { public static final int SLEEP_TIME = 250; private Synthesizer synthesizer = MidiSystem.getSynthesizer(); private Sequencer sequencer = MidiSystem.getSequencer(false); public MIDIPlayer(final MetaEventRelay metaEventRelay) throws MidiUnavailableException, InvalidMidiDataException, MetaEventListeningUnavailableException { this(); if (!sequencer.addMetaEventListener(metaEventRelay)) { throw new MetaEventListeningUnavailableException(); } } public MIDIPlayer() throws MidiUnavailableException, InvalidMidiDataException { sequencer.open(); synthesizer.open(); sequencer.getTransmitter().setReceiver(synthesizer.getReceiver()); //sequencer.setTempoInBPM(60); } /** Load a Soundfont (extension .sf2 or .dls) for use with the Synthesizer. * @return true if the Soundfont was loaded successfully, false otherwise. */ public boolean loadSoundbank(File file) { try { Soundbank soundbank = MidiSystem.getSoundbank(file); if (synthesizer.isSoundbankSupported(soundbank)) { return synthesizer.loadAllInstruments(soundbank); } } catch (javax.sound.midi.InvalidMidiDataException exception) { return false; } catch (java.io.IOException exception) { return false; } return false; } public void setSequence(Sequence sequence) throws InvalidMidiDataException { sequencer.setSequence(sequence); } public void start() { sequencer.start(); } public boolean isRunning() { return sequencer.isRunning(); } public void stop() { sequencer.stop(); } public void close() { if (isRunning()) stop(); sequencer.close(); synthesizer.close(); } }