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.

329 lines
9.2KB

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