|
-
- /*******************************************************************************/
- /* Copyright (C) 2009 Jonathan Moore Liles */
- /* */
- /* This program is free software; you can redistribute it and/or modify it */
- /* under the terms of the GNU General Public License as published by the */
- /* Free Software Foundation; either version 2 of the License, or (at your */
- /* option) any later version. */
- /* */
- /* This program is distributed in the hope that it will be useful, but WITHOUT */
- /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
- /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
- /* more details. */
- /* */
- /* You should have received a copy of the GNU General Public License along */
- /* with This program; see the file COPYING. If not,write to the Free Software */
- /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
- /*******************************************************************************/
-
- #pragma once
-
- #include <FL/Fl.H>
- #include <FL/Fl_Group.H>
-
- #include <stdlib.h>
- #include "debug.h"
- #include <vector>
-
- #include "Thread.H"
-
- #include "Loggable.H"
- #include "JACK/Port.H"
- #include "OSC/Endpoint.H"
-
- class Chain;
- class Module_Parameter_Editor;
- class Fl_Menu_;
- class Fl_Menu_Button;
- class Fl_Button;
-
- class Module : public Fl_Group, public Loggable {
-
- int _ins;
- int _outs;
- int _instances;
- nframes_t _nframes;
- Chain *_chain;
- bool _is_default;
-
- Module_Parameter_Editor *_editor;
-
- static nframes_t _sample_rate;
- static Module *_copied_module_empty;
- static char *_copied_module_settings;
-
- void init ( void );
-
- void insert_menu_cb ( const Fl_Menu_ *m );
- static void insert_menu_cb ( Fl_Widget *w, void *v );
-
- void menu_cb ( const Fl_Menu_ *m );
- static void menu_cb ( Fl_Widget *w, void *v );
- Fl_Menu_Button & menu ( void ) const;
-
- void copy ( void ) const;
- void paste_before ( void );
-
- protected:
-
- volatile bool _bypass;
-
- public:
-
- /* true if this module was added by default and not under normal user control */
- bool is_default ( void ) const { return _is_default; }
- void is_default ( bool v ) { _is_default = v; }
-
- virtual void update ( void ) {}
-
- class Port
- {
- /* char *type_names[] = { "Audio", "Control" }; */
- /* char *direction_names[] = { "Input", "Output" }; */
-
- void update_connected_port_buffer ( void )
- {
- if ( connected() )
- connected_port()->_buf = _buf;
- }
-
- public:
-
- enum Direction { INPUT, OUTPUT };
- enum Type { AUDIO, CONTROL };
-
- /* hints for control ports (specifically control inputs) */
- struct Hints
- {
- enum Type { LINEAR, LOGARITHMIC, BOOLEAN, INTEGER };
-
- Type type;
- bool ranged;
- float minimum;
- float maximum;
- float default_value;
- int dimensions;
- bool visible;
-
- Hints ( )
- {
- type = LINEAR;
- ranged = false;
- minimum = 0;
- maximum = 1; /* FIXME: totally bogus, but some
- * plugins (SWH delays) don't
- * provide an upper bound. */
- default_value = 0.0f;
- dimensions = 1;
- visible = true;
- }
- };
-
- static int osc_control_change_exact ( float v, void *user_data );
- static int osc_control_change_cv ( float v, void *user_data );
-
- void learn_osc ( void );
-
- Hints hints;
-
- Port ( Module *module, Direction direction, Type type, const char *name = 0 )
- {
- _name = name;
- _direction = direction;
- _type = type;
- _buf = 0;
- _nframes = 0;
- _connected = 0;
- _module = module;
- _scaled_signal = 0;
- _unscaled_signal = 0;
- }
-
- Port ( const Port& p )
- {
- _name = p._name;
- _direction = p._direction;
- _type = p._type;
- _buf = p._buf;
- _nframes = p._nframes;
- _connected = p._connected;
- _module = p._module;
- hints = p.hints;
- _scaled_signal = p._scaled_signal;
- _unscaled_signal = p._unscaled_signal;
- }
-
- virtual ~Port ( )
- {
- // change_osc_path( NULL );
- // disconnect();
- }
-
- const char *name ( void ) const { return _name; }
- Type type ( void ) const { return _type; }
- Direction direction ( void ) const { return _direction; }
-
- Module * module ( void ) const { return _module; }
- nframes_t nframes ( void ) const { return _nframes; }
-
- void buffer ( void *buf, nframes_t nframes ) { _buf = buf; _nframes = nframes; };
- void *buffer ( void ) const { return _buf; }
-
- OSC::Signal *scaled_signal ( void ) { return _scaled_signal; }
-
- const char *osc_path ( )
- {
- if ( _scaled_signal )
- return _scaled_signal->path();
- else
- return NULL;
- }
-
- char *osc_number_path ( void );
-
- void update_osc_port ( )
- {
- // if ( INPUT == _direction )
- change_osc_path( generate_osc_path() );
- }
-
- void destroy_osc_port ( )
- {
- delete _unscaled_signal;
- delete _scaled_signal;
-
- _unscaled_signal = _scaled_signal = NULL;
- }
-
- void control_value_no_callback ( float f )
- {
- /* can also be called from the OSC thread */
- ASSERT( Thread::is( "UI" ) || Thread::is( "OSC" ),
- "Function called from wrong thread! (is %s)", Thread::current()->name() );
-
- if ( buffer() )
- {
- *((float*)buffer()) = f;
- }
-
- if ( _scaled_signal )
- {
-
- if ( hints.ranged )
- {
- // scale value to range.
-
- float scale = hints.maximum - hints.minimum;
- float offset = hints.minimum;
-
- f = ( f - offset ) / scale;
- }
-
- if ( f > 1.0 )
- f = 1.0;
- else if ( f < 0.0 )
- f = 0.0;
-
- // _scaled_signal->value( f );
- }
- }
-
- void control_value ( float f )
- {
- control_value_no_callback( f );
- _module->handle_control_changed( this );
- if ( connected() )
- connected_port()->_module->handle_control_changed( connected_port() );
- }
-
- float control_value ( ) const
- {
- if ( buffer() )
- return *((float*)buffer());
- else
- return 0.0f;
- }
-
- bool connected ( void ) const { return _connected; }
- bool connected_osc ( void ) const;
-
- Port *connected_port ( void ) const
- {
- return _connected;
- }
-
- void connect_to ( Port *to )
- {
- _buf = to->_buf;
- to->_connected = this;
- _connected = to;
- }
-
- void connect_to ( void *buf )
- {
- _buf = buf;
- update_connected_port_buffer();
- }
-
- void send_feedback ( void );
-
- void disconnect ( void )
- {
- if ( _connected && _connected != (void*)0x01 )
- {
- _connected->_connected = NULL;
- _connected = NULL;
- }
- else
- _connected = NULL;
-
- /* FIXME: do something! */
- }
-
- private:
-
- char *generate_osc_path ( void );
- void change_osc_path ( char *path );
-
- Port *_connected;
- Type _type;
- Direction _direction;
- const char *_name;
- void *_buf;
- nframes_t _nframes;
- Module *_module;
-
-
- OSC::Signal *_scaled_signal;
- OSC::Signal *_unscaled_signal;
-
- static void handle_signal_connection_state_changed ( OSC::Signal *, void *o );
- };
-
- void bbox ( int &X, int &Y, int &W, int &H )
- {
- X += + 5;
- Y += 5;
- W -= 10;
- H -= 10;
- }
-
- Module ( int W, int H, const char *L = 0 );
- Module ( );
- Module ( bool is_default, int W, int H, const char *L = 0 );
-
- virtual ~Module ( );
-
- LOG_NAME_FUNC( Module );
-
- nframes_t nframes ( void ) const { return _nframes; }
- void resize_buffers ( nframes_t v ) { _nframes = v; }
-
-
- int instances ( void ) const { return _instances; }
- void instances ( int i ) { _instances = i; }
-
- bool is_being_controlled ( void ) const
- {
- for ( nframes_t i = control_input.size(); i--; )
- if ( control_input[i].connected() )
- return true;
- return false;
- }
-
- bool is_controlling ( void ) const
- {
- for ( nframes_t i = control_output.size(); i--; )
- if ( control_output[i].connected() )
- return true;
- return false;
- }
-
- bool
- is_being_controlled_osc ( void ) const
- {
- for ( nframes_t i = control_input.size(); i--; )
- if ( control_input[i].connected_osc() )
- return true;
- return false;
- }
-
- virtual const char *name ( void ) const = 0;
-
- std::vector<Port> audio_input;
- std::vector<Port> audio_output;
- std::vector<Port> control_input;
- std::vector<Port> control_output;
-
- void add_port ( const Port &p )
- {
- if ( p.type() == Port::AUDIO && p.direction() == Port::INPUT )
- audio_input.push_back( p );
- else if ( p.type() == Port::AUDIO && p.direction() == Port::OUTPUT )
- audio_output.push_back( p );
- else if ( p.type() == Port::CONTROL && p.direction() == Port::INPUT )
- control_input.push_back( p );
- else if ( p.type() == Port::CONTROL && p.direction() == Port::OUTPUT )
- control_output.push_back( p );
- }
-
- int noutputs ( void ) const
- {
- return audio_output.size();
- }
-
- int ninputs ( void ) const
- {
- return audio_input.size();
- }
-
- int ncontrol_inputs ( void ) const
- {
- return control_input.size();
- }
-
- int ncontrol_outputs ( void ) const
- {
- return control_output.size();
- }
-
- int nvisible_control_inputs ( void ) const
- {
- int n = 0;
- for ( std::vector<Port>::const_iterator i = control_input.begin();
- i != control_input.end();
- i++ )
- if ( i->hints.visible )
- n++;
-
- return n;
- }
-
- virtual bool bypass ( void ) const { return _bypass; }
- virtual void bypass ( bool v ) { _bypass = v; redraw(); }
-
- virtual bool bypassable ( void ) const
- {
- return ninputs() == noutputs() ||
- ( ninputs() == 1 && noutputs() == 2 );
- }
-
- int control_input_port_index ( Port *p )
- {
- for ( nframes_t i = control_input.size(); i--; )
- if ( &control_input[i] == p )
- return i;
-
- return -1;
- }
-
- int control_output_port_index ( Port *p )
- {
- for ( nframes_t i = control_output.size(); i--; )
- if ( &control_output[i] == p )
- return i;
-
- return -1;
- }
-
- Chain *chain ( void ) const { return _chain; }
- void chain ( Chain * v );
-
- char *get_parameters ( void ) const;
- void set_parameters ( const char * );
-
- void send_feedback ( void );
- virtual bool initialize ( void ) { return true; }
-
- /* for the given number of inputs, return how many outputs this
- * plugin would have. -1 if this plugin can't support so many
- * inputs. */
- virtual int can_support_inputs ( int n ) = 0;
- /* called by the chain whenever we need to adjust our input
- * channel configuration, but only if can_support_inputs() returns
- * true */
- virtual bool configure_inputs ( int n ) = 0;
-
- virtual void process ( nframes_t ) = 0;
-
- /* called whenever the module is initialized or when the sample rate is changed at runtime */
- virtual void handle_sample_rate_change ( nframes_t sample_rate ) {}
-
- /* called whenever the value of a control port is changed.
- This can be used to take appropriate action from the GUI thread */
- virtual void handle_control_changed ( Port * );
-
- /* called whenever the name of the chain changes (usually because
- * the name of the mixer strip changed). */
- virtual void handle_chain_name_changed ();
-
- virtual void handle_port_connection_change () {}
-
- #define MODULE_CLONE_FUNC(class) \
- virtual Module *clone_empty ( void ) const \
- { \
- return new class (); \
- }
-
- virtual Module *clone_empty ( void ) const { return NULL; }
- Module *clone ( Chain *dest ) const;
- Module *clone ( void ) const;
-
- protected:
-
- nframes_t sample_rate ( void ) const { return Module::_sample_rate; }
-
- void draw_connections ( void );
- void draw_label ( int X, int Y, int W, int H );
- void draw_box ( int X, int Y, int W, int H );
-
- virtual void draw ( void ) { Module::draw_box(x(),y(),w(),h()); Module::draw_label(x(),y(),w(),h()); }
- virtual int handle ( int m );
-
- virtual void get ( Log_Entry &e ) const;
- virtual void set ( Log_Entry &e );
-
- public:
-
- static void set_sample_rate ( nframes_t srate ) { _sample_rate = srate; }
-
- void command_open_parameter_editor();
- virtual void command_activate ( void );
- virtual void command_deactivate ( void );
- virtual void command_remove ( void );
-
- };
|