hey,
i’m scratching my head about the following for some time:
my keyboard sends bs+pc on ch 0 when i press one out of 24 instrument buttons. i want to identify the button pressed and forward an individual message to the midi-out. unfortunately those messages are not in any order but arbitrary sets from the gx-standard (i suppose), so i can’t ignore the bs and apply some offset to the pc to get a button-number.
at the moment i can think of 2 solutions to parse those incoming messages, but i’m not very pleased with both of them:
Option 1: straight forward - compare incoming sets to a table of known sets
-have a table, where each button is represented by its bs(msb) + bs(lsb) + pc
-store incoming bs+pc in a temporary struct-variable
-when pc was received, compare the set in the variable with each set in the table. the index of the table-entry that matches the variable, gives me the button number.
Option 2: a finite-state machine (did this already for incoming sysex-messages):
example code for 2 buttons:
// BS-MSB BS-LSB PC
// button1 0x00 0x70 0x01
// button2 0x00 0x44 0x05
unsigned char state; // 0xFF = set complete, 0xFE = unknown set
unsigned char last_state;
unsigned char button_pressed;
void process_messages(unsigned char msg_type, unsigned char value) {
// msg_type 0x00=BS-MSB, 0x20=BS-LSB, 0xC0=PC
last_state=state;
switch state {
case 0: //no bytes received so far
switch value {
case 0x00:
state=1;
}
case 1: //0x00 received
switch value {
case 0x70:
state=2;
break;
case 0x44:
state=3;
}
case 2: //0x00 0x70 received
switch value {
case 0x01:
button_pressed=1;
state=0xFF;
}
case 3: //0x00 0x44 received
switch value {
case 0x05:
button_pressed=2;
state=0xFF;
}
}
if (state == 0xFF) //button recognized, do something with it
do_something(button_pressed);
if (last_state == state) //state didn't change -> unknown set
state = 0xFE;
if (msg_type == 0xC0) //set completed -> start over
state = 0;
}
Option 1 means, that in worst case, the programm has to do 24x3=72 table-lookups. i read those are really slow. as my app isn’t doing too much at the moment, this might be a minor issue, but i don’t like to start out that unefficient ![]()
Option 2 lacks overview, as the actual sets are spread over many cases, also the code really explodes, if i do this for all the 24 buttons. At the same time the function becomes quite complex (regarding execution paths). in the sdcc manual i read, that complexity shouldnt be more than 10, which i go far beyond. so this option seems to drop out completely.
Do you have any other ideas, how to do this? or maybe a way, to improve my options?
As i mentioned, i’m using option 2 for parsing sysex messages and it works (30 states). but i feel, it’s really ugly and it is hard to read out the messages or add new ones. so any ideas here are very welcome too ![]()
Thanks!
Alex