Click here to Skip to main content
15,879,095 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
MIDI is a big endian wire protocol.

I'm trying to provide accessors to get/set the least significant and most significant byte of a 16-bit MIDI message payload.

My concern is I have LSB and MSB backward. I always get mixed up with stuff like this and I have already switched it around once. I think it has to do with my terrible sense of direction, since I've had endianness explained to me, and I understand it completely in concept, i just get MSB and LSB relative to the system backward a lot.

It needs to be in the perspective of a big endian system, such that msb() would be the Most Significant Byte on a big endian system.

See the code in what I have tried.

You may wonder why the extra masking by 0x7F. MIDI only uses the low 7-bits of a byte for data payloads, meaning a 16 bit number is actually represented by 14 bits with a "hole" in it.

What I have tried:

C++
inline uint8_t msb() const {
    if(bits::endian_mode::little_endian==bits::endianness()) {
        return (value16 >> 8)&0x7f;
    } else {
        return value16 & 0x7f;
    }
}
inline void msb(uint8_t value) {
    if(bits::endian_mode::little_endian==bits::endianness()) {
        value16 = (value16 & 0x7f) | uint16_t((value & 0x7f)<<8);
    } else {
        value16 = (value16 & uint16_t(0x7f<<8)) | (value & 0x7f);
    }
}
inline uint8_t lsb() const {
    if(bits::endian_mode::little_endian==bits::endianness()) {
        return value16 & 0x7f;
    } else {
        return (value16 >> 8)&0x7f;
    }
}
inline void lsb(uint8_t value) {
    if(bits::endian_mode::little_endian==bits::endianness()) {
        value16 = (value16 & uint16_t(0x7f<<8)) | (value & 0x7f);
    } else {
        value16 = (value16 & 0x7f) | uint16_t((value & 0x7f)<<8);
    }
}
Posted
Updated 5-May-22 20:34pm
v2

1 solution

It doesn't look correct to me.
Take, for instance your msb function (I didn't scrutinize the other ones), it takes value and stores it in the second byte of value16 on a little endian machine.
The following program

C++
#include <arpa/inet.h>
using namespace std;

void show(uint16_t u16)
{
  uint8_t * p = reinterpret_cast< uint8_t * > ( & u16 );
  cout << hex << p[0] << p[1] << "\n";
}

inline void msb(uint16_t & value16, uint8_t value)
{
  value16 = (value16 & 0x7f) | uint16_t((value & 0x7f)<<8);
}

int main()
{
  uint16_t bes = htons(0x666F);
  show(bes);

  uint16_t beh = 0x6F6F;
  msb(beh, 0x66);
  show(beh);
}


outputs
fo
of

on my little endian Linux box
 
Share this answer
 
v2
Comments
honey the codewitch 6-May-22 7:18am    
I'm confused. "Take, for instance your msb function (I didn't scrutinize the other ones), it takes value and stores it in the second byte of value16 on a little endian machine."

Masking off the 8th bit is part of the midi spec.


That's what it's supposed to do. My only question is is that LSB or MSB?
CPallini 6-May-22 7:38am    
Possibly I didn't get you. Anyway...
Say we have a little endian machine and want to put (our machine) 0x666F to the MIDI big endian stream.
This is done correctly by the htons(0x666F) that swap the bytes. The msb function, on the other hand, doesn't swap the bytes.
honey the codewitch 6-May-22 7:53am    
It shoves the bits high if it's little endian - as seen by the shift, otherwise it shifts them low.

If it shifts them high, is that MSB or LSB? That's what I'm trying to figure out. Right now I call it MSB
CPallini 6-May-22 8:34am    
If you take a byte, say b, and do
uint16_t h = b << 8;
then you are assigning b to MSB(h) both on a little and a big endian machine.
honey the codewitch 6-May-22 8:42am    
that's weird to me, because Most significant would refer to the value that affects the high numbers, and Least significant would be the value that affects the low numbers no? That would be different for machines of different endian types, unless I'm missing something. It's frightfully early and I'm still catching up on coffee.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900