UDP網絡通訊OSC 協議

使用方法數組

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 ); }

 

和我以前的解釋同樣,如今這個能夠照着本身解析了

相關文章
相關標籤/搜索