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.

445 lines
13KB

  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. #pragma once
  19. #include <FL/Fl.H>
  20. #include <FL/Fl_Group.H>
  21. #include <stdlib.h>
  22. #include "debug.h"
  23. #include <vector>
  24. #include "Thread.H"
  25. #include "Loggable.H"
  26. #include "JACK/Port.H"
  27. #include "OSC/Endpoint.H"
  28. class Chain;
  29. class Module_Parameter_Editor;
  30. class Fl_Menu_;
  31. class Fl_Menu_Button;
  32. class Fl_Button;
  33. class Module : public Fl_Group, public Loggable {
  34. int _ins;
  35. int _outs;
  36. int _instances;
  37. nframes_t _nframes;
  38. Chain *_chain;
  39. bool _is_default;
  40. bool _bypass;
  41. Module_Parameter_Editor *_editor;
  42. static Module *_copied_module_empty;
  43. static char *_copied_module_settings;
  44. void init ( void );
  45. void insert_menu_cb ( const Fl_Menu_ *m );
  46. static void insert_menu_cb ( Fl_Widget *w, void *v );
  47. void menu_cb ( const Fl_Menu_ *m );
  48. static void menu_cb ( Fl_Widget *w, void *v );
  49. Fl_Menu_Button & menu ( void ) const;
  50. void copy ( void ) const;
  51. void paste_before ( void );
  52. public:
  53. /* true if this module was added by default and not under normal user control */
  54. bool is_default ( void ) const { return _is_default; }
  55. void is_default ( bool v ) { _is_default = v; }
  56. virtual bool allows_external_control ( void ) const { return true; }
  57. class Port
  58. {
  59. /* char *type_names[] = { "Audio", "Control" }; */
  60. /* char *direction_names[] = { "Input", "Output" }; */
  61. void update_connected_port_buffer ( void )
  62. {
  63. if ( connected() )
  64. connected_port()->_buf = _buf;
  65. }
  66. public:
  67. enum Direction { INPUT, OUTPUT };
  68. enum Type { AUDIO, CONTROL };
  69. /* hints for control ports (specifically control inputs) */
  70. struct Hints
  71. {
  72. enum Type { LINEAR, LOGARITHMIC, BOOLEAN, INTEGER };
  73. Type type;
  74. bool ranged;
  75. float minimum;
  76. float maximum;
  77. float default_value;
  78. int dimensions;
  79. Hints ( )
  80. {
  81. type = LINEAR;
  82. ranged = false;
  83. minimum = 0;
  84. maximum = 0;
  85. default_value = 0.0f;
  86. dimensions = 1;
  87. }
  88. };
  89. static int osc_control_change_exact ( float v, void *user_data );
  90. static int osc_control_change_cv ( float v, void *user_data );
  91. Hints hints;
  92. Port ( Module *module, Direction direction, Type type, const char *name = 0 )
  93. {
  94. _name = name;
  95. _direction = direction;
  96. _type = type;
  97. _buf = 0;
  98. _nframes = 0;
  99. _connected = 0;
  100. _module = module;
  101. _scaled_signal = 0;
  102. _unscaled_signal = 0;
  103. }
  104. Port ( const Port& p )
  105. {
  106. _name = p._name;
  107. _direction = p._direction;
  108. _type = p._type;
  109. _buf = p._buf;
  110. _nframes = p._nframes;
  111. _connected = p._connected;
  112. _module = p._module;
  113. hints = p.hints;
  114. _scaled_signal = p._scaled_signal;
  115. _unscaled_signal = p._unscaled_signal;
  116. }
  117. virtual ~Port ( )
  118. {
  119. // change_osc_path( NULL );
  120. // disconnect();
  121. }
  122. const char *name ( void ) const { return _name; }
  123. Type type ( void ) const { return _type; }
  124. Direction direction ( void ) const { return _direction; }
  125. Module * module ( void ) const { return _module; }
  126. nframes_t nframes ( void ) const { return _nframes; }
  127. void buffer ( void *buf, nframes_t nframes ) { _buf = buf; _nframes = nframes; };
  128. void *buffer ( void ) const { return _buf; }
  129. const char *osc_path ( )
  130. {
  131. if ( _scaled_signal )
  132. return _scaled_signal->path();
  133. else
  134. return NULL;
  135. }
  136. void update_osc_port ( )
  137. {
  138. // if ( INPUT == _direction )
  139. change_osc_path( generate_osc_path() );
  140. }
  141. void destroy_osc_port ( )
  142. {
  143. delete _unscaled_signal;
  144. delete _scaled_signal;
  145. _unscaled_signal = _scaled_signal = NULL;
  146. }
  147. void control_value_no_callback ( float f )
  148. {
  149. /* can also be called from the OSC thread */
  150. ASSERT( Thread::is( "UI" ) || Thread::is( "OSC" ),
  151. "Function called from wrong thread! (is %s)", Thread::current()->name() );
  152. if ( buffer() )
  153. {
  154. *((float*)buffer()) = f;
  155. }
  156. }
  157. void control_value ( float f )
  158. {
  159. control_value_no_callback( f );
  160. _module->handle_control_changed( this );
  161. if ( connected() )
  162. connected_port()->_module->handle_control_changed( connected_port() );
  163. }
  164. float control_value ( ) const
  165. {
  166. if ( buffer() )
  167. return *((float*)buffer());
  168. else
  169. return 0.0f;
  170. }
  171. bool connected ( void ) const { return _connected; }
  172. bool connected_osc ( void ) const;
  173. Port *connected_port ( void ) const
  174. {
  175. return _connected;
  176. }
  177. void connect_to ( Port *to )
  178. {
  179. _buf = to->_buf;
  180. to->_connected = this;
  181. _connected = to;
  182. }
  183. void connect_to ( void *buf )
  184. {
  185. _buf = buf;
  186. update_connected_port_buffer();
  187. }
  188. void disconnect ( void )
  189. {
  190. if ( _connected && _connected != (void*)0x01 )
  191. {
  192. _connected->_connected = NULL;
  193. _connected = NULL;
  194. }
  195. else
  196. _connected = NULL;
  197. /* FIXME: do something! */
  198. }
  199. private:
  200. char *generate_osc_path ( void );
  201. void change_osc_path ( char *path );
  202. Port *_connected;
  203. Type _type;
  204. Direction _direction;
  205. const char *_name;
  206. void *_buf;
  207. nframes_t _nframes;
  208. Module *_module;
  209. OSC::Signal *_scaled_signal;
  210. OSC::Signal *_unscaled_signal;
  211. static void handle_signal_connection_state_changed ( OSC::Signal *, void *o );
  212. };
  213. void bbox ( int &X, int &Y, int &W, int &H )
  214. {
  215. X = x() + 5;
  216. Y = y() + 5;
  217. W = w() - 10;
  218. H = h() - 10;
  219. }
  220. Module ( int W, int H, const char *L = 0 );
  221. Module ( );
  222. Module ( bool is_default, int W, int H, const char *L = 0 );
  223. virtual ~Module ( );
  224. LOG_NAME_FUNC( Module );
  225. nframes_t nframes ( void ) const { return _nframes; }
  226. void resize_buffers ( nframes_t v ) { _nframes = v; }
  227. int instances ( void ) const { return _instances; }
  228. void instances ( int i ) { _instances = i; }
  229. bool is_being_controlled ( void ) const
  230. {
  231. for ( nframes_t i = control_input.size(); i--; )
  232. if ( control_input[i].connected() )
  233. return true;
  234. return false;
  235. }
  236. bool is_controlling ( void ) const
  237. {
  238. for ( nframes_t i = control_output.size(); i--; )
  239. if ( control_output[i].connected() )
  240. return true;
  241. return false;
  242. }
  243. bool
  244. is_being_controlled_osc ( void ) const
  245. {
  246. for ( nframes_t i = control_input.size(); i--; )
  247. if ( control_input[i].connected_osc() )
  248. return true;
  249. return false;
  250. }
  251. virtual const char *name ( void ) const = 0;
  252. std::vector<Port> audio_input;
  253. std::vector<Port> audio_output;
  254. std::vector<Port> control_input;
  255. std::vector<Port> control_output;
  256. void add_port ( const Port &p )
  257. {
  258. if ( p.type() == Port::AUDIO && p.direction() == Port::INPUT )
  259. audio_input.push_back( p );
  260. else if ( p.type() == Port::AUDIO && p.direction() == Port::OUTPUT )
  261. audio_output.push_back( p );
  262. else if ( p.type() == Port::CONTROL && p.direction() == Port::INPUT )
  263. control_input.push_back( p );
  264. else if ( p.type() == Port::CONTROL && p.direction() == Port::OUTPUT )
  265. control_output.push_back( p );
  266. }
  267. int noutputs ( void ) const
  268. {
  269. return audio_output.size();
  270. }
  271. int ninputs ( void ) const
  272. {
  273. return audio_input.size();
  274. }
  275. int ncontrol_inputs ( void ) const
  276. {
  277. return control_input.size();
  278. }
  279. int ncontrol_outputs ( void ) const
  280. {
  281. return control_output.size();
  282. }
  283. bool bypass ( void ) const { return _bypass; }
  284. void bypass ( bool v ) { _bypass = v; redraw(); }
  285. int control_input_port_index ( Port *p )
  286. {
  287. for ( nframes_t i = control_input.size(); i--; )
  288. if ( &control_input[i] == p )
  289. return i;
  290. return -1;
  291. }
  292. int control_output_port_index ( Port *p )
  293. {
  294. for ( nframes_t i = control_output.size(); i--; )
  295. if ( &control_output[i] == p )
  296. return i;
  297. return -1;
  298. }
  299. Chain *chain ( void ) const { return _chain; }
  300. void chain ( Chain * v )
  301. {
  302. if ( _chain != v )
  303. {
  304. _chain = v;
  305. for ( int i = 0; i < ncontrol_inputs(); ++i )
  306. {
  307. control_input[i].update_osc_port();
  308. }
  309. }
  310. }
  311. char *get_parameters ( void ) const;
  312. void set_parameters ( const char * );
  313. virtual bool initialize ( void ) { return true; }
  314. /* for the given number of inputs, return how many outputs this
  315. * plugin would have. -1 if this plugin can't support so many
  316. * inputs. */
  317. virtual int can_support_inputs ( int n ) = 0;
  318. /* called by the chain whenever we need to adjust our input
  319. * channel configuration, but only if can_support_inputs() returns
  320. * true */
  321. virtual bool configure_inputs ( int n ) = 0;
  322. virtual void process ( nframes_t ) = 0;
  323. /* called whenever the value of a control port is changed.
  324. This can be used to take appropriate action from the GUI thread */
  325. virtual void handle_control_changed ( Port * );
  326. /* called whenever the name of the chain changes (usually because
  327. * the name of the mixer strip changed). */
  328. virtual void handle_chain_name_changed ();
  329. virtual void handle_port_connection_change () {}
  330. #define MODULE_CLONE_FUNC(class) \
  331. virtual Module *clone_empty ( void ) const \
  332. { \
  333. return new class (); \
  334. }
  335. virtual Module *clone_empty ( void ) const { return NULL; }
  336. Module *clone ( Chain *dest ) const;
  337. Module *clone ( void ) const;
  338. protected:
  339. void draw_connections ( void );
  340. void draw_label ( void );
  341. void draw_box ( void );
  342. virtual void draw ( void ) { Module::draw_box(); Module::draw_label(); }
  343. virtual int handle ( int m );
  344. virtual void get ( Log_Entry &e ) const;
  345. virtual void set ( Log_Entry &e );
  346. public:
  347. void command_open_parameter_editor();
  348. virtual void command_activate ( void );
  349. virtual void command_deactivate ( void );
  350. virtual void command_remove ( void );
  351. };