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.

882 lines
24KB

  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. void
  47. Signal::value ( float f )
  48. {
  49. for ( std::list<Target*>::const_iterator i = _outgoing.begin();
  50. i != _outgoing.end();
  51. ++i )
  52. {
  53. // DMESSAGE( "Sending signal value %i %f", (*i)->signal_id, f );
  54. if ( (*i)->value != f )
  55. {
  56. (*i)->value = f;
  57. _endpoint->send( (*i)->peer->addr,
  58. "/signal/change",
  59. (*i)->signal_id,
  60. f );
  61. }
  62. }
  63. }
  64. void
  65. Signal::get_connected_peer_name_and_path ( char **peer_name, char **path )
  66. {
  67. Target *t = _outgoing.back();
  68. Signal *s = get_peer_signal_by_id( t->peer, t->signal_id );
  69. *peer_name = strdup( t->peer->name );
  70. *path = strdup( s->path() );
  71. }
  72. void
  73. Endpoint::error_handler(int num, const char *msg, const char *path)
  74. {
  75. WARNING( "LibLO server error %d in path %s: %s\n", num, path, msg);
  76. }
  77. Endpoint::Endpoint ( )
  78. {
  79. }
  80. int
  81. Endpoint::init ( int proto, const char *port )
  82. {
  83. DMESSAGE( "Creating OSC server" );
  84. _server = lo_server_new_with_proto( port, proto, error_handler );
  85. if ( ! _server )
  86. {
  87. WARNING( "Error creating OSC server" );
  88. return -1;
  89. }
  90. add_method( "/signal/change", "if", &Endpoint::osc_sig_handler, this, "" );
  91. add_method( NULL, "", &Endpoint::osc_generic, this, "" );
  92. add_method( NULL, NULL, &Endpoint::osc_signal_lister, this, "" );
  93. add_method( "/reply", NULL, &Endpoint::osc_reply, this, "" );
  94. return 0;
  95. }
  96. Endpoint::~Endpoint ( )
  97. {
  98. // lo_server_thread_free( _st );
  99. lo_server_free( _server );
  100. }
  101. OSC::Target *
  102. Endpoint::find_target_by_peer_address ( std::list<Target*> *l, lo_address addr )
  103. {
  104. for ( std::list<Target*>::iterator i = l->begin();
  105. i != l->end();
  106. ++i )
  107. {
  108. if ( address_matches( addr, (*i)->peer->addr ) )
  109. {
  110. return *i;
  111. }
  112. }
  113. return NULL;
  114. }
  115. OSC::Signal *
  116. Endpoint::find_signal_by_id ( int id )
  117. {
  118. for ( std::list<Signal*>::iterator i = _signals.begin();
  119. i != _signals.end();
  120. ++i )
  121. {
  122. if ( (*i)->id() == id )
  123. return *i;
  124. }
  125. return NULL;
  126. }
  127. OSC::Signal *
  128. Endpoint::find_peer_signal_by_path ( Peer *p, const char *path )
  129. {
  130. for ( std::list<Signal*>::iterator i = p->_signals.begin();
  131. i != p->_signals.end();
  132. ++i )
  133. {
  134. if ( !strcmp( (*i)->path(), path ) )
  135. return *i;
  136. }
  137. return NULL;
  138. }
  139. int
  140. Endpoint::osc_sig_handler ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  141. {
  142. Signal *o;
  143. float f = 0.0;
  144. if ( !strcmp( path, "/signal/change" ) && !strcmp( types, "if" ) )
  145. {
  146. /* accept a value for numbered signal */
  147. int id = argv[0]->i;
  148. f = argv[1]->f;
  149. o = ((Endpoint*)user_data)->find_signal_by_id( id );
  150. if ( ! o )
  151. {
  152. WARNING( "Unknown signal id %i", id );
  153. return 0;
  154. }
  155. }
  156. else if ( ! strcmp( types, "f" ) )
  157. {
  158. /* accept a value for signal named in path */
  159. o = (Signal*)user_data;
  160. f = argv[0]->f;
  161. }
  162. else if ( ! types || 0 == types[0] )
  163. {
  164. /* reply with current value */
  165. o = (Signal*)user_data;
  166. o->_endpoint->send( lo_message_get_source( msg ), "/reply", path, o->value() );
  167. }
  168. else
  169. {
  170. return -1;
  171. }
  172. Target *t = NULL;
  173. if ( 0 == o->_incoming.size() ||
  174. ! ( t = find_target_by_peer_address( &o->_incoming, lo_message_get_source( msg ) ) ) )
  175. {
  176. /* message came from an unconnected peer, just set the value exactly */
  177. }
  178. else
  179. {
  180. /* message is from a connected source, do mixing. */
  181. t->value = f;
  182. f = 0.0;
  183. for ( std::list<Target*>::const_iterator i = o->_incoming.begin();
  184. i != o->_incoming.end();
  185. ++i )
  186. {
  187. f += (*i)->value;
  188. }
  189. }
  190. o->_value = f;
  191. o->_handler( f, o->_user_data );
  192. return 0;
  193. }
  194. int
  195. Endpoint::osc_generic ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  196. {
  197. // OSC_DMSG();
  198. if ( argc || path[ strlen(path) - 1 ] != '/' )
  199. return -1;
  200. Endpoint *ep = (Endpoint*)user_data;
  201. for ( std::list<Method*>::const_iterator i = ep->_methods.begin(); i != ep->_methods.end(); ++i )
  202. {
  203. if ( ! (*i)->path() )
  204. continue;
  205. if (! strncmp( (*i)->path(), path, strlen(path) ) )
  206. {
  207. /* asprintf( &stored_path, "%s (%s); %s", path, typespec, argument_description ); */
  208. ((Endpoint*)user_data)->send( lo_message_get_source( msg ), "/reply", path, (*i)->path() );
  209. }
  210. }
  211. ((Endpoint*)user_data)->send( lo_message_get_source( msg ), "/reply", path );
  212. return 0;
  213. }
  214. int
  215. Endpoint::osc_signal_lister ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  216. {
  217. // OSC_DMSG();
  218. Signal::Direction dir;
  219. if ( ! strcmp( path, "/signal/list_inputs" ) )
  220. {
  221. dir = Signal::Input;
  222. }
  223. else if ( ! strcmp( path, "/signal/list_outputs" ) )
  224. {
  225. dir = Signal::Output;
  226. }
  227. else
  228. return -1;
  229. const char *prefix = NULL;
  230. if ( argc )
  231. prefix = &argv[0]->s;
  232. Endpoint *ep = (Endpoint*)user_data;
  233. for ( std::list<Signal*>::const_iterator i = ep->_signals.begin(); i != ep->_signals.end(); ++i )
  234. {
  235. Signal *o = *i;
  236. if ( dir == Signal::Bidirectional ||
  237. dir == o->_direction )
  238. {
  239. if ( ! prefix || ! strncmp( o->path(), prefix, strlen(prefix) ) )
  240. {
  241. ep->send( lo_message_get_source( msg ),
  242. "/reply",
  243. path,
  244. o->path(),
  245. o->id(),
  246. o->parameter_limits().min,
  247. o->parameter_limits().max,
  248. o->parameter_limits().default_value
  249. );
  250. }
  251. }
  252. }
  253. ep->send( lo_message_get_source( msg ), "/reply", path );
  254. return 0;
  255. }
  256. bool
  257. Endpoint::address_matches ( lo_address addr1, lo_address addr2 )
  258. {
  259. char *purl = strdup( lo_address_get_port( addr1 ) );
  260. char *url = strdup( lo_address_get_port( addr2 ) );
  261. bool r = !strcmp( purl, url );
  262. free( purl );
  263. free( url );
  264. return r;
  265. }
  266. void
  267. Endpoint::list_peers ( void (*callback) (const char *, const char *, int, void * ), void *v )
  268. {
  269. for ( std::list<Peer*>::iterator i = _peers.begin();
  270. i != _peers.end();
  271. ++i )
  272. {
  273. for ( std::list<Signal*>::iterator j = (*i)->_signals.begin();
  274. j != (*i)->_signals.end();
  275. ++j )
  276. {
  277. // DMESSAGE( "Running callback" );
  278. callback( (*i)->name, (*j)->path(), (*j)->id(), v );
  279. }
  280. }
  281. }
  282. Peer *
  283. Endpoint::find_peer_by_address ( lo_address addr )
  284. {
  285. char *url = strdup( lo_address_get_port( addr ) );
  286. Peer *p = NULL;
  287. for ( std::list<Peer*>::iterator i = _peers.begin();
  288. i != _peers.end();
  289. ++i )
  290. {
  291. char *purl = strdup( lo_address_get_port( (*i)->addr ) );
  292. if ( !strcmp( purl, url ) )
  293. {
  294. free( purl );
  295. p = *i;
  296. break;
  297. }
  298. free(purl);
  299. }
  300. free( url );
  301. return p;
  302. }
  303. Peer *
  304. Endpoint::find_peer_by_name ( const char *name )
  305. {
  306. for ( std::list<Peer*>::iterator i = _peers.begin();
  307. i != _peers.end();
  308. ++i )
  309. {
  310. if ( !strcmp( name, (*i)->name ) )
  311. {
  312. return *i;
  313. }
  314. }
  315. return NULL;
  316. }
  317. bool
  318. Endpoint::connect_signal( OSC::Signal *s, const char *peer_name, const char *signal_path )
  319. {
  320. if ( s->_direction == Signal::Output )
  321. {
  322. Peer *p = find_peer_by_name( peer_name );
  323. if ( ! p )
  324. return false;
  325. Signal *ps = find_peer_signal_by_path( p, signal_path );
  326. if ( ! ps )
  327. return false;
  328. MESSAGE( "Connecting signal output \"%s\" to %s:%i", s->path(), peer_name, s->_id );
  329. if ( p )
  330. {
  331. Target *t = new Target();
  332. t->peer = p;
  333. t->signal_id = ps->_id;
  334. s->_outgoing.push_back( t );
  335. send( p->addr, "/signal/connect",
  336. s->_id, /* our signal id */
  337. t->signal_id /* their signal id */ );
  338. return true;
  339. }
  340. }
  341. return false;
  342. }
  343. bool
  344. Endpoint::connect_signal( OSC::Signal *s, const char *peer_name, int signal_id )
  345. {
  346. if ( s->_direction == Signal::Output )
  347. {
  348. Peer *p = find_peer_by_name( peer_name );
  349. if ( !p )
  350. return false;
  351. MESSAGE( "Connecting signal output \"%s\" to %s:%i", s->path(), peer_name, signal_id );
  352. if ( p )
  353. {
  354. Target *t = new Target();
  355. t->peer = p;
  356. t->signal_id = signal_id;
  357. s->_outgoing.push_back( t );
  358. send( p->addr, "/signal/connect",
  359. s->_id, /* our signal id */
  360. t->signal_id /* their signal id */ );
  361. return true;
  362. }
  363. }
  364. return false;
  365. }
  366. Signal *
  367. Signal::get_peer_signal_by_id ( Peer *p, int signal_id )
  368. {
  369. for ( std::list<Signal *>::iterator i = p->_signals.begin();
  370. i != p->_signals.end();
  371. ++i )
  372. {
  373. if ( (*i)->_id == signal_id )
  374. return *i;
  375. }
  376. return NULL;
  377. }
  378. int
  379. Endpoint::osc_reply ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  380. {
  381. Endpoint *ep = (Endpoint*)user_data;
  382. if ( argc && !strcmp( &argv[0]->s, "/signal/list_inputs" ) )
  383. {
  384. Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
  385. if ( ! p )
  386. {
  387. WARNING( "Got input list reply from unknown peer." );
  388. return 0;
  389. }
  390. if ( argc == 1 )
  391. {
  392. p->_scanning = false;
  393. DMESSAGE( "Done scanning %s", p->name );
  394. }
  395. else if ( p->_scanning )
  396. {
  397. DMESSAGE( "Peer %s has signal %s", p->name, &argv[1]->s );
  398. Signal *s = new Signal( &argv[1]->s, Signal::Input );
  399. s->_id = argv[2]->i;
  400. s->parameter_limits().min = argv[3]->f;
  401. s->parameter_limits().max = argv[4]->f;
  402. s->parameter_limits().default_value = argv[4]->f;
  403. p->_signals.push_back( s );
  404. }
  405. return 0;
  406. }
  407. else
  408. return -1;
  409. }
  410. Method *
  411. Endpoint::add_method ( const char *path, const char *typespec, lo_method_handler handler, void *user_data, const char *argument_description )
  412. {
  413. // DMESSAGE( "Added OSC method %s (%s)", path, typespec );
  414. lo_server_add_method( _server, path, typespec, handler, user_data );
  415. Method *md = new Method;
  416. if ( path )
  417. md->_path = strdup( path );
  418. if ( typespec )
  419. md->_typespec = strdup( typespec );
  420. if ( argument_description )
  421. md->_documentation = strdup( argument_description );
  422. if ( typespec )
  423. md->_parameter_limits = new Parameter_Limits[strlen(typespec)];
  424. _methods.push_back( md );
  425. return md;
  426. }
  427. Signal *
  428. Endpoint::add_signal ( const char *path, Signal::Direction dir, signal_handler handler, void *user_data )
  429. {
  430. Signal *md = new Signal( path, dir );
  431. if ( path )
  432. md->_path = strdup( path );
  433. md->_handler = handler;
  434. md->_user_data = user_data;
  435. md->_endpoint = this;
  436. _signals.push_back( md );
  437. if ( dir == Signal::Input )
  438. {
  439. lo_server_add_method( _server, path, NULL, osc_sig_handler, md );
  440. }
  441. return md;
  442. }
  443. void
  444. Endpoint::del_method ( const char *path, const char *typespec )
  445. {
  446. // DMESSAGE( "Deleted OSC method %s (%s)", path, typespec );
  447. lo_server_del_method( _server, path, typespec );
  448. for ( std::list<Method *>::iterator i = _methods.begin(); i != _methods.end(); ++i )
  449. {
  450. if ( ! (*i)->path() )
  451. continue;
  452. if ( ! strcmp( path, (*i)->path() ) &&
  453. ! strcmp( typespec, (*i)->typespec() ) )
  454. {
  455. delete *i;
  456. i = _methods.erase( i );
  457. break;
  458. }
  459. }
  460. }
  461. void
  462. Endpoint::del_method ( Method *meth )
  463. {
  464. // DMESSAGE( "Deleted OSC method %s (%s)", path, typespec );
  465. lo_server_del_method( _server, meth->path(), meth->typespec() );
  466. delete meth;
  467. _methods.remove( meth );
  468. }
  469. void
  470. Endpoint::del_signal ( Signal *o )
  471. {
  472. // DMESSAGE( "Deleted OSC method %s (%s)", path, typespec );
  473. lo_server_del_method( _server, o->path(), "f" );
  474. delete o;
  475. _signals.remove( o );
  476. }
  477. void
  478. Endpoint::scan_peer ( const char *name, const char *url )
  479. {
  480. Peer *p = new Peer;
  481. p->name = strdup( name );
  482. p->addr = lo_address_new_from_url( url );
  483. p->_scanning = true;
  484. _peers.push_back( p );
  485. send( p->addr, "/signal/list_inputs" );
  486. }
  487. void *
  488. Endpoint::osc_thread ( void * arg )
  489. {
  490. ((Endpoint*)arg)->osc_thread();
  491. return NULL;
  492. }
  493. void
  494. Endpoint::osc_thread ( void )
  495. {
  496. _thread.name( "OSC" );
  497. DMESSAGE( "OSC Thread running" );
  498. run();
  499. }
  500. void
  501. Endpoint::start ( void )
  502. {
  503. if ( !_thread.clone( &Endpoint::osc_thread, this ) )
  504. FATAL( "Could not create OSC thread" );
  505. /* lo_server_thread_start( _st ); */
  506. }
  507. void
  508. Endpoint::stop ( void )
  509. {
  510. _thread.join();
  511. // lo_server_thread_stop( _st );
  512. }
  513. int
  514. Endpoint::port ( void ) const
  515. {
  516. return lo_server_get_port( _server );
  517. }
  518. char *
  519. Endpoint::url ( void ) const
  520. {
  521. return lo_server_get_url( _server );
  522. }
  523. /** Process any waiting events and return immediately */
  524. void
  525. Endpoint::check ( void ) const
  526. {
  527. wait( 0 );
  528. }
  529. /** Process any waiting events and return after timeout */
  530. void
  531. Endpoint::wait ( int timeout ) const
  532. {
  533. if ( lo_server_wait( _server, timeout ) )
  534. while ( lo_server_recv_noblock( _server, 0 ) ) { }
  535. }
  536. /** Process events forever */
  537. void
  538. Endpoint::run ( void ) const
  539. {
  540. for ( ;; )
  541. {
  542. lo_server_recv( _server );
  543. }
  544. }
  545. int
  546. Endpoint::send ( lo_address to, const char *path, std::list< OSC_Value > values )
  547. {
  548. lo_message m = lo_message_new();
  549. for ( std::list< OSC_Value >::const_iterator i = values.begin();
  550. i != values.end();
  551. ++i )
  552. {
  553. const OSC_Value *ov = &(*i);
  554. switch ( ov->type() )
  555. {
  556. case 'f':
  557. DMESSAGE( "Adding float %f", ((OSC_Float*)ov)->value() );
  558. lo_message_add_float( m, ((OSC_Float*)ov)->value() );
  559. break;
  560. case 'i':
  561. DMESSAGE( "Adding int %i", ((OSC_Int*)ov)->value() );
  562. lo_message_add_int32( m, ((OSC_Int*)ov)->value() );
  563. break;
  564. case 's':
  565. DMESSAGE( "Adding string %s", ((OSC_String*)ov)->value() );
  566. lo_message_add_string( m, ((OSC_String*)ov)->value() );
  567. break;
  568. default:
  569. FATAL( "Unknown format: %c", ov->type() );
  570. break;
  571. }
  572. }
  573. DMESSAGE( "Path: %s", path );
  574. lo_bundle b = lo_bundle_new( LO_TT_IMMEDIATE );
  575. lo_bundle_add_message(b, path, m );
  576. int r = lo_send_bundle_from( to, _server, b );
  577. // int r = lo_send_message_from( to, _server, path, m );
  578. // lo_message_free( m );
  579. return r;
  580. }
  581. int
  582. Endpoint::send ( lo_address to, const char *path )
  583. {
  584. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "" );
  585. }
  586. int
  587. Endpoint::send ( lo_address to, const char *path, int v )
  588. {
  589. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "i", v );
  590. }
  591. int
  592. Endpoint::send ( lo_address to, const char *path, float v )
  593. {
  594. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "f", v );
  595. }
  596. int
  597. Endpoint::send ( lo_address to, const char *path, double v )
  598. {
  599. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "d", v );
  600. }
  601. int
  602. Endpoint::send ( lo_address to, const char *path, const char * v )
  603. {
  604. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "s", v );
  605. }
  606. int
  607. Endpoint::send ( lo_address to, const char *path, const char * v1, float v2 )
  608. {
  609. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sf", v1, v2 );
  610. }
  611. int
  612. Endpoint::send ( lo_address to, const char *path, const char * v1, const char *v2 )
  613. {
  614. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ss", v1, v2 );
  615. }
  616. int
  617. Endpoint::send ( lo_address to, const char *path, const char * v1, const char *v2, const char *v3 )
  618. {
  619. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sss", v1, v2, v3 );
  620. }
  621. int
  622. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, int v3, int v4 )
  623. {
  624. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "siii", v1, v2, v3, v4 );
  625. }
  626. int
  627. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, int v3, int v4, int v5 )
  628. {
  629. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ssiii", v1, v2, v3, v4, v5 );
  630. }
  631. int
  632. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, int v4, int v5, int v6 )
  633. {
  634. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sssiii", v1, v2, v3, v4, v5, v6 );
  635. }
  636. int
  637. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2 )
  638. {
  639. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "si", v1, v2 );
  640. }
  641. int
  642. Endpoint::send ( lo_address to, const char *path, int v1, const char *v2 )
  643. {
  644. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "is", v1, v2 );
  645. }
  646. int
  647. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, const char *v3 )
  648. {
  649. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sis", v1, v2, v3 );
  650. }
  651. int
  652. Endpoint::send ( lo_address to, const char *path, int v1, const char *v2, const char *v3, const char *v4 )
  653. {
  654. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "isss", v1, v2, v3, v4 );
  655. }
  656. int
  657. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, const char *v3, const char *v4, const char *v5 )
  658. {
  659. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sisss", v1, v2, v3, v4, v5 );
  660. }
  661. int
  662. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, const char *v4, const char *v5 )
  663. {
  664. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sssss", v1, v2, v3, v4, v5 );
  665. }
  666. int
  667. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, const char *v4 )
  668. {
  669. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ssss", v1, v2, v3, v4 );
  670. }
  671. int
  672. Endpoint::send ( lo_address to, const char *path, lo_message msg )
  673. {
  674. return lo_send_message_from( to, _server, path, msg );
  675. }
  676. int
  677. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, int v3, float v4, float v5, float v6 )
  678. {
  679. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ssifff", v1, v2, v3, v4, v5, v6 );
  680. }
  681. int
  682. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, int v3 )
  683. {
  684. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sii", v1, v2, v3 );
  685. }
  686. int
  687. Endpoint::send ( lo_address to, const char *path, int v1, int v2 )
  688. {
  689. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ii", v1, v2 );
  690. }
  691. int
  692. Endpoint::send ( lo_address to, const char *path, int v1, float v2 )
  693. {
  694. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "if", v1, v2 );
  695. }
  696. }