Calculating Pitch Values ​​for CoreMIDI for iOS?

I need to collect 14 bits of MIDI Pitch Bend values ​​from raw UInt16 values ​​in iOS. I am wondering if anyone has the opportunity to come up with an elegant solution? Here, where I am - I will have a chance to check this, probably later today, but if I hear earlier, fine:

Firstly, some preliminary MIDI messages are interesting to someone.

The MIDI Pitch Bend is divided into one status byte, followed by two Data Bytes (this is a 14-bit controller), these two data bytes are associated with their status byte, as leading with zero status bits , in MIDI Spec they are displayed in the order MSB → LSB

(Edit: update, actually StatusLSBMSB )

(i.e. 1110 0000, 0111 1111, 0111 1111)

The challenge is how to split ARM / Intel 16bit UInt16 into two 7-bit segments on iOS and make sense for MIDI?

Please keep in mind that since we are dealing with an unsigned integer, the value 0 is not a neutral bend of the fundamental tone, but rather a complete step down - where as a neutral bend of pitch it is defined as 8192 - and 16,383 - a full step up,

So here is my best guess on how to do this:

UInt16 msbAnd = base10ValueUInt16 & 16256; //clearing out LSB 
UInt16 msbAndShift = msbAnd << 1; //shift into leading Byte, with 0 status bit

UInt16 lsbAnd = base10ValueUInt16 & 127; //isolating LSB
UInt16 finalTwoBytePitchWord = msbFinalAndShift | lsbAnd; //make UInt16 word

UInt16 finalTwoBytePitchWordFlipped = CFSwapInt16HostToBig(finalTwoBytePitchWord); //Endian tweak

, , endian Intel/ARM, , , MIDI (MIDI - STATUS → MSB → LSB): MIDI- .

, ? - ? ( , ?)... , , .

+1
1

, , . iOS ARM Intel; -. , . ; .

MIDI . , 16- (, , 14 ), , , .

, , . : STATUS, LSB, MSB. !

7 : . 7 : 7 , .

, 16- ; .

.

#include <stdio.h>
#include <stdint.h>  // for C standard uint8_t and uint16_t
// or, if you prefer, use unsigned char and unsigned short, or Byte and UInt16;
// they'll all work, although some are more portable than others

void encode14BitValue(uint16_t value, uint8_t *out_msb, uint8_t *out_lsb)
{
    uint16_t mask = 0x007F;  // low 7 bits on
                             // "(1 << 7) - 1" is arguably clearer
    *out_lsb = value & mask;
    *out_msb = (value & (mask << 7)) >> 7;
}

int main(int argc, const char * argv[])
{
    typedef struct {
        uint16_t in;
        uint8_t expected_msb;
        uint8_t expected_lsb;
    } test_case;

    test_case cases[] = {
        { 0x0000, 0x00, 0x00 },
        { 0x0001, 0x00, 0x01 },
        { 0x0002, 0x00, 0x02 },
        { 0x0004, 0x00, 0x04 },
        { 0x0008, 0x00, 0x08 },
        { 0x0009, 0x00, 0x09 },
        { 0x000F, 0x00, 0x0F },
        { 0x0010, 0x00, 0x10 },
        { 0x0011, 0x00, 0x11 },
        { 0x001F, 0x00, 0x1F },
        { 0x0020, 0x00, 0x20 },
        { 0x0040, 0x00, 0x40 },
        { 0x0070, 0x00, 0x70 },
        { 0x007F, 0x00, 0x7F },
        { 0x0080, 0x01, 0x00 },
        { 0x0081, 0x01, 0x01 },
        { 0x008F, 0x01, 0x0F },
        { 0x0090, 0x01, 0x10 },
        { 0x00FF, 0x01, 0x7F },
        { 0x0100, 0x02, 0x00 },
        { 0x0200, 0x04, 0x00 },
        { 0x0400, 0x08, 0x00 },
        { 0x0800, 0x10, 0x00 },
        { 0x1000, 0x20, 0x00 },
        { 0x1FFF, 0x3F, 0x7F },
        { 0x2000, 0x40, 0x00 },
        { 0x2001, 0x40, 0x01 },
        { 0x3FFF, 0x7F, 0x7F },
    };

    int passed = 1;
    for (int i = 0, c = sizeof(cases) / sizeof(cases[0]); i < c; i++) {
        uint8_t msb, lsb;
        encode14BitValue(cases[i].in, &msb, &lsb);

        if (cases[i].expected_msb != msb || cases[i].expected_lsb != lsb) {
            printf("failed: 0x%04hX expected 0x%02hhX 0x%02hhX got 0x%02hhX 0x%02hhX\n", cases[i].in, cases[i].expected_msb, cases[i].expected_lsb, msb, lsb);
            passed = 0;
        }
    }

    return passed ? 0 : 1;
}

, 16- , . , , , , MIDI . , - , . . , , MSB LSB .

+4

All Articles