summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/ardour/ardour/lua_api.h15
-rw-r--r--libs/ardour/ardour/luabindings.h1
-rw-r--r--libs/ardour/lua_api.cc76
-rw-r--r--libs/ardour/luabindings.cc12
-rw-r--r--libs/ardour/wscript2
5 files changed, 105 insertions, 1 deletions
diff --git a/libs/ardour/ardour/lua_api.h b/libs/ardour/ardour/lua_api.h
index c69469f184..3aab2f937d 100644
--- a/libs/ardour/ardour/lua_api.h
+++ b/libs/ardour/ardour/lua_api.h
@@ -20,6 +20,7 @@
#define _ardour_lua_api_h_
#include <string>
+#include <lo/lo.h>
#include <boost/shared_ptr.hpp>
#include "ardour/libardour_visibility.h"
@@ -31,6 +32,20 @@ namespace ARDOUR { namespace LuaAPI {
boost::shared_ptr<ARDOUR::Processor> new_luaproc (ARDOUR::Session *s, const std::string&);
+ /**
+ * OSC is kinda special, lo_address is a void* and lo_send() has varags
+ * and typed arguments which makes it hard to bind, even lo_cpp.
+ */
+ class LuaOSCAddress {
+ public:
+ LuaOSCAddress (std::string uri) {
+ _addr = lo_address_new_from_url (uri.c_str());
+ }
+ ~LuaOSCAddress () { if (_addr) { lo_address_free (_addr); } }
+ int send (lua_State *L);
+ lo_address _addr;
+ };
+
} } /* namespace */
#endif // _ardour_lua_api_h_
diff --git a/libs/ardour/ardour/luabindings.h b/libs/ardour/ardour/luabindings.h
index 65f4c23bf7..4650858dff 100644
--- a/libs/ardour/ardour/luabindings.h
+++ b/libs/ardour/ardour/luabindings.h
@@ -30,6 +30,7 @@ namespace ARDOUR {
LIBARDOUR_API extern void common (lua_State* L);
LIBARDOUR_API extern void dsp (lua_State* L);
LIBARDOUR_API extern void session (lua_State* L);
+ LIBARDOUR_API extern void osc (lua_State* L);
LIBARDOUR_API extern void set_session (lua_State* L, Session *s);
diff --git a/libs/ardour/lua_api.cc b/libs/ardour/lua_api.cc
index 99a9b1b493..78b95bec0a 100644
--- a/libs/ardour/lua_api.cc
+++ b/libs/ardour/lua_api.cc
@@ -65,3 +65,79 @@ ARDOUR::LuaAPI::new_luaproc (Session *s, const string& name)
return boost::shared_ptr<Processor> (new PluginInsert (*s, p));
}
+
+int
+ARDOUR::LuaAPI::LuaOSCAddress::send (lua_State *L)
+{
+ LuaOSCAddress * const luaosc = luabridge::Userdata::get <LuaOSCAddress> (L, 1, false);
+ if (!luaosc) {
+ return luaL_error (L, "Invalid pointer to OSC.Address");
+ }
+ if (!luaosc->_addr) {
+ return luaL_error (L, "Invalid Destination Address");
+ }
+
+ int top = lua_gettop(L);
+ if (top < 3) {
+ return luaL_argerror (L, 1, "invalid number of arguments, :send (path, type, ...)");
+ }
+
+ const char* path = luaL_checkstring (L, 2);
+ const char* type = luaL_checkstring (L, 3);
+ assert (path && type);
+
+ if ((int) strlen(type) != top - 3) {
+ return luaL_argerror (L, 3, "type description does not match arguments");
+ }
+
+ lo_message msg = lo_message_new ();
+
+ for (int i = 4; i <= top; ++i) {
+ char t = type[i - 4];
+ int lt = lua_type(L, i);
+ int ok = -1;
+ switch(lt) {
+ case LUA_TSTRING:
+ if (t == LO_STRING) {
+ ok = lo_message_add_string (msg, luaL_checkstring(L, i));
+ } else if (t == LO_CHAR) {
+ char c = luaL_checkstring (L, i) [0];
+ ok = lo_message_add_char (msg, c);
+ }
+ break;
+ case LUA_TBOOLEAN:
+ if (t == LO_TRUE || t == LO_FALSE) {
+ if (lua_toboolean (L, i)) {
+ ok = lo_message_add_true (msg);
+ } else {
+ ok = lo_message_add_false (msg);
+ }
+ }
+ break;
+ case LUA_TNUMBER:
+ if (t == LO_INT32) {
+ ok = lo_message_add_int32 (msg, (int32_t) luaL_checkinteger(L, i));
+ }
+ else if (t == LO_FLOAT) {
+ ok = lo_message_add_float (msg, (float) luaL_checknumber(L, i));
+ }
+ else if (t == LO_DOUBLE) {
+ ok = lo_message_add_double (msg, (double) luaL_checknumber(L, i));
+ }
+ else if (t == LO_INT64) {
+ ok = lo_message_add_double (msg, (int64_t) luaL_checknumber(L, i));
+ }
+ break;
+ default:
+ break;
+ }
+ if (ok != 0) {
+ return luaL_argerror (L, i, "type description does not match parameter");
+ }
+ }
+
+ int rv = lo_send_message (luaosc->_addr, path, msg);
+ lo_message_free (msg);
+ luabridge::Stack<int>::push (L, rv);
+ return 1;
+}
diff --git a/libs/ardour/luabindings.cc b/libs/ardour/luabindings.cc
index ef7d450deb..4f11c66980 100644
--- a/libs/ardour/luabindings.cc
+++ b/libs/ardour/luabindings.cc
@@ -638,6 +638,18 @@ LuaBindings::session (lua_State* L)
}
void
+LuaBindings::osc (lua_State* L)
+{
+ luabridge::getGlobalNamespace (L)
+ .beginNamespace ("OSC")
+ .beginClass<LuaAPI::LuaOSCAddress> ("Address")
+ .addConstructor<void (*) (std::string)> ()
+ .addCFunction ("send", &LuaAPI::LuaOSCAddress::send)
+ .endClass ()
+ .endNamespace ();
+}
+
+void
LuaBindings::set_session (lua_State* L, Session *s)
{
/* LuaBridge uses unique keys to identify classes/c-types.
diff --git a/libs/ardour/wscript b/libs/ardour/wscript
index 5b7abaa9c8..070f24ef46 100644
--- a/libs/ardour/wscript
+++ b/libs/ardour/wscript
@@ -367,7 +367,7 @@ def build(bld):
obj.includes = ['.', '../surfaces/control_protocol', '..']
obj.name = 'libardour'
obj.target = 'ardour'
- obj.uselib = ['GLIBMM','GTHREAD','AUBIO','SIGCPP','XML','UUID',
+ obj.uselib = ['GLIBMM','GTHREAD','AUBIO','SIGCPP','XML','UUID', 'LO',
'SNDFILE','SAMPLERATE','LRDF','AUDIOUNITS', 'GIOMM',
'OSX','BOOST','CURL','TAGLIB','VAMPSDK','VAMPHOSTSDK','RUBBERBAND']
obj.use = ['libpbd','libmidipp','libevoral',