[SCM] calf/master: + OSC: Rewritten to allow realtime-safe operation when necessary

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:37:17 UTC 2013


The following commit has been merged in the master branch:
commit 25bc89f58bedb6e501a5c56082724dfcbd6e0aba
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date:   Thu Jun 5 22:14:28 2008 +0000

    + OSC: Rewritten to allow realtime-safe operation when necessary
    
    
    git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@195 78b06b96-2940-0410-b7fc-879d825d01d8

diff --git a/ChangeLog b/ChangeLog
index 95e40a6..3fb8e27 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Version 0.0.14?
++ OSC: totally new OSC wrapper, to allow for realtime-safe parsing
+
+Version 0.0.13
++ Fixed several problems related to 64-bit environments and OpenSUSE (thanks
+oc2pus!)
++ Added NOCONFIGURE environment variable support to autogen.sh
+
 Version 0.0.12
 + RotarySpeaker: work in progress; enabled by default just in case it's
   useful for anyone
diff --git a/src/Makefile.am b/src/Makefile.am
index 4e50058..107bacd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,11 +38,13 @@ calfmakerdf_SOURCES = makerdf.cpp
 calfmakerdf_LDADD = libcalfstatic.la
 
 calfbenchmark_SOURCES = benchmark.cpp
-calfbenchmark_LDADD = $(GLIB_DEPS_LIBS)
+calfbenchmark_LDADD = $(GLIB_DEPS_LIBS) 
 
 if USE_DSSI_GUI
 calfdssigui_SOURCES = dssigui.cpp
 calfdssigui_LDADD = libcalfstatic.la libcalfgui.la $(GLIB_DEPS_LIBS) $(GUI_DEPS_LIBS)
+calfbenchmark_CXXFLAGS = $(AM_CXXFLAGS) -DTEST_OSC
+calfbenchmark_LDADD += libcalfgui.la
 endif
 
 calf_la_SOURCES = modules.cpp giface.cpp monosynth.cpp organ.cpp osctl.cpp preset.cpp synth.cpp utils.cpp
diff --git a/src/benchmark.cpp b/src/benchmark.cpp
index dd65ef2..1fef413 100644
--- a/src/benchmark.cpp
+++ b/src/benchmark.cpp
@@ -33,6 +33,7 @@ using namespace dsp;
 
 #ifdef TEST_OSC
 #include <calf/osctl.h>
+#include <calf/osctlnet.h>
 using namespace osctl;
 #endif
 
@@ -328,35 +329,67 @@ void reverbir_calc()
 }
 
 #ifdef TEST_OSC
+
+struct my_sink: public osc_message_sink<osc_strstream>
+{
+    GMainLoop *loop;
+    osc_message_dump<osc_strstream, ostream> dump;
+    my_sink() : dump(cout) {}
+    virtual void receive_osc_message(std::string address, std::string type_tag, osc_strstream &buffer)
+    {
+        dump.receive_osc_message(address, type_tag, buffer);
+        assert(address == "/blah");
+        assert(type_tag == "bsii");
+
+        string_buffer blob;
+        string str;
+        uint32_t val1, val2;
+        buffer >> blob >> str >> val1 >> val2;
+        assert(blob.data == "123");
+        assert(str == "test");
+        assert(val1 == 1);
+        assert(val2 == 2);
+        g_main_loop_quit(loop);
+    }
+    
+};
+
 void osctl_test()
 {
     string sdata = string("\000\000\000\003123\000test\000\000\000\000\000\000\000\001\000\000\000\002", 24);
-    osc_stream is(sdata);
-    vector<osc_data> data;
-    is.read("bsii", data);
-    assert(is.pos == sdata.length());
-    assert(data.size() == 4);
-    assert(data[0].type == osc_blob);
-    assert(data[1].type == osc_string);
-    assert(data[2].type == osc_i32);
-    assert(data[3].type == osc_i32);
-    assert(data[0].strval == "123");
-    assert(data[1].strval == "test");
-    assert(data[2].i32val == 1);
-    assert(data[3].i32val == 2);
-    osc_stream os("");
-    os.write(data);
-    assert(os.buffer == sdata);
+    string_buffer sb(sdata);
+    osc_strstream is(sb);
+    osc_inline_typed_strstream os;
+    
+    string_buffer blob;
+    string str;
+    uint32_t val1, val2;
+    is >> blob >> str >> val1 >> val2;
+    assert(blob.data == "123");
+    assert(str == "test");
+    assert(val1 == 1);
+    assert(val2 == 2);
+    
+    os << blob << str << val1 << val2;
+    assert(os.buf_data.data == sdata);
+    assert(os.buf_types.data == "bsii");
+    
+    GMainLoop *main_loop = g_main_loop_new(NULL, FALSE);
+    my_sink sink;
+    sink.loop = main_loop;
     osc_server srv;
+    srv.sink = &sink;
     srv.bind("0.0.0.0", 4541);
     
     osc_client cli;
     cli.bind("0.0.0.0", 0);
     cli.set_addr("0.0.0.0", 4541);
-    if (!cli.send("/blah", data))
+    if (!cli.send("/blah", os))
+    {
         g_error("Could not send the OSC message");
+    }
     
-    g_main_loop_run(g_main_loop_new(NULL, FALSE));
+    g_main_loop_run(main_loop);
 }
 #endif
 
diff --git a/src/calf/osctl.h b/src/calf/osctl.h
index f907917..0914a24 100644
--- a/src/calf/osctl.h
+++ b/src/calf/osctl.h
@@ -25,6 +25,7 @@
 #include <errno.h>
 #include <netinet/in.h>
 #include <netdb.h>
+#include <iostream>
 
 namespace osctl
 {
@@ -54,72 +55,385 @@ enum osc_type
 
 extern const char *osc_type_name(osc_type type);
 
-// perhaps a little inefficient, but this is OSC anyway, so efficiency
-// goes out of the window right from start :)
-struct osc_data
+struct osc_exception: public std::exception
+{
+    virtual const char *what() const throw() { return "OSC parsing error"; }
+};
+
+struct osc_read_exception: public std::exception
+{
+    virtual const char *what() const throw() { return "OSC buffer underflow"; }
+};
+
+struct osc_write_exception: public std::exception
 {
-    osc_type type;
-    union {
-        int32_t i32val;
-        uint64_t tsval;
-        float f32val;
-        double f64val;
-    };
-    std::string strval;
-    osc_data()
+    virtual const char *what() const throw() { return "OSC buffer overflow"; }
+};
+
+struct null_buffer
+{
+    static bool read(uint8_t *dest, uint32_t bytes)
     {
-        type = osc_nil;
+        return false;
     }
-    osc_data(std::string _sval, osc_type _type = osc_string)
-    : type(_type)
-    , strval(_sval)
+    static bool write(uint8_t *dest, uint32_t bytes)
     {
+        return true;
     }
-    osc_data(int ival)
-    : type(osc_i32)
-    , i32val(ival)
+    static void clear()
     {
     }
-    osc_data(float fval)
-    : type(osc_f32)
-    , f32val(fval)
+};
+
+struct raw_buffer
+{
+    uint8_t *ptr;
+    uint32_t pos, count, size;
+    
+    raw_buffer()
     {
+        ptr = NULL;
+        pos = count = size = 0;
     }
-    std::string to_string() const;
-    ~osc_data()
+    raw_buffer(uint8_t *_ptr, uint32_t _count, uint32_t _size)
     {
+        set(_ptr, _count, _size);
+    }
+    inline void set(uint8_t *_ptr, uint32_t _count, uint32_t _size)
+    {
+        ptr = _ptr;
+        pos = 0;
+        count = _count;
+        size = _size;
+    }
+    bool read(uint8_t *dest, uint32_t bytes)
+    {
+        if (pos + bytes > count)
+            return false;
+        memcpy(dest, ptr + pos, bytes);
+        pos += bytes;
+        return true;
+    }
+    bool write(const uint8_t *src, uint32_t bytes)
+    {
+        if (count + bytes > size)
+            return false;
+        memcpy(ptr + count, src, bytes);
+        count += bytes;
+        return true;
+    }
+    int read_left()
+    {
+        return count - pos;
+    }
+    int write_left()
+    {
+        return size - count;
+    }
+    inline int write_misalignment()
+    {
+        return 4 - (count & 3);
+    }
+    void clear()
+    {
+        pos = 0;
+        count = 0;
+    }
+    int tell()
+    {
+        return pos;
+    }
+    void seek(int _pos)
+    {
+        pos = _pos;
     }
 };
 
-struct osc_exception: public std::exception
+struct string_buffer
 {
-    virtual const char *what() const throw() { return "OSC parsing error"; }
-};
+    std::string data;
+    uint32_t pos, size;
     
+    string_buffer()
+    {
+        pos = 0;
+        size = 1048576;
+    }
+    string_buffer(std::string _data, int _size = 1048576)
+    {
+        data = _data;
+        pos = 0;
+        size = _size;
+    }
+    bool read(uint8_t *dest, uint32_t bytes)
+    {
+        if (pos + bytes > data.length())
+            return false;
+        memcpy(dest, &data[pos], bytes);
+        pos += bytes;
+        return true;
+    }
+    bool write(const uint8_t *src, uint32_t bytes)
+    {
+        if (data.length() + bytes > size)
+            return false;
+        uint32_t wpos = data.length();
+        data.resize(wpos + bytes);
+        memcpy(&data[wpos], src, bytes);
+        return true;
+    }
+    inline int read_left()
+    {
+        return data.length() - pos;
+    }
+    inline int write_left()
+    {
+        return size - data.length();
+    }
+    inline int write_misalignment()
+    {
+        return 4 - (data.length() & 3);
+    }
+    void clear()
+    {
+        data.clear();
+        pos = 0;
+    }
+    int tell()
+    {
+        return pos;
+    }
+    void seek(int _pos)
+    {
+        pos = _pos;
+    }
+};
+
+template<class Buffer, class TypeBuffer = null_buffer, bool Throw = true>
 struct osc_stream
 {
-    std::string buffer;
-    unsigned int pos;
-    
-    osc_stream() : pos(0) {}
-    osc_stream(const std::string &_buffer, unsigned int _pos = 0)
-    : buffer(_buffer), pos(_pos) {}
+    Buffer &buffer;
+    TypeBuffer *type_buffer;
+    bool error;
     
-    inline void copy_from(void *dest, int bytes)
+    osc_stream(Buffer &_buffer) : buffer(_buffer), type_buffer(NULL), error(false) {}
+    osc_stream(Buffer &_buffer, TypeBuffer &_type_buffer) : buffer(_buffer), type_buffer(&_type_buffer), error(false) {}
+    inline void pad()
     {
-        if (pos + bytes > buffer.length())
-            throw osc_exception();
-        memcpy(dest, &buffer[pos], bytes);
-        pos += bytes;
+        uint32_t zero = 0;
+        write(&zero, buffer.write_misalignment());
     }
-    
-    void read(osc_type type, osc_data &od);
-    void write(const osc_data &od);
-    
-    void read(const char *tags, std::vector<osc_data> &data);
-    void write(const std::vector<osc_data> &data);
+    inline void read(void *dest, uint32_t bytes)
+    {
+        if (!buffer.read((uint8_t *)dest, bytes))
+        {
+            if (Throw)
+                throw osc_read_exception();
+            else
+            {
+                error = true;
+                memset(dest, 0, bytes);
+            }
+        }
+    }
+    inline void write(const void *src, uint32_t bytes)
+    {
+        if (!buffer.write((const uint8_t *)src, bytes))
+        {
+            if (Throw)
+                throw osc_write_exception();
+            else
+                error = true;
+        }
+    }
+    inline void clear()
+    {
+        buffer.clear();
+        if (type_buffer)
+            type_buffer->clear();
+    }
+    inline void write_type(char ch)
+    {
+        if (type_buffer)
+            type_buffer->write((uint8_t *)&ch, 1);
+    }
+};
+
+typedef osc_stream<string_buffer> osc_strstream;
+typedef osc_stream<string_buffer, string_buffer> osc_typed_strstream;
+
+struct osc_inline_strstream: public string_buffer, public osc_strstream
+{
+    osc_inline_strstream()
+    : string_buffer(), osc_strstream(static_cast<string_buffer &>(*this))
+    {
+    }
+};
+
+struct osc_str_typed_buffer_pair
+{
+    string_buffer buf_data, buf_types;
 };
 
+struct osc_inline_typed_strstream: public osc_str_typed_buffer_pair, public osc_typed_strstream
+{
+    osc_inline_typed_strstream()
+    : osc_str_typed_buffer_pair(), osc_typed_strstream(buf_data, buf_types)
+    {
+    }
+};
+
+template<class Buffer, class TypeBuffer>
+inline osc_stream<Buffer, TypeBuffer> &
+operator <<(osc_stream<Buffer, TypeBuffer> &s, uint32_t val)
+{
+    val = htonl(val);
+    s.write(&val, 4);
+    s.write_type(osc_i32);
+    return s;
+}
+
+template<class Buffer, class TypeBuffer>
+inline osc_stream<Buffer, TypeBuffer> &
+operator >>(osc_stream<Buffer, TypeBuffer> &s, uint32_t &val)
+{
+    s.read(&val, 4);
+    val = htonl(val);
+    return s;
+}
+
+template<class Buffer, class TypeBuffer>
+inline osc_stream<Buffer, TypeBuffer> &
+operator >>(osc_stream<Buffer, TypeBuffer> &s, int32_t &val)
+{
+    s.read(&val, 4);
+    val = htonl(val);
+    return s;
+}
+
+template<class Buffer, class TypeBuffer>
+inline osc_stream<Buffer, TypeBuffer> &
+operator <<(osc_stream<Buffer, TypeBuffer> &s, float val)
+{
+    union { float v; uint32_t i; } val2;
+    val2.v = val;
+    val2.i = htonl(val2.i);
+    s.write(&val2.i, 4);
+    s.write_type(osc_f32);
+    return s;
+}
+
+template<class Buffer, class TypeBuffer>
+inline osc_stream<Buffer, TypeBuffer> &
+operator >>(osc_stream<Buffer, TypeBuffer> &s, float &val)
+{
+    union { float v; uint32_t i; } val2;
+    s.read(&val2.i, 4);
+    val2.i = htonl(val2.i);
+    val = val2.v;
+    return s;
+}
+
+template<class Buffer, class TypeBuffer>
+inline osc_stream<Buffer, TypeBuffer> &
+operator <<(osc_stream<Buffer, TypeBuffer> &s, const std::string &str)
+{
+    s.write(&str[0], str.length());
+    s.pad();
+    s.write_type(osc_string);
+    return s;
+}
+
+template<class Buffer, class TypeBuffer>
+inline osc_stream<Buffer, TypeBuffer> &
+operator >>(osc_stream<Buffer, TypeBuffer> &s, std::string &str)
+{
+    // inefficient...
+    char five[5];
+    five[4] = '\0';
+    str.resize(0);
+    while(1)
+    {
+        s.read(five, 4);
+        if (five[0] == '\0')
+            break;
+        str += five;
+        if (!five[1] || !five[2] || !five[3])
+            break;
+    }
+    return s;
+}
+
+template<class Buffer, class TypeBuffer, class DestBuffer>
+inline osc_stream<Buffer, TypeBuffer> &
+read_buffer_from_osc_stream(osc_stream<Buffer, TypeBuffer> &s, DestBuffer &buf)
+{
+    uint32_t nlen = 0;
+    s.read(&nlen, 4);
+    uint32_t len = htonl(nlen);
+    // write length in network order
+    for (uint32_t i = 0; i < len; i += 1024)
+    {
+        uint8_t tmp[1024];
+        uint32_t part = std::min((uint32_t)1024, len - i);
+        s.read(tmp, part);
+        buf.write(tmp, part);
+    }
+    // pad
+    s.read(&nlen, 4 - (len & 3));
+    return s;
+}
+
+template<class Buffer, class TypeBuffer, class SrcBuffer>
+inline osc_stream<Buffer, TypeBuffer> &
+write_buffer_to_osc_stream(osc_stream<Buffer, TypeBuffer> &s, SrcBuffer &buf)
+{
+    uint32_t len = buf.read_left();
+    uint32_t nlen = ntohl(len);
+    s.write(&nlen, 4);
+    // write length in network order
+    for (uint32_t i = 0; i < len; i += 1024)
+    {
+        uint8_t tmp[1024];
+        uint32_t part = std::min((uint32_t)1024, len - i);
+        buf.read(tmp, part);
+        s.write(tmp, part);
+    }
+    s.pad();
+    s.write_type(osc_blob);
+    return s;
+}
+
+template<class Buffer, class TypeBuffer>
+inline osc_stream<Buffer, TypeBuffer> &
+operator >>(osc_stream<Buffer, TypeBuffer> &s, raw_buffer &str)
+{
+    return read_buffer_from_osc_stream(s, str);
+}
+
+template<class Buffer, class TypeBuffer>
+inline osc_stream<Buffer, TypeBuffer> &
+operator >>(osc_stream<Buffer, TypeBuffer> &s, string_buffer &str)
+{
+    return read_buffer_from_osc_stream(s, str);
+}
+
+template<class Buffer, class TypeBuffer>
+inline osc_stream<Buffer, TypeBuffer> &
+operator <<(osc_stream<Buffer, TypeBuffer> &s, raw_buffer &str)
+{
+    return write_buffer_to_osc_stream(s, str);
+}
+
+template<class Buffer, class TypeBuffer>
+inline osc_stream<Buffer, TypeBuffer> &
+operator <<(osc_stream<Buffer, TypeBuffer> &s, string_buffer &str)
+{
+    return write_buffer_to_osc_stream(s, str);
+}
+
+// XXXKF: I don't support reading binary blobs yet
+
 struct osc_net_bad_address: public std::exception
 {
     std::string addr, error_msg;
@@ -160,15 +474,68 @@ struct osc_net_dns_exception: public std::exception
     virtual ~osc_net_dns_exception() throw () {}
 };
     
+template<class OscStream>
 struct osc_message_sink
 {
-    virtual void receive_osc_message(std::string address, std::string type_tag, const std::vector<osc_data> &args)=0;
+    virtual void receive_osc_message(std::string address, std::string type_tag, OscStream &buffer)=0;
     virtual ~osc_message_sink() {}
 };
 
-struct osc_message_dump: public osc_message_sink
+template<class OscStream, class DumpStream>
+struct osc_message_dump: public osc_message_sink<OscStream>
 {
-    virtual void receive_osc_message(std::string address, std::string type_tag, const std::vector<osc_data> &args);
+    DumpStream &stream;
+    osc_message_dump(DumpStream &_stream) : stream(_stream) {}
+        
+    virtual void receive_osc_message(std::string address, std::string type_tag, OscStream &buffer)
+    {
+        int pos = buffer.buffer.tell();
+        stream << "address: " << address << ", type tag: " << type_tag << std::endl;
+        for (unsigned int i = 0; i < type_tag.size(); i++)
+        {
+            stream << "Argument " << i << " is ";
+            switch(type_tag[i])
+            {
+                case 'i': 
+                {
+                    uint32_t val;
+                    buffer >> val;
+                    stream << val;
+                    break;
+                }
+                case 'f': 
+                {
+                    float val;
+                    buffer >> val;
+                    stream << val;
+                    break;
+                }
+                case 's': 
+                {
+                    std::string val;
+                    buffer >> val;
+                    stream << val;
+                    break;
+                }
+                case 'b': 
+                {
+                    osctl::string_buffer val;
+                    buffer >> val;
+                    stream << "blob (" << val.data.length() << " bytes)";
+                    break;
+                }
+                default:
+                {
+                    stream << "unknown - cannot parse more arguments" << std::endl;
+                    i = type_tag.size();
+                    break;
+                }
+            }
+            stream << std::endl;
+        }
+        stream << std::flush;
+        buffer.buffer.seek(pos);
+    }
 };
 
 };
diff --git a/src/calf/osctlnet.h b/src/calf/osctlnet.h
index d177cf0..7d18cf3 100644
--- a/src/calf/osctlnet.h
+++ b/src/calf/osctlnet.h
@@ -42,10 +42,10 @@ struct osc_socket
 
 struct osc_server: public osc_socket
 {
-    static osc_message_dump dump;
-    osc_message_sink *sink;
+    osc_message_dump<osc_strstream, std::ostream> dump;
+    osc_message_sink<osc_strstream> *sink;
     
-    osc_server() : sink(&dump) {}
+    osc_server() : dump(std::cout), sink(&dump) {}
     
     virtual void on_bind();
     
@@ -59,7 +59,7 @@ struct osc_client: public osc_socket
     
     void set_addr(const char *hostaddr, int port);
     void set_url(const char *url);
-    bool send(const std::string &address, const std::vector<osc_data> &args);
+    bool send(const std::string &address, osctl::osc_typed_strstream &stream);
     bool send(const std::string &address);
 };
 
diff --git a/src/dssigui.cpp b/src/dssigui.cpp
index 0e7e84c..05cfca8 100644
--- a/src/dssigui.cpp
+++ b/src/dssigui.cpp
@@ -27,13 +27,12 @@
 #include <calf/modules_dev.h>
 #include <calf/benchmark.h>
 #include <calf/main_win.h>
+#include <calf/osctl.h>
+#include <calf/osctlnet.h>
 
 using namespace std;
 using namespace dsp;
 using namespace synth;
-
-#include <calf/osctl.h>
-#include <calf/osctlnet.h>
 using namespace osctl;
 
 #define debug_printf(...)
@@ -108,10 +107,9 @@ struct plugin_proxy: public plugin_proxy_base, public line_graph_iface
         params[param_no] = value;
         if (send_osc)
         {
-            vector<osc_data> data;
-            data.push_back(osc_data(param_no + get_param_port_offset()));
-            data.push_back(osc_data(value));
-            client->send("/control", data);
+            osc_inline_typed_strstream str;
+            str << (uint32_t)(param_no + get_param_port_offset()) << value;
+            client->send("/control", str);
         }
     }
     virtual int get_param_count() {
@@ -128,10 +126,9 @@ struct plugin_proxy: public plugin_proxy_base, public line_graph_iface
     }
     virtual bool activate_preset(int bank, int program) { 
         if (send_osc) {
-            vector<osc_data> data;
-            data.push_back(osc_data(bank));
-            data.push_back(osc_data(program));
-            client->send("/program", data);
+            osc_inline_typed_strstream str;
+            str << (uint32_t)(bank) << (uint32_t)(program);
+            client->send("/program", str);
             return false;
         }
         return false;
@@ -160,18 +157,16 @@ struct plugin_proxy: public plugin_proxy_base, public line_graph_iface
     }
     virtual void execute(int command_no) { 
         if (send_osc) {
-            vector<osc_data> data;
             stringstream ss;
             ss << command_no;
             
-            data.push_back(osc_data("ExecCommand"));
-            data.push_back(osc_data(ss.str()));
-            client->send("/configure", data);
-            data.clear();
-
-            data.push_back(osc_data("ExecCommand"));
-            data.push_back(osc_data(""));
-            client->send("/configure", data);
+            osc_inline_typed_strstream str;
+            str << "ExecCommand" << ss.str();
+            client->send("/configure", str);
+            
+            str.clear();
+            str << "ExecCommand" << "";
+            client->send("/configure", str);
         }
     }
 };
@@ -214,7 +209,7 @@ GMainLoop *mainloop;
 
 static bool osc_debug = false;
 
-struct dssi_osc_server: public osc_server, public osc_message_sink
+struct dssi_osc_server: public osc_server, public osc_message_sink<osc_strstream>
 {
     plugin_proxy_base *plugin;
     main_window *main_win;
@@ -254,13 +249,15 @@ struct dssi_osc_server: public osc_server, public osc_message_sink
         global_presets.get_for_plugin(presets, effect_name.c_str());
     }
     
-    void receive_osc_message(std::string address, std::string type_tag, const std::vector<osc_data> &args)
+    virtual void receive_osc_message(std::string address, std::string args, osc_strstream &buffer)
     {
         if (osc_debug)
-            dump.receive_osc_message(address, type_tag, args);
-        if (address == prefix + "/update" && args.size() && args[0].type == osc_string)
+            dump.receive_osc_message(address, args, buffer);
+        if (address == prefix + "/update" && args == "s")
         {
-            debug_printf("UPDATE: %s\n", args[0].strval.c_str());
+            string str;
+            buffer >> str;
+            debug_printf("UPDATE: %s\n", str.c_str());
             return;
         }
         if (address == prefix + "/quit")
@@ -269,9 +266,13 @@ struct dssi_osc_server: public osc_server, public osc_message_sink
             g_main_loop_quit(mainloop);
             return;
         }
-        if (address == prefix + "/program"&& args.size() >= 2 && args[0].type == osc_i32 && args[1].type == osc_i32)
+        if (address == prefix + "/program"&& args == "ii")
         {
-            unsigned int nr = args[0].i32val * 128 + args[1].i32val;
+            uint32_t bank, program;
+            
+            buffer >> bank >> program;
+            
+            unsigned int nr = bank * 128 + program;
             debug_printf("PROGRAM %d\n", nr);
             if (nr == 0)
             {
@@ -297,10 +298,14 @@ struct dssi_osc_server: public osc_server, public osc_message_sink
             // cli.send("/update", data);
             return;
         }
-        if (address == prefix + "/control" && args.size() >= 2 && args[0].type == osc_i32 && args[1].type == osc_f32)
+        if (address == prefix + "/control" && args == "if")
         {
-            int idx = args[0].i32val - plugin->get_param_port_offset();
-            float val = args[1].f32val;
+            uint32_t port;
+            float val;
+            
+            buffer >> port >> val;
+            
+            int idx = port - plugin->get_param_port_offset();
             debug_printf("CONTROL %d %f\n", idx, val);
             bool sosc = plugin->send_osc;
             plugin->send_osc = false;
@@ -377,8 +382,9 @@ int main(int argc, char *argv[])
     
     debug_printf("URI = %s\n", srv.get_uri().c_str());
     
-    vector<osc_data> data;
-    data.push_back(osc_data(srv.get_uri(), osc_string));
+    string data_buf, type_buf;
+    osc_inline_typed_strstream data;
+    data << srv.get_uri();
     if (!srv.cli.send("/update", data))
     {
         g_error("Could not send the initial update message via OSC to %s", argv[optind]);
diff --git a/src/osctl.cpp b/src/osctl.cpp
index 8172ec2..583ce2d 100644
--- a/src/osctl.cpp
+++ b/src/osctl.cpp
@@ -8,6 +8,7 @@
 using namespace osctl;
 using namespace std;
 
+#if 0
 std::string osc_data::to_string() const
 {
     std::stringstream ss;
@@ -31,6 +32,7 @@ std::string osc_data::to_string() const
     }
     return ss.str();
 }
+#endif
 
 const char *osctl::osc_type_name(osc_type type)
 {
@@ -57,6 +59,7 @@ const char *osctl::osc_type_name(osc_type type)
     }
 }
 
+#if 0
 void osc_stream::read(osc_type type, osc_data &od)
 {
     od.type = type;
@@ -174,3 +177,4 @@ void osc_message_dump::receive_osc_message(std::string address, std::string type
     }
 }
 
+#endif
diff --git a/src/osctlnet.cpp b/src/osctlnet.cpp
index c9e8754..fd8afd5 100644
--- a/src/osctlnet.cpp
+++ b/src/osctlnet.cpp
@@ -11,15 +11,16 @@ using namespace std;
 
 void osc_server::parse_message(const char *buffer, int len)
 {
-    vector<osc_data> data;
-    osc_stream str(string(buffer, len));
-    str.read("ss", data);
-    if (!data[0].strval.empty() && data[0].strval[0] == '/'
-      &&!data[1].strval.empty() && data[1].strval[0] == ',')
+    osctl::string_buffer buf(string(buffer, len));
+    osc_strstream str(buf);
+    string address, type_tag;
+    str >> address;
+    str >> type_tag;
+    // cout << "Address " << address << " type tag " << type_tag << endl << flush;
+    if (!address.empty() && address[0] == '/'
+      &&!type_tag.empty() && type_tag[0] == ',')
     {
-        vector<osc_data> data2;
-        str.read(data[1].strval.substr(1).c_str(), data2);
-        sink->receive_osc_message(data[0].strval, data[1].strval, data2);
+        sink->receive_osc_message(address, type_tag.substr(1), str);
     }
 }
 
@@ -122,33 +123,23 @@ void osc_client::set_url(const char *url)
     addr.sin_addr = *(struct in_addr *)he->h_addr;
 }
 
-bool osc_client::send(const std::string &address, const std::vector<osc_data> &args)
+bool osc_client::send(const std::string &address, osctl::osc_typed_strstream &stream)
 {
-    vector<osc_data> data;
-    std::string type_tag = ",";
-    osc_stream str;
-    str.write(prefix + address);
-    for (unsigned int i = 0; i < args.size(); i++)
-        type_tag += char(args[i].type);
-    str.write(type_tag);
-    
-    for (unsigned int i = 0; i < args.size(); i++)
-        str.write(args[i]);    
+    std::string type_tag = "," + stream.type_buffer->data;
+    osc_inline_strstream hdr;
+    hdr << prefix + address << "," + stream.type_buffer->data;
+    string str = hdr.data + stream.buffer.data;
     
     // printf("sending %s\n", str.buffer.c_str());
 
-    return ::sendto(socket, str.buffer.data(), str.buffer.length(), 0, (sockaddr *)&addr, sizeof(addr)) == (int)str.buffer.length();
+    return ::sendto(socket, str.data(), str.length(), 0, (sockaddr *)&addr, sizeof(addr)) == (int)str.length();
 }
 
 bool osc_client::send(const std::string &address)
 {
-    vector<osc_data> data;
-    std::string type_tag = ",";
-    osc_stream str;
-    str.write(prefix + address);
-    str.write(type_tag);
-    return ::sendto(socket, str.buffer.data(), str.buffer.length(), 0, (sockaddr *)&addr, sizeof(addr)) == (int)str.buffer.length();
+    osc_inline_strstream hdr;
+    hdr << prefix + address << ",";
+    
+    return ::sendto(socket, hdr.data.data(), hdr.data.length(), 0, (sockaddr *)&addr, sizeof(addr)) == (int)hdr.data.length();
 }
 
-osc_message_dump osc_server::dump;
-
diff --git a/src/utils.cpp b/src/utils.cpp
index ce15501..b1b6b4b 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -29,28 +29,28 @@ using namespace osctl;
 
 string calf_utils::encodeMap(const dictionary &data)
 {
-    osc_stream str;
-    str.write((int32_t)data.size());
+    osctl::string_buffer sb;
+    osc_stream<osctl::string_buffer> str(sb);
+    str << (uint32_t)data.size();
     for(dictionary::const_iterator i = data.begin(); i != data.end(); i++)
     {
-        str.write(osc_data(i->first));
-        str.write(osc_data(i->second));
+        str << i->first << i->second;
     }
-    return str.buffer;
+    return sb.data;
 }
 
 void calf_utils::decodeMap(dictionary &data, const string &src)
 {
-    osc_stream str(src);
-    osc_data tmp, tmp2;
-    int32_t count = 0;
-    str.read(osc_i32, tmp);
-    count = tmp.i32val;
+    osctl::string_buffer sb(src);
+    osc_stream<osctl::string_buffer> str(sb);
+    uint32_t count = 0;
+    str >> count;
+    string tmp, tmp2;
     data.clear();
-    for (int i = 0; i < count; i++)
+    for (uint32_t i = 0; i < count; i++)
     {
-        str.read(osc_string, tmp);
-        str.read(osc_string, tmp2);
-        data[tmp.strval] = tmp2.strval;
+        str >> tmp;
+        str >> tmp2;
+        data[tmp] = tmp2;
     }
 }

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list