[SOLVED] MIDI Channel with avr/C/C++

While trying to edit MIDI-USB adapter this code to also receive MIDI channel, I stumbel upon weird issue where the MIDI channel number (precisely last 4 bits of the MIDI status message) wont get assigned to the variable “kanal”, and original “kanal” value is used instead (14 in this code)

void receiveUART() {
    static enum { NOTEON, NOTEOFF, CONTROL, OTHER } state = OTHER;
    static uint8_t msg, data[2], dp=0;
    uint8_t kanal = 14;
    if(!(UCSR1A & (1<<RXC1))) return; // no data waiting

    // There are several limitations to the code below:
    // 1. System real-time messages ignored
    // 2. Only note on, off and control change handled
    msg = UDR1;
#ifdef DEBUG
    UDR1 = msg; // echo on TX for debugging
    LEDs_ToggleLEDs(LEDS_LED2);
#endif

    if(msg & 0x80) { // MIDI status byte
        kanal = msg & 0x0F; // LAST 4 BITS
        switch(msg >> 4) { // Remove channel
            case 0xB:
                state = CONTROL;
                dp = 0;
                break;
            case 0x8:
                state = NOTEOFF;
                dp = 0;
                break;
            case 0x9:
                state = NOTEON;
                dp = 0;
                break;
            default:
                // Just forget everything else for now, including
                // 0xF8 (time) and 0xFE (active sensing)
                //state = OTHER;
                break;
        }
    } else { // MIDI data byte
        data[dp++] = msg;
        if(dp >= 2) {
            switch(state) {
                case NOTEON:
                    sendMIDI(MIDI_COMMAND_NOTE_ON, kanal, data[0], data[1]);
                    break;
                case NOTEOFF:
                    sendMIDI(MIDI_COMMAND_NOTE_OFF, kanal, data[0], data[1]);
                    break;
                case CONTROL:
                    sendMIDI(MIDI_COMMAND_CONTROL_CHANGE, kanal, data[0], data[1]);
                    break;
                default: // ignore
                    break;
            }
            dp = 0; // ready for running status
        }
    }
}

void sendMIDI(uint8_t command, uint8_t channel, uint8_t data1, uint8_t data2) {
    MIDI_EventPacket_t event = (MIDI_EventPacket_t) {
        .Event       = MIDI_EVENT(0, command),
        .Data1       = command | channel,
        .Data2       = data1,
        .Data3       = data2,
    };

    MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface, &event);
    MIDI_Device_Flush(&Keyboard_MIDI_Interface);
}

It would be better if you posted your entire sketch. Looking at what you did provide in order for kanal to contain the least significant 4 bits of msg then msg MUST have the most significant bit set.

    if(msg & 0x80) { // MIDI status byte
        kanal = msg & 0x0F; // LAST 4 BITS

Can you use the serial port console to verify this?

Cant use serial console, but it works perfectly as a 5DIN MIDI-IN to USB MIDI-OUT adapter. As far as Im aware, that means that Arduino Leonardo receives the status code properly. Only problem, "kanal" doesnt get updated, so I cant send MIDI messages on the proper channels. Status message should look like this, if note off on channel 4 = 1000 0011

And to my limited knowledge,
1000 0011
AND
0000 1111
should result in
0000 0011

motorko: Cant use serial console, but it works perfectly as a 5DIN MIDI-IN to USB MIDI-OUT adapter. As far as Im aware, that means that Arduino Leonardo receives the status code properly.

It sounds like you are assuming that msg has the most significant bit set.

motorko: Only problem, "kanal" doesnt get updated, so I cant send MIDI messages on the proper channels. Status message should look like this, if note off on channel 4 = 1000 0011 And to my limited knowledge, 1000 0011 AND 0000 1111 should result in 0000 0011

With the code you provided that is the ONLY reason kanal would not be updated, so I have nothing else to go on. Otherwise you are assuming the code did not do what you told it. So highly unlikely that it is not worth considering.

If you have a spare digital output you could turn on an LED if you enter the if(msg & 0x80) code block and confirm whether or not the bit is set.

SOLVED IT!

static uint8_t msg, data[2], dp=0;
uint8_t kanal = 10;

I had it written so that the variable would be declared every time a function ran, and that created the problem, since the function requires 3 runs to get the full MIDI message if Im right (Status, Data 1, Data 2) before its sent out via USB, and since I assigned the channel number to “kanal” only in the first run, it would always get rewritten later.

So the fix is to make the variable static - make it so that its declared only the very first time a function is ran:

static uint8_t msg, kanal = 10, data[2], dp=0;

Thx for the help!