Assists music production by grouping standalone programs into sessions. Community version of "Non Session Manager".
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

376 lines
13KB

  1. /*******************************************************************************/
  2. /* Copyright (C) 2010 Jonathan Moore Liles */
  3. /* */
  4. /* This program is free software; you can redistribute it and/or modify it */
  5. /* under the terms of the GNU General Public License as published by the */
  6. /* Free Software Foundation; either version 2 of the License, or (at your */
  7. /* option) any later version. */
  8. /* */
  9. /* This program is distributed in the hope that it will be useful, but WITHOUT */
  10. /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
  11. /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
  12. /* more details. */
  13. /* */
  14. /* You should have received a copy of the GNU General Public License along */
  15. /* with This program; see the file COPYING. If not,write to the Free Software */
  16. /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  17. /*******************************************************************************/
  18. #pragma once
  19. #include <lo/lo.h>
  20. #include "Thread.H"
  21. #include <list>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <sigc++/sigc++.h>
  25. namespace OSC
  26. {
  27. class OSC_Value
  28. {
  29. protected:
  30. char _type;
  31. float f;
  32. double d;
  33. int i;
  34. const char *s;
  35. public:
  36. OSC_Value ( const OSC_Value &rhs )
  37. {
  38. _type = rhs._type;
  39. f =rhs.f;
  40. d = rhs.d;
  41. i = rhs.i;
  42. s = rhs.s;
  43. }
  44. OSC_Value ( )
  45. {
  46. _type = 0;
  47. f = 0;
  48. d = 0;
  49. i = 0;
  50. s = 0;
  51. }
  52. virtual ~OSC_Value ( ) { }
  53. virtual char type ( void ) const { return _type; }
  54. };
  55. class OSC_Float : public OSC_Value
  56. {
  57. public:
  58. float value ( void ) const { return f; }
  59. OSC_Float ( float v )
  60. {
  61. _type = 'f';
  62. f = v;
  63. }
  64. };
  65. class OSC_Int : public OSC_Value
  66. {
  67. public:
  68. int value ( void ) const { return i; }
  69. OSC_Int ( int v )
  70. {
  71. _type = 'i';
  72. i = v;
  73. }
  74. };
  75. class OSC_String : public OSC_Value
  76. {
  77. public:
  78. const char * value ( void ) const { return s; }
  79. OSC_String ( const char *v )
  80. {
  81. _type = 's';
  82. s = v;
  83. }
  84. };
  85. struct Parameter_Limits
  86. {
  87. float min;
  88. float max;
  89. float default_value;
  90. };
  91. class Endpoint;
  92. class Signal;
  93. struct Peer
  94. {
  95. bool _scanning;
  96. char *name;
  97. lo_address addr;
  98. std::list<Signal*> _signals;
  99. };
  100. typedef int (*signal_handler) ( float value, void *user_data );
  101. class Signal
  102. {
  103. static int next_id;
  104. public:
  105. enum Direction {
  106. Input,
  107. Output,
  108. Bidirectional
  109. };
  110. private:
  111. Endpoint *_endpoint;
  112. Peer *_peer;
  113. int _id;
  114. char *_path;
  115. char *_documentation;
  116. float _value;
  117. std::list<Signal*> _outgoing;
  118. std::list<Signal*> _incoming;
  119. Direction _direction;
  120. signal_handler _handler;
  121. void *_user_data;
  122. Parameter_Limits _parameter_limits;
  123. public:
  124. Signal ( const char *path, Direction dir )
  125. {
  126. _direction = dir;
  127. _path = strdup( path );
  128. _id = ++next_id;
  129. _value = 0.0f;
  130. _endpoint = NULL;
  131. _peer = NULL;
  132. }
  133. sigc::signal <void,Signal*> signal_connection_state_changed;
  134. ~Signal ( );
  135. static Signal *get_peer_signal_by_id ( Peer *p, int signal_id );
  136. int noutput_connections() { return _outgoing.size(); }
  137. bool connected ( void ) const { return _outgoing.size() + _incoming.size(); }
  138. char * get_output_connection_peer_name_and_path ( int n );
  139. int id ( void ) const { return _id; }
  140. Direction direction ( void ) const { return _direction; }
  141. void parameter_limits ( float min, float max, float default_value )
  142. {
  143. _parameter_limits.min = min;
  144. _parameter_limits.max = max;
  145. _parameter_limits.default_value = default_value;
  146. _value = default_value;
  147. }
  148. const Parameter_Limits& parameter_limits ( void ) const { return _parameter_limits; }
  149. const char *path ( void ) const { return _path; }
  150. void rename ( const char *name );
  151. /* publishes value to targets */
  152. void value ( float v );
  153. /* get current value */
  154. float value ( void ) const { return _value; }
  155. bool is_connected_to ( const Signal *s ) const;
  156. friend class Endpoint;
  157. };
  158. class Method
  159. {
  160. char *_path;
  161. char *_typespec;
  162. char *_documentation;
  163. public:
  164. const char *path ( void ) { return _path; }
  165. const char *typespec ( void ) { return _typespec; }
  166. Method ( );
  167. ~Method ( );
  168. friend class Endpoint;
  169. };
  170. class Endpoint
  171. {
  172. static void error_handler(int num, const char *msg, const char *path);
  173. static int osc_reply ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
  174. static int osc_signal_lister ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
  175. static int osc_generic ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
  176. static int osc_sig_handler ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
  177. static int osc_sig_renamed ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
  178. static int osc_sig_removed ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
  179. static int osc_sig_created ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
  180. static int osc_sig_disconnect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
  181. static int osc_sig_connect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
  182. static int osc_sig_hello ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
  183. void scan_peer ( const char *name, const char *url );
  184. Thread _thread;
  185. // lo_server_thread _st;
  186. lo_server _server;
  187. std::list<Peer*> _peers;
  188. std::list<Signal*> _signals;
  189. std::list<Method*> _methods;
  190. static void *osc_thread ( void *arg );
  191. void osc_thread ( void );
  192. OSC::Signal *find_signal_by_id ( int id );
  193. OSC::Signal *find_peer_signal_by_path ( Peer *p, const char *path );
  194. OSC::Signal *find_peer_signal_by_id ( Peer *p, int id );
  195. Peer *find_peer_by_name ( const char *name );
  196. Peer *find_peer_by_address ( lo_address addr );
  197. static bool address_matches ( lo_address addr1, lo_address addr2 );
  198. static Signal *find_target_by_peer_address ( std::list<Signal*> *l, lo_address addr );
  199. char *_name;
  200. void del_signal ( Signal *signal );
  201. void send_signal_rename_notifications( Signal *s );
  202. public:
  203. void list_peer_signals ( void (*callback) (const char *, const OSC::Signal *, void * ), void *v );
  204. int init ( int proto, const char *port = 0 );
  205. Endpoint ( );
  206. ~Endpoint ( );
  207. bool disconnect_signal ( OSC::Signal *s, OSC::Signal *d );
  208. bool disconnect_signal ( OSC::Signal *s, const char *peer_name, const char *signal_path );
  209. bool connect_signal ( OSC::Signal *s, OSC::Signal *d );
  210. bool connect_signal ( OSC::Signal *s, const char *peer_name, const char *signal_path );
  211. bool connect_signal ( OSC::Signal *s, const char *peer_name, int signal_id );
  212. bool connect_signal ( OSC::Signal *s, const char *peer_and_path );
  213. Signal * add_signal ( const char *path, Signal::Direction dir, float min, float max, float default_value, signal_handler handler, void *user_data );
  214. Method *add_method ( const char *path, const char *typespec, lo_method_handler handler, void *user_data, const char *argument_description );
  215. void del_method ( const char *path, const char *typespec );
  216. void del_method ( Method* method );
  217. void start ( void );
  218. void stop ( void );
  219. int port ( void ) const;
  220. char * url ( void ) const;
  221. void check ( void ) const;
  222. void wait ( int timeout ) const;
  223. void run ( void ) const;
  224. void name ( const char *name ) { _name = strdup( name ); }
  225. const char *name ( void ) { return _name; }
  226. void hello ( const char *url );
  227. int send ( lo_address to, const char *path, std::list< OSC_Value > values );
  228. /* overloads for common message formats */
  229. int send ( lo_address to, const char *path );
  230. int send ( lo_address to, const char *path, float v );
  231. int send ( lo_address to, const char *path, double v );
  232. int send ( lo_address to, const char *path, int v );
  233. int send ( lo_address to, const char *path, long v );
  234. int send ( lo_address to, const char *path, int v1, int v2 );
  235. int send ( lo_address to, const char *path, int v1, float v2 );
  236. int send ( lo_address to, const char *path, int v1, int v2, float v3 );
  237. int send ( lo_address to, const char *path, const char *v );
  238. int send ( lo_address to, const char *path, const char *v1, float v2 );
  239. int send ( lo_address to, const char *path, const char *v1, int v2, int v3 );
  240. int send ( lo_address to, const char *path, const char *v1, const char *v2 );
  241. int send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3 );
  242. int send ( lo_address to, const char *path, const char *v1, int v2, int v3, int v4 );
  243. int send ( lo_address to, const char *path, const char *v1, const char *v2, int v3, int v4, int v5 );
  244. int send ( lo_address to, const char *path, const char *v1, int v2 );
  245. int send ( lo_address to, const char *path, int v1, const char *v2 );
  246. int send ( lo_address to, const char *path, const char *v1, int v2, int v3, float v4 );
  247. int send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, int v4, int v5, int v6 );
  248. int send ( lo_address to, const char *path, const char *v1, int v2, const char *v3 );
  249. int send ( lo_address to, const char *path, int v1, const char *v2, const char *v3, const char *v4 );
  250. int send ( lo_address to, const char *path, const char *v1, int v2, const char *v3, const char *v4, const char *v5 );
  251. int send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, const char *v4, const char *v5 );
  252. int send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, const char *v4 );
  253. int send ( lo_address to, const char *path, lo_message msg );
  254. int send ( lo_address to, const char *path, const char *v1, const char *v2, int v3, float v4, float v5, float v6 );
  255. int send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, int v4, float v5, float v6, float v7 );
  256. // can be used to point back to owning object.
  257. void *owner;
  258. sigc::signal <void> signal_peer_scan_complete;
  259. friend Signal::~Signal();
  260. friend void Signal::rename ( const char *name );
  261. };
  262. };
  263. /* helper macros for defining OSC handlers */
  264. /* #define OSC_NAME( name ) osc_ ## name */
  265. #define OSC_DMSG() DMESSAGE( "Got OSC message: %s", path );
  266. // #define OSC_HANDLER( name ) static int OSC_NAME( name ) ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  267. /* #define OSC_REPLY_OK() ((OSC::Endpoint*)user_data)->send( lo_message_get_source( msg ), path, "ok" ) */
  268. /* #define OSC_REPLY( value ) ((OSC::Endpoint*)user_data)->send( lo_message_get_source( msg ), path, value ) */
  269. /* #define OSC_REPLY_ERR() ((OSC::Endpoint*)user_data)->send( lo_message_get_source( msg ), path, "err" ) */
  270. /* #define OSC_ENDPOINT() ((OSC::Endpoint*)user_data) */