Mittlerweile hat das Projekt den Status erreicht, in dem ich es mal praxisnah testen kann.
So sieht mein momentanes Routing aus:
Manche Browser schneiden das Bild an der rechten Seite ab - hier die komplette version:
http://www.ucapps.de/midi_router/midi_router_default.gif
Und so der Code in router.c (meiner Meinung nach ist es noch einigermassen ueberschaubar 
/////////////////////////////////////////////////////////////////////////////
// These functions are called from the MIDI parser when a new package has been
// received. They can be modified to customize the routing
//
// evnt0, evnt1, evnt2: the bytes of the MIDI event which has been received
//
// ptype: package type
// - 0x02 two-byte system common message like MTC, Song Select, etc.
// - 0x03 three-byte system common message like SSP, etc.
// - 0x04 SysEx starts or continues
// - 0x05 SysEx ends with following single byte
// - 0x06 SysEx ends with following two bytes
// - 0x07 SysEx ends with following three bytes
// - 0x08 Note Off
// - 0x09 Note On
// - 0x0a Poly-Key Pressure
// - 0x0b Control Change
// - 0x0c Program Change
// - 0x0d Channel Pressure
// - 0x0e Pitch Bend
// - 0x0f single byte like MIDI Clock/Start/Stop/Continue
/////////////////////////////////////////////////////////////////////////////
void ROUTER_Rx_INT0(unsigned char ptype, unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
// Core MIDI IN, connected to my PC
// lock/release this routing path on SysEx streams
ROUTER_LockPathOnSysEx(PORT_INT0, ptype);
// forward data to the MIDI OUTs of all IIC slaves
ROUTER_Tx_IIC0(ptype, evnt0, evnt1, evnt2);
ROUTER_Tx_IIC1(ptype, evnt0, evnt1, evnt2);
ROUTER_Tx_IIC2(ptype, evnt0, evnt1, evnt2);
ROUTER_Tx_IIC3(ptype, evnt0, evnt1, evnt2);
}
void ROUTER_Rx_IIC0(unsigned char ptype, unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
// IIC0: connected to my MIDIbox SID
// lock/release this routing path on SysEx streams
ROUTER_LockPathOnSysEx(PORT_IIC0, ptype);
// forward data to the Core MIDI OUT
ROUTER_Tx_INT0(ptype, evnt0, evnt1, evnt2);
}
void ROUTER_Rx_IIC1(unsigned char ptype, unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
// IIC1: connected to my MIDIbox FM
// lock/release this routing path on SysEx streams
ROUTER_LockPathOnSysEx(PORT_IIC1, ptype);
// forward data to the Core MIDI OUT
ROUTER_Tx_INT0(ptype, evnt0, evnt1, evnt2);
}
void ROUTER_Rx_IIC2(unsigned char ptype, unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
// IIC2: connected to my MIDIbox SEQ
// lock/release this routing path on SysEx streams
ROUTER_LockPathOnSysEx(PORT_IIC2, ptype);
// forward MIDI clock/start/stop/continue to all IIC modules
if( evnt0 >= 0xf8 && evnt0 <= 0xfc ) {
ROUTER_Tx_IIC0(ptype, evnt0, evnt1, evnt2);
ROUTER_Tx_IIC1(ptype, evnt0, evnt1, evnt2);
ROUTER_Tx_IIC2(ptype, evnt0, evnt1, evnt2);
ROUTER_Tx_IIC3(ptype, evnt0, evnt1, evnt2);
}
if( (ptype >= 0x08 && ptype <= 0x0e) && ((evnt0 & 0x0f) >= MIDI_CHN9) ) {
// directly forward MIDI channel #9..#16 messages to MIDIbox SID and MIDIbox FM only
ROUTER_Tx_IIC0(ptype, evnt0, evnt1, evnt2);
ROUTER_Tx_IIC1(ptype, evnt0, evnt1, evnt2);
} else {
// forward all other events to the Core MIDI OUT
ROUTER_Tx_INT0(ptype, evnt0, evnt1, evnt2);
}
}
void ROUTER_Rx_IIC3(unsigned char ptype, unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
unsigned char transposed_note;
// IIC3: connected to my Yamaha AN1x
// lock/release this routing path on SysEx streams
ROUTER_LockPathOnSysEx(PORT_IIC3, ptype);
// if note on/off at channel #16 has been received, change it in the
// following way:
// - send notes < C-4 to MIDIbox SID (IIC0), Channel #9
// - send notes < C-4 to MIDIbox SEQ (IIC2), Channel #1, transposed by 2 octaves
// - send notes >= C-4 to MIDIbox FM (IIC1), Channel #13
if( (ptype >= 0x08 && ptype <= 0x09) && ((evnt0 & 0x0f) == MIDI_CHN16) ) {
if( evnt1 < 0x3c ) { // evnt1 contains note number, 0x3c is C-4
ROUTER_Tx_IIC0(ptype, (evnt0 & 0xf0) | MIDI_CHN9, evnt1, evnt2);
transposed_note = evnt1 + 2*12;
while( transposed_note > 127 ) // avoid invalid notes,
transposed_note -= 12; // transpose back until note number <= 127
ROUTER_Tx_IIC2(ptype, (evnt0 & 0xf0) | MIDI_CHN1, transposed_note, evnt2);
} else {
ROUTER_Tx_IIC1(ptype, (evnt0 & 0xf0) | MIDI_CHN13, evnt1, evnt2);
}
}
// forward data (also) to the Core MIDI OUT
ROUTER_Tx_INT0(ptype, evnt0, evnt1, evnt2);
}
[/code]
Die USB Option kommt hier nicht zum Einsatz, dies wird ein separates Projekt (da MIOS auf
dem PIC18F4550 aufgrund diverser Silicon Bugs nicht sauber laeuft)
Bei USB gibt es dann 8 zusaetzliche Rx/Tx Kanaele, die man ebenfalls beliebig "verdrahten" kann.
Gruss,
Thorsten.