This N°9 Posted September 9, 2008 Report Share Posted September 9, 2008 hello all,what types of midi-events are passed to MPROC_NotifyReceivedEvnt ?there are one-byte(just status-byte, f.e. system realtime msgs), two byte (f.e. program change) andthree byte(f.e. note on, note off) messages. (and sysex of course).which of these are catched my the MIOS-parser? ???is it a problem to forward a one/two bytes msg. with a second/third 0 byte to the output?I would like to catch all channel-specific messages (evnt0 < 0xf0) and manipulate the channel.all others (incl. sysex) should just be sent to the output unchanged.thanks in advance, this Quote Link to comment Share on other sites More sharing options...
Durisian Posted September 9, 2008 Report Share Posted September 9, 2008 I believe >F0 is not captured by NotifyReceivedEventWith the inbuilt midi merger active, you should be able to temporarily disable it when a standard midi event has been recieved...void MIOS_MPROC_MergerDisable(void) DESCRIPTIONthis function allows you to temporary disable the MIDI merger processing during receiving a new event. It's used by SysEx parsers to prevent the forwarding of SysEx strings, but can also used by the USER_MPROC_NotifyReceivedByte hook to filter other events The merger will be enabled again after a complete MIDI event has been received! Maybe something like this: void MPROC_NotifyReceivedByte(unsigned char byte) { // temporarily disable the midi merger if(byte > 0x7f && byte < 0xf0) { MIOS_MPROC_MergerDisable(); } } I'm not sure if this will work - depends on whether it sends the message that reactivates the merger.... void MPROC_NotifyReceivedEvent(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) { evntType= evnt0 & 0xF0 // keep high nibble only channel = 4; // set channel // send message MIOS_MIDI_TxBufferPut(evntType + channel); MIOS_MIDI_TxBufferPut(evnt1); MIOS_MIDI_TxBufferPut(evnt2); } Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 9, 2008 Author Report Share Posted September 9, 2008 thanks for the input, this is a new approach..like this I don't have to forward all the bytes myself (faster)depends on whether it sends the message that reactivates the merger....I'm not sure I get what you mean, who(what) is IT? :)I think your code is exactly right: - on reception of the status byte we are IN the message, merger disable- complete message will be passed to recvEvnt- because the merger is off, the message will not be autom. be forwarded- MIOS enables merger (this is after the complete event has been received)if the merger is on or off while putting the bytes doesnt make a difference I think.. Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 9, 2008 Author Report Share Posted September 9, 2008 this example does all the forwarding without midi-merger.. :http://ucapps.de/mios_c_forward_chn1.htmlis the midi-merger-ability a newer MIOS-feature? Quote Link to comment Share on other sites More sharing options...
TK. Posted September 9, 2008 Report Share Posted September 9, 2008 No, the merger is available since MIOS V1.0The merger hack proposed by Durisian won't work perfectly, as merger data is forwarded before the hooks are called (corrected: it's forwarded after the MPROC_NotifyReceivedByte() hook has been called, so it could work, but I propably never tested this usecase during implementation phase...). For your usecase (modifying the incoming stream before forwarding it to MIDI Out), just use the example that you already found.Best Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 9, 2008 Author Report Share Posted September 9, 2008 so what would be an example application of the case described here?:void MIOS_MPROC_MergerDisable(void)DESCRIPTIONthis function allows you to temporary disable the MIDI merger processing during receiving a new event. It's used by SysEx parsers to prevent the forwarding of SysEx strings, but can also used by the USER_MPROC_NotifyReceivedByte hook to filter other events The merger will be enabled again after a complete MIDI event has been received! Quote Link to comment Share on other sites More sharing options...
TK. Posted September 9, 2008 Report Share Posted September 9, 2008 This function allows you to disable the merger for the current and upcoming bytes until a new event begins. It's mainly intended for SysEx messages, and untested for other MIDI events. Many MIDIbox applications are using this inside the SysEx parser to allow to chain MIDIboxes with the same SysEx Header.However, as mentioned before: the programming example is the best solution for your usecase, otherwise the example wouldn't exist!Best Regards, Thorsten.P.S.: corrected wording - it could work, although I haven't intended this (and it's untested) Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 10, 2008 Author Report Share Posted September 10, 2008 I was so free to pimp the code for forwarding system-messages a little:void MPROC_NotifyReceivedByte(unsigned char byte) __wparam{ //this function forwards all system messages to the output static unsigned char fx_status = 0; if(byte >= 0xf0){//system status byte MIOS_MIDI_TxBufferPut(byte); //determine status switch(byte){ case 0xf1://midi timecode case 0xf3://songselect fx_status = 1; break; case 0xf2://songposition pointer fx_status = 2; break; case 0xf0://sysex, forward until 0xf7 fx_status = 0xff; break; default://applies also on 0xf7! fx_status = 0; } } else if(fx_status){ MIOS_MIDI_TxBufferPut(byte); if(fx_status!=0xff) fx_status--; } }I beleive it's faster than the original code (and more compact-> easier to read -> less bugs):-less conditions, > 0xf0 is a status byte anyway-case instead of if-chain (I'am not sure if this really results in faster code, but for it is more natural to do it with case in this case I think so).I know it doesn't really matter that much, but I like aesthetic code ;Dby the way: is there some official repository / place for code-snippets? Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 10, 2008 Author Report Share Posted September 10, 2008 questions to TK concerning the "merger disable hack":you say:This function allows you to disable the merger for the current and upcoming bytes until a new event beginsif I disable the forwarding on receiving a status-byte, this byte will not be forwarded. fact: every midi-message starts with a status byte (byte & 0x80 == 1). a sysex is the only message whos last byte is also a status byte.does the "disable code" block the forwarding of the stop-status-byte of the sysex too? and if so, does it look explicitly for THE stop-status-byte or just for any status byte? if it looks for ANY status byte to restart the merging, the hack would not work, because the merger would not forward the statusbyte ofthe next message, so this message would be lost.if it looks explicitly for the stop-byte of the sysex, the forwarding would not start again.only if the code would distinguish (between) the sysex-stop-byte and any other status-byte, the hack would work.why I want to know this: - I think that the forwarding by the merger is faster code than any code produced by the sdcc compiler?- If I do parsing on application level, every byte will be double-parsed, once by MIOS and once by my applicationI could check this in the MIOS-code myself, but I'm not fit in assembler, so it would take me quite time to find the place where ithappens. maybe you (TK) can answer these questions directly by heart.by the way: thanks for your correctionas merger data is forwarded before the hooks are called (corrected: it's forwarded after the MPROC_NotifyReceivedByte() hook has been calledthe origial version confused me, thats why I asked "so what would be an example application of the case described here?"another proposal: if I stop the merger with MIOS_MIDI_MergerSet on receiving "my" event, and start it again on any other event?if the mergin' happens after MPROC_NotifyReceivedByte, this should work (?) Quote Link to comment Share on other sites More sharing options...
TK. Posted September 11, 2008 Report Share Posted September 11, 2008 I don't think, that the additional processing in the C program really affects the performance of your application, therefore it doesn't make much sense for me to evaluate a function I programmed ca. 5 years ago. You could try the hack by yourself, if it works fine - ok - if you find an error, then go the proposed way (I'm not planning to enhance the integrated merger of MIOS)Best Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 12, 2008 Author Report Share Posted September 12, 2008 ok, I will head for the asm code then. because I just want to know. you are right,but I can be quite picky sometimes.. regards, this Quote Link to comment Share on other sites More sharing options...
Durisian Posted October 9, 2008 Report Share Posted October 9, 2008 I'm trying to stop messages on channel 16... (0x0f) being forwarded by the merger. So I'm experimenting with this code but have some interesting effects. void MPROC_NotifyReceivedByte(unsigned char byte) __wparam { if(byte >= 0x80 && byte < 0xf0) { if (byte & 0x0f == 15) { MIOS_MPROC_MergerDisable(); } } } Firstly I discovered that the merger does not automatically re-activate when a complete midi message is recieved. So I added if(byte >= 0x80 && byte < 0xf0) { if (byte & 0x0f == 15) { MIOS_MPROC_MergerDisable(); } else { MIOS_MPROC_MergerEnable(); } } Now this almost worked. Except channels 2,4,6,8,10,12,14, 16. are not fowarded. but channels 1,3,5,7,9,11,13 and 15 are forwarded just fine. cool huh? ok..... I just had a brainwave.... if(byte >= 0x80 && byte < 0xf0) { channel = byte & 0x0f; if (channel == 15) { MIOS_MPROC_MergerDisable(); } else { MIOS_MPROC_MergerEnable(); } } ..........YAY!!2 things of note:& and if are not friendsand disabling the merger in this fashion seems to work just fine Quote Link to comment Share on other sites More sharing options...
stryd_one Posted October 9, 2008 Report Share Posted October 9, 2008 & and if are not friendsMore parentheses will help there. Quote Link to comment Share on other sites More sharing options...
bugfight Posted October 10, 2008 Report Share Posted October 10, 2008 if(byte >= 0x80 && byte < 0xf0) { if (byte & 0x0f == 15) { MIOS_MPROC_MergerDisable(); } else { MIOS_MPROC_MergerEnable(); } } more specifically, you have to be careful about order of operations. even when the operator precedence is enough, it is good practice to use parenthesis to explicitly specify the order like this: if((byte >= 0x80) && (byte < 0xf0)) { if (15 == (byte & 0x0f)) { MIOS_MPROC_MergerDisable(); } else { MIOS_MPROC_MergerEnable(); } } Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.