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.

361 lines
10KB

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