使用方法數組
OscMessage mesg; mesg.setAddress("m"); mesg.addIntArg(10); mesg.addIntArg(11); mesg.addIntArg(12); g_oscSend.sendMessage(mesg);
先作記錄,再作程序ui
整個消息是放在一個數組中spa
前8個字符作頭 爲#bundle\0code
下面8個字節記錄時間 這裏都是1, 內存中爲 0 0 0 0 0 0 0 1blog
再下面4個字節 整數 ,這裏的數字大小指的是,osc地址的地址距離數據末尾的字節數 ,(也就是接收到數據包的長度減去這個值,就是osc消息的Adrrs的位置)內存
再下面就是地址字符串 大小根據字符串大小 ,而後4個字節對齊,不足補到4的倍數字符串
再下面是全部參數的類型 第一個是 逗號,不知爲什麼這樣, 下面纔是類型, 這裏若是數量不是4的倍數也要補get
接下來是每一個參數的內存string
類型it
enum TypeTagValues { TRUE_TYPE_TAG = 'T', FALSE_TYPE_TAG = 'F', NIL_TYPE_TAG = 'N', INFINITUM_TYPE_TAG = 'I', INT32_TYPE_TAG = 'i', FLOAT_TYPE_TAG = 'f', CHAR_TYPE_TAG = 'c', RGBA_COLOR_TYPE_TAG = 'r', MIDI_MESSAGE_TYPE_TAG = 'm', INT64_TYPE_TAG = 'h', TIME_TAG_TYPE_TAG = 't', DOUBLE_TYPE_TAG = 'd', STRING_TYPE_TAG = 's', SYMBOL_TYPE_TAG = 'S', BLOB_TYPE_TAG = 'b', ARRAY_BEGIN_TYPE_TAG = '[', ARRAY_END_TYPE_TAG = ']' };
其中 bool 沒有內存,只有一個tag
int32 4個字節
float 4個字節
char 4個字節
int64 8 個字節
double 8個字節
timetag 8個字節
string 補到4的倍數
2018-4-28
找到了一個代碼實現
enum class ArgType : char { INTEGER_32 = 'i', FLOAT = 'f', DOUBLE = 'd', STRING = 's', BLOB = 'b', MIDI = 'm', TIME_TAG = 't', INTEGER_64 = 'h', BOOL_T = 'T', BOOL_F = 'F', CHAR = 'c', NULL_T = 'N', IMPULSE = 'I', NONE = NULL_T };
void Bundle::setTimetag( uint64_t ntp_time ) { uint64_t a = htonll( ntp_time ); ByteArray<8> b; memcpy( b.data(), reinterpret_cast<uint8_t*>( &a ), 8 ); mDataBuffer->insert( mDataBuffer->begin() + 12, b.begin(), b.end() ); } void Bundle::initializeBuffer() { static const std::string id = "#bundle"; mDataBuffer.reset( new std::vector<uint8_t>( 20 ) ); std::copy( id.begin(), id.end(), mDataBuffer->begin() + 4 ); (*mDataBuffer)[19] = 1; }
size_t addressLen = mAddress.size() + getTrailingZeros( mAddress.size() ); auto typesSize = mDataViews.size() + 1; std::vector<char> typesArray( typesSize + getTrailingZeros( typesSize ) , 0 ); typesArray[0] = ','; int i = 1; for( auto & dataView : mDataViews ) typesArray[i++] = Argument::translateArgTypeToCharType( dataView.getType() ); if( ! mCache ) mCache = ByteBufferRef( new ByteBuffer() ); size_t typesArrayLen = typesArray.size(); ByteArray<4> sizeArray; int32_t messageSize = addressLen + typesArrayLen + mDataBuffer.size(); auto endianSize = htonl( messageSize ); memcpy( sizeArray.data(), reinterpret_cast<uint8_t*>( &endianSize ), 4 ); mCache->resize( 4 + messageSize ); std::copy( sizeArray.begin(), sizeArray.end(), mCache->begin() ); std::copy( mAddress.begin(), mAddress.end(), mCache->begin() + 4 ); std::copy( typesArray.begin(), typesArray.end(), mCache->begin() + 4 + addressLen ); std::copy( mDataBuffer.begin(), mDataBuffer.end(), mCache->begin() + 4 + addressLen + typesArrayLen ); auto dataPtr = mCache->data() + 4 + addressLen + typesArrayLen; for( auto & dataView : mDataViews ) { if( dataView.needsEndianSwapForTransmit() ) dataView.swapEndianForTransmit( dataPtr ); }
static uint8_t getTrailingZeros( size_t bufferSize ) { return 4 - ( bufferSize % 4 ); }
和我以前的解釋同樣,如今這個能夠照着本身解析了