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.

264 lines
6.7KB

  1. /*******************************************************************************/
  2. /* Copyright (C) 2008 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 "Client.H"
  19. #include "Port.H"
  20. #include <algorithm>
  21. namespace JACK
  22. {
  23. nframes_t Client::_sample_rate = 0;
  24. Client::Client ( )
  25. {
  26. _freewheeling = false;
  27. _zombified = false;
  28. _client = NULL;
  29. _xruns = 0;
  30. }
  31. Client::~Client ( )
  32. {
  33. jack_client_close( _client );
  34. }
  35. /** Tell JACK to stop calling process callback. This MUST be called in
  36. * an inheriting class' destructor */
  37. void
  38. Client::deactivate ( )
  39. {
  40. jack_deactivate( _client );
  41. }
  42. /*******************/
  43. /* Static Wrappers */
  44. /*******************/
  45. int
  46. Client::process ( nframes_t nframes, void *arg )
  47. {
  48. return ((Client*)arg)->process( nframes );
  49. }
  50. int
  51. Client::sync ( jack_transport_state_t state, jack_position_t *pos, void *arg )
  52. {
  53. return ((Client*)arg)->sync( state, pos );
  54. }
  55. int
  56. Client::xrun ( void *arg )
  57. {
  58. ++((Client*)arg)->_xruns;
  59. return ((Client*)arg)->xrun();
  60. }
  61. void
  62. Client::timebase ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t *pos, int new_pos, void *arg )
  63. {
  64. ((Client*)arg)->timebase( state, nframes, pos, new_pos );
  65. }
  66. void
  67. Client::freewheel ( int starting, void *arg )
  68. {
  69. ((Client*)arg)->_freewheeling = starting;
  70. ((Client*)arg)->freewheel( starting );
  71. }
  72. int
  73. Client::buffer_size ( nframes_t nframes, void *arg )
  74. {
  75. return ((Client*)arg)->buffer_size( nframes );
  76. }
  77. void
  78. Client::thread_init ( void *arg )
  79. {
  80. ((Client*)arg)->thread_init();
  81. }
  82. void
  83. Client::shutdown ( void *arg )
  84. {
  85. ((Client*)arg)->_zombified = true;
  86. ((Client*)arg)->shutdown();
  87. }
  88. void
  89. Client::port_connect ( jack_port_id_t a, jack_port_id_t b, int connect, void *arg )
  90. {
  91. ((Client*)arg)->port_connect( a, b, connect );
  92. }
  93. /** Connect to JACK using client name /client_name/. Return a static
  94. * pointer to actual name as reported by JACK */
  95. const char *
  96. Client::init ( const char *client_name, unsigned int opts )
  97. {
  98. if (( _client = jack_client_open ( client_name, (jack_options_t)0, NULL )) == 0 )
  99. return NULL;
  100. #define set_callback( name ) jack_set_ ## name ## _callback( _client, &Client:: name , this )
  101. set_callback( thread_init );
  102. set_callback( process );
  103. set_callback( xrun );
  104. set_callback( freewheel );
  105. set_callback( buffer_size );
  106. set_callback( port_connect );
  107. /* FIXME: should we wait to register this until after the project
  108. has been loaded (and we have disk threads running)? */
  109. if ( opts & SLOW_SYNC )
  110. set_callback( sync );
  111. if ( opts & TIMEBASE_MASTER )
  112. jack_set_timebase_callback( _client, 0, &Client::timebase, this );
  113. jack_on_shutdown( _client, &Client::shutdown, this );
  114. jack_activate( _client );
  115. _sample_rate = frame_rate();
  116. return jack_get_client_name( _client );
  117. }
  118. /* THREAD: RT */
  119. /** enter or leave freehweeling mode */
  120. void
  121. Client::freewheeling ( bool yes )
  122. {
  123. if ( jack_set_freewheel( _client, yes ) )
  124. ;
  125. // WARNING( "Unkown error while setting freewheeling mode" );
  126. }
  127. void
  128. Client::port_added ( Port *p )
  129. {
  130. std::list < JACK::Port * >::iterator i = std::find( _active_ports.begin(), _active_ports.end(), p );
  131. if ( i != _active_ports.end() )
  132. return;
  133. _active_ports.push_back( p );
  134. }
  135. void
  136. Client::port_removed ( Port *p )
  137. {
  138. _active_ports.remove( p );
  139. }
  140. void
  141. Client::freeze_ports ( void )
  142. {
  143. for ( std::list < JACK::Port * >::iterator i = _active_ports.begin();
  144. i != _active_ports.end();
  145. ++i )
  146. {
  147. (*i)->freeze();
  148. }
  149. }
  150. void
  151. Client::thaw_ports ( void )
  152. {
  153. /* Sort ports for the sake of clients (e.g. patchage), for
  154. * whom the order of creation may matter (for display) */
  155. _active_ports.sort();
  156. for ( std::list < JACK::Port * >::iterator i = _active_ports.begin();
  157. i != _active_ports.end();
  158. ++i )
  159. {
  160. (*i)->thaw();
  161. }
  162. }
  163. void
  164. Client::close ( void )
  165. {
  166. jack_deactivate( _client );
  167. jack_client_close( _client );
  168. _client = NULL;
  169. }
  170. const char *
  171. Client::name ( const char *s )
  172. {
  173. /* Because the JACK API does not provide a mechanism for renaming
  174. * clients, we have to save connections, destroy our client,
  175. * create a client with the new name, and restore our
  176. * connections. Lovely. */
  177. freeze_ports();
  178. jack_deactivate( _client );
  179. jack_client_close( _client );
  180. _client = NULL;
  181. s = init( s );
  182. thaw_ports();
  183. return s;
  184. }
  185. void
  186. Client::transport_stop ( )
  187. {
  188. jack_transport_stop( _client );
  189. }
  190. void
  191. Client::transport_start ( )
  192. {
  193. jack_transport_start( _client );
  194. }
  195. void
  196. Client::transport_locate ( nframes_t frame )
  197. {
  198. jack_transport_locate( _client, frame );
  199. }
  200. jack_transport_state_t
  201. Client::transport_query ( jack_position_t *pos )
  202. {
  203. return jack_transport_query( _client, pos );
  204. }
  205. }