View Issue Details

IDCategoryLast Update
0007136features2020-04-19 20:18
ReporterOnkelDeadAssigned Toovenwerks 
ReproducibilityN/A 
Status closedResolutionfixed 
Product Version5.4 
Fixed in Version 
Summary0007136: Add OSC support to access strips internal sends
DescriptionAs already described in https://community.ardour.org/node/14083, I would like you to add some additional features to the OSC implementation of Ardour.

Intention is to get knowledge of the assigned internal sends a strip owns.
Find a patch file attached, which contains my implementation.

The response to the message /strip/sends will contain the following arguments:
0. An integer identifying the strip (sid) the list belongs to (once before the list of sends)
1. An integer identifying the target strip (sid)
2. A string with the name of the send
3. An integer with the zero based index of the send (may be obsolete)
4. A float value with the current sends slider position (0.0 ... 1.0)
5. An integer indicating if the send is enabled. (0 or 1)
This list repeats from point 1. for each internal send

I assume that in case banking is in place, there will be more work to do.
Additional InformationAdditionally to the sends stuff, I have included another OSC message, which let me rename a strip from an OSC client. I use this to name the strips corresponding to the instrument/mic plugged to my audio interface during stage setup. Would be fine o introduce it beside.
TagsNo tags attached.

Activities

OnkelDead

2016-11-23 11:00

reporter  

get_sends.patch (7,130 bytes)
diff -Naur 5.4.429.org/ardour/libs/surfaces/osc/osc.cc 5.4.429/ardour/libs/surfaces/osc/osc.cc
--- 5.4.429.org/ardour/libs/surfaces/osc/osc.cc	2016-11-23 11:10:55.431101728 +0100
+++ 5.4.429/ardour/libs/surfaces/osc/osc.cc	2016-11-23 11:19:30.446738754 +0100
@@ -46,6 +46,7 @@
 #include "ardour/plugin_insert.h"
 #include "ardour/presentation_info.h"
 #include "ardour/send.h"
+#include "ardour/internal_send.h"
 #include "ardour/phase_control.h"
 #include "ardour/solo_isolate_control.h"
 #include "ardour/solo_safe_control.h"
@@ -599,6 +600,11 @@
 		REGISTER_CALLBACK (serv, "/strip/send/fader", "iif", route_set_send_fader);
 		REGISTER_CALLBACK (serv, "/strip/send/enable", "iif", route_set_send_enable);
 
+                REGISTER_CALLBACK(serv, "/strip/name", "is", route_rename);
+                REGISTER_CALLBACK(serv, "/strip/sends", "i", route_get_sends);
+                REGISTER_CALLBACK(serv, "/strip/receives", "i", route_get_receives);                
+                
+        
 		/* still not-really-standardized query interface */
 		//REGISTER_CALLBACK (serv, "/ardour/*/#current_value", "", current_value);
 		//REGISTER_CALLBACK (serv, "/ardour/set", "", set);
@@ -1789,6 +1795,99 @@
 	return 0;
 }
 
+void
+OSC::route_get_sends(lo_message msg) {
+	if (!session) {
+		return;
+	}
+
+	lo_arg **argv = lo_message_get_argv(msg);
+
+	int rid = argv[0]->i;
+
+	boost::shared_ptr<Stripable> strip = get_strip(rid, get_address(msg));
+	boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (strip);
+	
+	lo_message reply = lo_message_new();
+	lo_message_add_int32(reply, rid);
+
+	int i = 0;
+	for (;;) {
+		boost::shared_ptr<Processor> p = r->nth_send(i++);
+
+		if (!p) {
+			break;
+		}
+		
+		boost::shared_ptr<InternalSend> isend = boost::dynamic_pointer_cast<InternalSend> (p);
+		if (isend) {
+//			boost::shared_ptr<Send> send = boost::dynamic_pointer_cast<Send> (p);
+			lo_message_add_int32(reply, get_sid(isend->target_route(), get_address(msg)));
+			lo_message_add_string(reply, isend->name().c_str());   
+			lo_message_add_int32(reply, i);
+			boost::shared_ptr<Amp> a = isend->amp();
+			lo_message_add_float(reply, gain_to_slider_position(a->gain_control()->get_value()));
+			lo_message_add_int32(reply, p->active() ? 1 : 0);
+		} 
+	}
+	// if used dedicated message path to identify this reply in async operation. Naming it #reply wont help the client to identify the content.
+	lo_send_message(lo_message_get_source(msg), "/strip/sends", reply);
+
+	lo_message_free(reply);
+}
+
+void
+OSC::route_get_receives(lo_message msg) {
+	if (!session) {
+		return;
+	}
+
+	lo_arg **argv = lo_message_get_argv(msg);
+
+	uint32_t rid = argv[0]->i;
+	
+
+	boost::shared_ptr<Stripable> strip = get_strip(rid, get_address(msg));
+	boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (strip);	
+
+	boost::shared_ptr<RouteList> route_list = session->get_routes();
+
+	lo_message reply = lo_message_new();
+	
+	for (RouteList::iterator i = route_list->begin(); i != route_list->end(); ++i) {
+		boost::shared_ptr<Route> tr = boost::dynamic_pointer_cast<Route> (*i);
+		if (!tr) {
+			continue;
+		}
+		int j = 0;
+		
+		for (;;) {
+			boost::shared_ptr<Processor> p = tr->nth_send(j++);
+
+			if (!p) {
+				break;
+			}
+
+			boost::shared_ptr<InternalSend> isend = boost::dynamic_pointer_cast<InternalSend> (p);
+			if (isend) {
+				if( isend->target_route()->id() == r->id()){
+					boost::shared_ptr<Amp> a = isend->amp();
+
+					lo_message_add_int32(reply, get_sid(tr, get_address(msg)));
+					lo_message_add_string(reply, tr->name().c_str());
+					lo_message_add_int32(reply, j);
+					lo_message_add_float(reply, gain_to_slider_position(a->gain_control()->get_value()));
+					lo_message_add_int32(reply, p->active() ? 1 : 0);
+				}				
+			}
+		}
+	}
+
+	// I have used a dedicated message path to identify this reply in async operation. Naming it #reply wont help the client to identify the content.
+	lo_send_message(lo_message_get_source(msg), "/strip/receives", reply);
+	lo_message_free(reply);
+}
+
 // strip calls
 int
 OSC::route_mute (int ssid, int yn, lo_message msg)
@@ -1967,6 +2066,21 @@
 }
 
 int
+OSC::route_rename(int ssid, char *newname, lo_message msg) {
+    if (!session) {
+        return -1;
+    }
+
+    boost::shared_ptr<Stripable> s = get_strip(ssid, get_address(msg));
+
+    if (s) {
+        s->set_name(std::string(newname));
+    }
+
+    return 0;
+}
+
+int
 OSC::sel_recsafe (uint32_t yn, lo_message msg)
 {
 	OSCSurface *sur = get_surface(get_address (msg));
diff -Naur 5.4.429.org/ardour/libs/surfaces/osc/osc.h 5.4.429/ardour/libs/surfaces/osc/osc.h
--- 5.4.429.org/ardour/libs/surfaces/osc/osc.h	2016-11-23 11:10:55.431101728 +0100
+++ 5.4.429/ardour/libs/surfaces/osc/osc.h	2016-11-23 11:20:43.107241156 +0100
@@ -212,6 +212,9 @@
 	int catchall (const char *path, const char *types, lo_arg **argv, int argc, void *data);
 	static int _catchall (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data);
 
+        void route_get_sends (lo_message msg);
+        void route_get_receives(lo_message msg);
+        
 	void routes_list (lo_message msg);
 	void transport_frame (lo_message msg);
 	void transport_speed (lo_message msg);
@@ -233,6 +236,9 @@
 		return 0;		\
 	}
 
+        PATH_CALLBACK_MSG(route_get_sends);
+        PATH_CALLBACK_MSG(route_get_receives);
+       
 	PATH_CALLBACK_MSG(routes_list);
 	PATH_CALLBACK_MSG(transport_frame);
 	PATH_CALLBACK_MSG(transport_speed);
@@ -401,6 +407,18 @@
 		return 0;						\
 	}
 
+#define PATH_CALLBACK2_MSG_s(name,arg1type,arg2type)			\
+        static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { \
+                return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, data); \
+        } \
+        int cb_ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data) { \
+                OSC_DEBUG;              \
+                if (argc > 1) {						\
+                        name (argv[0]->arg1type, &argv[1]->arg2type, data); \
+                }							\
+                return 0;						\
+        }
+
 #define PATH_CALLBACK3(name,arg1type,arg2type,arg3type)                \
         static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { \
                return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, data); \
@@ -436,6 +454,7 @@
 	PATH_CALLBACK4(set_surface,i,i,i,i);
 	PATH_CALLBACK2(locate,i,i);
 	PATH_CALLBACK2(loop_location,i,i);
+        PATH_CALLBACK2_MSG_s(route_rename,i,s);
 	PATH_CALLBACK2_MSG(route_mute,i,i);
 	PATH_CALLBACK2_MSG(route_solo,i,i);
 	PATH_CALLBACK2_MSG(route_solo_iso,i,i);
@@ -460,6 +479,7 @@
 	PATH_CALLBACK2_MSG(route_plugin_activate,i,i);
 	PATH_CALLBACK2_MSG(route_plugin_deactivate,i,i);
 
+	int route_rename (int rid, char *s, lo_message msg);
 	int route_mute (int rid, int yn, lo_message msg);
 	int route_solo (int rid, int yn, lo_message msg);
 	int route_solo_iso (int rid, int yn, lo_message msg);
get_sends.patch (7,130 bytes)

ovenwerks

2016-11-25 06:13

reporter   ~0019039

Thank you for the patch. I have merged it on my local copy and am working the bugs out. (crashes on non-existent routes, doesn't work for manual port setting)

ovenwerks

2016-11-25 15:28

reporter   ~0019042

Added via commit 98f1cb76edc316cc9e69b210b4ca2b22797caa13

system

2020-04-19 20:18

developer   ~0023680

Issue has been closed automatically, by Trigger Close Plugin.
Feel free to re-open with additional information if you think the issue is not resolved.

Issue History

Date Modified Username Field Change
2016-11-23 11:00 OnkelDead New Issue
2016-11-23 11:00 OnkelDead File Added: get_sends.patch
2016-11-25 06:13 ovenwerks Note Added: 0019039
2016-11-25 15:28 ovenwerks Note Added: 0019042
2016-11-25 15:28 ovenwerks Status new => resolved
2016-11-25 15:28 ovenwerks Resolution open => fixed
2016-11-25 15:28 ovenwerks Assigned To => ovenwerks
2020-04-19 20:18 system Note Added: 0023680
2020-04-19 20:18 system Status resolved => closed