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,8 +272,8 @@ 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() );
chain()->configure_ports(); if ( chain() )
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();
} }
} }
@ -130,14 +131,15 @@ Meter_Module::configure_inputs ( int n )
for ( int i = n; i--; ) for ( int i = n; i--; )
f[i] = -70.0f; f[i] = -70.0f;
control_output[0].connect_to( f); control_output[0].connect_to( f );
} }
if ( control_value ) if ( control_value )
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,90 +199,38 @@ 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
Mixer_Strip::process ( nframes_t nframes ) 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,14 +69,97 @@ 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
format is 1.0:2.0:... Where 1.0 is the value of the first control 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. 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;
@ -60,15 +167,53 @@ Module::describe_inputs ( void ) const
if ( control_input.size() ) if ( control_input.size() )
{ {
for ( unsigned int i = 0; i < control_input.size(); ++i ) for ( unsigned int i = 0; i < control_input.size(); ++i )
sp += snprintf( sp, 1024 - (sp - s),"%f:", control_input[i].control_value() ); sp += snprintf( sp, 1024 - (sp - s),"%f:", control_input[i].control_value() );
*(sp - 1) = '\0'; *(sp - 1) = '\0';
} }
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" ) )
{
bool r = replay( fp );
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 );