| @@ -64,6 +64,9 @@ Fl_Scalepack::draw ( void ) | |||
| if ( child( i )->visible() ) | |||
| ++v; | |||
| if ( 0 == v ) | |||
| return; | |||
| int sz, pos; | |||
| if ( type() == HORIZONTAL ) | |||
| @@ -71,6 +71,7 @@ | |||
| #include "FL/Fl_Scroll.H" | |||
| #include <string.h> | |||
| #include "Mixer_Strip.H" | |||
| #include <dsp.h> | |||
| @@ -80,16 +81,59 @@ std::list <Chain*> Chain::chain; | |||
| Chain::Chain ( int X, int Y, int W, int H, const char *L ) : | |||
| Fl_Group( X, Y, W, H, L) | |||
| void | |||
| Chain::get ( Log_Entry &e ) const | |||
| { | |||
| e.add( ":strip", strip() ); | |||
| } | |||
| void | |||
| Chain::set ( Log_Entry &e ) | |||
| { | |||
| for ( int i = 0; i < e.size(); ++i ) | |||
| { | |||
| const char *s, *v; | |||
| e.get( i, &s, &v ); | |||
| if ( ! strcmp( s, ":strip" ) ) | |||
| { | |||
| int i; | |||
| sscanf( v, "%X", &i ); | |||
| Mixer_Strip *t = (Mixer_Strip*)Loggable::find( i ); | |||
| assert( t ); | |||
| t->chain( this ); | |||
| } | |||
| } | |||
| } | |||
| /* Chain::Chain ( int X, int Y, int W, int H, const char *L ) : */ | |||
| /* Fl_Group( X, Y, W, H, L) */ | |||
| Chain::Chain ( ) : Fl_Group( 0, 0, 100, 100, "") | |||
| { | |||
| _outs = 1; | |||
| _ins = 1; | |||
| int X = 0; | |||
| int Y = 0; | |||
| int W = 100; | |||
| int H = 100; | |||
| /* _outs = 1; */ | |||
| /* _ins = 1; */ | |||
| _configure_outputs_callback = NULL; | |||
| _strip = NULL; | |||
| _name = NULL; | |||
| labelsize( 10 ); | |||
| align( FL_ALIGN_TOP ); | |||
| { Fl_Tabs *o = tabs = new Fl_Tabs( X, Y, W, H ); | |||
| { Fl_Group *o = new Fl_Group( X, Y + 24, W, H - 24, "Chain" ); | |||
| o->box( FL_FLAT_BOX ); | |||
| @@ -127,11 +171,27 @@ Chain::Chain ( int X, int Y, int W, int H, const char *L ) : | |||
| end(); | |||
| chain.push_back( this ); | |||
| log_create(); | |||
| } | |||
| Chain::~Chain ( ) | |||
| { | |||
| chain.remove( this ); | |||
| log_destroy(); | |||
| } | |||
| void | |||
| Chain::log_children ( void ) | |||
| { | |||
| log_create(); | |||
| for ( int i = 0; i < modules(); ++i ) | |||
| { | |||
| module(i)->log_create(); | |||
| } | |||
| } | |||
| /* Fill this chain with JACK I/O, Gain, and Meter modules. */ | |||
| @@ -139,22 +199,30 @@ void | |||
| Chain::initialize_with_default ( void ) | |||
| { | |||
| { | |||
| JACK_Module *jm = new JACK_Module( 50, 50, "JACK" ); | |||
| jm->chain( this ); | |||
| jm->configure_outputs( 1 ); | |||
| { JACK_Module *m = new JACK_Module(); | |||
| m->is_default( true ); | |||
| m->chain( this ); | |||
| m->configure_outputs( 1 ); | |||
| m->initialize(); | |||
| add( m ); | |||
| } | |||
| { Module *m = new Gain_Module(); | |||
| m->is_default( true ); | |||
| m->initialize(); | |||
| add( m ); | |||
| } | |||
| jm->initialize(); | |||
| jm->color( FL_BLACK ); | |||
| insert( NULL, jm ); | |||
| { Module *m = new Meter_Module(); | |||
| m->is_default( true ); | |||
| add( m ); | |||
| } | |||
| { | |||
| JACK_Module *m = new JACK_Module( 50, 50, "JACK" ); | |||
| { JACK_Module *m = new JACK_Module(); | |||
| m->is_default( true ); | |||
| m->chain( this ); | |||
| m->initialize(); | |||
| m->color( FL_BLACK ); | |||
| insert( NULL, m ); | |||
| add( m ); | |||
| } | |||
| } | |||
| @@ -204,8 +272,8 @@ Chain::remove ( Module *m ) | |||
| void | |||
| Chain::configure_ports ( void ) | |||
| { | |||
| int old_outs = outs(); | |||
| int nouts = 0; | |||
| /* int old_outs = outs(); */ | |||
| int nouts = 0; | |||
| engine->lock(); | |||
| @@ -215,15 +283,15 @@ Chain::configure_ports ( void ) | |||
| nouts = module( i )->noutputs(); | |||
| } | |||
| outs( nouts ); | |||
| /* outs( nouts ); */ | |||
| int req_buffers = required_buffers(); | |||
| if ( outs() != old_outs ) | |||
| { | |||
| if ( configure_outputs_callback() ) | |||
| configure_outputs_callback()( this, _configure_outputs_userdata ); | |||
| } | |||
| /* if ( outs() != old_outs ) */ | |||
| /* { */ | |||
| /* if ( configure_outputs_callback() ) */ | |||
| /* configure_outputs_callback()( this, _configure_outputs_userdata ); */ | |||
| /* } */ | |||
| DMESSAGE( "required_buffers = %i", req_buffers ); | |||
| @@ -329,6 +397,12 @@ Chain::name ( const char *name ) | |||
| #include "FL/menu_popup.H" | |||
| bool | |||
| Chain::add ( Module *m ) | |||
| { | |||
| return insert( NULL, m ); | |||
| } | |||
| bool | |||
| Chain::insert ( Module *m, Module *n ) | |||
| { | |||
| @@ -389,6 +463,8 @@ Chain::insert ( Module *m, Module *n ) | |||
| n->ncontrol_inputs(), | |||
| n->ncontrol_outputs() ); | |||
| strip()->handle_module_added( n ); | |||
| configure_ports(); | |||
| engine->unlock(); | |||
| @@ -498,23 +574,23 @@ Chain::build_process_queue ( void ) | |||
| m->handle_port_connection_change(); | |||
| } | |||
| DMESSAGE( "Process queue looks like:" ); | |||
| /* DMESSAGE( "Process queue looks like:" ); */ | |||
| for ( std::list<Module*>::const_iterator i = process_queue.begin(); i != process_queue.end(); ++i ) | |||
| { | |||
| const Module* m = *i; | |||
| if ( m->audio_input.size() || m->audio_output.size() ) | |||
| DMESSAGE( "\t%s", (*i)->name() ); | |||
| else if ( m->control_output.size() ) | |||
| DMESSAGE( "\t%s -->", (*i)->name() ); | |||
| else if ( m->control_input.size() ) | |||
| DMESSAGE( "\t%s <--", (*i)->name() ); | |||
| /* if ( m->audio_input.size() || m->audio_output.size() ) */ | |||
| /* DMESSAGE( "\t%s", (*i)->name() ); */ | |||
| /* else if ( m->control_output.size() ) */ | |||
| /* DMESSAGE( "\t%s -->", (*i)->name() ); */ | |||
| /* else if ( m->control_input.size() ) */ | |||
| /* DMESSAGE( "\t%s <--", (*i)->name() ); */ | |||
| { | |||
| char *s = m->describe_inputs(); | |||
| char *s = m->get_parameters(); | |||
| DMESSAGE( "(%s)", s ); | |||
| /* DMESSAGE( "(%s)", s ); */ | |||
| delete[] s; | |||
| } | |||
| @@ -564,10 +640,9 @@ Chain::handle ( int m ) | |||
| { | |||
| if ( test_press( FL_BUTTON3 | FL_CTRL ) ) | |||
| { | |||
| if ( FL_BLACK == m->color() ) | |||
| if ( m->is_default() ) | |||
| { | |||
| /* FIXME: hack */ | |||
| fl_alert( "Cannot delete this module." ); | |||
| fl_alert( "Default modules may not be deleted." ); | |||
| } | |||
| else | |||
| { | |||
| @@ -604,6 +679,11 @@ Chain::handle ( int m ) | |||
| return Fl_Group::handle( m ); | |||
| } | |||
| void | |||
| Chain::strip ( Mixer_Strip * ms ) | |||
| { | |||
| _strip = ms; | |||
| } | |||
| void | |||
| Chain::process ( nframes_t nframes ) | |||
| @@ -17,6 +17,8 @@ | |||
| /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |||
| /*******************************************************************************/ | |||
| #pragma once | |||
| #include <FL/Fl.H> | |||
| #include <FL/Fl_Pack.H> | |||
| #include <FL/Fl_Button.H> | |||
| @@ -25,11 +27,13 @@ | |||
| #include "JACK/Port.H" | |||
| #include <vector> | |||
| #include <list> | |||
| #include "Loggable.H" | |||
| class Mixer_Strip; | |||
| class Fl_Flowpack; | |||
| class Fl_Tabs; | |||
| class Chain : public Fl_Group { | |||
| class Chain : public Fl_Group, public Loggable { | |||
| Fl_Pack *modules_pack; | |||
| Fl_Flowpack *controls_pack; | |||
| @@ -38,8 +42,10 @@ class Chain : public Fl_Group { | |||
| void cb_handle(Fl_Widget*); | |||
| static void cb_handle(Fl_Widget*, void*); | |||
| int _ins; | |||
| int _outs; | |||
| /* int _ins; */ | |||
| /* int _outs; */ | |||
| Mixer_Strip *_strip; | |||
| // sample_t **_buffer; | |||
| // int _nbuffers; | |||
| @@ -59,9 +65,20 @@ class Chain : public Fl_Group { | |||
| static std::vector <Module::Port> port; | |||
| static std::list <Chain*> chain; | |||
| protected: | |||
| void get ( Log_Entry &e ) const; | |||
| void set ( Log_Entry &e ); | |||
| int handle ( int m ); | |||
| void draw ( void ); | |||
| public: | |||
| void resize ( int X, int Y, int W, int H ); | |||
| Mixer_Strip *strip ( void ) const { return _strip; } | |||
| void strip ( Mixer_Strip *v ); | |||
| const char *name ( void ) const { return _name; } | |||
| void name ( const char *name ); | |||
| @@ -69,18 +86,20 @@ public: | |||
| int required_buffers ( void ); | |||
| Chain ( int X, int Y, int W, int H, const char *L = 0 ); | |||
| Chain ( ); | |||
| virtual ~Chain ( ); | |||
| bool can_support_input_channels ( int n ); | |||
| void ins ( int i ) { _ins = i; } | |||
| void outs ( int i ) { _outs = i; } | |||
| int ins ( void ) const { return _ins; } | |||
| int outs ( void ) const { return _outs; } | |||
| /* void ins ( int i ) { _ins = i; } */ | |||
| /* void outs ( int i ) { _outs = i; } */ | |||
| /* int ins ( void ) const { return _ins; } */ | |||
| /* int outs ( void ) const { return _outs; } */ | |||
| int modules ( void ) const { return modules_pack->children(); } | |||
| Module *module ( int n ) const { return (Module*)modules_pack->child( n ); } | |||
| void remove ( Module *m ); | |||
| bool add ( Module *m ); | |||
| bool insert ( Module *m, Module *n ); | |||
| void add_control ( Module *m ); | |||
| @@ -98,10 +117,7 @@ public: | |||
| void process ( nframes_t ); | |||
| protected: | |||
| int handle ( int m ); | |||
| void draw ( void ); | |||
| void resize ( int X, int Y, int W, int H ); | |||
| void log_children ( void ); | |||
| LOG_CREATE_FUNC( Chain ); | |||
| }; | |||
| @@ -38,8 +38,56 @@ const float CONTROL_UPDATE_FREQ = 0.1f; | |||
| Controller_Module::Controller_Module ( int W, int H, const char *L ) | |||
| : Module ( W, 100, L ) | |||
| void | |||
| Controller_Module::get ( Log_Entry &e ) const | |||
| { | |||
| Port *p = control_output[0].connected_port(); | |||
| Module *m = p->module(); | |||
| e.add( ":module", m ); | |||
| e.add( ":port", m->control_input_port_index( p ) ); | |||
| Module::get( e ); | |||
| } | |||
| void | |||
| Controller_Module::set ( Log_Entry &e ) | |||
| { | |||
| Module::set( e ); | |||
| int port = -1; | |||
| Module *module = NULL; | |||
| for ( int i = 0; i < e.size(); ++i ) | |||
| { | |||
| const char *s, *v; | |||
| e.get( i, &s, &v ); | |||
| if ( ! strcmp( s, ":port" ) ) | |||
| { | |||
| port = atoi( v ); | |||
| } | |||
| else if ( ! strcmp( s, ":module" ) ) | |||
| { | |||
| int i; | |||
| sscanf( v, "%X", &i ); | |||
| Module *t = (Module*)Loggable::find( i ); | |||
| assert( t ); | |||
| module = t; | |||
| } | |||
| } | |||
| if ( port >= 0 && module ) | |||
| control_output[0].connect_to( &module->control_input[port] ); | |||
| } | |||
| Controller_Module::Controller_Module ( bool is_default ) : Module( is_default, 50, 100, name() ) | |||
| { | |||
| // label( "" ); | |||
| box( FL_NO_BOX ); | |||
| @@ -47,6 +95,7 @@ Controller_Module::Controller_Module ( int W, int H, const char *L ) | |||
| _pad = true; | |||
| control = 0; | |||
| control_value =0.0f; | |||
| add_port( Port( this, Port::OUTPUT, Port::CONTROL ) ); | |||
| mode( GUI ); | |||
| @@ -56,11 +105,15 @@ Controller_Module::Controller_Module ( int W, int H, const char *L ) | |||
| end(); | |||
| Fl::add_timeout( CONTROL_UPDATE_FREQ, update_cb, this ); | |||
| log_create(); | |||
| } | |||
| Controller_Module::~Controller_Module ( ) | |||
| { | |||
| Fl::remove_timeout( update_cb, this ); | |||
| log_destroy(); | |||
| } | |||
| @@ -42,7 +42,8 @@ public: | |||
| Mode mode ( void ) const { return _mode; } | |||
| void mode ( Mode v ) { _mode = v; } | |||
| Controller_Module ( int W, int H, const char *L=0 ); | |||
| Controller_Module ( bool is_default = false ); | |||
| // Controller_Module ( int W, int H, const char *L=0 ); | |||
| virtual ~Controller_Module ( ); | |||
| const char *name ( void ) const { return "Controller"; } | |||
| @@ -57,8 +58,13 @@ public: | |||
| void connect_to ( Port *p ); | |||
| LOG_CREATE_FUNC( Controller_Module ); | |||
| protected: | |||
| void get ( Log_Entry &e ) const; | |||
| void set ( Log_Entry &e ); | |||
| // virtual void draw ( void ); | |||
| virtual void process ( void ); | |||
| @@ -22,8 +22,8 @@ | |||
| #include <math.h> | |||
| #include <dsp.h> | |||
| Gain_Module::Gain_Module ( int W, int H, const char *L ) | |||
| : Module ( W, 24, L ) | |||
| Gain_Module::Gain_Module ( ) | |||
| : Module ( 50, 24, name() ) | |||
| { | |||
| add_port( Port( this, Port::INPUT, Port::AUDIO ) ); | |||
| add_port( Port( this, Port::OUTPUT, Port::AUDIO ) ); | |||
| @@ -41,13 +41,16 @@ Gain_Module::Gain_Module ( int W, int H, const char *L ) | |||
| add_port( p ); | |||
| color( FL_BLACK ); | |||
| // color( FL_BLACK ); | |||
| end(); | |||
| log_create(); | |||
| } | |||
| Gain_Module::~Gain_Module ( ) | |||
| { | |||
| log_destroy(); | |||
| } | |||
| @@ -25,6 +25,7 @@ class Gain_Module : public Module | |||
| { | |||
| public: | |||
| Gain_Module ( ); | |||
| Gain_Module ( int W, int H, const char *L=0 ); | |||
| virtual ~Gain_Module ( ); | |||
| @@ -33,6 +34,8 @@ public: | |||
| int can_support_inputs ( int n ) { return n; } | |||
| bool configure_inputs ( int n ); | |||
| LOG_CREATE_FUNC( Gain_Module ); | |||
| protected: | |||
| virtual void process ( void ); | |||
| @@ -25,8 +25,10 @@ | |||
| #include <string.h> | |||
| #include "Chain.H" | |||
| JACK_Module::JACK_Module ( int W, int H, const char *L ) | |||
| : Module ( W, 24, L ) | |||
| JACK_Module::JACK_Module ( ) | |||
| : Module ( 50, 24, name() ) | |||
| { | |||
| /* FIXME: how do Controls find out that a connected value has changed? How does this work in ladspa? */ | |||
| { | |||
| @@ -54,8 +56,18 @@ JACK_Module::JACK_Module ( int W, int H, const char *L ) | |||
| } | |||
| end(); | |||
| log_create(); | |||
| } | |||
| JACK_Module::~JACK_Module ( ) | |||
| { | |||
| log_destroy(); | |||
| configure_inputs( 0 ); | |||
| } | |||
| int | |||
| JACK_Module::can_support_inputs ( int n ) | |||
| { | |||
| @@ -137,11 +149,6 @@ JACK_Module::initialize ( void ) | |||
| return true; | |||
| } | |||
| JACK_Module::~JACK_Module ( ) | |||
| { | |||
| configure_inputs( 0 ); | |||
| } | |||
| void | |||
| JACK_Module::handle_control_changed ( Port *p ) | |||
| { | |||
| @@ -149,16 +156,20 @@ JACK_Module::handle_control_changed ( Port *p ) | |||
| { | |||
| DMESSAGE( "Adjusting number of inputs (JACK outputs)" ); | |||
| configure_inputs( p->control_value() ); | |||
| chain()->configure_ports(); | |||
| if ( chain() ) | |||
| chain()->configure_ports(); | |||
| } | |||
| else if ( 0 == strcmp( p->name(), "Outputs" ) ) | |||
| { | |||
| DMESSAGE( "Adjusting number of outputs (JACK inputs)" ); | |||
| if ( chain()->can_configure_outputs( this, p->control_value() ) ) | |||
| if ( chain() && chain()->can_configure_outputs( this, p->control_value() ) ) | |||
| { | |||
| configure_outputs( p->control_value() ); | |||
| chain()->configure_ports(); | |||
| } | |||
| else | |||
| configure_outputs( p->control_value() ); | |||
| } | |||
| } | |||
| @@ -26,20 +26,16 @@ | |||
| class JACK_Module : public Module | |||
| { | |||
| const char *_strip_name; | |||
| std::vector<JACK::Port> jack_input; | |||
| std::vector<JACK::Port> jack_output; | |||
| public: | |||
| JACK_Module ( int W, int H, const char *L=0 ); | |||
| JACK_Module ( ); | |||
| virtual ~JACK_Module ( ); | |||
| const char *name ( void ) const { return "JACK"; } | |||
| void strip_name ( const char *name ) { _strip_name = name; } | |||
| bool initialize ( void ); | |||
| int can_support_inputs ( int ); | |||
| @@ -51,6 +47,8 @@ public: | |||
| void handle_control_changed ( Port *p ); | |||
| void handle_chain_name_changed (); | |||
| LOG_CREATE_FUNC( JACK_Module ); | |||
| protected: | |||
| virtual void process ( void ); | |||
| @@ -40,8 +40,58 @@ const float CONTROL_UPDATE_FREQ = 0.1f; | |||
| Meter_Indicator_Module::Meter_Indicator_Module ( int W, int H, const char *L ) | |||
| : Module ( W, 100, L ) | |||
| void | |||
| Meter_Indicator_Module::get ( Log_Entry &e ) const | |||
| { | |||
| Port *p = control_input[0].connected_port(); | |||
| Module *m = p->module(); | |||
| e.add( ":module", m ); | |||
| e.add( ":port", m->control_output_port_index( p ) ); | |||
| Module::get( e ); | |||
| } | |||
| void | |||
| Meter_Indicator_Module::set ( Log_Entry &e ) | |||
| { | |||
| Module::set( e ); | |||
| int port; | |||
| Module *module = NULL; | |||
| for ( int i = 0; i < e.size(); ++i ) | |||
| { | |||
| const char *s, *v; | |||
| e.get( i, &s, &v ); | |||
| if ( ! strcmp( s, ":port" ) ) | |||
| { | |||
| port = atoi( v ); | |||
| } | |||
| else if ( ! strcmp( s, ":module" ) ) | |||
| { | |||
| int i; | |||
| sscanf( v, "%X", &i ); | |||
| Module *t = (Module*)Loggable::find( i ); | |||
| assert( t ); | |||
| module = t; | |||
| } | |||
| } | |||
| if ( port >= 0 && module ) | |||
| control_input[0].connect_to( &module->control_output[port] ); | |||
| } | |||
| Meter_Indicator_Module::Meter_Indicator_Module ( bool is_default ) | |||
| : Module ( is_default, 50, 100, name() ) | |||
| { | |||
| box( FL_NO_BOX ); | |||
| @@ -55,6 +105,7 @@ Meter_Indicator_Module::Meter_Indicator_Module ( int W, int H, const char *L ) | |||
| dpm_pack->type( FL_HORIZONTAL ); | |||
| control_value = new float[1]; | |||
| *control_value = -70.0f; | |||
| end(); | |||
| @@ -64,9 +115,14 @@ Meter_Indicator_Module::Meter_Indicator_Module ( int W, int H, const char *L ) | |||
| Meter_Indicator_Module::~Meter_Indicator_Module ( ) | |||
| { | |||
| if ( control_value ) | |||
| { | |||
| delete[] control_value; | |||
| control_value = NULL; | |||
| } | |||
| Fl::remove_timeout( update_cb, this ); | |||
| log_destroy(); | |||
| } | |||
| @@ -39,7 +39,7 @@ class Meter_Indicator_Module : public Module | |||
| public: | |||
| Meter_Indicator_Module ( int W, int H, const char *L=0 ); | |||
| Meter_Indicator_Module ( bool is_default = false ); | |||
| virtual ~Meter_Indicator_Module ( ); | |||
| const char *name ( void ) const { return "Meter Indicator"; } | |||
| @@ -54,8 +54,12 @@ public: | |||
| void connect_to ( Port *p ); | |||
| LOG_CREATE_FUNC( Meter_Indicator_Module ); | |||
| protected: | |||
| void get ( Log_Entry &e ) const; | |||
| void set ( Log_Entry &e ); | |||
| // virtual void draw ( void ); | |||
| virtual void process ( void ); | |||
| @@ -31,8 +31,8 @@ const float METER_UPDATE_FREQ = 0.1f; | |||
| Meter_Module::Meter_Module ( int W, int, const char *L ) | |||
| : Module ( W, 100, L ) | |||
| Meter_Module::Meter_Module ( ) | |||
| : Module ( 50, 100, name() ) | |||
| { | |||
| box( FL_THIN_UP_FRAME ); | |||
| dpm_pack = new Fl_Scalepack( x(), y(), w(), h() ); | |||
| @@ -57,6 +57,7 @@ Meter_Module::Meter_Module ( int W, int, const char *L ) | |||
| Fl::add_timeout( METER_UPDATE_FREQ, update_cb, this ); | |||
| log_create(); | |||
| } | |||
| Meter_Module::~Meter_Module ( ) | |||
| @@ -65,6 +66,8 @@ Meter_Module::~Meter_Module ( ) | |||
| delete[] control_value; | |||
| Fl::remove_timeout( update_cb, this ); | |||
| log_destroy(); | |||
| } | |||
| void | |||
| @@ -117,8 +120,6 @@ Meter_Module::configure_inputs ( int n ) | |||
| audio_input.pop_back(); | |||
| audio_output.back().disconnect(); | |||
| audio_output.pop_back(); | |||
| control_output.back().disconnect(); | |||
| control_output.pop_back(); | |||
| } | |||
| } | |||
| @@ -130,14 +131,15 @@ Meter_Module::configure_inputs ( int n ) | |||
| for ( int i = n; i--; ) | |||
| f[i] = -70.0f; | |||
| control_output[0].connect_to( f); | |||
| control_output[0].connect_to( f ); | |||
| } | |||
| if ( control_value ) | |||
| delete [] control_value; | |||
| control_value = new float[n]; | |||
| for ( int i = n; i--; ) | |||
| control_value[i] = -70.0f; | |||
| return true; | |||
| } | |||
| @@ -34,7 +34,7 @@ class Meter_Module : public Module | |||
| public: | |||
| Meter_Module ( int W, int H, const char *L=0 ); | |||
| Meter_Module ( ); | |||
| virtual ~Meter_Module ( ); | |||
| const char *name ( void ) const { return "Meter"; } | |||
| @@ -42,6 +42,8 @@ public: | |||
| int can_support_inputs ( int n ) { return n > 0 ? n : -1; } | |||
| bool configure_inputs ( int n ); | |||
| LOG_CREATE_FUNC( Meter_Module ); | |||
| protected: | |||
| virtual int handle ( int m ); | |||
| @@ -24,9 +24,12 @@ | |||
| #include <FL/Fl_Pack.H> | |||
| #include <FL/Fl_Scroll.H> | |||
| #include <FL/Fl_Menu_Bar.H> | |||
| #include "Engine/Engine.H" | |||
| #include "Project.H" | |||
| #include <string.h> | |||
| #include "debug.h" | |||
| @@ -48,12 +51,18 @@ Mixer::Mixer ( int X, int Y, int W, int H, const char *L ) : | |||
| { | |||
| box( FL_NO_BOX ); | |||
| labelsize( 96 ); | |||
| { | |||
| Fl_Scroll *o = scroll = new Fl_Scroll( X, Y, W, H ); | |||
| { Fl_Menu_Bar *o = new Fl_Menu_Bar( X, Y, W, 24 ); | |||
| o->add( "&Project/&New" ); | |||
| o->add( "&Project/&Open" ); | |||
| o->add( "&Project/&Quit" ); | |||
| o->add( "&Mixer/&Add Strip" ); | |||
| o->add( "&Options" ); | |||
| } | |||
| { Fl_Scroll *o = scroll = new Fl_Scroll( X, Y + 24, W, H - 24 ); | |||
| o->box( FL_NO_BOX ); | |||
| o->type( Fl_Scroll::HORIZONTAL_ALWAYS ); | |||
| { | |||
| Fl_Pack *o = mixer_strips = new Fl_Pack( X, Y, W, H - 18 ); | |||
| Fl_Pack *o = mixer_strips = new Fl_Pack( X, Y + 24, W, H - 18 - 24 ); | |||
| label( "Non-Mixer" ); | |||
| align( (Fl_Align)(FL_ALIGN_CENTER | FL_ALIGN_INSIDE) ); | |||
| o->box( FL_NO_BOX ); | |||
| @@ -84,9 +93,9 @@ void Mixer::resize ( int X, int Y, int W, int H ) | |||
| { | |||
| Fl_Group::resize( X, Y, W, H ); | |||
| mixer_strips->resize( X, Y, W, H - 18 ); | |||
| mixer_strips->resize( X, Y + 24, W, H - 18 - 24 ); | |||
| scroll->resize( X, Y, W, H ); | |||
| scroll->resize( X, Y + 24, W, H - 24 ); | |||
| } | |||
| void Mixer::add ( Mixer_Strip *ms ) | |||
| @@ -181,7 +190,7 @@ void | |||
| Mixer::snapshot ( void ) | |||
| { | |||
| for ( int i = 0; i < mixer_strips->children(); ++i ) | |||
| ((Mixer_Strip*)mixer_strips->child( i ))->log_create(); | |||
| ((Mixer_Strip*)mixer_strips->child( i ))->log_children(); | |||
| } | |||
| @@ -197,6 +206,16 @@ Mixer::new_strip ( void ) | |||
| // scroll->size( mixer_strips->w(), scroll->h() ); | |||
| } | |||
| bool | |||
| Mixer::save ( void ) | |||
| { | |||
| MESSAGE( "Saving state" ); | |||
| Loggable::snapshot_callback( &Mixer::snapshot, this ); | |||
| Loggable::snapshot( "save.mix" ); | |||
| return true; | |||
| } | |||
| int | |||
| Mixer::handle ( int m ) | |||
| { | |||
| @@ -216,9 +235,8 @@ Mixer::handle ( int m ) | |||
| } | |||
| else if ( Fl::event_ctrl() && Fl::event_key() == 's' ) | |||
| { | |||
| MESSAGE( "Saving state" ); | |||
| Loggable::snapshot_callback( &Mixer::snapshot, this ); | |||
| Loggable::snapshot( "save.mix" ); | |||
| // save(); | |||
| Project::save(); | |||
| return 1; | |||
| } | |||
| else | |||
| @@ -56,6 +56,8 @@ public: | |||
| void remove ( Mixer_Strip *ms ); | |||
| bool contains ( Mixer_Strip *ms ); | |||
| bool save ( void ); | |||
| Mixer ( int X, int Y, int W, int H, const char *L ); | |||
| virtual ~Mixer(); | |||
| }; | |||
| @@ -58,12 +58,8 @@ void | |||
| Mixer_Strip::get ( Log_Entry &e ) const | |||
| { | |||
| e.add( ":name", name() ); | |||
| // e.add( ":controllable", controllable() ); | |||
| // e.add( ":inputs", _in.size() ); | |||
| /* e.add( ":gain", gain_slider->value() ); */ | |||
| e.add( ":meter_point", prepost_button->value() ? "pre" : "post" ); | |||
| e.add( ":width", prepost_button->value() ? "wide" : "narrow" ); | |||
| e.add( ":color", (unsigned long)color()); | |||
| } | |||
| void | |||
| @@ -77,13 +73,7 @@ Mixer_Strip::set ( Log_Entry &e ) | |||
| if ( ! strcmp( s, ":name" ) ) | |||
| name( v ); | |||
| // else if ( ! strcmp( s, ":controllable" ) ) | |||
| // controllable( atoi( v ) ); | |||
| else if ( ! strcmp( s, ":inputs" ) ) | |||
| configure_ports( atoi( v ) ); | |||
| /* else if ( ! strcmp( s, ":gain" ) ) */ | |||
| /* gain_slider->value( atof( v ) ); */ | |||
| else if ( ! strcmp( s, ":meter_point" ) ) | |||
| else if ( ! strcmp( s, ":width" ) ) | |||
| prepost_button->value( strcmp( v, "pre" ) == 0 ); | |||
| else if ( ! strcmp( s, ":color" ) ) | |||
| { | |||
| @@ -96,23 +86,62 @@ Mixer_Strip::set ( Log_Entry &e ) | |||
| mixer->add( this ); | |||
| } | |||
| void | |||
| Mixer_Strip::log_children ( void ) | |||
| { | |||
| log_create(); | |||
| _chain->log_children(); | |||
| } | |||
| Mixer_Strip::Mixer_Strip( const char *strip_name, int channels ) : Fl_Group( 0, 0, 120, 600 ) | |||
| void | |||
| Mixer_Strip::chain ( Chain *c ) | |||
| { | |||
| if ( _chain ) | |||
| delete _chain; | |||
| _chain = c; | |||
| c->strip( this ); | |||
| Fl_Group *g = signal_group; | |||
| c->resize( g->x(), g->y(), g->w(), g->h() ); | |||
| g->add( c ); | |||
| g->resizable( c ); | |||
| c->labelsize( 10 ); | |||
| c->align( FL_ALIGN_TOP ); | |||
| c->color( FL_RED ); | |||
| c->configure_outputs_callback( configure_outputs, this ); | |||
| c->name( name() ); | |||
| gain_controller->chain( c ); | |||
| jack_input_controller->chain( c ); | |||
| meter_indicator->chain( c ); | |||
| } | |||
| /* add a new mixer strip (with default configuration) */ | |||
| Mixer_Strip::Mixer_Strip( const char *strip_name, int channels ) : Fl_Group( 0, 0, 120, 600 ) | |||
| { | |||
| label( strdup( strip_name ) ); | |||
| init(); | |||
| chain( new Chain() ); | |||
| _chain->initialize_with_default(); | |||
| _chain->configure_ports(); | |||
| color( (Fl_Color)rand() ); | |||
| // name( strdup( strip_name ) ); | |||
| configure_ports( channels ); | |||
| log_create(); | |||
| } | |||
| /* virgin strip created from journal */ | |||
| Mixer_Strip::Mixer_Strip() : Fl_Group( 0, 0, 120, 600 ) | |||
| { | |||
| init(); | |||
| @@ -122,7 +151,7 @@ Mixer_Strip::Mixer_Strip() : Fl_Group( 0, 0, 120, 600 ) | |||
| Mixer_Strip::~Mixer_Strip ( ) | |||
| { | |||
| configure_ports( 0 ); | |||
| log_destroy(); | |||
| } | |||
| @@ -154,7 +183,8 @@ Mixer_Strip::name ( const char *name ) { | |||
| char *s = strdup( name ); | |||
| name_field->value( s ); | |||
| label( s ); | |||
| chain->name( s ); | |||
| if ( _chain ) | |||
| _chain->name( s ); | |||
| } | |||
| void | |||
| @@ -169,90 +199,38 @@ Mixer_Strip::configure_outputs ( void ) | |||
| DMESSAGE( "Got signal to configure outputs" ); | |||
| } | |||
| bool | |||
| Mixer_Strip::configure_ports ( int n ) | |||
| /* called by the chain to let us know that a module has been added */ | |||
| void | |||
| Mixer_Strip::handle_module_added ( Module *m ) | |||
| { | |||
| /* /\* figure out how many buffers we have to create *\/ */ | |||
| /* int required_buffers = chain->required_buffers(); */ | |||
| /* engine->lock(); */ | |||
| /* if ( chain_buffers > 0 ) */ | |||
| /* { */ | |||
| /* for ( int i = chain_buffers; --i; ) */ | |||
| /* { */ | |||
| /* delete chain_buffer[i]; */ | |||
| /* chain_buffer[i] = NULL; */ | |||
| /* } */ | |||
| /* delete chain_buffer; */ | |||
| /* chain_buffer = NULL; */ | |||
| /* chain_buffers = 0; */ | |||
| /* } */ | |||
| /* sample_t **buf = new sample_t*[required_buffers]; */ | |||
| /* for ( int i = 0; i < required_buffers; ++i ) */ | |||
| /* buf[i] = new sample_t[nframes]; */ | |||
| /* chain_buffers = required_buffers; */ | |||
| /* chain_buffer = buf; */ | |||
| /* engine->unlock(); */ | |||
| /* /\* FIXME: bogus *\/ */ | |||
| /* return true; */ | |||
| if ( m->is_default() ) | |||
| { | |||
| DMESSAGE( "Connecting controls to default module \"%s\"", m->name() ); | |||
| /* connect default modules to their default controllers/indicators */ | |||
| if ( ! strcmp( m->name(), "JACK" ) && m->ninputs() == 0 ) | |||
| { | |||
| if ( !jack_input_controller->control_output[0].connected() ) | |||
| jack_input_controller->connect_to( &m->control_input[1] ); | |||
| } | |||
| else if ( ! strcmp( m->name(), "Gain" ) ) | |||
| { | |||
| gain_controller->connect_to( &m->control_input[0] ); | |||
| } | |||
| else if ( ! strcmp( m->name(), "Meter" ) ) | |||
| { | |||
| meter_indicator->connect_to( &m->control_output[0] ); | |||
| } | |||
| } | |||
| } | |||
| void | |||
| Mixer_Strip::process ( nframes_t nframes ) | |||
| { | |||
| THREAD_ASSERT( RT ); | |||
| /* sample_t *gain_buf = NULL; */ | |||
| /* float g = gain_slider->value(); */ | |||
| /* if ( _control && _control->connected() ) */ | |||
| /* { */ | |||
| /* gain_buf = (sample_t*)_control->buffer( nframes ); */ | |||
| /* /\* // bring it up to 0.0-2.0f *\/ */ | |||
| /* /\* for ( int i = nframes; i--; ) *\/ */ | |||
| /* /\* gain_buf[i] += 1.0f; *\/ */ | |||
| /* // apply gain from slider */ | |||
| /* buffer_apply_gain( gain_buf, nframes, g ); */ | |||
| /* /\* FIXME: bullshit! *\/ */ | |||
| /* _control_peak = gain_buf[0]; */ | |||
| /* } */ | |||
| /* else */ | |||
| /* { */ | |||
| /* _control_peak = 0; */ | |||
| /* } */ | |||
| /* for ( int i = channels(); i--; ) */ | |||
| /* { */ | |||
| /* if ( _in[i].connected()) */ | |||
| /* { */ | |||
| /* if ( gain_buf ) */ | |||
| /* buffer_copy_and_apply_gain_buffer( (sample_t*)_out[i].buffer( nframes ), (sample_t*)_in[i].buffer( nframes ), gain_buf, nframes ); */ | |||
| /* else */ | |||
| /* buffer_copy_and_apply_gain( (sample_t*)_out[i].buffer( nframes ), (sample_t*)_in[i].buffer( nframes ), nframes, g ); */ | |||
| /* sample_t *meter_buffer = prepost_button->value() == 1 ? (sample_t*)_in[i].buffer( nframes ) : (sample_t*)_out[i].buffer( nframes ); */ | |||
| /* /\* set peak value (in dB) *\/ */ | |||
| /* _peak[i] = 20 * log10( get_peak_sample( meter_buffer, nframes ) / 2.0f ); */ | |||
| /* } */ | |||
| /* else */ | |||
| /* { */ | |||
| /* buffer_fill_with_silence( (sample_t*)_out[i].buffer( nframes ), nframes ); */ | |||
| /* } */ | |||
| /* } */ | |||
| chain->process( nframes ); | |||
| _chain->process( nframes ); | |||
| } | |||
| /* update GUI with values from RT thread */ | |||
| @@ -265,6 +243,8 @@ Mixer_Strip::update ( void ) | |||
| void | |||
| Mixer_Strip::init ( ) | |||
| { | |||
| _chain = 0; | |||
| chain_buffers = 0; | |||
| chain_buffer = NULL; | |||
| @@ -332,24 +312,31 @@ Mixer_Strip::init ( ) | |||
| { Fl_Pack* o = fader_pack = new Fl_Pack(4, 116, 103, 330 ); | |||
| o->spacing( 20 ); | |||
| o->type( Fl_Pack::HORIZONTAL ); | |||
| { Controller_Module *o = gain_controller = new Controller_Module( true ); | |||
| // o->chain( _chain ); | |||
| o->pad( false ); | |||
| // o->connect_to( &gain_module->control_input[0] ); | |||
| o->size( 33, 0 ); | |||
| } | |||
| { Meter_Indicator_Module *o = meter_indicator = new Meter_Indicator_Module( true ); | |||
| // o->chain( _chain ); | |||
| o->pad( false ); | |||
| // o->connect_to( &meter_module->control_output[0] ); | |||
| o->size( 58, 0 ); | |||
| o->clip_children( 0 ); | |||
| Fl_Group::current()->resizable(o); | |||
| } | |||
| o->end(); | |||
| Fl_Group::current()->resizable(o); | |||
| } // Fl_Group* o | |||
| o->end(); | |||
| Fl_Group::current()->resizable(o); | |||
| } | |||
| { Fl_Group *o = new Fl_Group( 4, 114, 110, 330, "Signal" ); | |||
| { Fl_Group *o = signal_group = new Fl_Group( 4, 114, 110, 330, "Signal" ); | |||
| o->labelsize( 9 ); | |||
| o->hide(); | |||
| { Chain *o = chain = new Chain( 4, 116, 110, 330 ); | |||
| o->labelsize( 10 ); | |||
| o->align( FL_ALIGN_TOP ); | |||
| o->color( FL_RED ); | |||
| o->configure_outputs_callback( configure_outputs, this ); | |||
| o->name( name() ); | |||
| o->initialize_with_default(); | |||
| Fl_Group::current()->resizable(o); | |||
| } | |||
| o->end(); | |||
| } | |||
| @@ -357,7 +344,9 @@ Mixer_Strip::init ( ) | |||
| Fl_Group::current()->resizable(o); | |||
| } | |||
| { Fl_Pack *o = new Fl_Pack( 2, 440, 114, 40 ); | |||
| // log_create(); | |||
| { Fl_Pack *o = panner_pack = new Fl_Pack( 2, 440, 114, 40 ); | |||
| o->spacing( 2 ); | |||
| o->type( Fl_Pack::VERTICAL ); | |||
| @@ -380,10 +369,11 @@ Mixer_Strip::init ( ) | |||
| } // Panner* o | |||
| #endif | |||
| { | |||
| Controller_Module *m = new Controller_Module( 100, 24, "Inputs" ); | |||
| m->chain( chain ); | |||
| Controller_Module *m = jack_input_controller = new Controller_Module( true ); | |||
| m->label( "Inputs" ); | |||
| m->chain( _chain ); | |||
| m->pad( false ); | |||
| m->connect_to( &chain->module( 0 )->control_input[1] ); | |||
| // m->connect_to( &_chain->module( 0 )->control_input[1] ); | |||
| m->size( 33, 24 ); | |||
| } | |||
| o->end(); | |||
| @@ -392,49 +382,8 @@ Mixer_Strip::init ( ) | |||
| end(); | |||
| color( FL_BLACK ); | |||
| // controllable( true ); | |||
| { | |||
| Module *gain_module; | |||
| { | |||
| Module *m = gain_module = new Gain_Module( 50, 50, "Gain" ); | |||
| m->initialize(); | |||
| chain->insert( chain->module( chain->modules() - 1 ), m ); | |||
| } | |||
| { | |||
| Controller_Module *m = new Controller_Module( 100, 0, "Gain" ); | |||
| m->chain( chain ); | |||
| m->pad( false ); | |||
| m->connect_to( &gain_module->control_input[0] ); | |||
| m->size( 33, 0 ); | |||
| fader_pack->add( m ); | |||
| } | |||
| Module *meter_module; | |||
| { | |||
| Module *m = meter_module = new Meter_Module( 50, 50, "Meter" ); | |||
| chain->insert( chain->module( chain->modules() - 1 ), m ); | |||
| } | |||
| { | |||
| Meter_Indicator_Module *m = new Meter_Indicator_Module( 100, 0, "" ); | |||
| m->chain( chain ); | |||
| m->pad( false ); | |||
| m->connect_to( &meter_module->control_output[0] ); | |||
| m->size( 58, 0 ); | |||
| m->clip_children( 0 ); | |||
| fader_pack->add( m ); | |||
| fader_pack->resizable( m ); | |||
| } | |||
| chain->configure_ports(); | |||
| } | |||
| // _chain->configure_ports(); | |||
| } | |||
| @@ -1,7 +1,24 @@ | |||
| // generated by Fast Light User Interface Designer (fluid) version 1.0108 | |||
| #ifndef Mixer_Strip_H | |||
| #define Mixer_Strip_H | |||
| /*******************************************************************************/ | |||
| /* Copyright (C) 2010 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 "DPM.H" | |||
| #include "Panner.H" | |||
| @@ -26,6 +43,9 @@ | |||
| #include "Loggable.H" | |||
| class Chain; | |||
| class Fl_Flowpack; | |||
| class Controller_Module; | |||
| class Meter_Indicator_Module; | |||
| class Module; | |||
| class Mixer_Strip : public Fl_Group, public Loggable { | |||
| @@ -42,8 +62,14 @@ public: | |||
| Fl_Input *name_field; | |||
| Fl_Flowpack *controls_pack; | |||
| Fl_Group *signal_group; | |||
| Fl_Pack *panner_pack; | |||
| Chain *_chain; | |||
| Chain *chain; | |||
| Controller_Module *gain_controller; | |||
| Controller_Module *jack_input_controller; | |||
| Meter_Indicator_Module *meter_indicator; | |||
| sample_t **chain_buffer; | |||
| int chain_buffers; | |||
| @@ -69,6 +95,10 @@ protected: | |||
| public: | |||
| void chain ( Chain *c ); | |||
| void log_children ( void ); | |||
| void color ( Fl_Color c ) | |||
| { | |||
| _color = c; | |||
| @@ -90,10 +120,11 @@ public: | |||
| bool configure_ports ( int n ); | |||
| void handle_module_added ( Module *m ); | |||
| void update ( void ); | |||
| // int channels ( void ) const { return _in.size(); } | |||
| void name ( const char *name ); | |||
| const char *name ( void ) const { return label(); } | |||
| }; | |||
| #endif | |||
| @@ -25,9 +25,33 @@ | |||
| #include <stdio.h> | |||
| #include "Module_Parameter_Editor.H" | |||
| #include "Chain.H" | |||
| Module::Module ( int W, int H, const char *L ) : Fl_Group( 0, 0, W, H, L ) | |||
| { | |||
| init(); | |||
| log_create(); | |||
| } | |||
| Module::Module ( bool is_default, int W, int H, const char *L ) : Fl_Group( 0, 0, W, H, L ), Loggable( !is_default ) | |||
| { | |||
| this->is_default( is_default ); | |||
| init(); | |||
| log_create(); | |||
| } | |||
| Module::Module ( ) : Fl_Group( 0, 0, 0, 50, "Unnamed" ) | |||
| { | |||
| init(); | |||
| log_create(); | |||
| } | |||
| Module::~Module ( ) | |||
| { | |||
| for ( unsigned int i = 0; i < audio_input.size(); ++i ) | |||
| @@ -47,12 +71,95 @@ Module::~Module ( ) | |||
| void | |||
| Module::init ( void ) | |||
| { | |||
| _is_default = false; | |||
| _editor = 0; | |||
| _chain = 0; | |||
| _instances = 1; | |||
| box( FL_UP_BOX ); | |||
| labeltype( FL_NO_LABEL ); | |||
| clip_children( 1 ); | |||
| } | |||
| void | |||
| Module::get ( Log_Entry &e ) const | |||
| { | |||
| // e.add( ":name", label() ); | |||
| // e.add( ":color", (unsigned long)color()); | |||
| { | |||
| char *s = get_parameters(); | |||
| if ( strlen( s ) ) | |||
| e.add( ":parameter_values", s ); | |||
| delete[] s; | |||
| } | |||
| e.add( ":is_default", is_default() ); | |||
| e.add( ":chain", chain() ); | |||
| } | |||
| void | |||
| Module::set ( Log_Entry &e ) | |||
| { | |||
| for ( int i = 0; i < e.size(); ++i ) | |||
| { | |||
| const char *s, *v; | |||
| e.get( i, &s, &v ); | |||
| if ( ! strcmp( s, ":chain" ) ) | |||
| { | |||
| /* This trickiness is because we may need to know the name of | |||
| our chain before we actually get added to it. */ | |||
| int i; | |||
| sscanf( v, "%X", &i ); | |||
| Chain *t = (Chain*)Loggable::find( i ); | |||
| assert( t ); | |||
| chain( t ); | |||
| } | |||
| } | |||
| for ( int i = 0; i < e.size(); ++i ) | |||
| { | |||
| const char *s, *v; | |||
| e.get( i, &s, &v ); | |||
| /* if ( ! strcmp( s, ":name" ) ) */ | |||
| /* label( v ); */ | |||
| if ( ! strcmp( s, ":parameter_values" ) ) | |||
| { | |||
| set_parameters( v ); | |||
| } | |||
| else if ( ! ( strcmp( s, ":is_default" ) ) ) | |||
| { | |||
| is_default( atoi( v ) ); | |||
| } | |||
| else if ( ! strcmp( s, ":chain" ) ) | |||
| { | |||
| int i; | |||
| sscanf( v, "%X", &i ); | |||
| Chain *t = (Chain*)Loggable::find( i ); | |||
| assert( t ); | |||
| t->add( this ); | |||
| } | |||
| } | |||
| } | |||
| /* return a string serializing this module's parameter settings. The | |||
| format is 1.0:2.0:... Where 1.0 is the value of the first control | |||
| input, 2.0 is the value of the second control input etc. | |||
| */ | |||
| */ | |||
| char * | |||
| Module::describe_inputs ( void ) const | |||
| Module::get_parameters ( void ) const | |||
| { | |||
| char *s = new char[1024]; | |||
| s[0] = 0; | |||
| @@ -60,15 +167,53 @@ Module::describe_inputs ( void ) const | |||
| if ( control_input.size() ) | |||
| { | |||
| for ( unsigned int i = 0; i < control_input.size(); ++i ) | |||
| sp += snprintf( sp, 1024 - (sp - s),"%f:", control_input[i].control_value() ); | |||
| for ( unsigned int i = 0; i < control_input.size(); ++i ) | |||
| sp += snprintf( sp, 1024 - (sp - s),"%f:", control_input[i].control_value() ); | |||
| *(sp - 1) = '\0'; | |||
| *(sp - 1) = '\0'; | |||
| } | |||
| return s; | |||
| } | |||
| void | |||
| Module::set_parameters ( const char *parameters ) | |||
| { | |||
| char *s = strdup( parameters ); | |||
| char *sp = s; | |||
| char *start = s; | |||
| int i = 0; | |||
| for ( char *sp = s; ; ++sp ) | |||
| { | |||
| if ( ':' == *sp || '\0' == *sp ) | |||
| { | |||
| char was = *sp; | |||
| *sp = '\0'; | |||
| DMESSAGE( start ); | |||
| if ( i < control_input.size() ) | |||
| control_input[i].control_value( atof( start ) ); | |||
| else | |||
| { | |||
| WARNING( "Module has no parameter at index %i", i ); | |||
| break; | |||
| } | |||
| i++; | |||
| if ( '\0' == was ) | |||
| break; | |||
| start = sp + 1; | |||
| } | |||
| } | |||
| free( s ); | |||
| } | |||
| void | |||
| @@ -87,10 +232,14 @@ Module::draw_box ( void ) | |||
| fl_push_clip( tx, ty, tw, th ); | |||
| Fl_Color c = is_default() ? FL_BLACK : color(); | |||
| int spacing = w() / instances(); | |||
| for ( int i = instances(); i--; ) | |||
| { | |||
| fl_draw_box( box(), tx + (spacing * i), ty, tw / instances(), th, Fl::belowmouse() == this ? fl_lighter( color() ) : color() ); | |||
| fl_draw_box( box(), tx + (spacing * i), ty, tw / instances(), th, Fl::belowmouse() == this ? fl_lighter( c ) : c ); | |||
| } | |||
| if ( audio_input.size() && audio_output.size() ) | |||
| @@ -30,41 +30,43 @@ | |||
| #include "util/Thread.H" | |||
| #include "Loggable.H" | |||
| class Chain; | |||
| class Module_Parameter_Editor; | |||
| class Module : public Fl_Group { | |||
| void init ( void ) | |||
| { | |||
| _editor = 0; | |||
| _chain = 0; | |||
| _instances = 1; | |||
| box( FL_UP_BOX ); | |||
| labeltype( FL_NO_LABEL ); | |||
| clip_children( 1 ); | |||
| } | |||
| class Module : public Fl_Group, public Loggable { | |||
| int _ins; | |||
| int _outs; | |||
| int _instances; | |||
| unsigned long _nframes; | |||
| Chain *_chain; | |||
| bool _is_default; | |||
| Module_Parameter_Editor *_editor; | |||
| void cb_handle(Fl_Widget*); | |||
| static void cb_handle(Fl_Widget*, void*); | |||
| void init ( void ); | |||
| 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; } | |||
| 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: | |||
| @@ -175,7 +177,7 @@ public: | |||
| void connect_to ( void *buf ) | |||
| { | |||
| _buf = buf; | |||
| // _connected = (Port*)0x01; | |||
| update_connected_port_buffer(); | |||
| } | |||
| void disconnect ( void ) | |||
| @@ -210,16 +212,14 @@ public: | |||
| H = h() - 10; | |||
| } | |||
| Module ( int W, int H, const char *L = 0 ) : Fl_Group( 0, 0, W, H, L ) | |||
| { | |||
| init(); | |||
| } | |||
| Module ( ) : Fl_Group( 0, 0, 0, 50, "Unnamed" ) | |||
| { | |||
| init(); | |||
| } | |||
| 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 ); | |||
| // static Module * pick_plugin ( void ); | |||
| @@ -286,10 +286,29 @@ public: | |||
| } | |||
| int control_input_port_index ( Port *p ) | |||
| { | |||
| for ( unsigned int i = control_input.size(); i--; ) | |||
| if ( &control_input[i] == p ) | |||
| return i; | |||
| return -1; | |||
| } | |||
| int control_output_port_index ( Port *p ) | |||
| { | |||
| for ( unsigned int i = control_output.size(); i--; ) | |||
| if ( &control_output[i] == p ) | |||
| return i; | |||
| return -1; | |||
| } | |||
| Chain *chain ( void ) const { return _chain; } | |||
| void chain ( Chain * v ) { _chain = v; } | |||
| char *describe_inputs ( void ) const; | |||
| char *get_parameters ( void ) const; | |||
| void set_parameters ( const char * ); | |||
| virtual bool initialize ( void ) { return true; } | |||
| @@ -314,8 +333,6 @@ public: | |||
| virtual void handle_port_connection_change () {} | |||
| protected: | |||
| void draw_connections ( void ); | |||
| @@ -325,4 +342,7 @@ protected: | |||
| virtual void draw ( void ) { Module::draw_box(); Module::draw_label(); } | |||
| virtual int handle ( int m ); | |||
| virtual void get ( Log_Entry &e ) const; | |||
| virtual void set ( Log_Entry &e ); | |||
| }; | |||
| @@ -281,7 +281,8 @@ Module_Parameter_Editor::bind_control ( int i ) | |||
| /* can only bind once */ | |||
| return; | |||
| Controller_Module *o = new Controller_Module( 50, 50, p->name() ); | |||
| Controller_Module *o = new Controller_Module(); | |||
| o->label( p->name() ); | |||
| o->chain( _module->chain() ); | |||
| o->connect_to( p ); | |||
| @@ -54,26 +54,54 @@ struct Plugin_Module::ImplementationData | |||
| Plugin_Module::Plugin_Module ( int , int , const char *L ) : Module( 50, 50, L ) | |||
| Plugin_Module::Plugin_Module ( ) : Module( 50, 50, name() ) | |||
| { | |||
| init(); | |||
| end(); | |||
| log_create(); | |||
| } | |||
| Plugin_Module::~Plugin_Module ( ) | |||
| { | |||
| log_destroy(); | |||
| plugin_instances( 0 ); | |||
| } | |||
| /* void */ | |||
| /* Plugin_Module::detect_plugins ( void ) */ | |||
| /* { */ | |||
| /* LADPSAInfo *li = new LADSPAInfo(); */ | |||
| /* } */ | |||
| void | |||
| Plugin_Module::get ( Log_Entry &e ) const | |||
| { | |||
| // char s[512]; | |||
| // snprintf( s, sizeof( s ), "ladspa:%lu", _idata->descriptor->UniqueID ); | |||
| e.add( ":plugin_id", _idata->descriptor->UniqueID ); | |||
| Module::get( e ); | |||
| } | |||
| void | |||
| Plugin_Module::set ( Log_Entry &e ) | |||
| { | |||
| for ( int i = 0; i < e.size(); ++i ) | |||
| { | |||
| const char *s, *v; | |||
| e.get( i, &s, &v ); | |||
| if ( ! strcmp( s, ":plugin_id" ) ) | |||
| { | |||
| load( (unsigned long) atoll ( v ) ); | |||
| } | |||
| } | |||
| Module::set( e ); | |||
| } | |||
| #include <FL/Fl_Menu_Button.H> | |||
| @@ -106,15 +134,9 @@ Plugin_Module::pick_plugin ( void ) | |||
| Plugin_Module::Plugin_Info *pi = (Plugin_Module::Plugin_Info*)menu->menu()[ menu->value() ].user_data(); | |||
| Plugin_Module *m = new Plugin_Module( 50, 50 ); | |||
| m->load( pi ); | |||
| Plugin_Module *m = new Plugin_Module(); | |||
| const char *plugin_name = pi->path; | |||
| char *label = strdup( rindex(plugin_name, '/') + 1 ); | |||
| m->label( label ); | |||
| m->load( pi->id ); | |||
| delete[] pia; | |||
| @@ -342,9 +364,14 @@ Plugin_Module::plugin_instances ( unsigned int n ) | |||
| } | |||
| bool | |||
| Plugin_Module::load ( Plugin_Module::Plugin_Info *pi ) | |||
| Plugin_Module::load ( unsigned long id ) | |||
| { | |||
| _idata->descriptor = ladspainfo->GetDescriptorByID( pi->id ); | |||
| if ( !ladspainfo ) | |||
| ladspainfo = new LADSPAInfo(); | |||
| _idata->descriptor = ladspainfo->GetDescriptorByID( id ); | |||
| label( _idata->descriptor->Name ); | |||
| _plugin_ins = _plugin_outs = 0; | |||
| @@ -488,9 +515,9 @@ Plugin_Module::load ( Plugin_Module::Plugin_Info *pi ) | |||
| bool neg_max = max < 0.0f ? true : false; | |||
| if (!neg_min && !neg_max) { | |||
| Default = exp(log(min) * lp + log(max) * up); | |||
| Default = exp(::log(min) * lp + ::log(max) * up); | |||
| } else if (neg_min && neg_max) { | |||
| Default = -exp(log(-min) * lp + log(-max) * up); | |||
| Default = -exp(::log(-min) * lp + ::log(-max) * up); | |||
| } else { | |||
| // Logarithmic range has asymptote | |||
| // so just use linear scale | |||
| @@ -20,6 +20,7 @@ | |||
| #pragma once | |||
| #include "Module.H" | |||
| #include "Loggable.H" | |||
| class Plugin_Module : Module { | |||
| @@ -61,7 +62,7 @@ class Plugin_Module : Module { | |||
| static Plugin_Info* discover ( void ); | |||
| bool load ( Plugin_Info * ); | |||
| bool load ( unsigned long id ); | |||
| void set_input_buffer ( int n, void *buf ); | |||
| void set_output_buffer ( int n, void *buf ); | |||
| @@ -77,7 +78,6 @@ class Plugin_Module : Module { | |||
| public: | |||
| Plugin_Module( int W, int H, const char *L = 0 ); | |||
| Plugin_Module ( ); | |||
| virtual ~Plugin_Module(); | |||
| @@ -97,8 +97,12 @@ public: | |||
| void handle_port_connection_change ( void ); | |||
| LOG_CREATE_FUNC( Plugin_Module ); | |||
| protected: | |||
| virtual int handle ( int ); | |||
| void get ( Log_Entry &e ) const; | |||
| void set ( Log_Entry &e ); | |||
| }; | |||
| @@ -0,0 +1,324 @@ | |||
| /*******************************************************************************/ | |||
| /* Copyright (C) 2008 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. */ | |||
| /*******************************************************************************/ | |||
| /* Routings for opening/closing/creation of projects. All the actual | |||
| project state belongs to Timeline and other classes. */ | |||
| /* Project management routines. */ | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include <sys/types.h> | |||
| #include <sys/stat.h> | |||
| #include <sys/fcntl.h> | |||
| #include <errno.h> | |||
| #include "Loggable.H" | |||
| #include "Project.H" | |||
| #include <FL/filename.H> | |||
| #include "const.h" | |||
| #include "util/debug.h" | |||
| #include "util/file.h" | |||
| #include "Mixer.H" | |||
| const int PROJECT_VERSION = 1; | |||
| const char *Project::_errstr[] = | |||
| { | |||
| "Not a Non-Mixer project", | |||
| "Locked by another process", | |||
| "Access denied", | |||
| "Incompatible project version" | |||
| }; | |||
| char Project::_name[256]; | |||
| char Project::_created_on[40]; | |||
| char Project::_path[512]; | |||
| bool Project::_is_open = false; | |||
| int Project::_lockfd = 0; | |||
| /***********/ | |||
| /* Private */ | |||
| /***********/ | |||
| void | |||
| Project::set_name ( const char *name ) | |||
| { | |||
| strcpy( Project::_name, name ); | |||
| if ( Project::_name[ strlen( Project::_name ) - 1 ] == '/' ) | |||
| Project::_name[ strlen( Project::_name ) - 1 ] = '\0'; | |||
| char *s = rindex( Project::_name, '/' ); | |||
| s = s ? s + 1 : Project::_name; | |||
| memmove( Project::_name, s, strlen( s ) + 1 ); | |||
| for ( s = Project::_name; *s; ++s ) | |||
| if ( *s == '_' || *s == '-' ) | |||
| *s = ' '; | |||
| } | |||
| bool | |||
| Project::write_info ( void ) | |||
| { | |||
| FILE *fp; | |||
| if ( ! ( fp = fopen( "info", "w" ) ) ) | |||
| { | |||
| WARNING( "could not open project info file for writing." ); | |||
| return false; | |||
| } | |||
| char s[40]; | |||
| if ( ! *_created_on ) | |||
| { | |||
| time_t t = time( NULL ); | |||
| ctime_r( &t, s ); | |||
| s[ strlen( s ) - 1 ] = '\0'; | |||
| } | |||
| else | |||
| strcpy( s, _created_on ); | |||
| fprintf( fp, "created by\n\t%s\ncreated on\n\t%s\nversion\n\t%d\n", | |||
| APP_TITLE " " VERSION, | |||
| s, | |||
| PROJECT_VERSION ); | |||
| fclose( fp ); | |||
| return true; | |||
| } | |||
| bool | |||
| Project::read_info ( int *version, char **creation_date ) | |||
| { | |||
| FILE *fp; | |||
| if ( ! ( fp = fopen( "info", "r" ) ) ) | |||
| { | |||
| WARNING( "could not open project info file for reading." ); | |||
| return false; | |||
| } | |||
| *version = 0; | |||
| *creation_date = 0; | |||
| char *name, *value; | |||
| while ( fscanf( fp, "%a[^\n]\n\t%a[^\n]\n", &name, &value ) == 2 ) | |||
| { | |||
| MESSAGE( "Info: %s = %s", name, value ); | |||
| if ( ! strcmp( name, "version" ) ) | |||
| *version = atoi( value ); | |||
| else if ( ! strcmp( name, "created on" ) ) | |||
| *creation_date = strdup( value ); | |||
| free( name ); | |||
| free( value ); | |||
| } | |||
| fclose( fp ); | |||
| return true; | |||
| } | |||
| /**********/ | |||
| /* Public */ | |||
| /**********/ | |||
| /** Save out any settings and unjournaled state... */ | |||
| bool | |||
| Project::save ( void ) | |||
| { | |||
| if ( ! open() ) | |||
| return true; | |||
| // tle->save_timeline_settings(); | |||
| return mixer->save(); | |||
| // return Loggable::save_unjournaled_state(); | |||
| } | |||
| /** Close the project (reclaiming all memory) */ | |||
| bool | |||
| Project::close ( void ) | |||
| { | |||
| if ( ! open() ) | |||
| return true; | |||
| if ( ! save() ) | |||
| return false; | |||
| /* Loggable::close(); */ | |||
| /* // write_info(); */ | |||
| _is_open = false; | |||
| *Project::_name = '\0'; | |||
| *Project::_created_on = '\0'; | |||
| release_lock( &_lockfd, ".lock" ); | |||
| return true; | |||
| } | |||
| /** Ensure a project is valid before opening it... */ | |||
| bool | |||
| Project::validate ( const char *name ) | |||
| { | |||
| bool r = true; | |||
| char pwd[512]; | |||
| fl_filename_absolute( pwd, sizeof( pwd ), "." ); | |||
| if ( chdir( name ) ) | |||
| { | |||
| WARNING( "Cannot change to project dir \"%s\"", name ); | |||
| return false; | |||
| } | |||
| if ( ! exists( "info" ) || | |||
| ! exists( "snapshot" )) | |||
| { | |||
| WARNING( "Not a Non-Mixer project: \"%s\"", name ); | |||
| r = false; | |||
| } | |||
| chdir( pwd ); | |||
| return r; | |||
| } | |||
| /** Try to open project /name/. Returns 0 if sucsessful, an error code | |||
| * otherwise */ | |||
| int | |||
| Project::open ( const char *name ) | |||
| { | |||
| if ( ! validate( name ) ) | |||
| return E_INVALID; | |||
| close(); | |||
| chdir( name ); | |||
| if ( ! acquire_lock( &_lockfd, ".lock" ) ) | |||
| return E_LOCKED; | |||
| int version; | |||
| char *creation_date; | |||
| if ( ! read_info( &version, &creation_date ) ) | |||
| return E_INVALID; | |||
| if ( version != PROJECT_VERSION ) | |||
| return E_VERSION; | |||
| if ( ! Loggable::replay( "snapshot" ) ) | |||
| return E_INVALID; | |||
| if ( creation_date ) | |||
| { | |||
| strcpy( _created_on, creation_date ); | |||
| free( creation_date ); | |||
| } | |||
| else | |||
| *_created_on = 0; | |||
| set_name( name ); | |||
| *_path = '\0'; | |||
| fl_filename_absolute( _path, sizeof( _path ), "." ); | |||
| _is_open = true; | |||
| // tle->load_timeline_settings(); | |||
| // timeline->zoom_fit(); | |||
| MESSAGE( "Loaded project \"%s\"", name ); | |||
| return 0; | |||
| } | |||
| /** Create a new project /name/ from existing template | |||
| * /template_name/ */ | |||
| bool | |||
| Project::create ( const char *name, const char *template_name ) | |||
| { | |||
| if ( exists( name ) ) | |||
| { | |||
| WARNING( "Project already exists" ); | |||
| return false; | |||
| } | |||
| close(); | |||
| if ( mkdir( name, 0777 ) ) | |||
| { | |||
| WARNING( "Cannot create project directory" ); | |||
| return false; | |||
| } | |||
| if ( chdir( name ) ) | |||
| FATAL( "WTF? Cannot change to new project directory" ); | |||
| mkdir( "sources", 0777 ); | |||
| creat( "snapshot", 0666 ); | |||
| /* TODO: copy template */ | |||
| write_info(); | |||
| if ( open( name ) == 0 ) | |||
| { | |||
| // /* add the bare essentials */ | |||
| // timeline->beats_per_minute( 0, 120 ); | |||
| // timeline->time( 0, 4, 4 ); | |||
| MESSAGE( "Created project \"%s\" from template \"%s\"", name, template_name ); | |||
| return true; | |||
| } | |||
| else | |||
| { | |||
| WARNING( "Failed to open newly created project" ); | |||
| return false; | |||
| } | |||
| } | |||
| /** Replace the journal with a snapshot of the current state */ | |||
| void | |||
| Project::compact ( void ) | |||
| { | |||
| Loggable::compact(); | |||
| } | |||
| @@ -0,0 +1,62 @@ | |||
| /*******************************************************************************/ | |||
| /* Copyright (C) 2008, 2010 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. */ | |||
| /*******************************************************************************/ | |||
| const char template_dir[] = "share/non-daw/templates"; | |||
| const char user_template_dir[] = "~/.non-daw/templates"; | |||
| #include "types.h" | |||
| class Project | |||
| { | |||
| static int _lockfd; | |||
| static bool _is_open; | |||
| static char _name[256]; | |||
| static char _path[512]; | |||
| static char _created_on[40]; | |||
| static bool write_info ( void ); | |||
| static bool read_info ( int *version, char **creation_date ); | |||
| static void set_name ( const char *name ); | |||
| static const char *_errstr[]; | |||
| public: | |||
| enum | |||
| { | |||
| E_INVALID = -1, | |||
| E_LOCKED = -2, | |||
| E_PERM = -3, | |||
| E_SAMPLERATE = -4, | |||
| E_VERSION = -5 | |||
| }; | |||
| static const char *errstr ( int n ) { return _errstr[ ( 0 - n ) - 1 ]; } | |||
| static const char *name ( void ) { return Project::_name; } | |||
| static void compact ( void ); | |||
| static bool close ( void ); | |||
| static bool save ( void ); | |||
| static bool validate ( const char *name ); | |||
| static int open ( const char *name ); | |||
| static bool open ( void ) { return _is_open; } | |||
| static bool create ( const char *name, const char *template_name ); | |||
| static const char *created_on ( void ) { return _created_on; } | |||
| }; | |||
| @@ -0,0 +1,22 @@ | |||
| /*******************************************************************************/ | |||
| /* Copyright (C) 2008 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. */ | |||
| /*******************************************************************************/ | |||
| #define APP_NAME "Non-Mixer" | |||
| #define APP_TITLE "The Non-Mixer" | |||
| #define __MODULE__ "non-mixer" | |||
| @@ -34,6 +34,7 @@ | |||
| #include "Engine/Engine.H" | |||
| #include "util/Thread.H" | |||
| #include "util/debug.h" | |||
| #include "Project.H" | |||
| Engine *engine; | |||
| Mixer *mixer; | |||
| @@ -44,6 +45,20 @@ Fl_Single_Window *main_window; | |||
| #include "Loggable.H" | |||
| #include <FL/Fl_Tooltip.H> | |||
| /* for registration */ | |||
| #include "Module.H" | |||
| #include "Gain_Module.H" | |||
| #include "Plugin_Module.H" | |||
| #include "JACK_Module.H" | |||
| #include "Meter_Module.H" | |||
| #include "Meter_Indicator_Module.H" | |||
| #include "Controller_Module.H" | |||
| #include "Chain.H" | |||
| #include <signal.h> | |||
| int | |||
| main ( int argc, char **argv ) | |||
| { | |||
| @@ -57,12 +72,21 @@ main ( int argc, char **argv ) | |||
| Fl_Tooltip::size( 14 ); | |||
| Fl_Tooltip::hoverdelay( 0.1f ); | |||
| Fl::visible_focus( 0 ); | |||
| // Fl::visible_focus( 0 ); | |||
| LOG_REGISTER_CREATE( Mixer_Strip ); | |||
| LOG_REGISTER_CREATE( Chain ); | |||
| LOG_REGISTER_CREATE( Plugin_Module ); | |||
| LOG_REGISTER_CREATE( Gain_Module ); | |||
| LOG_REGISTER_CREATE( Meter_Module ); | |||
| LOG_REGISTER_CREATE( JACK_Module ); | |||
| LOG_REGISTER_CREATE( Meter_Indicator_Module ); | |||
| LOG_REGISTER_CREATE( Controller_Module ); | |||
| init_boxtypes(); | |||
| signal( SIGPIPE, SIG_IGN ); | |||
| Fl::get_system_colors(); | |||
| Fl::scheme( "plastic" ); | |||
| // Fl::scheme( "gtk+" ); | |||
| @@ -91,11 +115,13 @@ main ( int argc, char **argv ) | |||
| if ( argc > 1 ) | |||
| { | |||
| char name[1024]; | |||
| /* char name[1024]; */ | |||
| snprintf( name, sizeof( name ), "%s/history", argv[1] ); | |||
| /* snprintf( name, sizeof( name ), "%s/history", argv[1] ); */ | |||
| Loggable::open( name ); | |||
| /* Loggable::open( name ); */ | |||
| MESSAGE( "Loading \"%s\"", argv[1] ); | |||
| Project::open( argv[1] ); | |||
| } | |||
| else | |||
| { | |||
| @@ -163,11 +163,16 @@ Loggable::load_unjournaled_state ( void ) | |||
| bool | |||
| Loggable::replay ( const char *file ) | |||
| { | |||
| FILE *fp = fopen( file, "r" ); | |||
| if ( FILE *fp = fopen( file, "r" ) ) | |||
| { | |||
| bool r = replay( fp ); | |||
| replay( fp ); | |||
| fclose( fp ); | |||
| fclose( fp ); | |||
| return r; | |||
| } | |||
| else | |||
| return false; | |||
| } | |||
| /** replay journal or snapshot */ | |||
| @@ -279,7 +284,7 @@ void | |||
| Loggable::update_id ( unsigned int id ) | |||
| { | |||
| /* make sure we're the last one */ | |||
| assert( _id == _log_id ); | |||
| ASSERT( _id == _log_id, "%u != %u", _id, _log_id ); | |||
| assert( _loggables[ _id ].loggable == this ); | |||
| _loggables[ _id ].loggable = NULL; | |||
| @@ -127,10 +127,10 @@ private: | |||
| static bool load_unjournaled_state ( void ); | |||
| static bool replay ( FILE *fp ); | |||
| static bool replay ( const char *name ); | |||
| public: | |||
| static bool replay ( const char *name ); | |||
| static bool snapshot( FILE * fp ); | |||
| static bool snapshot( const char *name ); | |||