/*
* Created on Feb 12, 2007
*
* Copyright (c) 2007 Jens Gulden
*
* http://www.frinika.com
*
* This file is part of Frinika.
*
* Frinika is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* Frinika 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.
* You should have received a copy of the GNU General Public License
* along with Frinika; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.frinika.sequencer.midi;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;
import java.util.Collection;
/**
* Allows to 'snoop' the data sent to a receiver, by passing data on to
* MidiMessageListeners.
*
* Note that instances of MidiMessageListener don't get directly connected to a
* MonitorReceiver (there are no addMidiMessageListener() /
* removeMidiMessageListener() methods on MonitorReceiver), but will be added to /
* removed from higher-level classes that use MonitorReceivers.
*
* @see MidiMessageListener
* @author Jens Gulden
*/
public class MonitorReceiver implements Receiver {
protected Receiver chained;
protected Collection<MidiMessageListener> listeners;
private static boolean isLinux = System.getProperty("os.name").equals(
"Linux");
public MonitorReceiver(Collection<MidiMessageListener> listeners,
Receiver chained) {
this.chained = chained;
this.listeners = listeners;
}
public void send(MidiMessage message, long timeStamp) {
// I hope no one is interested in these events
if (message.getStatus() >= ShortMessage.MIDI_TIME_CODE)
return;
if (isLinux) {
if (message.getStatus() == ShortMessage.PITCH_BEND) {
ShortMessage mess = (ShortMessage) message;
short low = (byte) mess.getData1();
short high = (byte) mess.getData2();
int channel = mess.getChannel();
// linux midi has a bug in the pitch bend this fixes the problem
low = (byte) mess.getData1();
high = (byte) mess.getData2();
high= (short) ((high+64) & 0x007f);
try {
mess.setMessage(ShortMessage.PITCH_BEND, channel,
low, high);
} catch (InvalidMidiDataException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
chained.send(message, timeStamp);
notifyListeners(message);
}
public void close() {
chained.close();
}
protected void notifyListeners(MidiMessage message) {
for (MidiMessageListener l : listeners) {
l.midiMessage(message);
}
}
}