ここ読んでやっとわかった。
http://opensoundcontrol.org/spec-1_0-examples
説明されればなんてことないけど、いきなり仕様を見ても気が滅入るんですわ・・・ということでちょっとまとめ。
ちなみに、仕様が分かると ObjCOSC に入っている main.m の PrintOSCArgs() の中身もあっという間に分かります。
--
普通にちょっとしたやりとりをするためのメッセージは、
基本的にはこんな構造のようです。
OSCアドレス(ASCII文字) + 1〜4個のヌル文字
+ 引数の個数と型を表す文字列(ASCII文字) + 1〜4個のヌル文字
+ 引数の値(バイナリ)
■ヌル文字
区切りの意味で挿入するわけだけども、データが4バイト単位にまとまるよう 1〜4個の間で数を調節します(いわゆるパディング)。
■OSCアドレス
/channel1/volume/
とかいうやつです。
■引数の個数と型を表す文字列
・1文字目はコンマ
・2文字目以降には、引数の数だけASCII文字を並べる。その文字は、float型なら 'f' , int型なら 'i' , char型なら 's' など。
例えば
,iifis
みたいな感じ。この例は引数5個で、型はそれぞれ int, int, float, int, char ですね。
■引数の値
上記で指定したデータを並べるだけです。でもバイナリなのが厄介。
iPhoneとのやりとりに使う場合はエンディアン問題が出ます。
http://akamatsu.org/aka/?lang=qtufeuecuie&paged=43
この記事のエンディアン変換のコード例、ちょっと紛らわしいところがあるので以下にウチで施した改造を改めて載せておきます。元の PrintOSCArgs() と比べてみて下さい。 floatの変換はintに比べて一手間多いですね。
void PrintOSCArgs(int arglen, const void* args)
{
const char* myArgTypes = (const char*) args;
const char* myArgs = myArgTypes + OSCPaddedStrlen(myArgTypes); int intValue;
float floatValue;
CFSwappedFloat32 swappedFloatValue;
while (*myArgTypes != '\0') {
switch (*myArgTypes) {
case 'i':
intValue = CFSwapInt32BigToHost(*((const int*)myArgs));
NSLog(@"\t\tread int %i", intValue);
myArgs += sizeof(int);
break;
case 'f':
swappedFloatValue.v = *((const float*)myArgs);
floatValue = CFConvertFloat32SwappedToHost(swappedFloatValue);
NSLog(@"\t\tread float %f", floatValue);
myArgs += sizeof(float);
break;
case 's':
NSLog(@"\t\tread string %s", myArgs);
myArgs += OSCPaddedStrlen(myArgs);
break;
}
myArgTypes++;
}
}