我覺得你的代碼是接近正確的,但它過於複雜。這個問題與iOS或Endianness或ARM或Intel無關;這只是普通的舊C比特。如果您正確編寫代碼,它將在any reasonable platform上工作,無需修改。你不需要圖書館;它只有幾行代碼。
最好在逐字節的基礎上使用MIDI。您需要一個採用16位無符號整數(我們將信任的值最多爲14位值)的函數並返回兩個單字節值,其中一個具有最高有效位,另一個具有最低有效位。
稍後,當您發送消息時,將按照適當的順序組合字節。 According to the specification,音輪信息是三個字節:狀態,然後是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時的錯誤補償了它。
嘿庫爾特,我得到的代碼運行的休息,有機會測試出我最好的猜測handywork在iOS採樣...它實際工作。有時是兩個錯誤的轉折作出正確的,在這種情況下,我通過翻轉字節到正確的順序錯誤的原因lucked了。感謝清理狀態 - > LSB - > MSB,並使其清晰離開字節序的編譯器...位操作是有點兒樂趣實際。 – OverToasty