UDP網絡通信OSC 協議


使用方法

OscMessage mesg;
mesg.setAddress("m");
mesg.addIntArg(10);
mesg.addIntArg(11);
mesg.addIntArg(12);

g_oscSend.sendMessage(mesg);

 

 

 

先做記錄,再做程序

 

整個消息是放在一個數組中

前8個字符做頭   為#bundle\0

下面8個字節記錄時間  這里都是1, 內存中為 0 0 0 0 0 0 0 1

再下面4個字節 整數  ,這里的數字大小指的是,osc地址的地址距離數據末尾的字節數 ,(也就是接收到數據包的長度減去這個值,就是osc消息的Adrrs的位置)

再下面就是地址字符串   大小根據字符串大小 ,然后4個字節對齊,不足補到4的倍數

再下面是所有參數的類型   第一個是 逗號,不知為何這樣,  下面才是類型, 這里如果數量不是4的倍數也要補

接下來是每個參數的內存

 

 

類型

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

 

和我之前的解釋一樣,現在這個可以照着自己解析了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM