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