2 /*******************************************************************************/
3 /* Copyright (C) 2009 Jonathan Moore Liles */
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. */
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 */
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 /*******************************************************************************/
23 #include <FL/Fl_Group.H>
32 #include "JACK/Port.H"
33 #include "OSC/Endpoint.H"
36 class Module_Parameter_Editor;
41 class Module : public Fl_Group, public Loggable {
51 Module_Parameter_Editor *_editor;
53 static Module *_copied_module_empty;
54 static char *_copied_module_settings;
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 );
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; }
78 /* char *type_names[] = { "Audio", "Control" }; */
79 /* char *direction_names[] = { "Input", "Output" }; */
81 void update_connected_port_buffer ( void )
84 connected_port()->_buf = _buf;
89 enum Direction { INPUT, OUTPUT };
90 enum Type { AUDIO, CONTROL };
92 /* hints for control ports (specifically control inputs) */
95 enum Type { LINEAR, LOGARITHMIC, BOOLEAN, INTEGER };
110 default_value = 0.0f;
115 static int osc_control_change_exact ( float v, void *user_data );
116 static int osc_control_change_cv ( float v, void *user_data );
120 Port ( Module *module, Direction direction, Type type, const char *name = 0 )
123 _direction = direction;
130 _unscaled_signal = 0;
133 Port ( const Port& p )
136 _direction = p._direction;
139 _nframes = p._nframes;
140 _connected = p._connected;
143 _scaled_signal = p._scaled_signal;
144 _unscaled_signal = p._unscaled_signal;
149 // change_osc_path( NULL );
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 ( )
165 if ( _scaled_signal )
166 return _scaled_signal->path();
171 void update_osc_port ( )
173 // if ( INPUT == _direction )
174 change_osc_path( generate_osc_path() );
177 void destroy_osc_port ( )
179 delete _unscaled_signal;
180 delete _scaled_signal;
182 _unscaled_signal = _scaled_signal = NULL;
185 void control_value_no_callback ( float f )
187 /* can also be called from the OSC thread */
188 ASSERT( Thread::is( "UI" ) || Thread::is( "OSC" ),
189 "Function called from wrong thread! (is %s)", Thread::current()->name() );
193 *((float*)buffer()) = f;
197 void control_value ( float f )
199 control_value_no_callback( f );
200 _module->handle_control_changed( this );
202 connected_port()->_module->handle_control_changed( connected_port() );
205 float control_value ( ) const
208 return *((float*)buffer());
213 bool connected ( void ) const { return _connected; }
214 bool connected_osc ( void ) const;
216 Port *connected_port ( void ) const
221 void connect_to ( Port *to )
224 to->_connected = this;
228 void connect_to ( void *buf )
231 update_connected_port_buffer();
234 void disconnect ( void )
236 if ( _connected && _connected != (void*)0x01 )
238 _connected->_connected = NULL;
244 /* FIXME: do something! */
249 char *generate_osc_path ( void );
250 void change_osc_path ( char *path );
254 Direction _direction;
261 OSC::Signal *_scaled_signal;
262 OSC::Signal *_unscaled_signal;
264 static void handle_signal_connection_state_changed ( OSC::Signal *, void *o );
267 void bbox ( int &X, int &Y, int &W, int &H )
275 Module ( int W, int H, const char *L = 0 );
277 Module ( bool is_default, int W, int H, const char *L = 0 );
281 LOG_NAME_FUNC( Module );
283 nframes_t nframes ( void ) const { return _nframes; }
284 void resize_buffers ( nframes_t v ) { _nframes = v; }
287 int instances ( void ) const { return _instances; }
288 void instances ( int i ) { _instances = i; }
290 bool is_being_controlled ( void ) const
292 for ( nframes_t i = control_input.size(); i--; )
293 if ( control_input[i].connected() )
298 bool is_controlling ( void ) const
300 for ( nframes_t i = control_output.size(); i--; )
301 if ( control_output[i].connected() )
307 is_being_controlled_osc ( void ) const
309 for ( nframes_t i = control_input.size(); i--; )
310 if ( control_input[i].connected_osc() )
315 virtual const char *name ( void ) const = 0;
317 std::vector<Port> audio_input;
318 std::vector<Port> audio_output;
319 std::vector<Port> control_input;
320 std::vector<Port> control_output;
322 void add_port ( const Port &p )
324 if ( p.type() == Port::AUDIO && p.direction() == Port::INPUT )
325 audio_input.push_back( p );
326 else if ( p.type() == Port::AUDIO && p.direction() == Port::OUTPUT )
327 audio_output.push_back( p );
328 else if ( p.type() == Port::CONTROL && p.direction() == Port::INPUT )
329 control_input.push_back( p );
330 else if ( p.type() == Port::CONTROL && p.direction() == Port::OUTPUT )
331 control_output.push_back( p );
334 int noutputs ( void ) const
336 return audio_output.size();
339 int ninputs ( void ) const
341 return audio_input.size();
344 int ncontrol_inputs ( void ) const
346 return control_input.size();
349 int ncontrol_outputs ( void ) const
351 return control_output.size();
354 bool bypass ( void ) const { return _bypass; }
355 void bypass ( bool v ) { _bypass = v; redraw(); }
357 int control_input_port_index ( Port *p )
359 for ( nframes_t i = control_input.size(); i--; )
360 if ( &control_input[i] == p )
366 int control_output_port_index ( Port *p )
368 for ( nframes_t i = control_output.size(); i--; )
369 if ( &control_output[i] == p )
375 Chain *chain ( void ) const { return _chain; }
376 void chain ( Chain * v )
382 for ( int i = 0; i < ncontrol_inputs(); ++i )
384 control_input[i].update_osc_port();
389 char *get_parameters ( void ) const;
390 void set_parameters ( const char * );
392 virtual bool initialize ( void ) { return true; }
394 /* for the given number of inputs, return how many outputs this
395 * plugin would have. -1 if this plugin can't support so many
397 virtual int can_support_inputs ( int n ) = 0;
398 /* called by the chain whenever we need to adjust our input
399 * channel configuration, but only if can_support_inputs() returns
401 virtual bool configure_inputs ( int n ) = 0;
403 virtual void process ( nframes_t ) = 0;
405 /* called whenever the value of a control port is changed.
406 This can be used to take appropriate action from the GUI thread */
407 virtual void handle_control_changed ( Port * );
409 /* called whenever the name of the chain changes (usually because
410 * the name of the mixer strip changed). */
411 virtual void handle_chain_name_changed ();
413 virtual void handle_port_connection_change () {}
415 #define MODULE_CLONE_FUNC(class) \
416 virtual Module *clone_empty ( void ) const \
418 return new class (); \
421 virtual Module *clone_empty ( void ) const { return NULL; }
422 Module *clone ( Chain *dest ) const;
423 Module *clone ( void ) const;
427 void draw_connections ( void );
428 void draw_label ( void );
429 void draw_box ( void );
431 virtual void draw ( void ) { Module::draw_box(); Module::draw_label(); }
432 virtual int handle ( int m );
434 virtual void get ( Log_Entry &e ) const;
435 virtual void set ( Log_Entry &e );
439 void command_open_parameter_editor();
440 virtual void command_activate ( void );
441 virtual void command_deactivate ( void );
442 virtual void command_remove ( void );