/* * JFugue - API for Music Programming * Copyright (C) 2003-2008 David Koelle * * http://www.jfugue.org * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ package org.jfugue; import javax.sound.midi.MidiDevice; import javax.sound.midi.MidiMessage; import javax.sound.midi.MidiSystem; import javax.sound.midi.MidiUnavailableException; import javax.sound.midi.Receiver; import javax.sound.midi.Sequence; import javax.sound.midi.Sequencer; import javax.sound.midi.Transmitter; /** * Represents an attached MIDI device, such as a keyboard. This class uses * javax.sound.MidiDevice, but is not derived from javax.sound.MidiDevice. * * @author David Koelle * @version 3.0 */ public class DeviceThatWillTransmitMidi { private MidiDevice device; private Transmitter transmitter; private MidiReceiverForTransmitterDevice mrftd; // private Receiver defaultReceiver; /** * Creates a new DeviceThatWillTransmitMidi using JFugue's Intelligent * Device Resolver to pick the most likely device to open. * * @throws MidiUnavailableException */ public DeviceThatWillTransmitMidi() throws MidiUnavailableException { this.device = IntelligentDeviceResolver.selectTransmitterDevice(); init(); } public DeviceThatWillTransmitMidi(MidiDevice.Info info) throws MidiUnavailableException { this.device = MidiSystem.getMidiDevice(info); init(); } private void init() throws MidiUnavailableException { try { if (!(device.isOpen())) { device.open(); } this.transmitter = device.getTransmitter(); this.mrftd = new MidiReceiverForTransmitterDevice(); } catch (MidiUnavailableException e) { device.close(); throw e; } } public Transmitter getTransmitter() { return this.transmitter; } public void addParserListener(ParserListener listener) { this.mrftd.getParser().addParserListener(listener); } public void removeParserListener(ParserListener listener) { this.mrftd.getParser().removeParserListener(listener); } /** * Reads a pattern from the external device - use this to record the keys * you're pressing on the keyboard! * * This method will return a JFugue Pattern, which you can then manipulate * to your heart's content. * * @return The Pattern representing the music played on the device */ public void startListening() { this.transmitter.setReceiver(this.mrftd); } public void stopListening() { // this.transmitter.setReceiver(this.defaultReceiver); device.close(); // this.transmitter.close(); // this.mrftd.close(); } public void listenForMillis(long millis) throws InterruptedException { startListening(); Thread.sleep(millis); stopListening(); } public Pattern getPatternFromListening() { return this.mrftd.getPattern(); } public Sequence getSequenceFromListening() { return this.mrftd.getSequence(); } public void close() { transmitter.close(); device.close(); // this.mrftd.close(); // this.transmitter.close(); } class MidiReceiverForTransmitterDevice implements Receiver { private MidiParser parser; private Sequencer sequencer; private Receiver sequencerReceiver; private MusicStringRenderer renderer; public MidiReceiverForTransmitterDevice() { System.out.println("Built mrftd"); parser = new MidiParser(); renderer = new MusicStringRenderer(); parser.addParserListener(renderer); try { sequencer = MidiSystem.getSequencer(); sequencerReceiver = sequencer.getReceiver(); } catch (MidiUnavailableException e) { e.printStackTrace(); } } public Parser getParser() { return this.parser; } @Override public void send(MidiMessage message, long timestamp) { System.out.println("Parsing " + message + " ts: " + timestamp); parser.parse(message, timestamp / (1000 * 4)); sequencerReceiver.send(message, timestamp); } @Override public void close() { sequencerReceiver.close(); } public Pattern getPattern() { return renderer.getPattern(); } public Sequence getSequence() { return sequencer.getSequence(); } } }