/* License see bottom*/
package jonkoshare.midi;
import java.util.logging.Logger;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;
import jonkoshare.staff.Note;
/**
* Reads midi events from a midi in device
* and forwards them to the dispatcher.
*
* @author methke01
* @since 0
*/
public class MidiReader extends Thread
implements Receiver {
private static final Logger log=Logger.getLogger(MidiReader.class.getName());
public MidiReader() {
}
// Thread
public void run() {
runFlag=true;
while(runFlag) {
try {
sleep(200);
} catch (Exception ex) {
// ex.printStackTrace();
}
}
}
// Receiver
public void close() {
// do nothing?
}
public void send(MidiMessage message, long timeStamp) {
/*
if (JRackAttack.spoolMidi()) {
debug("receiving "+MidiReader.formatMidiMessage(message));
debug(message.getLength()+" bytes)");
}
*/
// Clock and active sensing won't be treated
// in any way
if (message.getStatus()==ShortMessage.ACTIVE_SENSING ||
message.getStatus()==ShortMessage.TIMING_CLOCK) {
return;
}
try {
// looks for the active MIDI channel to reprogram
// the incoming NOTE-events to become events of the
// right channel (RackAttack has 12 of them each with
// a possibly different sound loaded)
if (message.getStatus()==ShortMessage.NOTE_ON ||
message.getStatus()==ShortMessage.NOTE_OFF) {
ShortMessage sm=(ShortMessage)message;
try {
sm.setMessage(sm.getCommand(),
getActiveMidiChannel(),
sm.getData1(), sm.getData2());
} catch (Exception ex) {
}
if (message.getStatus()==ShortMessage.NOTE_ON) {
Note n=new Note(sm.getData1());
NoteDispatcher.getInstance().notePlayed(n);
}
}
MidiThread.getInstance().enqueueEvent(message);
} catch (Exception ex) {
throw new MidiException(ex);
}
}
/**
* Liefert den aktiven Midi-Kanal. Es kommt sehr
* häufig vor, dass Ereignisse von einem Midi-Gerät
* ohne Kanalinformation abgegriffen werden. Damit
* ein Kanal rekonstruiert werden kann, hat der
* Reader ein solches Attribut.
* @return
*/
public int getActiveMidiChannel() {
return activeMidiChannel;
}
public void setActiveMidiChannel(int can) {
activeMidiChannel=can;
}
public boolean isRunning() {
return runFlag;
}
public void setRunning(boolean state) {
runFlag=state;
}
public void done() {
runFlag=false;
}
public static final String formatMidiMessage(MidiMessage msg) {
if (msg==null) {
return "";
}
byte bts[]=msg.getMessage();
StringBuffer sb=new StringBuffer();
for(byte b:bts) {
String str=Integer.toHexString(b & 0xFF);
if (str.length()<2) {
sb.append("0");
}
sb.append(str);
sb.append(" ");
}
return sb.toString();
}
protected void debug(String msg) {
log.finest(msg);
}
private boolean runFlag;
/**
* Holds value of property keyInDevice.
*/
private MidiDevice keyInDevice;
/**
* Getter for property keyInDevice.
* @return Value of property keyInDevice.
*/
public MidiDevice getKeyboardInDevice() {
return this.keyInDevice;
}
/**
* Setter for property keyInDevice.
* @param keyInDevice New value of property keyInDevice.
*/
public void setKeyboardInDevice(MidiDevice keyInDevice) {
if (this.keyInDevice !=null && this.keyInDevice.isOpen()) {
this.keyInDevice.close();
}
this.keyInDevice = keyInDevice;
if (this.keyInDevice !=null && !this.keyInDevice.isOpen()) {
try {
this.keyInDevice.open();
this.keyInDevice.getTransmitter().setReceiver(this);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
/**
* Holds value of property nextProgramNumber.
*/
private int nextProgramNumber;
/**
* Getter for property nextProgramNumber.
* @return Value of property nextProgramNumber.
*/
public int getNextProgramNumber() {
return this.nextProgramNumber;
}
/**
* Setter for property nextProgramNumber.
* @param nextProgramNumber New value of property nextProgramNumber.
*/
public void setNextProgramNumber(int nextProgramNumber) {
this.nextProgramNumber = nextProgramNumber;
}
private int activeMidiChannel;
}
/*
Copyright (C) 2008 Onkobu Tanaake
This program 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 3 of the License, or
(at your option) any later version.
This program 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 this program (gplv3.txt).
*/