Has anyone here used the script by @Hugo to send midi clock via Pin Pa2? I'm not enough of a coder to write this myself...
Hugo Extra Midi IO / Clock
Hey there @Blindsmyth.
I was trying to archieve the same and failed .
Reading the midi docs and a tutorial for arduino , I could successfully "infer?" the way to do it in axo world.
Here is the patch , original extra_io_midi , with the added code . But I attach also the needed code modification ( or just copy all and replace ) the receiving script object
extra_midi_io_clk.axp (8.5 KB)
uint8_t StatusToMsgLength(uint8_t t){
switch(t) {
case 0x0:
case 0x1:
case 0x2:
case 0x3:
case 0x4:
case 0x5:
case 0x6:
case 0x7:
return 0;
case 0x8:
case 0x9:
case 0xa:
case 0xb:
return 3;
case 0xc:
case 0xd:
return 2;
case 0xe:
return 3;
default:
return -1;
}
}
uint8_t SysToMsgLength(uint8_t t){
switch(t) {
case 0x0:
return -1; // 0xf0=sysex start. may vary
case 0x1:
return 2; // 0xf1=MIDI Time Code. 2 bytes
case 0x2:
return 3; // 0xf2=MIDI Song position. 3 bytes
case 0x3:
return 2; // 0xf3=MIDI Song Select. 2 bytes.
case 0x4:
return 1; // 0xf4=undefined
case 0x5:
return 1; // 0xf5=undefined
case 0x6:
return 1; // 0xf6=TUNE Request
case 0x7:
return 1; // 0xf7=sysex end.
case 0x8:
return 1; // 0xf8=timing clock. 1 byte
case 0x9:
return 1; // 0xf9=proposed measure end?
case 0xa:
return 1; // 0xfa=start. 1 byte
case 0xb:
return 1; // 0xfb=continue. 1 byte
case 0xc:
return 1; // 0xfc=stop. 1 byte
case 0xd:
return 1; // 0xfd=undefined
case 0xe:
return 1; // 0xfe=active sensing. 1 byte
case 0xf:
default:
return 3; // 0xff= not reset, but a META-EVENT, which is always 3 bytes
}
}
unsigned char MidiByte0;
unsigned char MidiByte1;
unsigned char MidiByte2;
unsigned char MidiCurData;
unsigned char MidiNumData;
uint8_t port = 0;
void setup(){
MidiNumData = 0;
MidiCurData = 0;
}
void MidiInByteHandler(uint8_t data) {
int8_t len;
if(data & 0xf8){
MidiInMsgHandler(MIDI_DEVICE_INTERNAL,port,0xf8,0,0);
}
if (data & 0x80) {
len = StatusToMsgLength(data >> 4);
if (len == -1) {
len = SysToMsgLength(data - 0xF0);
}
if (len == 1) {
MidiInMsgHandler(MIDI_DEVICE_INTERNAL,port,data,0,0);
} else {
MidiByte0 = data;
MidiNumData = len - 1;
MidiCurData = 0;
}
}
// FILTER AND SEND CLOCK MESSAGE
else // not a status byte
{
if (MidiCurData == 0) {
MidiByte1 = data;
if (MidiNumData == 1) {
// 2 byte message complete
MidiInMsgHandler(MIDI_DEVICE_INTERNAL,port,MidiByte0, MidiByte1,0);
MidiCurData = 0;
}
else
MidiCurData++;
}
else if (MidiCurData == 1) {
MidiByte2 = data;
if (MidiNumData == 2) {
MidiInMsgHandler(MIDI_DEVICE_INTERNAL,port,MidiByte0, MidiByte1, MidiByte2);
MidiCurData = 0;
}
}
}
//LogTextMessage("data, %d",data);
}
void loop(){
while(!sdGetWouldBlock(&SD2))
{
char ch = sdGet(&SD2);
MidiInByteHandler(ch);
}
}
so no start/stop etc just yet big shout out to @Hugo for this wonderful code. You guys could try and let me know , im not really sure if I correctly did this step in particular , but hey , my Ibar 16 is happy and dancing via UART
Raspberry Pi as hub for USB midi devices - advice?
Fixed the error I had before, but still doesnt really works . If I send just midi clock it wont update the clock out. Only when receiving other data , something with the midi callback , hope someone can throw some light on this
he there! I have gotten this to work eventually but I don't find the patch right now and I'm too toasted from work.
this is a patch with a modified cc out thing object to send via the serial pins.
its not that hard, you have to define your midi function in the local part and then call it in the k-rate part.
just compare the codes, you can figure it out.
xtra io clock.axp (6.8 KB)
otherwise i can still look for my clock object tomorrow. good night!
EDIT: found it! too tired to test, but i remember i had it working
xtra midi clock.axp (1.7 KB)
hm , not working here . But I see what you mean I guess.
I just realised that you wanted to output midi clock while Im trying to receive it on PA1 and route it to internal.
But yes would be cool to archieve this too .