F450

2005年03月09日の日記 ‣ 可変長16進数表記への変換

古いデータが多く含まれているため、デッドリンクがあったり記事等を正しく表示できなかったりする可能性があります。また、これらの日記に対する新たなコメントやトラックバックは受け付けていません。予めご了承下さい。
2005年03月09日(水)の日記

可変長16進数表記への変換

SMFにおける可変長16進数への変換の関数が、
検索しても2バイトまでとか中途半端なものしかなかったので自作。
SMFでは可変長16進数は最大4バイトまでなのでそれ以上になる値は弾く。
コードの横幅節約のためにビット演算のオペランドに16進数を用いたので読みにくいかもしれませんが、
変換アルゴリズム(というほどたいそうなものか分かりませんが)はコードの下に書いてあります。
unsigned int variableLength(unsigned int unsignedInt) {
enum { HTBMIDIInvalidValue = 0xFFFFFFFF };
if (unsignedInt <= 0x7F) return unsignedInt; /* 0x7F以下ならそのまま。 */
else if (unsignedInt > 0x0FFFFFFF) return HTBMIDIInvalidValue;
/* 0x0FFFFFFFを超える数字は4バイト以内で表せない。 */
else {
/* ↓変数bnは最下位からn番目のバイトの値 */
unsigned int b1 = unsignedInt & 0x7F;
unsigned int b2 = ((unsignedInt & 0x3F80) << 1) | 0x8000;
if (unsignedInt <= 0x3FFF) return b1 + b2;
else {
unsigned int b3 = ((unsignedInt & 0x1FC000) << 2) | 0x800000;
if (unsignedInt <= 0x1FFFFF) return b1 + b2 + b3;
else {
unsigned int b4 = ((unsignedInt & 0x0FE00000) << 3) | 0x80000000;
return b1 + b2 + b3 + b4;
}
}
}
}
▼結果が1バイトとなる場合 = 0x7F以下
そのまま

▼結果が2バイトとなる場合 = 0x3FFF以下
00aa bbbb cccc dddd (bit表記)

1aab bbbc 0ccc dddd

▼結果が3バイトとなる場合 = 0x1FFFFF以下
000a bbbb cccc dddd eeee ffff

1abb bbcc 1ccd ddde 0eee ffff

▼結果が4バイトとなる場合 = 0x0FFFFFFF以下
0000 aaaa bbbb cccc dddd eeee ffff gggg

1aaa abbb 1bcc ccdd 1dde eeef 0fff gggg
2005/03/09(水) 16:06:08 (JST)

この日記へのコメント

この日記へのコメントはありません。

この日記へのトラックバック

この日記へのトラックバックはありません。