[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