non/Mixer/Mixer_Strip.C

467 lines
13 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*******************************************************************************/
/* Copyright (C) 2009 Jonathan Moore Liles */
/* */
/* This program is free software; you can redistribute it and/or modify it */
/* under the terms of the GNU General Public License as published by the */
/* Free Software Foundation; either version 2 of the License, or (at your */
/* option) any later version. */
/* */
/* This program is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
/* more details. */
/* */
/* You should have received a copy of the GNU General Public License along */
/* with This program; see the file COPYING. If not,write to the Free Software */
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*******************************************************************************/
/* Mixer strip control. Handles GUI and control I/O for this strip. */
/* A mixer strip is home to some (JACK) input ports, a fader, some
* meters, and a filter chain which can terminate either at the input
* to the spacializer or some (JACK) output ports. Since mixer strips
* are not necessarily in a 1:1 association with Non-DAW tracks, there
* is no need for busses per se. If you want to route the output of
* several strips into a single fader or filter chain, then you just
* gives those strips JACK outputs and connect them to the common
* inputs. This mechanism can also do away with the need for 'sends'
* and 'inserts'.
*/
/* Each mixer strip comprises a fader and a panner */
#include "Mixer_Strip.H"
#include "Engine/Engine.H"
#include <dsp.h>
#include <string.h>
#include "debug.h"
#include <FL/Fl_Tabs.H>
#include "FL/Fl_Flowpack.H"
#include "Mixer.H"
#include "Chain.H"
#include "Gain_Module.H"
#include "Meter_Module.H"
#include "Controller_Module.H"
#include "Meter_Indicator_Module.H"
#include "util/debug.h"
extern Mixer *mixer;
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( ":color", (unsigned long)color());
}
void
Mixer_Strip::set ( Log_Entry &e )
{
for ( int i = 0; i < e.size(); ++i )
{
const char *s, *v;
e.get( i, &s, &v );
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" ) )
prepost_button->value( strcmp( v, "pre" ) == 0 );
else if ( ! strcmp( s, ":color" ) )
{
color( (Fl_Color)atoll( v ) );
redraw();
}
}
if ( ! mixer->contains( this ) )
mixer->add( this );
}
Mixer_Strip::Mixer_Strip( const char *strip_name, int channels ) : Fl_Group( 0, 0, 120, 600 )
{
label( strdup( strip_name ) );
init();
color( (Fl_Color)rand() );
// name( strdup( strip_name ) );
configure_ports( channels );
log_create();
}
Mixer_Strip::Mixer_Strip() : Fl_Group( 0, 0, 120, 600 )
{
init();
log_create();
}
Mixer_Strip::~Mixer_Strip ( )
{
configure_ports( 0 );
}
void Mixer_Strip::cb_handle(Fl_Widget* o) {
// parent()->parent()->damage( FL_DAMAGE_ALL, x(), y(), w(), h() );
if ( o == close_button )
((Mixer*)parent())->remove( this );
else if ( o == name_field )
name( name_field->value() );
else if ( o == prepost_button )
{
if ( ((Fl_Button*)o)->value() )
size( 300, h() );
else
size( 120, h() );
parent()->parent()->redraw();
}
}
void Mixer_Strip::cb_handle(Fl_Widget* o, void* v) {
((Mixer_Strip*)(v))->cb_handle(o);
}
void
Mixer_Strip::name ( const char *name ) {
char *s = strdup( name );
name_field->value( s );
label( s );
chain->name( s );
}
void
Mixer_Strip::configure_outputs ( Fl_Widget *o, void *v )
{
((Mixer_Strip*)v)->configure_outputs();
}
void
Mixer_Strip::configure_outputs ( void )
{
DMESSAGE( "Got signal to configure outputs" );
}
bool
Mixer_Strip::configure_ports ( int n )
{
/* /\* 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; */
}
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 );
}
/* update GUI with values from RT thread */
void
Mixer_Strip::update ( void )
{
THREAD_ASSERT( UI );
}
void
Mixer_Strip::init ( )
{
chain_buffers = 0;
chain_buffer = NULL;
box(FL_THIN_UP_BOX);
clip_children( 1 );
Fl_Pack *gain_pack;
{ Fl_Pack *o = new Fl_Pack( 2, 2, 114, 100 );
o->type( Fl_Pack::VERTICAL );
o->spacing( 2 );
{
Fl_Input *o = name_field = new Fl_Sometimes_Input( 2, 2, 144, 24 );
o->color( color() );
o->box( FL_FLAT_BOX );
o->labeltype( FL_NO_LABEL );
o->labelcolor( FL_GRAY0 );
o->textcolor( FL_FOREGROUND_COLOR );
o->value( name() );
o->callback( cb_handle, (void*)this );
}
{ Fl_Scalepack *o = new Fl_Scalepack( 7, 143, 110, 25 );
o->type( Fl_Pack::HORIZONTAL );
{ Fl_Button* o = close_button = new Fl_Button(7, 143, 35, 25, "X");
o->tooltip( "Remove strip" );
o->type(0);
o->labeltype( FL_EMBOSSED_LABEL );
o->color( FL_LIGHT1 );
o->selection_color( FL_RED );
o->labelsize(10);
o->callback( ((Fl_Callback*)cb_handle), this );
} // Fl_Button* o
o->end();
} // Fl_Group* o
{ Fl_Flip_Button* o = prepost_button = new Fl_Flip_Button(61, 183, 45, 22, "narrow/wide");
o->type(1);
// o->box(FL_ROUNDED_BOX);
o->box( FL_THIN_DOWN_BOX );
o->color((Fl_Color)106);
o->selection_color((Fl_Color)65);
o->labeltype(FL_NORMAL_LABEL);
o->labelfont(0);
o->labelsize(14);
o->labelcolor(FL_FOREGROUND_COLOR);
o->align(FL_ALIGN_CLIP);
o->callback( ((Fl_Callback*)cb_handle), this );
o->when(FL_WHEN_RELEASE);
} // Fl_Flip_Button* o
// { Fl_Pack* o = new Fl_Pack(8, 208, 103, 471);
// { Fl_Pack* o = gain_pack = new Fl_Pack(8, 208, 103, 516 );
o->end();
}
Fl_Pack *fader_pack;
{ Fl_Tabs *o = new Fl_Tabs( 4, 104, 110, 330 );
o->clip_children( 1 );
o->box( FL_NO_BOX );
{ Fl_Group *o = new Fl_Group( 4, 114, 110, 330, "Fader" );
o->labelsize( 9 );
o->box( FL_NO_BOX );
{ Fl_Pack* o = fader_pack = new Fl_Pack(4, 116, 103, 330 );
o->spacing( 20 );
o->type( Fl_Pack::HORIZONTAL );
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" );
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();
}
o->end();
Fl_Group::current()->resizable(o);
}
{ Fl_Pack *o = new Fl_Pack( 2, 440, 114, 40 );
o->spacing( 2 );
o->type( Fl_Pack::VERTICAL );
{ Fl_Box *o = new Fl_Box( 0, 0, 100, 24 );
o->align( (Fl_Align)(FL_ALIGN_BOTTOM | FL_ALIGN_INSIDE) );
o->labelsize( 10 );
o->label( "Pan" );
}
#if 0
{ Panner* o = new Panner(0, 0, 110, 90);
o->box(FL_THIN_UP_BOX);
o->color(FL_GRAY0);
o->selection_color(FL_BACKGROUND_COLOR);
o->labeltype(FL_NORMAL_LABEL);
o->labelfont(0);
o->labelsize(11);
o->labelcolor(FL_FOREGROUND_COLOR);
o->align(FL_ALIGN_TOP);
o->when(FL_WHEN_RELEASE);
} // Panner* o
#endif
{
Controller_Module *m = new Controller_Module( 100, 24, "Inputs" );
m->chain( chain );
m->pad( false );
m->connect_to( &chain->module( 0 )->control_input[1] );
m->size( 33, 24 );
}
o->end();
}
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();
}
}
int
Mixer_Strip::handle ( int m )
{
Logger log( this );
static Fl_Color orig_color;
switch ( m )
{
case FL_ENTER:
orig_color = name_field->color();
color( FL_BLACK );
name_field->redraw();
return 1;
break;
case FL_LEAVE:
name_field->color( orig_color );
name_field->redraw();
return 1;
break;
default:
return Fl_Group::handle( m );
}
return 0;
}