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.

349 lines
10.0KB

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