#MIDIメッセージのデータ
MIDIの通信で使われるMIDIメッセージは1バイトづつシリアルで送られます。この中で命令を指すステータの部分はbit7 がHi ,データ部分はbit7がLo と決められています。bit7=Hiのバイトのデータはそのままでは通信に使えません。
##システムエクスクルーシブ
MIDIのメッセージに任意のデータ列を送るためのシステムエクスクルーシブメッセージがあります。他のメッセージと同じく F0h で始まり F7h で終わる一連のバイト列ですが、その間のデータ部分も必ずbit7=Loでないといけません。送りたいデータ列が普通のバイナリデータでもbit7をLoにした変換処置をして送出/受取しないといけないわけです。
##8bit->7bit , 7bit->8bit
今回YMF825boardを使ったシンセサイザモジュールを作るにあたり、音色データをシステムエクスクルーシブメッセージで送る様な機能がどうしても必要になると考えました。
このため8bitデータ列を7bitデータ列に変換/戻す処理が必要になるわけです。この手の処理コードは以前は雑誌の記事か、どこかのサイトに転がっていたと記憶するのですが、最近は用途もない様で検索しても見つかりませんでした。そこで改めてコードを書いてみました。何か役に立てれてばとお思います。無保証ですが自由にお使い下さって結構です。
int encode87(unsigned char* src,unsigned char* dst,int n)
8bitデータ列 7バイト分を7bitデータ列8バイトへ変換します
src : 変換元ポインタ
dat : 変換先ポインタ
n : 変換データバイト数
int decode87(unsigned char* src,unsigned char* dst,int n)
7bitデータ列 8バイト分を8bitデータ列7バイトへ変換します
src : 変換元ポインタ
dat : 変換先ポインタ
n : 変換データバイト数
やっている事は 7バイトのデータ列の各々8bitめを8バイト目の各bit0-bit6へ格納して一連のデータ列に変換しています。デコード時はその反対の処理を行います。
これで任意のバイナリーデータをMIDIシステムエクスクルーシブメッセージの中に入れ込む事ができます。
/*
8bit Binary String <-> 7bit Binary String
Ringoro
*/
#include <stdio.h>
unsigned char indata[]={0x85,0x85,0x85,0x81,0x85,0x82,0x88,
0x71,203,135,230,122,232,0x80,
0x71,203,135,230,122,232,0x00,
0x81,110,120,230,100,100,0xFE,
0x81,0x92,0x12};
unsigned char outdata[sizeof(indata) * 8 / 7 + 1];
unsigned char decoded[sizeof(indata)];
int encode87(unsigned char* ,unsigned char* ,int );
int decode87(unsigned char* ,unsigned char* ,int );
int main()
{
int max,c,i,j,n,pt;
unsigned char b8;
max=sizeof(indata); // max input data count
pt = 0; // data out point
n = encode87(indata,outdata,max);
puts("");
for(i=0;i<max;i++){
printf("%02X",indata[i]);
if( (i % 7)== 6)
{printf(" ");}
}
puts("");
for(i=0;i<=n;i++){
printf("%02X",outdata[i]);
}
n = decode87(outdata,decoded,n);
puts("");
for(i=0;i<n;i++){
printf("%02X",decoded[i]);
if( (i % 7 ) == 6 )
{printf(" ");}
}
puts("");
}
/*
encode 8bit x 7 to 7bit x 8
src : input data ponter.
dst : output data pointer.
max : input data bytes.
return : encoded data bytes.
*/
int encode87(unsigned char *src,unsigned char *dst,int max)
{
int n,i,pt;
unsigned char b8;
pt = 0;
n=0;
while(n < max){
b8=0;
for(i=0; i<7 && n < max;i++,n++){
*(dst+pt)=*(src+n) & 0x7F;
// printf("%02X ",*(src+n));
pt++;
b8= b8 | ((*(src+n) & 0x80) >> 7) << i;
// printf("%02X ",b8);
}
*(dst+pt++)=b8;
//printf("%d ",pt);
}
return pt-1;
}
/*
decode 7bit x 8 to 8bit x 7
src : input data ponter.
dst : output data pointer.
max : input data bytes.
return : encoded data bytes.
*/
int decode87(unsigned char *src,unsigned char *dst,int max)
{
int n,i,j,pt;
unsigned char b8;
pt = 0;
n=0;
while(n < max){
for(i=0; i< 7 && n < max;i++,n++){
*(dst+pt)=*(src+n);
pt++;
}
b8=*(src + n++);
// printf("n:%d B8:%02X \n",n,b8 );
for(j=0;j<i;j++){
*(dst+pt-i+j) = (*(dst+pt-i+j)) | ((b8 >> j) << 7);
}
}
return pt;
}