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.

215 lines
5.6KB

  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. Client::Client ( )
  24. {
  25. _freewheeling = false;
  26. _zombified = false;
  27. _client = NULL;
  28. _xruns = 0;
  29. }
  30. Client::~Client ( )
  31. {
  32. jack_client_close( _client );
  33. }
  34. /** Tell JACK to calling process callback. This MUST be called in
  35. * an inheriting class' destructor */
  36. void
  37. Client::deactivate ( )
  38. {
  39. jack_deactivate( _client );
  40. }
  41. /*******************/
  42. /* Static Wrappers */
  43. /*******************/
  44. int
  45. Client::process ( nframes_t nframes, void *arg )
  46. {
  47. return ((Client*)arg)->process( nframes );
  48. }
  49. int
  50. Client::sync ( jack_transport_state_t state, jack_position_t *pos, void *arg )
  51. {
  52. return ((Client*)arg)->sync( state, pos );
  53. }
  54. int
  55. Client::xrun ( void *arg )
  56. {
  57. ++((Client*)arg)->_xruns;
  58. return ((Client*)arg)->xrun();
  59. }
  60. void
  61. Client::timebase ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t *pos, int new_pos, void *arg )
  62. {
  63. ((Client*)arg)->timebase( state, nframes, pos, new_pos );
  64. }
  65. void
  66. Client::freewheel ( int starting, void *arg )
  67. {
  68. ((Client*)arg)->_freewheeling = starting;
  69. ((Client*)arg)->freewheel( starting );
  70. }
  71. int
  72. Client::buffer_size ( nframes_t nframes, void *arg )
  73. {
  74. return ((Client*)arg)->buffer_size( nframes );
  75. }
  76. void
  77. Client::thread_init ( void *arg )
  78. {
  79. ((Client*)arg)->thread_init();
  80. }
  81. void
  82. Client::shutdown ( void *arg )
  83. {
  84. ((Client*)arg)->_zombified = true;
  85. ((Client*)arg)->shutdown();
  86. }
  87. /** Connect to JACK using client name /client_name/. Return a static
  88. * pointer to actual name as reported by JACK */
  89. const char *
  90. Client::init ( const char *client_name )
  91. {
  92. if (( _client = jack_client_open ( client_name, (jack_options_t)0, NULL )) == 0 )
  93. return NULL;
  94. #define set_callback( name ) jack_set_ ## name ## _callback( _client, &Client:: name , this )
  95. set_callback( thread_init );
  96. set_callback( process );
  97. set_callback( xrun );
  98. set_callback( freewheel );
  99. set_callback( buffer_size );
  100. /* FIXME: should we wait to register this until after the project
  101. has been loaded (and we have disk threads running)? */
  102. set_callback( sync );
  103. jack_set_timebase_callback( _client, 0, &Client::timebase, this );
  104. jack_on_shutdown( _client, &Client::shutdown, this );
  105. jack_activate( _client );
  106. _sample_rate = frame_rate();
  107. return jack_get_client_name( _client );
  108. }
  109. /* THREAD: RT */
  110. /** enter or leave freehweeling mode */
  111. void
  112. Client::freewheeling ( bool yes )
  113. {
  114. if ( jack_set_freewheel( _client, yes ) )
  115. ;
  116. // WARNING( "Unkown error while setting freewheeling mode" );
  117. }
  118. void
  119. Client::port_added ( Port *p )
  120. {
  121. std::list < JACK::Port * >::iterator i = std::find( _active_ports.begin(), _active_ports.end(), p );
  122. if ( i != _active_ports.end() )
  123. return;
  124. _active_ports.push_back( p );
  125. }
  126. void
  127. Client::port_removed ( Port *p )
  128. {
  129. _active_ports.remove( p );
  130. }
  131. void
  132. Client::freeze_ports ( void )
  133. {
  134. for ( std::list < JACK::Port * >::iterator i = _active_ports.begin();
  135. i != _active_ports.end();
  136. ++i )
  137. {
  138. (*i)->freeze();
  139. }
  140. }
  141. void
  142. Client::thaw_ports ( void )
  143. {
  144. for ( std::list < JACK::Port * >::iterator i = _active_ports.begin();
  145. i != _active_ports.end();
  146. ++i )
  147. {
  148. (*i)->thaw();
  149. }
  150. }
  151. const char *
  152. Client::name ( const char *s )
  153. {
  154. /* Because the JACK API does not provide a mechanism for renaming
  155. * clients, we have to save connections, destroy our client,
  156. * create a client with the new name, and restore our
  157. * connections. Lovely. */
  158. freeze_ports();
  159. jack_deactivate( _client );
  160. jack_client_close( _client );
  161. _client = NULL;
  162. s = init( s );
  163. thaw_ports();
  164. return s;
  165. }
  166. }