Jump to content

what type of messages are passed to MPROC_NotifyReceivedEvnt ?


This N°9
 Share

Recommended Posts

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) and

three 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

Link to comment
Share on other sites

I believe >F0 is not captured by NotifyReceivedEvent

With 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)

DESCRIPTION

this 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);

}

Link to comment
Share on other sites

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..

Link to comment
Share on other sites

No, the merger is available since MIOS V1.0

The 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.

Link to comment
Share on other sites

so what would be an example application of the case described here?:

void MIOS_MPROC_MergerDisable(void)

DESCRIPTION

this 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!

Link to comment
Share on other sites

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)

Link to comment
Share on other sites

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  ;D

by the way: is there some official repository / place for code-snippets?

Link to comment
Share on other sites

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 begins

if 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 of

the 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 application

I 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 it

happens. maybe you (TK) can answer these questions directly by heart.

by the way: thanks for your correction

as merger data is forwarded before the hooks are called (corrected: it's forwarded after the MPROC_NotifyReceivedByte() hook has been called

the 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 (?)

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

  • 4 weeks later...

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 friends

and disabling the merger in this fashion seems to work just fine

Link to comment
Share on other sites

    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();
        }
    }

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...