nonlib: Remove sigc++ dependencey from OSC::Endpoint.
[nondaw.git] / mixer / src / Module.H
blob109e558c851543632652d5cb8310e5636ce140b3
2 /*******************************************************************************/
3 /* Copyright (C) 2009 Jonathan Moore Liles                                     */
4 /*                                                                             */
5 /* This program is free software; you can redistribute it and/or modify it     */
6 /* under the terms of the GNU General Public License as published by the       */
7 /* Free Software Foundation; either version 2 of the License, or (at your      */
8 /* option) any later version.                                                  */
9 /*                                                                             */
10 /* This program is distributed in the hope that it will be useful, but WITHOUT */
11 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       */
12 /* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for   */
13 /* more details.                                                               */
14 /*                                                                             */
15 /* You should have received a copy of the GNU General Public License along     */
16 /* with This program; see the file COPYING.  If not,write to the Free Software */
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
18 /*******************************************************************************/
20 #pragma once
22 #include <FL/Fl.H>
23 #include <FL/Fl_Group.H>
25 #include <stdlib.h>
26 #include "debug.h"
27 #include <vector>
29 #include "Thread.H"
31 #include "Loggable.H"
32 #include "JACK/Port.H"
33 #include "OSC/Endpoint.H"
35 class Chain;
36 class Module_Parameter_Editor;
37 class Fl_Menu_;
38 class Fl_Menu_Button;
39 class Fl_Button;
41 class Module : public Fl_Group, public Loggable {
43     int _ins;
44     int _outs;
45     int _instances;
46     nframes_t _nframes;
47     Chain *_chain;
48     bool _is_default;
49     bool _bypass;
51     Module_Parameter_Editor *_editor;
53     static Module *_copied_module_empty;
54     static char *_copied_module_settings;
56     void init ( void );
58     void insert_menu_cb ( const Fl_Menu_ *m );
59     static void insert_menu_cb ( Fl_Widget *w, void *v );
61     void menu_cb ( const Fl_Menu_ *m );
62     static void menu_cb ( Fl_Widget *w, void *v );
63     Fl_Menu_Button & menu ( void ) const;
65     void copy ( void ) const;
66     void paste_before ( void );
68 public:
70     /* true if this module was added by default and not under normal user control */
71     bool is_default ( void ) const { return _is_default; }
72     void is_default ( bool v ) { _is_default = v; }
74     virtual bool allows_external_control ( void ) const { return true; }
76     class Port
77     {
78         /* char *type_names[] = { "Audio", "Control" }; */
79         /* char *direction_names[] = { "Input", "Output" }; */
81         void update_connected_port_buffer ( void )
82             {
83                 if ( connected() )
84                     connected_port()->_buf = _buf;
85             }
87     public:
89         enum Direction { INPUT, OUTPUT };
90         enum Type { AUDIO, CONTROL };
92         /* hints for control ports (specifically control inputs) */
93         struct Hints
94         {
95             enum Type { LINEAR, LOGARITHMIC, BOOLEAN, INTEGER };
97             Type type;
98             bool ranged;
99             float minimum;
100             float maximum;
101             float default_value;
102             int dimensions;
103             
104             Hints ( )
105                 {
106                     type = LINEAR;
107                     ranged = false;
108                     minimum = 0;
109                     maximum = 0;
110                     default_value = 0.0f;
111                     dimensions = 1;
112                 }
113         };
115         static int osc_control_change_exact ( float v, void *user_data );
116         static int osc_control_change_cv ( float v, void *user_data );
118         Hints hints;
120         Port ( Module *module, Direction direction, Type type, const char *name = 0 )
121             {
122                 _name = name;
123                 _direction = direction;
124                 _type = type;
125                 _buf = 0;
126                 _nframes = 0;
127                 _connected = 0;
128                 _module = module;
129                 _scaled_signal = 0;
130                 _unscaled_signal = 0;
131             }
133         Port ( const Port& p )
134             {
135                 _name = p._name;
136                 _direction = p._direction;
137                 _type = p._type;
138                 _buf = p._buf;
139                 _nframes = p._nframes;
140                 _connected = p._connected;
141                 _module = p._module;
142                 hints = p.hints;
143                 _scaled_signal = p._scaled_signal;
144                 _unscaled_signal = p._unscaled_signal;
145             }
147         virtual ~Port ( )
148             {
149                 //     change_osc_path( NULL );
150                 //   disconnect();
151             }
153         const char *name ( void ) const { return _name; }
154         Type type ( void ) const { return _type; }
155         Direction direction ( void ) const  { return _direction; }
157         Module * module ( void ) const { return _module; }
158         nframes_t nframes ( void ) const { return _nframes; }
160         void buffer ( void *buf, nframes_t nframes ) { _buf = buf; _nframes = nframes; };
161         void *buffer ( void ) const { return _buf; }
163         const char *osc_path ( )
164             {
165                 if ( _scaled_signal )
166                     return _scaled_signal->path();
167                 else
168                     return NULL;
169             }
171         void update_osc_port ( )
172             {
173 //                if ( INPUT == _direction )
174                 change_osc_path( generate_osc_path() );
175             }
177         void destroy_osc_port ( )
178             {
179                 delete _unscaled_signal;
180                 delete _scaled_signal;
181                 
182                 _unscaled_signal = _scaled_signal = NULL;
183             }
185         void control_value_no_callback ( float f )
186             {
187                 THREAD_ASSERT( UI );
189                 if ( buffer() )
190                 {
191                     *((float*)buffer()) = f;
192                 }
193             }
195         void control_value ( float f )
196             {
197                 control_value_no_callback( f );
198                 _module->handle_control_changed( this );
199                 if ( connected() )
200                     connected_port()->_module->handle_control_changed( connected_port() );
201             }
203         float control_value ( ) const
204             {
205                 if ( buffer() )
206                     return *((float*)buffer());
207                 else
208                     return 0.0f;
209             }
211         bool connected ( void ) const { return _connected; }
212         bool connected_osc ( void ) const;
214         Port *connected_port ( void ) const
215             {
216                 return _connected;
217             }
219         void connect_to ( Port *to )
220             {
221                 _buf = to->_buf;
222                 to->_connected = this;
223                 _connected = to;
224             }
226         void connect_to ( void *buf )
227             {
228                 _buf = buf;
229                 update_connected_port_buffer();
230             }
232         void disconnect ( void )
233             {
234                 if ( _connected && _connected != (void*)0x01 )
235                 {
236                     _connected->_connected = NULL;
237                     _connected = NULL;
238                 }
239                 else
240                     _connected = NULL;
242                 /* FIXME: do something! */
243             }
245     private:
247         char *generate_osc_path ( void );
248         void change_osc_path ( char *path );
249     
250         Port *_connected;
251         Type _type;
252         Direction _direction;
253         const char *_name;
254         void *_buf;
255         nframes_t _nframes;
256         Module *_module;
259         OSC::Signal *_scaled_signal;
260         OSC::Signal *_unscaled_signal;
262         static void handle_signal_connection_state_changed ( OSC::Signal *, void *o );
263     };
265     void bbox ( int &X, int &Y, int &W, int &H )
266         {
267             X = x() + 5;
268             Y = y() + 5;
269             W = w() - 10;
270             H = h() - 10;
271         }
273     Module ( int W, int H, const char *L = 0 );
274     Module ( );
275     Module ( bool is_default, int W, int H, const char *L = 0 );
277     virtual ~Module ( );
279     LOG_NAME_FUNC( Module );
281     nframes_t nframes ( void ) const { return _nframes; }
282     void resize_buffers ( nframes_t v ) { _nframes = v; }
285     int instances ( void ) const { return _instances; }
286     void instances ( int i ) { _instances = i; }
288     bool is_being_controlled ( void ) const
289         {
290             for ( nframes_t i = control_input.size(); i--; )
291                 if ( control_input[i].connected() )
292                     return true;
293             return false;
294         }
296     bool is_controlling ( void ) const
297         {
298             for ( nframes_t i = control_output.size(); i--; )
299                 if ( control_output[i].connected() )
300                     return true;
301             return false;
302         }
304     bool
305     is_being_controlled_osc ( void ) const
306         {
307             for ( nframes_t i = control_input.size(); i--; )
308                 if ( control_input[i].connected_osc() )
309                     return true;
310             return false;
311         }
313     virtual const char *name ( void ) const = 0;
315     std::vector<Port> audio_input;
316     std::vector<Port> audio_output;
317     std::vector<Port> control_input;
318     std::vector<Port> control_output;
320     void add_port ( const Port &p )
321         {
322             if ( p.type() == Port::AUDIO && p.direction() == Port::INPUT )
323                 audio_input.push_back( p );
324             else if ( p.type() == Port::AUDIO && p.direction() == Port::OUTPUT )
325                 audio_output.push_back( p );
326             else if ( p.type() == Port::CONTROL && p.direction() == Port::INPUT )
327                 control_input.push_back( p );
328             else if ( p.type() == Port::CONTROL && p.direction() == Port::OUTPUT )
329                 control_output.push_back( p );
330         }
332     int noutputs ( void ) const
333         {
334             return audio_output.size();
335         }
337     int ninputs ( void ) const
338         {
339             return audio_input.size();
340         }
342     int ncontrol_inputs ( void ) const
343         {
344             return control_input.size();
345         }
347     int ncontrol_outputs ( void ) const
348         {
349             return control_output.size();
350         }
352     bool bypass ( void ) const { return _bypass; }
353     void bypass ( bool v ) { _bypass = v; redraw(); }
355     int control_input_port_index ( Port *p )
356         {
357             for ( nframes_t i = control_input.size(); i--; )
358                 if ( &control_input[i] == p )
359                     return i;
361             return -1;
362         }
364     int control_output_port_index ( Port *p )
365         {
366             for ( nframes_t i = control_output.size(); i--; )
367                 if ( &control_output[i] == p )
368                     return i;
370             return -1;
371         }
373     Chain *chain ( void ) const { return _chain; }
374     void chain ( Chain * v )
375         {
376             if ( _chain != v )
377             {
378                 _chain = v; 
380                 for ( int i = 0; i < ncontrol_inputs(); ++i )
381                 {
382                     control_input[i].update_osc_port();
383                 }
384             }
385         }
387     char *get_parameters ( void ) const;
388     void set_parameters ( const char * );
390     virtual bool initialize ( void ) { return true; }
392     /* for the given number of inputs, return how many outputs this
393      * plugin would have. -1 if this plugin can't support so many
394      * inputs. */
395     virtual int can_support_inputs ( int n ) = 0;
396     /* called by the chain whenever we need to adjust our input
397      * channel configuration, but only if can_support_inputs() returns
398      * true */
399     virtual bool configure_inputs ( int n ) = 0;
401     virtual void process ( nframes_t ) = 0;
403     /* called whenever the value of a control port is changed.
404        This can be used to take appropriate action from the GUI thread */
405     virtual void handle_control_changed ( Port * );
407     /* called whenever the name of the chain changes (usually because
408      * the name of the mixer strip changed). */
409     virtual void handle_chain_name_changed ();
411     virtual void handle_port_connection_change () {}
413 #define MODULE_CLONE_FUNC(class)                                \
414     virtual Module *clone_empty ( void ) const                  \
415         {                                                       \
416             return new class ();                                \
417         }
419     virtual Module *clone_empty ( void ) const { return NULL; }
420     Module *clone ( Chain *dest ) const;
421     Module *clone ( void ) const;
423 protected:
425     void draw_connections ( void );
426     void draw_label ( void );
427     void draw_box ( void );
429     virtual void draw ( void ) { Module::draw_box(); Module::draw_label(); }
430     virtual int handle ( int m );
432     virtual void get ( Log_Entry &e ) const;
433     virtual void set ( Log_Entry &e );
435 public:
437     void command_open_parameter_editor();
438     void command_activate ( void );
439     void command_deactivate ( void );
440     void command_remove ( void );