Mixer: Changes to support project saving/loading.

This commit is contained in:
Jonathan Moore Liles 2009-12-27 23:25:28 -06:00
parent b7079c6147
commit d7f74e8e15
28 changed files with 1176 additions and 299 deletions

View File

@ -64,6 +64,9 @@ Fl_Scalepack::draw ( void )
if ( child( i )->visible() ) if ( child( i )->visible() )
++v; ++v;
if ( 0 == v )
return;
int sz, pos; int sz, pos;
if ( type() == HORIZONTAL ) if ( type() == HORIZONTAL )

View File

@ -71,6 +71,7 @@
#include "FL/Fl_Scroll.H" #include "FL/Fl_Scroll.H"
#include <string.h> #include <string.h>
#include "Mixer_Strip.H"
#include <dsp.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 ) : void
Fl_Group( X, Y, W, H, L) Chain::get ( Log_Entry &e ) const
{ {
_outs = 1; e.add( ":strip", strip() );
_ins = 1; }
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, "")
{
int X = 0;
int Y = 0;
int W = 100;
int H = 100;
/* _outs = 1; */
/* _ins = 1; */
_configure_outputs_callback = NULL; _configure_outputs_callback = NULL;
_strip = NULL;
_name = NULL; _name = NULL;
labelsize( 10 );
align( FL_ALIGN_TOP );
{ Fl_Tabs *o = tabs = new Fl_Tabs( X, Y, W, H ); { Fl_Tabs *o = tabs = new Fl_Tabs( X, Y, W, H );
{ Fl_Group *o = new Fl_Group( X, Y + 24, W, H - 24, "Chain" ); { Fl_Group *o = new Fl_Group( X, Y + 24, W, H - 24, "Chain" );
o->box( FL_FLAT_BOX ); o->box( FL_FLAT_BOX );
@ -127,11 +171,27 @@ Chain::Chain ( int X, int Y, int W, int H, const char *L ) :
end(); end();
chain.push_back( this ); chain.push_back( this );
log_create();
} }
Chain::~Chain ( ) Chain::~Chain ( )
{ {
chain.remove( this ); 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. */ /* Fill this chain with JACK I/O, Gain, and Meter modules. */
@ -139,22 +199,30 @@ void
Chain::initialize_with_default ( void ) Chain::initialize_with_default ( void )
{ {
{ { JACK_Module *m = new JACK_Module();
JACK_Module *jm = new JACK_Module( 50, 50, "JACK" ); m->is_default( true );
jm->chain( this ); m->chain( this );
jm->configure_outputs( 1 ); m->configure_outputs( 1 );
m->initialize();
jm->initialize(); add( m );
jm->color( FL_BLACK );
insert( NULL, jm );
} }
{ { Module *m = new Gain_Module();
JACK_Module *m = new JACK_Module( 50, 50, "JACK" ); m->is_default( true );
m->initialize();
add( m );
}
{ Module *m = new Meter_Module();
m->is_default( true );
add( m );
}
{ JACK_Module *m = new JACK_Module();
m->is_default( true );
m->chain( this ); m->chain( this );
m->initialize(); m->initialize();
m->color( FL_BLACK ); add( m );
insert( NULL, m );
} }
} }
@ -204,7 +272,7 @@ Chain::remove ( Module *m )
void void
Chain::configure_ports ( void ) Chain::configure_ports ( void )
{ {
int old_outs = outs(); /* int old_outs = outs(); */
int nouts = 0; int nouts = 0;
engine->lock(); engine->lock();
@ -215,15 +283,15 @@ Chain::configure_ports ( void )
nouts = module( i )->noutputs(); nouts = module( i )->noutputs();
} }
outs( nouts ); /* outs( nouts ); */
int req_buffers = required_buffers(); int req_buffers = required_buffers();
if ( outs() != old_outs ) /* if ( outs() != old_outs ) */
{ /* { */
if ( configure_outputs_callback() ) /* if ( configure_outputs_callback() ) */
configure_outputs_callback()( this, _configure_outputs_userdata ); /* configure_outputs_callback()( this, _configure_outputs_userdata ); */
} /* } */
DMESSAGE( "required_buffers = %i", req_buffers ); DMESSAGE( "required_buffers = %i", req_buffers );
@ -329,6 +397,12 @@ Chain::name ( const char *name )
#include "FL/menu_popup.H" #include "FL/menu_popup.H"
bool
Chain::add ( Module *m )
{
return insert( NULL, m );
}
bool bool
Chain::insert ( Module *m, Module *n ) Chain::insert ( Module *m, Module *n )
{ {
@ -389,6 +463,8 @@ Chain::insert ( Module *m, Module *n )
n->ncontrol_inputs(), n->ncontrol_inputs(),
n->ncontrol_outputs() ); n->ncontrol_outputs() );
strip()->handle_module_added( n );
configure_ports(); configure_ports();
engine->unlock(); engine->unlock();
@ -498,23 +574,23 @@ Chain::build_process_queue ( void )
m->handle_port_connection_change(); 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 ) for ( std::list<Module*>::const_iterator i = process_queue.begin(); i != process_queue.end(); ++i )
{ {
const Module* m = *i; const Module* m = *i;
if ( m->audio_input.size() || m->audio_output.size() ) /* if ( m->audio_input.size() || m->audio_output.size() ) */
DMESSAGE( "\t%s", (*i)->name() ); /* DMESSAGE( "\t%s", (*i)->name() ); */
else if ( m->control_output.size() ) /* else if ( m->control_output.size() ) */
DMESSAGE( "\t%s -->", (*i)->name() ); /* DMESSAGE( "\t%s -->", (*i)->name() ); */
else if ( m->control_input.size() ) /* else if ( m->control_input.size() ) */
DMESSAGE( "\t%s <--", (*i)->name() ); /* DMESSAGE( "\t%s <--", (*i)->name() ); */
{ {
char *s = m->describe_inputs(); char *s = m->get_parameters();
DMESSAGE( "(%s)", s ); /* DMESSAGE( "(%s)", s ); */
delete[] s; delete[] s;
} }
@ -564,10 +640,9 @@ Chain::handle ( int m )
{ {
if ( test_press( FL_BUTTON3 | FL_CTRL ) ) if ( test_press( FL_BUTTON3 | FL_CTRL ) )
{ {
if ( FL_BLACK == m->color() ) if ( m->is_default() )
{ {
/* FIXME: hack */ fl_alert( "Default modules may not be deleted." );
fl_alert( "Cannot delete this module." );
} }
else else
{ {
@ -604,6 +679,11 @@ Chain::handle ( int m )
return Fl_Group::handle( m ); return Fl_Group::handle( m );
} }
void
Chain::strip ( Mixer_Strip * ms )
{
_strip = ms;
}
void void
Chain::process ( nframes_t nframes ) Chain::process ( nframes_t nframes )

View File

@ -17,6 +17,8 @@
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*******************************************************************************/ /*******************************************************************************/
#pragma once
#include <FL/Fl.H> #include <FL/Fl.H>
#include <FL/Fl_Pack.H> #include <FL/Fl_Pack.H>
#include <FL/Fl_Button.H> #include <FL/Fl_Button.H>
@ -25,11 +27,13 @@
#include "JACK/Port.H" #include "JACK/Port.H"
#include <vector> #include <vector>
#include <list> #include <list>
#include "Loggable.H"
class Mixer_Strip;
class Fl_Flowpack; class Fl_Flowpack;
class Fl_Tabs; class Fl_Tabs;
class Chain : public Fl_Group { class Chain : public Fl_Group, public Loggable {
Fl_Pack *modules_pack; Fl_Pack *modules_pack;
Fl_Flowpack *controls_pack; Fl_Flowpack *controls_pack;
@ -38,8 +42,10 @@ class Chain : public Fl_Group {
void cb_handle(Fl_Widget*); void cb_handle(Fl_Widget*);
static void cb_handle(Fl_Widget*, void*); static void cb_handle(Fl_Widget*, void*);
int _ins; /* int _ins; */
int _outs; /* int _outs; */
Mixer_Strip *_strip;
// sample_t **_buffer; // sample_t **_buffer;
// int _nbuffers; // int _nbuffers;
@ -59,9 +65,20 @@ class Chain : public Fl_Group {
static std::vector <Module::Port> port; static std::vector <Module::Port> port;
static std::list <Chain*> chain; 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: 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; } const char *name ( void ) const { return _name; }
void name ( const char *name ); void name ( const char *name );
@ -69,18 +86,20 @@ public:
int required_buffers ( void ); int required_buffers ( void );
Chain ( int X, int Y, int W, int H, const char *L = 0 ); Chain ( int X, int Y, int W, int H, const char *L = 0 );
Chain ( );
virtual ~Chain ( ); virtual ~Chain ( );
bool can_support_input_channels ( int n ); bool can_support_input_channels ( int n );
void ins ( int i ) { _ins = i; } /* void ins ( int i ) { _ins = i; } */
void outs ( int i ) { _outs = i; } /* void outs ( int i ) { _outs = i; } */
int ins ( void ) const { return _ins; } /* int ins ( void ) const { return _ins; } */
int outs ( void ) const { return _outs; } /* int outs ( void ) const { return _outs; } */
int modules ( void ) const { return modules_pack->children(); } int modules ( void ) const { return modules_pack->children(); }
Module *module ( int n ) const { return (Module*)modules_pack->child( n ); } Module *module ( int n ) const { return (Module*)modules_pack->child( n ); }
void remove ( Module *m ); void remove ( Module *m );
bool add ( Module *m );
bool insert ( Module *m, Module *n ); bool insert ( Module *m, Module *n );
void add_control ( Module *m ); void add_control ( Module *m );
@ -98,10 +117,7 @@ public:
void process ( nframes_t ); void process ( nframes_t );
protected: void log_children ( void );
int handle ( int m );
void draw ( void );
void resize ( int X, int Y, int W, int H );
LOG_CREATE_FUNC( Chain );
}; };

View File

@ -38,8 +38,56 @@ const float CONTROL_UPDATE_FREQ = 0.1f;
Controller_Module::Controller_Module ( int W, int H, const char *L ) void
: Module ( W, 100, L ) 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( "" ); // label( "" );
box( FL_NO_BOX ); box( FL_NO_BOX );
@ -47,6 +95,7 @@ Controller_Module::Controller_Module ( int W, int H, const char *L )
_pad = true; _pad = true;
control = 0; control = 0;
control_value =0.0f; control_value =0.0f;
add_port( Port( this, Port::OUTPUT, Port::CONTROL ) ); add_port( Port( this, Port::OUTPUT, Port::CONTROL ) );
mode( GUI ); mode( GUI );
@ -56,11 +105,15 @@ Controller_Module::Controller_Module ( int W, int H, const char *L )
end(); end();
Fl::add_timeout( CONTROL_UPDATE_FREQ, update_cb, this ); Fl::add_timeout( CONTROL_UPDATE_FREQ, update_cb, this );
log_create();
} }
Controller_Module::~Controller_Module ( ) Controller_Module::~Controller_Module ( )
{ {
Fl::remove_timeout( update_cb, this ); Fl::remove_timeout( update_cb, this );
log_destroy();
} }

View File

@ -42,7 +42,8 @@ public:
Mode mode ( void ) const { return _mode; } Mode mode ( void ) const { return _mode; }
void mode ( Mode v ) { _mode = v; } 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 ( ); virtual ~Controller_Module ( );
const char *name ( void ) const { return "Controller"; } const char *name ( void ) const { return "Controller"; }
@ -57,8 +58,13 @@ public:
void connect_to ( Port *p ); void connect_to ( Port *p );
LOG_CREATE_FUNC( Controller_Module );
protected: protected:
void get ( Log_Entry &e ) const;
void set ( Log_Entry &e );
// virtual void draw ( void ); // virtual void draw ( void );
virtual void process ( void ); virtual void process ( void );

View File

@ -22,8 +22,8 @@
#include <math.h> #include <math.h>
#include <dsp.h> #include <dsp.h>
Gain_Module::Gain_Module ( int W, int H, const char *L ) Gain_Module::Gain_Module ( )
: Module ( W, 24, L ) : Module ( 50, 24, name() )
{ {
add_port( Port( this, Port::INPUT, Port::AUDIO ) ); add_port( Port( this, Port::INPUT, Port::AUDIO ) );
add_port( Port( this, Port::OUTPUT, 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 ); add_port( p );
color( FL_BLACK ); // color( FL_BLACK );
end(); end();
log_create();
} }
Gain_Module::~Gain_Module ( ) Gain_Module::~Gain_Module ( )
{ {
log_destroy();
} }

View File

@ -25,6 +25,7 @@ class Gain_Module : public Module
{ {
public: public:
Gain_Module ( );
Gain_Module ( int W, int H, const char *L=0 ); Gain_Module ( int W, int H, const char *L=0 );
virtual ~Gain_Module ( ); virtual ~Gain_Module ( );
@ -33,6 +34,8 @@ public:
int can_support_inputs ( int n ) { return n; } int can_support_inputs ( int n ) { return n; }
bool configure_inputs ( int n ); bool configure_inputs ( int n );
LOG_CREATE_FUNC( Gain_Module );
protected: protected:
virtual void process ( void ); virtual void process ( void );

View File

@ -25,8 +25,10 @@
#include <string.h> #include <string.h>
#include "Chain.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? */ /* 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(); end();
log_create();
} }
JACK_Module::~JACK_Module ( )
{
log_destroy();
configure_inputs( 0 );
}
int int
JACK_Module::can_support_inputs ( int n ) JACK_Module::can_support_inputs ( int n )
{ {
@ -137,11 +149,6 @@ JACK_Module::initialize ( void )
return true; return true;
} }
JACK_Module::~JACK_Module ( )
{
configure_inputs( 0 );
}
void void
JACK_Module::handle_control_changed ( Port *p ) 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)" ); DMESSAGE( "Adjusting number of inputs (JACK outputs)" );
configure_inputs( p->control_value() ); configure_inputs( p->control_value() );
if ( chain() )
chain()->configure_ports(); chain()->configure_ports();
} }
else if ( 0 == strcmp( p->name(), "Outputs" ) ) else if ( 0 == strcmp( p->name(), "Outputs" ) )
{ {
DMESSAGE( "Adjusting number of outputs (JACK inputs)" ); 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() ); configure_outputs( p->control_value() );
chain()->configure_ports(); chain()->configure_ports();
} }
else
configure_outputs( p->control_value() );
} }
} }

View File

@ -26,20 +26,16 @@
class JACK_Module : public Module class JACK_Module : public Module
{ {
const char *_strip_name;
std::vector<JACK::Port> jack_input; std::vector<JACK::Port> jack_input;
std::vector<JACK::Port> jack_output; std::vector<JACK::Port> jack_output;
public: public:
JACK_Module ( int W, int H, const char *L=0 ); JACK_Module ( );
virtual ~JACK_Module ( ); virtual ~JACK_Module ( );
const char *name ( void ) const { return "JACK"; } const char *name ( void ) const { return "JACK"; }
void strip_name ( const char *name ) { _strip_name = name; }
bool initialize ( void ); bool initialize ( void );
int can_support_inputs ( int ); int can_support_inputs ( int );
@ -51,6 +47,8 @@ public:
void handle_control_changed ( Port *p ); void handle_control_changed ( Port *p );
void handle_chain_name_changed (); void handle_chain_name_changed ();
LOG_CREATE_FUNC( JACK_Module );
protected: protected:
virtual void process ( void ); virtual void process ( void );

View File

@ -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 ); 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 ); dpm_pack->type( FL_HORIZONTAL );
control_value = new float[1]; control_value = new float[1];
*control_value = -70.0f;
end(); end();
@ -64,9 +115,14 @@ Meter_Indicator_Module::Meter_Indicator_Module ( int W, int H, const char *L )
Meter_Indicator_Module::~Meter_Indicator_Module ( ) Meter_Indicator_Module::~Meter_Indicator_Module ( )
{ {
if ( control_value ) if ( control_value )
{
delete[] control_value; delete[] control_value;
control_value = NULL;
}
Fl::remove_timeout( update_cb, this ); Fl::remove_timeout( update_cb, this );
log_destroy();
} }

View File

@ -39,7 +39,7 @@ class Meter_Indicator_Module : public Module
public: public:
Meter_Indicator_Module ( int W, int H, const char *L=0 ); Meter_Indicator_Module ( bool is_default = false );
virtual ~Meter_Indicator_Module ( ); virtual ~Meter_Indicator_Module ( );
const char *name ( void ) const { return "Meter Indicator"; } const char *name ( void ) const { return "Meter Indicator"; }
@ -54,8 +54,12 @@ public:
void connect_to ( Port *p ); void connect_to ( Port *p );
LOG_CREATE_FUNC( Meter_Indicator_Module );
protected: protected:
void get ( Log_Entry &e ) const;
void set ( Log_Entry &e );
// virtual void draw ( void ); // virtual void draw ( void );
virtual void process ( void ); virtual void process ( void );

View File

@ -31,8 +31,8 @@ const float METER_UPDATE_FREQ = 0.1f;
Meter_Module::Meter_Module ( int W, int, const char *L ) Meter_Module::Meter_Module ( )
: Module ( W, 100, L ) : Module ( 50, 100, name() )
{ {
box( FL_THIN_UP_FRAME ); box( FL_THIN_UP_FRAME );
dpm_pack = new Fl_Scalepack( x(), y(), w(), h() ); 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 ); Fl::add_timeout( METER_UPDATE_FREQ, update_cb, this );
log_create();
} }
Meter_Module::~Meter_Module ( ) Meter_Module::~Meter_Module ( )
@ -65,6 +66,8 @@ Meter_Module::~Meter_Module ( )
delete[] control_value; delete[] control_value;
Fl::remove_timeout( update_cb, this ); Fl::remove_timeout( update_cb, this );
log_destroy();
} }
void void
@ -117,8 +120,6 @@ Meter_Module::configure_inputs ( int n )
audio_input.pop_back(); audio_input.pop_back();
audio_output.back().disconnect(); audio_output.back().disconnect();
audio_output.pop_back(); audio_output.pop_back();
control_output.back().disconnect();
control_output.pop_back();
} }
} }
@ -137,7 +138,8 @@ Meter_Module::configure_inputs ( int n )
delete [] control_value; delete [] control_value;
control_value = new float[n]; control_value = new float[n];
for ( int i = n; i--; )
control_value[i] = -70.0f;
return true; return true;
} }

View File

@ -34,7 +34,7 @@ class Meter_Module : public Module
public: public:
Meter_Module ( int W, int H, const char *L=0 ); Meter_Module ( );
virtual ~Meter_Module ( ); virtual ~Meter_Module ( );
const char *name ( void ) const { return "Meter"; } const char *name ( void ) const { return "Meter"; }
@ -42,6 +42,8 @@ public:
int can_support_inputs ( int n ) { return n > 0 ? n : -1; } int can_support_inputs ( int n ) { return n > 0 ? n : -1; }
bool configure_inputs ( int n ); bool configure_inputs ( int n );
LOG_CREATE_FUNC( Meter_Module );
protected: protected:
virtual int handle ( int m ); virtual int handle ( int m );

View File

@ -24,9 +24,12 @@
#include <FL/Fl_Pack.H> #include <FL/Fl_Pack.H>
#include <FL/Fl_Scroll.H> #include <FL/Fl_Scroll.H>
#include <FL/Fl_Menu_Bar.H>
#include "Engine/Engine.H" #include "Engine/Engine.H"
#include "Project.H"
#include <string.h> #include <string.h>
#include "debug.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 ); box( FL_NO_BOX );
labelsize( 96 ); labelsize( 96 );
{ { Fl_Menu_Bar *o = new Fl_Menu_Bar( X, Y, W, 24 );
Fl_Scroll *o = scroll = new Fl_Scroll( X, Y, W, H ); 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->box( FL_NO_BOX );
o->type( Fl_Scroll::HORIZONTAL_ALWAYS ); 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" ); label( "Non-Mixer" );
align( (Fl_Align)(FL_ALIGN_CENTER | FL_ALIGN_INSIDE) ); align( (Fl_Align)(FL_ALIGN_CENTER | FL_ALIGN_INSIDE) );
o->box( FL_NO_BOX ); 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 ); 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 ) void Mixer::add ( Mixer_Strip *ms )
@ -181,7 +190,7 @@ void
Mixer::snapshot ( void ) Mixer::snapshot ( void )
{ {
for ( int i = 0; i < mixer_strips->children(); ++i ) 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() ); // 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 int
Mixer::handle ( int m ) Mixer::handle ( int m )
{ {
@ -216,9 +235,8 @@ Mixer::handle ( int m )
} }
else if ( Fl::event_ctrl() && Fl::event_key() == 's' ) else if ( Fl::event_ctrl() && Fl::event_key() == 's' )
{ {
MESSAGE( "Saving state" ); // save();
Loggable::snapshot_callback( &Mixer::snapshot, this ); Project::save();
Loggable::snapshot( "save.mix" );
return 1; return 1;
} }
else else

View File

@ -56,6 +56,8 @@ public:
void remove ( Mixer_Strip *ms ); void remove ( Mixer_Strip *ms );
bool contains ( Mixer_Strip *ms ); bool contains ( Mixer_Strip *ms );
bool save ( void );
Mixer ( int X, int Y, int W, int H, const char *L ); Mixer ( int X, int Y, int W, int H, const char *L );
virtual ~Mixer(); virtual ~Mixer();
}; };

View File

@ -58,12 +58,8 @@ void
Mixer_Strip::get ( Log_Entry &e ) const Mixer_Strip::get ( Log_Entry &e ) const
{ {
e.add( ":name", name() ); e.add( ":name", name() );
// e.add( ":controllable", controllable() ); e.add( ":width", prepost_button->value() ? "wide" : "narrow" );
// e.add( ":inputs", _in.size() );
/* e.add( ":gain", gain_slider->value() ); */
e.add( ":meter_point", prepost_button->value() ? "pre" : "post" );
e.add( ":color", (unsigned long)color()); e.add( ":color", (unsigned long)color());
} }
void void
@ -77,13 +73,7 @@ Mixer_Strip::set ( Log_Entry &e )
if ( ! strcmp( s, ":name" ) ) if ( ! strcmp( s, ":name" ) )
name( v ); name( v );
// else if ( ! strcmp( s, ":controllable" ) ) else if ( ! strcmp( s, ":width" ) )
// 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" ) )
prepost_button->value( strcmp( v, "pre" ) == 0 ); prepost_button->value( strcmp( v, "pre" ) == 0 );
else if ( ! strcmp( s, ":color" ) ) else if ( ! strcmp( s, ":color" ) )
{ {
@ -96,23 +86,62 @@ Mixer_Strip::set ( Log_Entry &e )
mixer->add( this ); mixer->add( this );
} }
void
Mixer_Strip::log_children ( void )
{
log_create();
_chain->log_children();
}
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 ) Mixer_Strip::Mixer_Strip( const char *strip_name, int channels ) : Fl_Group( 0, 0, 120, 600 )
{ {
label( strdup( strip_name ) ); label( strdup( strip_name ) );
init(); init();
chain( new Chain() );
_chain->initialize_with_default();
_chain->configure_ports();
color( (Fl_Color)rand() ); color( (Fl_Color)rand() );
// name( strdup( strip_name ) ); // name( strdup( strip_name ) );
configure_ports( channels );
log_create(); log_create();
} }
/* virgin strip created from journal */
Mixer_Strip::Mixer_Strip() : Fl_Group( 0, 0, 120, 600 ) Mixer_Strip::Mixer_Strip() : Fl_Group( 0, 0, 120, 600 )
{ {
init(); init();
@ -122,7 +151,7 @@ Mixer_Strip::Mixer_Strip() : Fl_Group( 0, 0, 120, 600 )
Mixer_Strip::~Mixer_Strip ( ) Mixer_Strip::~Mixer_Strip ( )
{ {
configure_ports( 0 ); log_destroy();
} }
@ -154,7 +183,8 @@ Mixer_Strip::name ( const char *name ) {
char *s = strdup( name ); char *s = strdup( name );
name_field->value( s ); name_field->value( s );
label( s ); label( s );
chain->name( s ); if ( _chain )
_chain->name( s );
} }
void void
@ -169,40 +199,30 @@ Mixer_Strip::configure_outputs ( void )
DMESSAGE( "Got signal to configure outputs" ); DMESSAGE( "Got signal to configure outputs" );
} }
bool /* called by the chain to let us know that a module has been added */
Mixer_Strip::configure_ports ( int n ) void
Mixer_Strip::handle_module_added ( Module *m )
{ {
/* /\* figure out how many buffers we have to create *\/ */ if ( m->is_default() )
/* int required_buffers = chain->required_buffers(); */ {
DMESSAGE( "Connecting controls to default module \"%s\"", m->name() );
/* 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; */
/* 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 void
@ -210,49 +230,7 @@ Mixer_Strip::process ( nframes_t nframes )
{ {
THREAD_ASSERT( RT ); THREAD_ASSERT( RT );
/* sample_t *gain_buf = NULL; */ _chain->process( nframes );
/* 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 );
} }
/* update GUI with values from RT thread */ /* update GUI with values from RT thread */
@ -265,6 +243,8 @@ Mixer_Strip::update ( void )
void void
Mixer_Strip::init ( ) Mixer_Strip::init ( )
{ {
_chain = 0;
chain_buffers = 0; chain_buffers = 0;
chain_buffer = NULL; chain_buffer = NULL;
@ -332,24 +312,31 @@ Mixer_Strip::init ( )
{ Fl_Pack* o = fader_pack = new Fl_Pack(4, 116, 103, 330 ); { Fl_Pack* o = fader_pack = new Fl_Pack(4, 116, 103, 330 );
o->spacing( 20 ); o->spacing( 20 );
o->type( Fl_Pack::HORIZONTAL ); 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(); o->end();
Fl_Group::current()->resizable(o); Fl_Group::current()->resizable(o);
} // Fl_Group* o } // Fl_Group* o
o->end(); o->end();
Fl_Group::current()->resizable(o); 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->labelsize( 9 );
o->hide(); 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(); o->end();
} }
@ -357,7 +344,9 @@ Mixer_Strip::init ( )
Fl_Group::current()->resizable(o); 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->spacing( 2 );
o->type( Fl_Pack::VERTICAL ); o->type( Fl_Pack::VERTICAL );
@ -380,10 +369,11 @@ Mixer_Strip::init ( )
} // Panner* o } // Panner* o
#endif #endif
{ {
Controller_Module *m = new Controller_Module( 100, 24, "Inputs" ); Controller_Module *m = jack_input_controller = new Controller_Module( true );
m->chain( chain ); m->label( "Inputs" );
m->chain( _chain );
m->pad( false ); 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 ); m->size( 33, 24 );
} }
o->end(); o->end();
@ -392,49 +382,8 @@ Mixer_Strip::init ( )
end(); end();
color( FL_BLACK ); 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();
} }

View File

@ -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 <FL/Fl.H>
#include "DPM.H" #include "DPM.H"
#include "Panner.H" #include "Panner.H"
@ -26,6 +43,9 @@
#include "Loggable.H" #include "Loggable.H"
class Chain; class Chain;
class Fl_Flowpack; class Fl_Flowpack;
class Controller_Module;
class Meter_Indicator_Module;
class Module;
class Mixer_Strip : public Fl_Group, public Loggable { class Mixer_Strip : public Fl_Group, public Loggable {
@ -42,8 +62,14 @@ public:
Fl_Input *name_field; Fl_Input *name_field;
Fl_Flowpack *controls_pack; 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; sample_t **chain_buffer;
int chain_buffers; int chain_buffers;
@ -69,6 +95,10 @@ protected:
public: public:
void chain ( Chain *c );
void log_children ( void );
void color ( Fl_Color c ) void color ( Fl_Color c )
{ {
_color = c; _color = c;
@ -90,10 +120,11 @@ public:
bool configure_ports ( int n ); bool configure_ports ( int n );
void handle_module_added ( Module *m );
void update ( void ); void update ( void );
// int channels ( void ) const { return _in.size(); } // int channels ( void ) const { return _in.size(); }
void name ( const char *name ); void name ( const char *name );
const char *name ( void ) const { return label(); } const char *name ( void ) const { return label(); }
}; };
#endif

View File

@ -25,9 +25,33 @@
#include <stdio.h> #include <stdio.h>
#include "Module_Parameter_Editor.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 ( ) Module::~Module ( )
{ {
for ( unsigned int i = 0; i < audio_input.size(); ++i ) for ( unsigned int i = 0; i < audio_input.size(); ++i )
@ -45,6 +69,89 @@ Module::~Module ( )
control_output.clear(); control_output.clear();
} }
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 /* return a string serializing this module's parameter settings. The
@ -52,7 +159,7 @@ Module::~Module ( )
input, 2.0 is the value of the second control input etc. input, 2.0 is the value of the second control input etc.
*/ */
char * char *
Module::describe_inputs ( void ) const Module::get_parameters ( void ) const
{ {
char *s = new char[1024]; char *s = new char[1024];
s[0] = 0; s[0] = 0;
@ -69,6 +176,44 @@ Module::describe_inputs ( void ) const
return s; 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 void
@ -87,10 +232,14 @@ Module::draw_box ( void )
fl_push_clip( tx, ty, tw, th ); fl_push_clip( tx, ty, tw, th );
Fl_Color c = is_default() ? FL_BLACK : color();
int spacing = w() / instances(); int spacing = w() / instances();
for ( int i = instances(); i--; ) 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() ) if ( audio_input.size() && audio_output.size() )

View File

@ -30,41 +30,43 @@
#include "util/Thread.H" #include "util/Thread.H"
#include "Loggable.H"
class Chain; class Chain;
class Module_Parameter_Editor; class Module_Parameter_Editor;
class Module : public Fl_Group { class Module : public Fl_Group, public Loggable {
void init ( void )
{
_editor = 0;
_chain = 0;
_instances = 1;
box( FL_UP_BOX );
labeltype( FL_NO_LABEL );
clip_children( 1 );
}
int _ins; int _ins;
int _outs; int _outs;
int _instances; int _instances;
unsigned long _nframes; unsigned long _nframes;
Chain *_chain; Chain *_chain;
bool _is_default;
Module_Parameter_Editor *_editor; Module_Parameter_Editor *_editor;
void cb_handle(Fl_Widget*); void cb_handle(Fl_Widget*);
static void cb_handle(Fl_Widget*, void*); static void cb_handle(Fl_Widget*, void*);
void init ( void );
public: 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 class Port
{ {
/* char *type_names[] = { "Audio", "Control" }; */ /* char *type_names[] = { "Audio", "Control" }; */
/* char *direction_names[] = { "Input", "Output" }; */ /* char *direction_names[] = { "Input", "Output" }; */
void update_connected_port_buffer ( void )
{
if ( connected() )
connected_port()->_buf = _buf;
}
public: public:
@ -175,7 +177,7 @@ public:
void connect_to ( void *buf ) void connect_to ( void *buf )
{ {
_buf = buf; _buf = buf;
// _connected = (Port*)0x01; update_connected_port_buffer();
} }
void disconnect ( void ) void disconnect ( void )
@ -210,16 +212,14 @@ public:
H = h() - 10; H = h() - 10;
} }
Module ( int W, int H, const char *L = 0 ) : Fl_Group( 0, 0, W, H, L ) Module ( int W, int H, const char *L = 0 );
{ Module ( );
init(); Module ( bool is_default, int W, int H, const char *L = 0 );
}
Module ( ) : Fl_Group( 0, 0, 0, 50, "Unnamed" )
{
init();
}
virtual ~Module ( ); virtual ~Module ( );
LOG_NAME_FUNC( Module );
// static Module * pick_plugin ( void ); // 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; } Chain *chain ( void ) const { return _chain; }
void chain ( Chain * v ) { _chain = v; } 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; } virtual bool initialize ( void ) { return true; }
@ -314,8 +333,6 @@ public:
virtual void handle_port_connection_change () {} virtual void handle_port_connection_change () {}
protected: protected:
void draw_connections ( void ); void draw_connections ( void );
@ -325,4 +342,7 @@ protected:
virtual void draw ( void ) { Module::draw_box(); Module::draw_label(); } virtual void draw ( void ) { Module::draw_box(); Module::draw_label(); }
virtual int handle ( int m ); virtual int handle ( int m );
virtual void get ( Log_Entry &e ) const;
virtual void set ( Log_Entry &e );
}; };

View File

@ -281,7 +281,8 @@ Module_Parameter_Editor::bind_control ( int i )
/* can only bind once */ /* can only bind once */
return; 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->chain( _module->chain() );
o->connect_to( p ); o->connect_to( p );

View File

@ -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(); init();
end(); end();
log_create();
} }
Plugin_Module::~Plugin_Module ( ) Plugin_Module::~Plugin_Module ( )
{ {
log_destroy();
plugin_instances( 0 ); plugin_instances( 0 );
} }
/* void */ void
/* Plugin_Module::detect_plugins ( void ) */ Plugin_Module::get ( Log_Entry &e ) const
/* { */ {
/* LADPSAInfo *li = new LADSPAInfo(); */ // 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> #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::Plugin_Info *pi = (Plugin_Module::Plugin_Info*)menu->menu()[ menu->value() ].user_data();
Plugin_Module *m = new Plugin_Module( 50, 50 ); Plugin_Module *m = new Plugin_Module();
m->load( pi ); m->load( pi->id );
const char *plugin_name = pi->path;
char *label = strdup( rindex(plugin_name, '/') + 1 );
m->label( label );
delete[] pia; delete[] pia;
@ -342,9 +364,14 @@ Plugin_Module::plugin_instances ( unsigned int n )
} }
bool 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; _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; bool neg_max = max < 0.0f ? true : false;
if (!neg_min && !neg_max) { 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) { } else if (neg_min && neg_max) {
Default = -exp(log(-min) * lp + log(-max) * up); Default = -exp(::log(-min) * lp + ::log(-max) * up);
} else { } else {
// Logarithmic range has asymptote // Logarithmic range has asymptote
// so just use linear scale // so just use linear scale

View File

@ -20,6 +20,7 @@
#pragma once #pragma once
#include "Module.H" #include "Module.H"
#include "Loggable.H"
class Plugin_Module : Module { class Plugin_Module : Module {
@ -61,7 +62,7 @@ class Plugin_Module : Module {
static Plugin_Info* discover ( void ); static Plugin_Info* discover ( void );
bool load ( Plugin_Info * ); bool load ( unsigned long id );
void set_input_buffer ( int n, void *buf ); void set_input_buffer ( int n, void *buf );
void set_output_buffer ( int n, void *buf ); void set_output_buffer ( int n, void *buf );
@ -77,7 +78,6 @@ class Plugin_Module : Module {
public: public:
Plugin_Module( int W, int H, const char *L = 0 );
Plugin_Module ( ); Plugin_Module ( );
virtual ~Plugin_Module(); virtual ~Plugin_Module();
@ -97,8 +97,12 @@ public:
void handle_port_connection_change ( void ); void handle_port_connection_change ( void );
LOG_CREATE_FUNC( Plugin_Module );
protected: protected:
virtual int handle ( int ); virtual int handle ( int );
void get ( Log_Entry &e ) const;
void set ( Log_Entry &e );
}; };

324
Mixer/Project.C Normal file
View File

@ -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();
}

62
Mixer/Project.H Normal file
View File

@ -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; }
};

22
Mixer/const.h Normal file
View File

@ -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"

View File

@ -34,6 +34,7 @@
#include "Engine/Engine.H" #include "Engine/Engine.H"
#include "util/Thread.H" #include "util/Thread.H"
#include "util/debug.h" #include "util/debug.h"
#include "Project.H"
Engine *engine; Engine *engine;
Mixer *mixer; Mixer *mixer;
@ -44,6 +45,20 @@ Fl_Single_Window *main_window;
#include "Loggable.H" #include "Loggable.H"
#include <FL/Fl_Tooltip.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 int
main ( int argc, char **argv ) main ( int argc, char **argv )
{ {
@ -57,12 +72,21 @@ main ( int argc, char **argv )
Fl_Tooltip::size( 14 ); Fl_Tooltip::size( 14 );
Fl_Tooltip::hoverdelay( 0.1f ); Fl_Tooltip::hoverdelay( 0.1f );
Fl::visible_focus( 0 ); // Fl::visible_focus( 0 );
LOG_REGISTER_CREATE( Mixer_Strip ); 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(); init_boxtypes();
signal( SIGPIPE, SIG_IGN );
Fl::get_system_colors(); Fl::get_system_colors();
Fl::scheme( "plastic" ); Fl::scheme( "plastic" );
// Fl::scheme( "gtk+" ); // Fl::scheme( "gtk+" );
@ -91,11 +115,13 @@ main ( int argc, char **argv )
if ( argc > 1 ) 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 else
{ {

View File

@ -163,11 +163,16 @@ Loggable::load_unjournaled_state ( void )
bool bool
Loggable::replay ( const char *file ) Loggable::replay ( const char *file )
{ {
FILE *fp = fopen( file, "r" ); if ( FILE *fp = fopen( file, "r" ) )
{
replay( fp ); bool r = replay( fp );
fclose( fp ); fclose( fp );
return r;
}
else
return false;
} }
/** replay journal or snapshot */ /** replay journal or snapshot */
@ -279,7 +284,7 @@ void
Loggable::update_id ( unsigned int id ) Loggable::update_id ( unsigned int id )
{ {
/* make sure we're the last one */ /* 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 ); assert( _loggables[ _id ].loggable == this );
_loggables[ _id ].loggable = NULL; _loggables[ _id ].loggable = NULL;

View File

@ -127,10 +127,10 @@ private:
static bool load_unjournaled_state ( void ); static bool load_unjournaled_state ( void );
static bool replay ( FILE *fp ); static bool replay ( FILE *fp );
static bool replay ( const char *name );
public: public:
static bool replay ( const char *name );
static bool snapshot( FILE * fp ); static bool snapshot( FILE * fp );
static bool snapshot( const char *name ); static bool snapshot( const char *name );