Browse Source

Mixer: Add new module "Aux" to allow creation of "send" topology without requiring an extra strip to control the send gain.

tags/non-daw-v1.2.0
Jonathan Moore Liles 12 years ago
parent
commit
fc5ef8f9f9
10 changed files with 390 additions and 116 deletions
  1. +179
    -0
      mixer/src/AUX_Module.C
  2. +54
    -0
      mixer/src/AUX_Module.H
  3. +1
    -1
      mixer/src/Controller_Module.H
  4. +72
    -39
      mixer/src/JACK_Module.C
  5. +23
    -11
      mixer/src/JACK_Module.H
  6. +1
    -1
      mixer/src/Meter_Module.H
  7. +50
    -56
      mixer/src/Module.C
  8. +7
    -7
      mixer/src/Module.H
  9. +2
    -1
      mixer/src/main.C
  10. +1
    -0
      mixer/wscript

+ 179
- 0
mixer/src/AUX_Module.C View File

@@ -0,0 +1,179 @@

/*******************************************************************************/
/* Copyright (C) 2013 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. */
/*******************************************************************************/

#include <FL/fl_draw.H>
#include "AUX_Module.H"
#include "dsp.h"

/* The purpose of this module is to provide auxiliary outputs, with
* gain. This allows one to create a 'send' type topology without
* having to use an extra strip to control the 'send' gain. */

AUX_Module::AUX_Module ( ) : JACK_Module ( false )
{
is_default( false );

_number = 0;

{
Port p( this, Port::INPUT, Port::CONTROL, "Gain (dB)" );
p.hints.type = Port::Hints::LOGARITHMIC;
p.hints.ranged = true;
p.hints.minimum = -70.0f;
p.hints.maximum = 6.0f;
p.hints.default_value = 0.0f;
p.connect_to( new float );
p.control_value( p.hints.default_value );

add_port( p );
}

log_create();

copy_label( "Aux" );
}

AUX_Module::~AUX_Module ( )
{
configure_outputs(0);
delete (float*)control_input[0].buffer();
}


void
AUX_Module::get ( Log_Entry &e ) const
{
e.add( ":number", number() );
JACK_Module::get(e);
}

void
AUX_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, ":number" ) ) )
{
number( atoi(v) );
}
}

JACK_Module::set(e);
}

void
AUX_Module::number ( int n )
{
_number = n;

char s[10];
snprintf( s, sizeof(s), "aux-%c", 'A' + n );
prefix( s );
snprintf( s, sizeof(s), "Aux (%c)", 'A' + n );
copy_label( s );
}

void
AUX_Module::process ( nframes_t nframes )
{
if ( !bypass() )
{
float g = DB_CO( control_input[0].control_value() );
for ( unsigned int i = 0; i < audio_input.size(); ++i )
{
if ( audio_input[i].connected() )
buffer_copy_and_apply_gain( (sample_t*)jack_output[i].buffer( nframes ), (sample_t*)audio_input[i].buffer(), nframes, g );
}
}
else
{
for ( unsigned int i = 0; i < audio_input.size(); ++i )
{
if ( audio_input[i].connected() )
buffer_fill_with_silence( (sample_t*)jack_output[i].buffer( nframes ), nframes );
}
}
}

void
AUX_Module::draw ( void )
{
int W = 5;

Module::draw_box(x(),y(),w() - W,h());
Module::draw_label(x(),y(),w() - W,h());

Module *m = this;
fl_color( fl_darker( FL_FOREGROUND_COLOR ) );

int spacing, offset;

spacing = h() / m->ninputs();
offset = spacing / 2;
for ( int i = m->ninputs(); i--; )
{
int xi = offset + ( spacing * i );
fl_rectf( m->x() + m->w() - W, m->y() + xi, W, 2 );
}
}

bool
AUX_Module::configure_outputs ( int n )
{
int on = audio_output.size();

if ( n > on )
{
for ( int i = on; i < n; ++i )
{
add_port( Port( this, Port::OUTPUT, Port::AUDIO ) );
}
}
else
{
for ( int i = on; i > n; --i )
{
audio_output.back().disconnect();
audio_output.pop_back();
}
}

return true;
}

bool
AUX_Module::configure_inputs ( int n )
{
bool b = JACK_Module::configure_inputs( n );

if ( b )
{
return configure_outputs( n );
}

return false;
}

+ 54
- 0
mixer/src/AUX_Module.H View File

@@ -0,0 +1,54 @@

/*******************************************************************************/
/* Copyright (C) 2013 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 "JACK_Module.H"

class AUX_Module : public JACK_Module
{
int _number;

protected:

virtual void get ( Log_Entry &e ) const;
virtual void set ( Log_Entry &e );

public:

virtual const char *name ( void ) const { return "AUX"; }

virtual bool configure_outputs ( int n );
virtual bool configure_inputs ( int n );

void number ( int n );
int number ( void ) const { return _number; }

AUX_Module ( );
virtual ~AUX_Module ( );

LOG_CREATE_FUNC( AUX_Module );

protected:

virtual void draw ( void );
virtual void process ( nframes_t nframes );

};


+ 1
- 1
mixer/src/Controller_Module.H View File

@@ -91,7 +91,7 @@ public:

void draw ( void )
{
draw_box();
draw_box(x(),y(),w(),h());
Fl_Group::draw();
}



+ 72
- 39
mixer/src/JACK_Module.C View File

@@ -32,41 +32,47 @@


JACK_Module::JACK_Module ( )
JACK_Module::JACK_Module ( bool log )
: Module ( 50, 24, name() )
{
/* FIXME: how do Controls find out that a connected value has changed? How does this work in ladspa? */
_prefix = 0;

if ( log )
{
Port p( this, Port::INPUT, Port::CONTROL, "Inputs" );
p.hints.type = Port::Hints::INTEGER;
p.hints.minimum = 0;
p.hints.maximum = 16;
p.hints.ranged = true;
/* FIXME: how do Controls find out that a connected value has changed? How does this work in ladspa? */
{
Port p( this, Port::INPUT, Port::CONTROL, "Inputs" );
p.hints.type = Port::Hints::INTEGER;
p.hints.minimum = 0;
p.hints.maximum = 16;
p.hints.ranged = true;
p.hints.visible = false;

p.connect_to( new float );
p.control_value_no_callback( 0 );
p.connect_to( new float );
p.control_value_no_callback( 0 );

add_port( p );
}
add_port( p );
}

{
Port p( this, Port::INPUT, Port::CONTROL, "Outputs" );
p.hints.type = Port::Hints::INTEGER;
p.hints.minimum = 0;
p.hints.maximum = 16;
p.hints.ranged = true;
{
Port p( this, Port::INPUT, Port::CONTROL, "Outputs" );
p.hints.type = Port::Hints::INTEGER;
p.hints.minimum = 0;
p.hints.maximum = 16;
p.hints.ranged = true;
p.hints.visible = false;

p.connect_to( new float );
p.control_value_no_callback( 0 );
p.connect_to( new float );
p.control_value_no_callback( 0 );

add_port( p );
}
add_port( p );
}
color( FL_BLACK );

end();
color( FL_BLACK );
log_create();
}

log_create();
end();
}

JACK_Module::~JACK_Module ( )
@@ -74,6 +80,8 @@ JACK_Module::~JACK_Module ( )
log_destroy();
configure_inputs( 0 );
configure_outputs( 0 );
if ( _prefix )
free( _prefix );
}

@@ -93,19 +101,26 @@ JACK_Module::configure_inputs ( int n )
{
for ( int i = on; i < n; ++i )
{
JACK::Port po( chain()->engine(), JACK::Port::Output, i );
JACK::Port *po = NULL;

if ( ! po.activate() )
if ( !_prefix )
po = new JACK::Port( chain()->engine(), JACK::Port::Output, i );
else
po = new JACK::Port( chain()->engine(), JACK::Port::Output, _prefix, i );

if ( ! po->activate() )
{
jack_port_activation_error( &po );
jack_port_activation_error( po );
return false;
}

if ( po.valid() )
if ( po->valid() )
{
add_port( Port( this, Port::INPUT, Port::AUDIO ) );
jack_output.push_back( po );
jack_output.push_back( *po );
}

delete po;
}
}
else
@@ -119,7 +134,8 @@ JACK_Module::configure_inputs ( int n )
}
}

control_input[0].control_value_no_callback( n );
if ( is_default() )
control_input[0].control_value_no_callback( n );

return true;
}
@@ -139,19 +155,26 @@ JACK_Module::configure_outputs ( int n )
{
for ( int i = on; i < n; ++i )
{
JACK::Port po( chain()->engine(), JACK::Port::Input, i );
JACK::Port *po = NULL;

if ( ! po.activate() )
if ( !_prefix )
po = new JACK::Port( chain()->engine(), JACK::Port::Input, i );
else
po = new JACK::Port( chain()->engine(), JACK::Port::Input, _prefix, i );

if ( ! po->activate() )
{
jack_port_activation_error( &po );
jack_port_activation_error( po );
return false;
}

if ( po.valid() )
if ( po->valid() )
{
add_port( Port( this, Port::OUTPUT, Port::AUDIO ) );
jack_input.push_back( po );
jack_input.push_back( *po );
}

delete po;
}
}
else
@@ -165,7 +188,8 @@ JACK_Module::configure_outputs ( int n )
}
}

control_input[1].control_value_no_callback( n );
if ( is_default() )
control_input[1].control_value_no_callback( n );

return true;
}
@@ -230,10 +254,19 @@ void
JACK_Module::process ( nframes_t nframes )
{
for ( unsigned int i = 0; i < audio_input.size(); ++i )
{
if ( audio_input[i].connected() )
buffer_copy( (sample_t*)jack_output[i].buffer( nframes ), (sample_t*)audio_input[i].buffer(), nframes );
buffer_copy( (sample_t*)jack_output[i].buffer( nframes ),
(sample_t*)audio_input[i].buffer(),
nframes );
}

for ( unsigned int i = 0; i < audio_output.size(); ++i )
{
if ( audio_output[i].connected() )
buffer_copy( (sample_t*)audio_output[i].buffer(), (sample_t*)jack_input[i].buffer( nframes ), nframes );
buffer_copy( (sample_t*)audio_output[i].buffer(),
(sample_t*)jack_input[i].buffer( nframes ),
nframes );
}
}

+ 23
- 11
mixer/src/JACK_Module.H View File

@@ -19,13 +19,27 @@

#pragma once


#include "Module.H"
#include "JACK/Port.H"
#include <vector>

class JACK_Module : public Module
{
char *_prefix;

protected:
void prefix ( const char *s )
{
if ( _prefix )
free( _prefix );
_prefix = NULL;
if ( s )
_prefix = strdup( s );
}

std::vector<JACK::Port> jack_input;
std::vector<JACK::Port> jack_output;

@@ -33,21 +47,19 @@ class JACK_Module : public Module

public:

JACK_Module ( );
JACK_Module ( bool log = true );
virtual ~JACK_Module ( );

const char *name ( void ) const { return "JACK"; }

bool initialize ( void );
virtual const char *name ( void ) const { return "JACK"; }

int can_support_inputs ( int );
bool configure_inputs ( int n );
bool configure_outputs ( int n );
virtual bool initialize ( void );

void add_output ( void );
virtual int can_support_inputs ( int );
virtual bool configure_inputs ( int n );
virtual bool configure_outputs ( int n );

void handle_control_changed ( Port *p );
void handle_chain_name_changed ();
virtual void handle_control_changed ( Port *p );
virtual void handle_chain_name_changed ();

LOG_CREATE_FUNC( JACK_Module );



+ 1
- 1
mixer/src/Meter_Module.H View File

@@ -48,5 +48,5 @@ protected:

virtual int handle ( int m );
virtual void process ( nframes_t nframes );
virtual void draw ( void ) { draw_box(); }
virtual void draw ( void ) { draw_box(x(),y(),w(),h()); }
};

+ 50
- 56
mixer/src/Module.C View File

@@ -33,6 +33,7 @@
#include "Mono_Pan_Module.H"
#include "Meter_Module.H"
#include "Plugin_Module.H"
#include "AUX_Module.H"

#include <FL/Fl_Menu_Button.H>
#include "FL/test_press.H"
@@ -395,7 +396,11 @@ Module::set ( Log_Entry &e )

e.get( i, &s, &v );

if ( ! strcmp( s, ":chain" ) )
if ( ! ( strcmp( s, ":is_default" ) ) )
{
is_default( atoi( v ) );
}
else 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. */
@@ -421,10 +426,6 @@ Module::set ( Log_Entry &e )
{
set_parameters( v );
}
else if ( ! ( strcmp( s, ":is_default" ) ) )
{
is_default( atoi( v ) );
}
else if ( ! ( strcmp( s, ":active" ) ) )
{
bypass( ! atoi( v ) );
@@ -527,17 +528,10 @@ Module::set_parameters ( const char *parameters )

void
Module::draw_box ( void )
Module::draw_box ( int tx, int ty, int tw, int th )
{
fl_color( fl_contrast( FL_FOREGROUND_COLOR, color() ) );

int tw, th, tx, ty;

tw = w();
th = h();
ty = y();
tx = x();

fl_push_clip( tx, ty, tw, th );

Fl_Color c = color();
@@ -575,10 +569,8 @@ Module::draw_box ( void )
}

void
Module::draw_label ( void )
Module::draw_label ( int tx, int ty, int tw, int th )
{
int tw, th, tx, ty;

bbox( tx, ty, tw, th );

const char *lp = label();
@@ -616,47 +608,53 @@ Module::draw_label ( void )
void
Module::insert_menu_cb ( const Fl_Menu_ *m )
{
unsigned long id = Plugin_Chooser::plugin_chooser( this->ninputs() );
const char * picked = m->mvalue()->label();

DMESSAGE("picked = %s", picked );

Module *mod = NULL;
switch ( id )
if ( !strcmp( picked, "Aux" ) )
{
case 0:
return;
case 1:
mod = new JACK_Module();
break;
case 2:
mod = new Gain_Module();
break;
case 3:
mod = new Meter_Module();
break;
case 4:
mod = new Mono_Pan_Module();
break;
default:
int n = 0;
for ( int i = 0; i < chain()->modules(); i++ )
{
Plugin_Module *m = new Plugin_Module();

m->load( id );

mod = m;
if ( !strcmp( chain()->module(i)->name(), "AUX" ) )
n++;
}

AUX_Module *jm = new AUX_Module();
jm->chain( chain() );
jm->number( n );
jm->configure_inputs( ninputs() );
jm->configure_outputs( ninputs() );
jm->initialize();
mod = jm;
}
else if ( !strcmp( picked, "Gain" ) )
mod = new Gain_Module();
else if ( !strcmp( picked, "Meter" ) )
mod = new Meter_Module();
else if ( !strcmp( picked, "Mono Pan" ))
mod = new Mono_Pan_Module();
else if ( !strcmp(picked, "Plugin" ))
{
unsigned long id = Plugin_Chooser::plugin_chooser( this->ninputs() );
if ( id == 0 )
return;
Plugin_Module *m = new Plugin_Module();
m->load( id );
mod = m;
}

if ( mod )
{
if ( !strcmp( mod->name(), "JACK" ) )
{
DMESSAGE( "Special casing JACK module" );
JACK_Module *jm = (JACK_Module*)mod;
jm->chain( chain() );
jm->configure_inputs( ninputs() );
jm->configure_outputs( ninputs() );
}

if ( ! chain()->insert( this, mod ) )
{
fl_alert( "Cannot insert this module at this point in the chain" );
@@ -737,16 +735,12 @@ Module::menu ( void ) const
{
insert_menu = new Fl_Menu_Button( 0, 0, 0, 0 );

insert_menu->add( "Gain", 0, 0, new unsigned long(2) );
insert_menu->add( "Meter", 0, 0, new unsigned long(3) );
insert_menu->add( "Mono Pan", 0, 0, new unsigned long(4) );

insert_menu->add( "Plugin", 0, 0, new unsigned long(4) );


/* Plugin_Module::add_plugins_to_menu( insert_menu ); */
insert_menu->add( "Gain", 0, 0 );
insert_menu->add( "Meter", 0, 0 );
insert_menu->add( "Mono Pan", 0, 0 );
insert_menu->add( "Aux", 0, 0 );
insert_menu->add( "Plugin", 0, 0 );

// menu_set_callback( insert_menu, &Module::insert_menu_cb, (void*)this );
insert_menu->callback( &Module::insert_menu_cb, (void*)this );
}



+ 7
- 7
mixer/src/Module.H View File

@@ -269,10 +269,10 @@ public:

void bbox ( int &X, int &Y, int &W, int &H )
{
X = x() + 5;
Y = y() + 5;
W = w() - 10;
H = h() - 10;
X += + 5;
Y += 5;
W -= 10;
H -= 10;
}

Module ( int W, int H, const char *L = 0 );
@@ -435,10 +435,10 @@ public:
protected:

void draw_connections ( void );
void draw_label ( void );
void draw_box ( void );
void draw_label ( int X, int Y, int W, int H );
void draw_box ( int X, int Y, int W, int H );

virtual void draw ( void ) { Module::draw_box(); Module::draw_label(); }
virtual void draw ( void ) { Module::draw_box(x(),y(),w(),h()); Module::draw_label(x(),y(),w(),h()); }
virtual int handle ( int m );

virtual void get ( Log_Entry &e ) const;


+ 2
- 1
mixer/src/main.C View File

@@ -51,7 +51,7 @@
#include "Mono_Pan_Module.H"
#include "Chain.H"
#include "Mixer_Strip.H"
#include "AUX_Module.H"
#include "NSM.H"

#include <signal.h>
@@ -156,6 +156,7 @@ main ( int argc, char **argv )
LOG_REGISTER_CREATE( Mono_Pan_Module );
LOG_REGISTER_CREATE( Meter_Indicator_Module );
LOG_REGISTER_CREATE( Controller_Module );
LOG_REGISTER_CREATE( AUX_Module );

signal( SIGPIPE, SIG_IGN );



+ 1
- 0
mixer/wscript View File

@@ -49,6 +49,7 @@ src/DPM.C
src/Engine/Engine.C
src/Gain_Module.C
src/JACK_Module.C
src/AUX_Module.C
src/LADSPAInfo.C
src/Meter_Indicator_Module.C
src/Meter_Module.C


Loading…
Cancel
Save