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.

273 lines
6.9KB

  1. /*******************************************************************************/
  2. /* Copyright (C) 2009 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 "const.h"
  19. #include <string.h>
  20. #include <FL/fl_ask.H>
  21. #include "dsp.h"
  22. #include "Engine/Engine.H"
  23. #include "Chain.H"
  24. #include "JACK_Module.H"
  25. JACK_Module::JACK_Module ( bool log )
  26. : Module ( 50, 24, name() )
  27. {
  28. _prefix = 0;
  29. if ( log )
  30. {
  31. /* FIXME: how do Controls find out that a connected value has changed? How does this work in ladspa? */
  32. {
  33. Port p( this, Port::INPUT, Port::CONTROL, "Inputs" );
  34. p.hints.type = Port::Hints::INTEGER;
  35. p.hints.minimum = 0;
  36. p.hints.maximum = 16;
  37. p.hints.ranged = true;
  38. p.hints.visible = false;
  39. p.connect_to( new float );
  40. p.control_value_no_callback( 0 );
  41. add_port( p );
  42. }
  43. {
  44. Port p( this, Port::INPUT, Port::CONTROL, "Outputs" );
  45. p.hints.type = Port::Hints::INTEGER;
  46. p.hints.minimum = 0;
  47. p.hints.maximum = 16;
  48. p.hints.ranged = true;
  49. p.hints.visible = false;
  50. p.connect_to( new float );
  51. p.control_value_no_callback( 0 );
  52. add_port( p );
  53. }
  54. color( FL_BLACK );
  55. log_create();
  56. }
  57. end();
  58. }
  59. JACK_Module::~JACK_Module ( )
  60. {
  61. log_destroy();
  62. configure_inputs( 0 );
  63. configure_outputs( 0 );
  64. if ( _prefix )
  65. free( _prefix );
  66. }
  67. int
  68. JACK_Module::can_support_inputs ( int )
  69. {
  70. return audio_output.size();
  71. }
  72. bool
  73. JACK_Module::configure_inputs ( int n )
  74. {
  75. int on = audio_input.size();
  76. if ( n > on )
  77. {
  78. for ( int i = on; i < n; ++i )
  79. {
  80. JACK::Port *po = NULL;
  81. if ( !_prefix )
  82. po = new JACK::Port( chain()->engine(), JACK::Port::Output, i );
  83. else
  84. po = new JACK::Port( chain()->engine(), JACK::Port::Output, _prefix, i );
  85. if ( ! po->activate() )
  86. {
  87. jack_port_activation_error( po );
  88. return false;
  89. }
  90. if ( po->valid() )
  91. {
  92. add_port( Port( this, Port::INPUT, Port::AUDIO ) );
  93. jack_output.push_back( *po );
  94. }
  95. delete po;
  96. }
  97. }
  98. else
  99. {
  100. for ( int i = on; i > n; --i )
  101. {
  102. audio_input.back().disconnect();
  103. audio_input.pop_back();
  104. jack_output.back().shutdown();
  105. jack_output.pop_back();
  106. }
  107. }
  108. if ( is_default() )
  109. control_input[0].control_value_no_callback( n );
  110. return true;
  111. }
  112. void
  113. JACK_Module::jack_port_activation_error ( JACK::Port *p )
  114. {
  115. fl_alert( "Could not activate JACK port \"%s\"", p->name() );
  116. }
  117. bool
  118. JACK_Module::configure_outputs ( int n )
  119. {
  120. int on = audio_output.size();
  121. if ( n > on )
  122. {
  123. for ( int i = on; i < n; ++i )
  124. {
  125. JACK::Port *po = NULL;
  126. if ( !_prefix )
  127. po = new JACK::Port( chain()->engine(), JACK::Port::Input, i );
  128. else
  129. po = new JACK::Port( chain()->engine(), JACK::Port::Input, _prefix, i );
  130. if ( ! po->activate() )
  131. {
  132. jack_port_activation_error( po );
  133. return false;
  134. }
  135. if ( po->valid() )
  136. {
  137. add_port( Port( this, Port::OUTPUT, Port::AUDIO ) );
  138. jack_input.push_back( *po );
  139. }
  140. delete po;
  141. }
  142. }
  143. else
  144. {
  145. for ( int i = on; i > n; --i )
  146. {
  147. audio_output.back().disconnect();
  148. audio_output.pop_back();
  149. jack_input.back().shutdown();
  150. jack_input.pop_back();
  151. }
  152. }
  153. if ( is_default() )
  154. control_input[1].control_value_no_callback( n );
  155. return true;
  156. }
  157. bool
  158. JACK_Module::initialize ( void )
  159. {
  160. return true;
  161. }
  162. void
  163. JACK_Module::handle_control_changed ( Port *p )
  164. {
  165. THREAD_ASSERT( UI );
  166. if ( 0 == strcmp( p->name(), "Inputs" ) )
  167. {
  168. DMESSAGE( "Adjusting number of inputs (JACK outputs)" );
  169. configure_inputs( p->control_value() );
  170. if ( chain() )
  171. chain()->configure_ports();
  172. }
  173. else if ( 0 == strcmp( p->name(), "Outputs" ) )
  174. {
  175. DMESSAGE( "Adjusting number of outputs (JACK inputs)" );
  176. if ( ! chain() )
  177. {
  178. configure_outputs( p->control_value() );
  179. }
  180. else if ( chain()->can_configure_outputs( this, p->control_value() ) )
  181. {
  182. configure_outputs( p->control_value() );
  183. chain()->configure_ports();
  184. }
  185. else
  186. {
  187. p->connected_port()->control_value( noutputs() );
  188. }
  189. }
  190. }
  191. void
  192. JACK_Module::handle_chain_name_changed ( void )
  193. {
  194. for ( unsigned int i = 0; i < jack_output.size(); ++i )
  195. jack_output[ i ].name( NULL, i );
  196. for ( unsigned int i = 0; i < jack_input.size(); ++i )
  197. jack_input[ i ].name( NULL, i );
  198. Module::handle_chain_name_changed();
  199. }
  200. /**********/
  201. /* Engine */
  202. /**********/
  203. void
  204. JACK_Module::process ( nframes_t nframes )
  205. {
  206. for ( unsigned int i = 0; i < audio_input.size(); ++i )
  207. {
  208. if ( audio_input[i].connected() )
  209. buffer_copy( (sample_t*)jack_output[i].buffer( nframes ),
  210. (sample_t*)audio_input[i].buffer(),
  211. nframes );
  212. }
  213. for ( unsigned int i = 0; i < audio_output.size(); ++i )
  214. {
  215. if ( audio_output[i].connected() )
  216. buffer_copy( (sample_t*)audio_output[i].buffer(),
  217. (sample_t*)jack_input[i].buffer( nframes ),
  218. nframes );
  219. }
  220. }