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.

1151 lines
31KB

  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. #include <lo/lo.h>
  19. #include "debug.h"
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <assert.h>
  24. #include "Endpoint.H"
  25. #include "Thread.H"
  26. namespace OSC
  27. {
  28. /**********/
  29. /* Method */
  30. /**********/
  31. Method::Method ( )
  32. {
  33. _path = _typespec = _documentation = 0;
  34. }
  35. Method::~Method ( )
  36. {
  37. if ( _path )
  38. free( _path );
  39. if ( _typespec )
  40. free( _typespec );
  41. }
  42. /**********/
  43. /* Signal */
  44. /**********/
  45. int Signal::next_id = 0;
  46. Signal::~Signal ( )
  47. {
  48. if ( _endpoint )
  49. {
  50. _endpoint->del_signal( this );
  51. }
  52. free( _path );
  53. _path = NULL;
  54. _endpoint = NULL;
  55. }
  56. void
  57. Signal::rename ( const char *path )
  58. {
  59. for ( std::list<Target*>::const_iterator i = _incoming.begin();
  60. i != _incoming.end();
  61. ++i )
  62. {
  63. _endpoint->send( (*i)->peer->addr,
  64. "/signal/renamed",
  65. (*i)->signal_id,
  66. path );
  67. }
  68. free( _path );
  69. _path = strdup( path );
  70. }
  71. bool
  72. Signal::is_connected_to ( const OSC::Signal *s ) const
  73. {
  74. for ( std::list<Target*>::const_iterator i = _outgoing.begin();
  75. i != _outgoing.end();
  76. ++i )
  77. {
  78. if ( (*i)->peer == s->_peer &&
  79. (*i)->signal_id == s->id() )
  80. return true;
  81. }
  82. return false;
  83. }
  84. void
  85. Signal::value ( float f )
  86. {
  87. for ( std::list<Target*>::const_iterator i = _outgoing.begin();
  88. i != _outgoing.end();
  89. ++i )
  90. {
  91. if ( (*i)->value != f )
  92. {
  93. (*i)->value = f;
  94. _endpoint->send( (*i)->peer->addr,
  95. "/signal/change",
  96. (*i)->signal_id,
  97. f );
  98. }
  99. }
  100. }
  101. void
  102. Signal::get_connected_peer_name_and_path ( char **peer_name, char **path )
  103. {
  104. Target *t = _outgoing.back();
  105. Signal *s = get_peer_signal_by_id( t->peer, t->signal_id );
  106. *peer_name = strdup( t->peer->name );
  107. *path = strdup( s->path() );
  108. }
  109. void
  110. Endpoint::error_handler(int num, const char *msg, const char *path)
  111. {
  112. WARNING( "LibLO server error %d in path %s: %s\n", num, path, msg);
  113. }
  114. Endpoint::Endpoint ( )
  115. {
  116. }
  117. int
  118. Endpoint::init ( int proto, const char *port )
  119. {
  120. DMESSAGE( "Creating OSC server" );
  121. _server = lo_server_new_with_proto( port, proto, error_handler );
  122. if ( ! _server )
  123. {
  124. WARNING( "Error creating OSC server" );
  125. return -1;
  126. }
  127. add_method( "/signal/hello", "s", &Endpoint::osc_sig_hello, this, "" );
  128. add_method( "/signal/connect", "ii", &Endpoint::osc_sig_connect, this, "" );
  129. add_method( "/signal/disconnect", "ii", &Endpoint::osc_sig_disconnect, this, "" );
  130. add_method( "/signal/renamed", "is", &Endpoint::osc_sig_renamed, this, "" );
  131. add_method( "/signal/change", "if", &Endpoint::osc_sig_handler, this, "" );
  132. add_method( NULL, "", &Endpoint::osc_generic, this, "" );
  133. add_method( "/signal/list", NULL, &Endpoint::osc_signal_lister, this, "" );
  134. add_method( "/reply", NULL, &Endpoint::osc_reply, this, "" );
  135. return 0;
  136. }
  137. Endpoint::~Endpoint ( )
  138. {
  139. // lo_server_thread_free( _st );
  140. lo_server_free( _server );
  141. }
  142. OSC::Target *
  143. Endpoint::find_target_by_peer_address ( std::list<Target*> *l, lo_address addr )
  144. {
  145. for ( std::list<Target*>::iterator i = l->begin();
  146. i != l->end();
  147. ++i )
  148. {
  149. if ( address_matches( addr, (*i)->peer->addr ) )
  150. {
  151. return *i;
  152. }
  153. }
  154. return NULL;
  155. }
  156. OSC::Signal *
  157. Endpoint::find_signal_by_id ( int id )
  158. {
  159. for ( std::list<Signal*>::iterator i = _signals.begin();
  160. i != _signals.end();
  161. ++i )
  162. {
  163. if ( (*i)->id() == id )
  164. return *i;
  165. }
  166. return NULL;
  167. }
  168. OSC::Signal *
  169. Endpoint::find_peer_signal_by_path ( Peer *p, const char *path )
  170. {
  171. for ( std::list<Signal*>::iterator i = p->_signals.begin();
  172. i != p->_signals.end();
  173. ++i )
  174. {
  175. if ( !strcmp( (*i)->path(), path ) )
  176. return *i;
  177. }
  178. return NULL;
  179. }
  180. OSC::Signal *
  181. Endpoint::find_peer_signal_by_id ( Peer *p, int id )
  182. {
  183. for ( std::list<Signal*>::iterator i = p->_signals.begin();
  184. i != p->_signals.end();
  185. ++i )
  186. {
  187. if ( id == (*i)->id() )
  188. return *i;
  189. }
  190. return NULL;
  191. }
  192. void
  193. Endpoint::hello ( const char *url )
  194. {
  195. lo_address addr = lo_address_new_from_url ( url );
  196. send( addr, "/signal/hello", name() );
  197. lo_address_free( addr );
  198. }
  199. int
  200. Endpoint::osc_sig_hello ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  201. {
  202. Endpoint *ep = (Endpoint*)user_data;
  203. const char *peer_name = &argv[0]->s;
  204. DMESSAGE( "Got hello from %s", peer_name );
  205. if ( ! ep->find_peer_by_name( peer_name ) )
  206. {
  207. char *url = lo_address_get_url( lo_message_get_source( msg ));
  208. ep->scan_peer( peer_name, url );
  209. ep->send( lo_message_get_source( msg ), "/signal/hello", ep->name() );
  210. free(url);
  211. }
  212. return 0;
  213. }
  214. int
  215. Endpoint::osc_sig_disconnect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  216. {
  217. int their_id = argv[0]->i;
  218. int our_id = argv[1]->i;
  219. Endpoint *ep = (Endpoint*)user_data;
  220. Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
  221. if ( ! p )
  222. return 0;
  223. Signal *ps = ep->find_peer_signal_by_id( p, their_id );
  224. if ( ! ps )
  225. return 0;
  226. Signal *s = ep->find_signal_by_id( our_id );
  227. if ( ! s )
  228. return 0;
  229. if ( s->_direction == Signal::Input )
  230. {
  231. for ( std::list<Target*>::iterator i = s->_incoming.begin();
  232. i != s->_incoming.end();
  233. ++i )
  234. {
  235. if ( (*i)->peer == p &&
  236. (*i)->signal_id == ps->id() )
  237. {
  238. DMESSAGE( "Peer %s has disconnected from signal %s", p->name, ps->path() );
  239. delete *i;
  240. i = s->_incoming.erase( i );
  241. return 0;
  242. }
  243. }
  244. }
  245. return 0;
  246. }
  247. int
  248. Endpoint::osc_sig_connect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  249. {
  250. int their_id = argv[0]->i;
  251. int our_id = argv[1]->i;
  252. Endpoint *ep = (Endpoint*)user_data;
  253. Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
  254. if ( ! p )
  255. {
  256. WARNING( "Got connection signal from unknown peer" );
  257. return 0;
  258. }
  259. Signal *ps = ep->find_peer_signal_by_id( p, their_id );
  260. if ( ! ps )
  261. {
  262. WARNING( "Unknown source signal" );
  263. return 0;
  264. }
  265. Signal *s = ep->find_signal_by_id( our_id );
  266. if ( ! s )
  267. {
  268. WARNING( "Unknown destination signal" );
  269. return 0;
  270. }
  271. DMESSAGE( "Peer %s has connected to signal %s", p->name, s->path() );
  272. if ( s->_direction == Signal::Input )
  273. {
  274. Target *t = new Target;
  275. t->peer = p;
  276. t->signal_id = ps->id();
  277. s->_incoming.push_back( t );
  278. return 0;
  279. }
  280. return 0;
  281. }
  282. int
  283. Endpoint::osc_sig_renamed ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  284. {
  285. int id = argv[0]->i;
  286. char *new_name = &argv[1]->s;
  287. Endpoint *ep = (Endpoint*)user_data;
  288. Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
  289. if ( ! p )
  290. {
  291. WARNING( "Got signal rename notification from unknown peer." );
  292. return 0;
  293. }
  294. Signal *o = ep->find_peer_signal_by_id( p, id );
  295. if ( ! o )
  296. {
  297. WARNING( "Unknown signal id %i", id );
  298. return 0;
  299. }
  300. DMESSAGE( "Signal %s was renamed to %s" );
  301. free( o->_path );
  302. o->_path = strdup( new_name );
  303. return 0;
  304. }
  305. int
  306. Endpoint::osc_sig_handler ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  307. {
  308. Signal *o;
  309. float f = 0.0;
  310. if ( !strcmp( path, "/signal/change" ) && !strcmp( types, "if" ) )
  311. {
  312. /* accept a value for numbered signal */
  313. int id = argv[0]->i;
  314. f = argv[1]->f;
  315. o = ((Endpoint*)user_data)->find_signal_by_id( id );
  316. if ( ! o )
  317. {
  318. WARNING( "Unknown signal id %i", id );
  319. return 0;
  320. }
  321. }
  322. else if ( ! strcmp( types, "f" ) )
  323. {
  324. /* accept a value for signal named in path */
  325. o = (Signal*)user_data;
  326. f = argv[0]->f;
  327. }
  328. else if ( ! types || 0 == types[0] )
  329. {
  330. /* reply with current value */
  331. o = (Signal*)user_data;
  332. o->_endpoint->send( lo_message_get_source( msg ), "/reply", path, o->value() );
  333. }
  334. else
  335. {
  336. return -1;
  337. }
  338. Target *t = NULL;
  339. if ( 0 == o->_incoming.size() ||
  340. ! ( t = find_target_by_peer_address( &o->_incoming, lo_message_get_source( msg ) ) ) )
  341. {
  342. /* message came from an unconnected peer, just set the value exactly */
  343. }
  344. else
  345. {
  346. /* message is from a connected source, do mixing. */
  347. t->value = f;
  348. f = 0.0;
  349. for ( std::list<Target*>::const_iterator i = o->_incoming.begin();
  350. i != o->_incoming.end();
  351. ++i )
  352. {
  353. f += (*i)->value;
  354. }
  355. }
  356. o->_value = f;
  357. o->_handler( f, o->_user_data );
  358. return 0;
  359. }
  360. int
  361. Endpoint::osc_generic ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  362. {
  363. // OSC_DMSG();
  364. if ( argc || path[ strlen(path) - 1 ] != '/' )
  365. return -1;
  366. Endpoint *ep = (Endpoint*)user_data;
  367. for ( std::list<Method*>::const_iterator i = ep->_methods.begin(); i != ep->_methods.end(); ++i )
  368. {
  369. if ( ! (*i)->path() )
  370. continue;
  371. if (! strncmp( (*i)->path(), path, strlen(path) ) )
  372. {
  373. /* asprintf( &stored_path, "%s (%s); %s", path, typespec, argument_description ); */
  374. ((Endpoint*)user_data)->send( lo_message_get_source( msg ), "/reply", path, (*i)->path() );
  375. }
  376. }
  377. ((Endpoint*)user_data)->send( lo_message_get_source( msg ), "/reply", path );
  378. return 0;
  379. }
  380. int
  381. Endpoint::osc_signal_lister ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  382. {
  383. // OSC_DMSG();
  384. const char *prefix = NULL;
  385. if ( argc )
  386. prefix = &argv[0]->s;
  387. Endpoint *ep = (Endpoint*)user_data;
  388. for ( std::list<Signal*>::const_iterator i = ep->_signals.begin(); i != ep->_signals.end(); ++i )
  389. {
  390. Signal *o = *i;
  391. if ( ! prefix || ! strncmp( o->path(), prefix, strlen(prefix) ) )
  392. {
  393. ep->send( lo_message_get_source( msg ),
  394. "/reply",
  395. path,
  396. o->path(),
  397. o->_direction == Signal::Input ? "in" : "out",
  398. o->id(),
  399. o->parameter_limits().min,
  400. o->parameter_limits().max,
  401. o->parameter_limits().default_value
  402. );
  403. }
  404. }
  405. ep->send( lo_message_get_source( msg ), "/reply", path );
  406. return 0;
  407. }
  408. bool
  409. Endpoint::address_matches ( lo_address addr1, lo_address addr2 )
  410. {
  411. char *purl = strdup( lo_address_get_port( addr1 ) );
  412. char *url = strdup( lo_address_get_port( addr2 ) );
  413. bool r = !strcmp( purl, url );
  414. free( purl );
  415. free( url );
  416. return r;
  417. }
  418. void
  419. Endpoint::list_peers ( void (*callback) (const char *, const OSC::Signal *, void * ), void *v )
  420. {
  421. for ( std::list<Peer*>::iterator i = _peers.begin();
  422. i != _peers.end();
  423. ++i )
  424. {
  425. for ( std::list<Signal*>::iterator j = (*i)->_signals.begin();
  426. j != (*i)->_signals.end();
  427. ++j )
  428. {
  429. // DMESSAGE( "Running callback" );
  430. callback( (*i)->name, *j, v );
  431. }
  432. }
  433. }
  434. Peer *
  435. Endpoint::find_peer_by_address ( lo_address addr )
  436. {
  437. char *url = strdup( lo_address_get_port( addr ) );
  438. Peer *p = NULL;
  439. for ( std::list<Peer*>::iterator i = _peers.begin();
  440. i != _peers.end();
  441. ++i )
  442. {
  443. char *purl = strdup( lo_address_get_port( (*i)->addr ) );
  444. if ( !strcmp( purl, url ) )
  445. {
  446. free( purl );
  447. p = *i;
  448. break;
  449. }
  450. free(purl);
  451. }
  452. free( url );
  453. return p;
  454. }
  455. Peer *
  456. Endpoint::find_peer_by_name ( const char *name )
  457. {
  458. for ( std::list<Peer*>::iterator i = _peers.begin();
  459. i != _peers.end();
  460. ++i )
  461. {
  462. if ( !strcmp( name, (*i)->name ) )
  463. {
  464. return *i;
  465. }
  466. }
  467. return NULL;
  468. }
  469. bool
  470. Endpoint::disconnect_signal( OSC::Signal *s, const char *peer_name, const char *signal_path )
  471. {
  472. if ( s->_direction == Signal::Output )
  473. {
  474. Peer *p = find_peer_by_name( peer_name );
  475. if ( ! p )
  476. return false;
  477. Signal *ps = find_peer_signal_by_path( p, signal_path );
  478. if ( ! ps )
  479. return false;
  480. MESSAGE( "Disconnecting signal output \"%s\" to %s:%i", s->path(), peer_name, ps->_id );
  481. for ( std::list<Target*>::iterator i = s->_outgoing.begin();
  482. i != s->_outgoing.end();
  483. ++i )
  484. {
  485. if ( (*i)->peer == p &&
  486. (*i)->signal_id == ps->id() )
  487. {
  488. send( p->addr, "/signal/disconnect",
  489. s->_id, /* our signal id */
  490. (*i)->signal_id /* their signal id */ );
  491. delete *i;
  492. i = s->_outgoing.erase( i );
  493. DMESSAGE( "Number of outgoing connections: %i", s->_outgoing.size() );
  494. return true;
  495. }
  496. }
  497. }
  498. return false;
  499. }
  500. bool
  501. Endpoint::connect_signal( OSC::Signal *s, const char *peer_name, const char *signal_path )
  502. {
  503. if ( s->_direction == Signal::Output )
  504. {
  505. Peer *p = find_peer_by_name( peer_name );
  506. if ( ! p )
  507. return false;
  508. Signal *ps = find_peer_signal_by_path( p, signal_path );
  509. if ( ! ps )
  510. return false;
  511. if ( s->is_connected_to( ps ) )
  512. {
  513. return false;
  514. }
  515. MESSAGE( "Connecting signal output \"%s\" to %s:%i", s->path(), peer_name, ps->_id );
  516. Target *t = new Target();
  517. t->peer = p;
  518. t->signal_id = ps->_id;
  519. s->_outgoing.push_back( t );
  520. send( p->addr, "/signal/connect",
  521. s->_id, /* our signal id */
  522. t->signal_id /* their signal id */ );
  523. return true;
  524. }
  525. return false;
  526. }
  527. bool
  528. Endpoint::connect_signal( OSC::Signal *s, const char *peer_name, int signal_id )
  529. {
  530. if ( s->_direction == Signal::Output )
  531. {
  532. Peer *p = find_peer_by_name( peer_name );
  533. if ( !p )
  534. return false;
  535. MESSAGE( "Connecting signal output \"%s\" to %s:%i", s->path(), peer_name, signal_id );
  536. if ( p )
  537. {
  538. Target *t = new Target();
  539. t->peer = p;
  540. t->signal_id = signal_id;
  541. s->_outgoing.push_back( t );
  542. send( p->addr, "/signal/connect",
  543. s->_id, /* our signal id */
  544. t->signal_id /* their signal id */ );
  545. return true;
  546. }
  547. }
  548. return false;
  549. }
  550. Signal *
  551. Signal::get_peer_signal_by_id ( Peer *p, int signal_id )
  552. {
  553. for ( std::list<Signal *>::iterator i = p->_signals.begin();
  554. i != p->_signals.end();
  555. ++i )
  556. {
  557. if ( (*i)->_id == signal_id )
  558. return *i;
  559. }
  560. return NULL;
  561. }
  562. int
  563. Endpoint::osc_reply ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  564. {
  565. Endpoint *ep = (Endpoint*)user_data;
  566. if ( argc && !strcmp( &argv[0]->s, "/signal/list" ) )
  567. {
  568. Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
  569. if ( ! p )
  570. {
  571. WARNING( "Got input list reply from unknown peer." );
  572. return 0;
  573. }
  574. if ( argc == 1 )
  575. {
  576. p->_scanning = false;
  577. DMESSAGE( "Done scanning %s", p->name );
  578. }
  579. else if ( p->_scanning )
  580. {
  581. DMESSAGE( "Peer %s has signal %s", p->name, &argv[1]->s );
  582. int dir = 0;
  583. if ( !strcmp( &argv[2]->s, "in" ) )
  584. dir = Signal::Input;
  585. else if ( !strcmp( &argv[2]->s, "out" ) )
  586. dir = Signal::Output;
  587. Signal *s = new Signal( &argv[1]->s, (Signal::Direction)dir );
  588. s->_peer = p;
  589. s->_id = argv[3]->i;
  590. s->parameter_limits().min = argv[4]->f;
  591. s->parameter_limits().max = argv[5]->f;
  592. s->parameter_limits().default_value = argv[6]->f;
  593. p->_signals.push_back( s );
  594. }
  595. return 0;
  596. }
  597. else
  598. return -1;
  599. }
  600. Method *
  601. Endpoint::add_method ( const char *path, const char *typespec, lo_method_handler handler, void *user_data, const char *argument_description )
  602. {
  603. // DMESSAGE( "Added OSC method %s (%s)", path, typespec );
  604. lo_server_add_method( _server, path, typespec, handler, user_data );
  605. Method *md = new Method;
  606. if ( path )
  607. md->_path = strdup( path );
  608. if ( typespec )
  609. md->_typespec = strdup( typespec );
  610. if ( argument_description )
  611. md->_documentation = strdup( argument_description );
  612. if ( typespec )
  613. md->_parameter_limits = new Parameter_Limits[strlen(typespec)];
  614. _methods.push_back( md );
  615. return md;
  616. }
  617. Signal *
  618. Endpoint::add_signal ( const char *path, Signal::Direction dir, signal_handler handler, void *user_data )
  619. {
  620. Signal *md = new Signal( path, dir );
  621. if ( path )
  622. md->_path = strdup( path );
  623. md->_handler = handler;
  624. md->_user_data = user_data;
  625. md->_endpoint = this;
  626. _signals.push_back( md );
  627. if ( dir == Signal::Input )
  628. {
  629. lo_server_add_method( _server, path, NULL, osc_sig_handler, md );
  630. }
  631. return md;
  632. }
  633. void
  634. Endpoint::del_method ( const char *path, const char *typespec )
  635. {
  636. // DMESSAGE( "Deleted OSC method %s (%s)", path, typespec );
  637. lo_server_del_method( _server, path, typespec );
  638. for ( std::list<Method *>::iterator i = _methods.begin(); i != _methods.end(); ++i )
  639. {
  640. if ( ! (*i)->path() )
  641. continue;
  642. if ( ! strcmp( path, (*i)->path() ) &&
  643. ! strcmp( typespec, (*i)->typespec() ) )
  644. {
  645. delete *i;
  646. i = _methods.erase( i );
  647. break;
  648. }
  649. }
  650. }
  651. void
  652. Endpoint::del_method ( Method *meth )
  653. {
  654. // DMESSAGE( "Deleted OSC method %s (%s)", path, typespec );
  655. lo_server_del_method( _server, meth->path(), meth->typespec() );
  656. delete meth;
  657. _methods.remove( meth );
  658. }
  659. void
  660. Endpoint::del_signal ( Signal *o )
  661. {
  662. // DMESSAGE( "Deleted OSC method %s (%s)", path, typespec );
  663. lo_server_del_method( _server, o->path(), "f" );
  664. // delete o;
  665. _signals.remove( o );
  666. }
  667. void
  668. Endpoint::scan_peer ( const char *name, const char *url )
  669. {
  670. Peer *p = new Peer;
  671. DMESSAGE( "Scanning peer %s @ %s...", name, url );
  672. p->name = strdup( name );
  673. p->addr = lo_address_new_from_url( url );
  674. p->_scanning = true;
  675. _peers.push_back( p );
  676. send( p->addr, "/signal/list" );
  677. }
  678. void *
  679. Endpoint::osc_thread ( void * arg )
  680. {
  681. ((Endpoint*)arg)->osc_thread();
  682. return NULL;
  683. }
  684. void
  685. Endpoint::osc_thread ( void )
  686. {
  687. _thread.name( "OSC" );
  688. DMESSAGE( "OSC Thread running" );
  689. run();
  690. }
  691. void
  692. Endpoint::start ( void )
  693. {
  694. if ( !_thread.clone( &Endpoint::osc_thread, this ) )
  695. FATAL( "Could not create OSC thread" );
  696. /* lo_server_thread_start( _st ); */
  697. }
  698. void
  699. Endpoint::stop ( void )
  700. {
  701. _thread.join();
  702. // lo_server_thread_stop( _st );
  703. }
  704. int
  705. Endpoint::port ( void ) const
  706. {
  707. return lo_server_get_port( _server );
  708. }
  709. char *
  710. Endpoint::url ( void ) const
  711. {
  712. return lo_server_get_url( _server );
  713. }
  714. /** Process any waiting events and return immediately */
  715. void
  716. Endpoint::check ( void ) const
  717. {
  718. wait( 0 );
  719. }
  720. /** Process any waiting events and return after timeout */
  721. void
  722. Endpoint::wait ( int timeout ) const
  723. {
  724. if ( lo_server_wait( _server, timeout ) )
  725. while ( lo_server_recv_noblock( _server, 0 ) ) { }
  726. }
  727. /** Process events forever */
  728. void
  729. Endpoint::run ( void ) const
  730. {
  731. for ( ;; )
  732. {
  733. lo_server_recv( _server );
  734. }
  735. }
  736. int
  737. Endpoint::send ( lo_address to, const char *path, std::list< OSC_Value > values )
  738. {
  739. lo_message m = lo_message_new();
  740. for ( std::list< OSC_Value >::const_iterator i = values.begin();
  741. i != values.end();
  742. ++i )
  743. {
  744. const OSC_Value *ov = &(*i);
  745. switch ( ov->type() )
  746. {
  747. case 'f':
  748. DMESSAGE( "Adding float %f", ((OSC_Float*)ov)->value() );
  749. lo_message_add_float( m, ((OSC_Float*)ov)->value() );
  750. break;
  751. case 'i':
  752. DMESSAGE( "Adding int %i", ((OSC_Int*)ov)->value() );
  753. lo_message_add_int32( m, ((OSC_Int*)ov)->value() );
  754. break;
  755. case 's':
  756. DMESSAGE( "Adding string %s", ((OSC_String*)ov)->value() );
  757. lo_message_add_string( m, ((OSC_String*)ov)->value() );
  758. break;
  759. default:
  760. FATAL( "Unknown format: %c", ov->type() );
  761. break;
  762. }
  763. }
  764. DMESSAGE( "Path: %s", path );
  765. lo_bundle b = lo_bundle_new( LO_TT_IMMEDIATE );
  766. lo_bundle_add_message(b, path, m );
  767. int r = lo_send_bundle_from( to, _server, b );
  768. // int r = lo_send_message_from( to, _server, path, m );
  769. // lo_message_free( m );
  770. return r;
  771. }
  772. int
  773. Endpoint::send ( lo_address to, const char *path )
  774. {
  775. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "" );
  776. }
  777. int
  778. Endpoint::send ( lo_address to, const char *path, int v )
  779. {
  780. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "i", v );
  781. }
  782. int
  783. Endpoint::send ( lo_address to, const char *path, float v )
  784. {
  785. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "f", v );
  786. }
  787. int
  788. Endpoint::send ( lo_address to, const char *path, double v )
  789. {
  790. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "d", v );
  791. }
  792. int
  793. Endpoint::send ( lo_address to, const char *path, const char * v )
  794. {
  795. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "s", v );
  796. }
  797. int
  798. Endpoint::send ( lo_address to, const char *path, const char * v1, float v2 )
  799. {
  800. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sf", v1, v2 );
  801. }
  802. int
  803. Endpoint::send ( lo_address to, const char *path, const char * v1, const char *v2 )
  804. {
  805. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ss", v1, v2 );
  806. }
  807. int
  808. Endpoint::send ( lo_address to, const char *path, const char * v1, const char *v2, const char *v3 )
  809. {
  810. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sss", v1, v2, v3 );
  811. }
  812. int
  813. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, int v3, int v4 )
  814. {
  815. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "siii", v1, v2, v3, v4 );
  816. }
  817. int
  818. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, int v3, int v4, int v5 )
  819. {
  820. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ssiii", v1, v2, v3, v4, v5 );
  821. }
  822. int
  823. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, int v4, int v5, int v6 )
  824. {
  825. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sssiii", v1, v2, v3, v4, v5, v6 );
  826. }
  827. int
  828. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2 )
  829. {
  830. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "si", v1, v2 );
  831. }
  832. int
  833. Endpoint::send ( lo_address to, const char *path, int v1, const char *v2 )
  834. {
  835. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "is", v1, v2 );
  836. }
  837. int
  838. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, const char *v3 )
  839. {
  840. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sis", v1, v2, v3 );
  841. }
  842. int
  843. Endpoint::send ( lo_address to, const char *path, int v1, const char *v2, const char *v3, const char *v4 )
  844. {
  845. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "isss", v1, v2, v3, v4 );
  846. }
  847. int
  848. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, const char *v3, const char *v4, const char *v5 )
  849. {
  850. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sisss", v1, v2, v3, v4, v5 );
  851. }
  852. int
  853. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, const char *v4, const char *v5 )
  854. {
  855. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sssss", v1, v2, v3, v4, v5 );
  856. }
  857. int
  858. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, const char *v4 )
  859. {
  860. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ssss", v1, v2, v3, v4 );
  861. }
  862. int
  863. Endpoint::send ( lo_address to, const char *path, lo_message msg )
  864. {
  865. return lo_send_message_from( to, _server, path, msg );
  866. }
  867. int
  868. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, int v3, float v4, float v5, float v6 )
  869. {
  870. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ssifff", v1, v2, v3, v4, v5, v6 );
  871. }
  872. int
  873. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, int v4, float v5, float v6, float v7 )
  874. {
  875. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sssifff", v1, v2, v3, v4, v5, v6, 7 );
  876. }
  877. int
  878. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, int v3 )
  879. {
  880. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sii", v1, v2, v3 );
  881. }
  882. int
  883. Endpoint::send ( lo_address to, const char *path, int v1, int v2 )
  884. {
  885. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ii", v1, v2 );
  886. }
  887. int
  888. Endpoint::send ( lo_address to, const char *path, int v1, float v2 )
  889. {
  890. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "if", v1, v2 );
  891. }
  892. }