Browse Source

Mixer: Implement slow fall off for meters.

tags/non-daw-v1.3.0
Jonathan Moore Liles 2 years ago
parent
commit
f5b215066a
11 changed files with 178 additions and 172 deletions
  1. +5
    -2
      mixer/src/Chain.C
  2. +42
    -61
      mixer/src/DPM.C
  3. +15
    -27
      mixer/src/DPM.H
  4. +1
    -1
      mixer/src/Group.C
  5. +5
    -8
      mixer/src/Meter.H
  6. +45
    -39
      mixer/src/Meter_Indicator_Module.C
  7. +35
    -15
      mixer/src/Meter_Module.C
  8. +13
    -0
      mixer/src/Meter_Module.H
  9. +2
    -2
      mixer/src/Mixer.C
  10. +8
    -5
      mixer/src/Module.H
  11. +7
    -12
      nonlib/dsp.C

+ 5
- 2
mixer/src/Chain.C View File

@@ -370,7 +370,7 @@ Chain::configure_ports ( void )
client()->lock();

for ( int i = 0; i < modules(); ++i )
{
{
module( i )->configure_inputs( nouts );
nouts = module( i )->noutputs();
}
@@ -573,6 +573,9 @@ Chain::insert ( Module *m, Module *n )
{
client()->lock();

Module::sample_rate( client()->sample_rate() );
n->resize_buffers( client()->nframes() );
if ( !m )
{
if ( modules() == 0 && n->can_support_inputs( 0 ) >= 0 )
@@ -938,7 +941,7 @@ Chain::buffer_size ( nframes_t nframes )
int
Chain::sample_rate_change ( nframes_t nframes )
{
Module::set_sample_rate ( nframes );
Module::sample_rate ( nframes );
for ( int i = 0; i < modules(); ++i )
{
Module *m = module(i);


+ 42
- 61
mixer/src/DPM.C View File

@@ -82,14 +82,6 @@ DPM::DPM ( int X, int Y, int W, int H, const char *L ) :

}

{
/* smoothing.cutoff(25); */
smoothing.cutoff(200);
smoothing.sample_rate(30000);
smoothing.reset(-70.0f);
/* clear initial hump */
}
resize( X,Y,W,H);
}

@@ -164,6 +156,7 @@ void DPM::bbox ( int &X, int &Y, int &W, int &H )
H = h();
}


void
DPM::draw ( void )
{
@@ -220,63 +213,51 @@ DPM::draw ( void )
}

_last_drawn_hi_segment = v;
for ( int p = lo; p <= hi; p++ )
{
Fl_Color c;

if ( p <= v )
{
if ( p == clipv )
c = fl_color_average( FL_YELLOW, div_color( p ), 0.40 );
else
c = div_color( p );
}
else if ( p == pv )
c = div_color( p );
else
c = fl_darker( FL_BACKGROUND_COLOR );//FL_DARK1; // fl_color_average( FL_BACKGROUND_COLOR, FL_BLACK, 0.50f );// FL_BACKGROUND_COLOR; //dim_div_color( p );
if ( ! active )
c = fl_inactive( c );

int yy = 0;
int xx = 0;
if ( type() == FL_HORIZONTAL )
{
xx = X + p * bw;
fl_rectf( xx + 1, Y, bw - 1, H, c );
}
else
{
yy = Y + H - ((p+1) * bh);
fl_rectf( X, yy + 1, W, bh - 1, c );
}

/* } */
/* else */
/* { */
/* if ( type() == FL_HORIZONTAL ) */
/* fl_draw_box( box(), X + (p * bw), Y, bw, H, c ); */
/* else */
/* fl_draw_box( box(), X, Y + H - ((p + 1) * bh), W, bh, c ); */
/* } */
Fl_Color c;
if ( p <= v )
{
if ( p == clipv )
c = fl_color_average( FL_YELLOW, div_color( p ), 0.40 );
else
c = div_color( p );
}
else if ( p == pv )
c = div_color( p );
else
c = fl_darker( FL_BACKGROUND_COLOR );//FL_DARK1; // fl_color_average( FL_BACKGROUND_COLOR, FL_BLACK, 0.50f );// FL_BACKGROUND_COLOR; //dim_div_color( p );
if ( ! active )
c = fl_inactive( c );
int yy = 0;
int xx = 0;
if ( type() == FL_HORIZONTAL )
{
xx = X + p * bw;
fl_rectf( xx + 1, Y, bw - 1, H, c );
}
else
{
yy = Y + H - ((p+1) * bh);
fl_rectf( X, yy + 1, W, bh - 1, c );
}
}

/* fl_color( fl_color_add_alpha( FL_WHITE, 127 ) ); */
fl_pop_clip();
}

/* for ( int i = 0; i < 50; i++ ) */
/* { */
/* int yy = Y + i * H / 50; */
/* if ( type() == FL_VERTICAL ) */
/* { */
/* int ww = i % 2 == 0 ? W : W / 2; */
/* fl_line( X + ((W/2) - ww/2), yy, X + ww - 1, yy ); */
/* } */
/* } */
void
DPM::update ( void )
{
/* do falloff */
float f = value() - 0.33f;
if ( f < -70.0f )
f = -78.0f;
fl_pop_clip();
value(f);
}

+ 15
- 27
mixer/src/DPM.H View File

@@ -22,7 +22,6 @@
#include <FL/Fl_Valuator.H> // for FL_HORIZONTAL and FL_VERTICAL

#include "Meter.H"
#include "dsp.h"

class DPM : public Meter
{
@@ -31,11 +30,7 @@ class DPM : public Meter
int _segments;
int _pixels_per_segment;
int _last_drawn_hi_segment;

Value_Smoothing_Filter smoothing;
float _value;

int pos ( float v )
{
float pv = deflection( v ) * ( _segments - 1 );
@@ -58,8 +53,7 @@ class DPM : public Meter
{
return _dim_gradient[ i * 127 / _segments ];
}


protected:

virtual void draw_label ( void );
@@ -70,34 +64,28 @@ protected:

public:

DPM ( int X, int Y, int W, int H, const char *L = 0 );

void value ( float v )
{
sample_t buf[1];

if ( smoothing.apply( buf, 1, v ) )
v = buf[0];
if ( _value != v )
{
if ( pos( v ) != pos( _value ) )
Meter::value( v );
}
void pixels_per_segment ( int v ) { _pixels_per_segment = v; }

_value = v;
}
float dim ( void ) const { return _dim; }
void dim ( float v ) { _dim = v; if ( visible_r() ) redraw(); }

float value ( void ) const
virtual void value ( float v )
{
return _value;
/* only trigger redraw for changes at or above our resolution*/
if ( pos( value() ) != pos( v ) && visible_r() )
damage( FL_DAMAGE_USER1 );
Meter::value( v );
}

void pixels_per_segment ( int v ) { _pixels_per_segment = v; }

float dim ( void ) const { return _dim; }
void dim ( float v ) { _dim = v; if ( visible_r() ) redraw(); }
virtual float value ( void ) { return Meter::value(); }

void update ( void );
static
void
blend ( int nbreaks, int* b, Fl_Color *c, Fl_Color bc )


+ 1
- 1
mixer/src/Group.C View File

@@ -275,7 +275,7 @@ Group::name ( const char *n )
if ( !active() )
{
Client::init( ename );
Module::set_sample_rate( sample_rate() );
Module::sample_rate( sample_rate() );
}
else
{


+ 5
- 8
mixer/src/Meter.H View File

@@ -84,17 +84,14 @@ public:

virtual void value ( float v )
{
if ( visible_r() )
damage( FL_DAMAGE_USER1 );

_value = v;

if ( _value > _peak )
_peak = _value;
_value = v;
if ( _value > _peak )
_peak = _value;
}

virtual float value ( void ) const { return _value; }
float peak ( void ) const { return _peak; }
virtual float peak ( void ) const { return _peak; }

void reset ( void ) { _peak = -80.0f; redraw(); }



+ 45
- 39
mixer/src/Meter_Indicator_Module.C View File

@@ -35,6 +35,7 @@

#include "Chain.H"
#include "DPM.H"
#include "dsp.h"

#include "FL/test_press.H"

@@ -64,8 +65,9 @@ Meter_Indicator_Module::Meter_Indicator_Module ( bool is_default )

end();

control_value = new float[1];
*control_value = -70.0f;
control_value = new float[1*2];
control_value[0] =
control_value[1] = 0;

align( (Fl_Align)(FL_ALIGN_CENTER | FL_ALIGN_INSIDE ) );

@@ -158,37 +160,29 @@ Meter_Indicator_Module::update ( void )
// A little hack to detect that the connected module's number
// of control outs has changed.
Port *p = control_input[0].connected_port();

if ( dpm_pack->children() != p->hints.dimensions )
{
/* engine->lock(); */

dpm_pack->clear();

control_value = new float[p->hints.dimensions];

for ( int i = p->hints.dimensions; i--; )
{

DPM *dpm = new DPM( x(), y(), w(), h() );
dpm->type( FL_VERTICAL );

dpm_pack->add( dpm );

control_value[i] = -70.0f;
dpm->value( -70.0f );
}

/* engine->unlock(); */
}
else
{
for ( int i = 0; i < dpm_pack->children(); ++i )
{
((DPM*)dpm_pack->child( i ))->value( control_value[i] );
control_value[i] = -70.0f;
}
}
for ( int i = 0; i < dpm_pack->children(); ++i )
{
DPM *o = (DPM*)dpm_pack->child(i);

float dB = CO_DB( control_value[i] );
if ( dB > o->value() )
o->value( dB );

o->update();
/* else */
/* { */
/* /\* do falloff *\/ */
/* float f = o->value() - 0.75f; */
/* if ( f < -70.0f ) */
/* f = -70.0f; */
/* o->value( f ); */
/* } */

control_value[i] = 0;
}
}
}

@@ -248,7 +242,7 @@ Meter_Indicator_Module::handle_control_changed ( Port *p )

control_value = new float[p->hints.dimensions];

for ( int i = p->hints.dimensions; i--; )
for ( int i = 0; i < p->hints.dimensions; i++ )
{
DPM *dpm = new DPM( x(), y(), w(), h() );
dpm->type( FL_VERTICAL );
@@ -257,8 +251,10 @@ Meter_Indicator_Module::handle_control_changed ( Port *p )
dpm_pack->add( dpm );
dpm_pack->redraw();

control_value[i] = -70.0f;
dpm->value( -70.0f );
control_value[i] = 0;
dpm->value( CO_DB( control_value[i] ));
}

redraw();
@@ -276,12 +272,22 @@ Meter_Indicator_Module::process ( nframes_t )
if ( control_input[0].connected() )
{
Port *p = control_input[0].connected_port();
volatile float *cv = control_value;
float *pv = (float*)control_input[0].buffer();

for ( int i = 0; i < p->hints.dimensions; ++i )
{
float dB = ((float*)control_input[0].buffer())[i];
if ( dB > control_value[i])
control_value[i] = dB;
/* peak value since we last checked */
if ( *pv > *cv )
{
*cv = *pv;
/* reset now that we've got it */
*pv = 0;
}

cv++;
pv++;
}
}
}

+ 35
- 15
mixer/src/Meter_Module.C View File

@@ -42,19 +42,22 @@ Meter_Module::Meter_Module ( )
dpm_pack->spacing( 1 );
control_value = 0;
peaks = 0;
meter_sample_period_count = 0;
meter_sample_periods = 0;
color( fl_darker( fl_darker( FL_BACKGROUND_COLOR )));

end();

Port p( this, Port::OUTPUT, Port::CONTROL, "dB level" );
p.hints.type = Port::Hints::LOGARITHMIC;
Port p( this, Port::OUTPUT, Port::CONTROL, "peak level" );
p.hints.type = Port::Hints::LINEAR;
p.hints.ranged = true;
p.hints.maximum = 6.0f;
p.hints.minimum = -70.0f;
p.hints.maximum = 10.0f;
p.hints.minimum = 0.0f;
p.hints.dimensions = 1;
p.connect_to( new float[1] );
p.control_value_no_callback( -70.0f );
p.control_value_no_callback( 0 );

add_port( p );

@@ -71,6 +74,8 @@ Meter_Module::~Meter_Module ( )




void Meter_Module::resize ( int X, int Y, int W, int H )
{
Fl_Group::resize(X,Y,W,H);
@@ -93,8 +98,12 @@ Meter_Module::update ( void )
{
for ( int i = dpm_pack->children(); i--; )
{
((DPM*)dpm_pack->child( i ))->value( control_value[i] );
control_value[i] = -70.0f;
DPM* o = ((DPM*)dpm_pack->child( i ));
o->value( CO_DB( control_value[i] ) );
o->update();
control_value[i] = 0;
}
}

@@ -117,7 +126,6 @@ Meter_Module::configure_inputs ( int n )

add_port( Port( this, Port::INPUT, Port::AUDIO ) );
add_port( Port( this, Port::OUTPUT, Port::AUDIO ) );

}
}
else
@@ -132,16 +140,20 @@ Meter_Module::configure_inputs ( int n )
audio_input.pop_back();
audio_output.back().disconnect();
audio_output.pop_back();

smoothing.pop_back();
}
}

/* DMESSAGE( "sample rate: %lu, nframes: %lu", sample_rate(), this->nframes() ); */

control_output[0].hints.dimensions = n;
delete[] (float*)control_output[0].buffer();
{
float *f = new float[n];

for ( int i = n; i--; )
f[i] = -70.0f;
f[i] = 0;

control_output[0].connect_to( f );
}
@@ -151,7 +163,7 @@ Meter_Module::configure_inputs ( int n )

control_value = new float[n];
for ( int i = n; i--; )
control_value[i] = -70.0f;
control_value[i] = 0;

if ( control_output[0].connected() )
control_output[0].connected_port()->module()->handle_control_changed( control_output[0].connected_port() );
@@ -193,11 +205,19 @@ Meter_Module::process ( nframes_t nframes )
{
for ( unsigned int i = 0; i < audio_input.size(); ++i )
{
// float dB = 20 * log10( get_peak_sample( (float*)audio_input[i].buffer(), nframes ) / 2.0f );
const float dB = 20 * log10( buffer_get_peak( (sample_t*) audio_input[i].buffer(), nframes ) );
const float peak = buffer_get_peak( (sample_t*) audio_input[i].buffer(), nframes );
/* const float RMS = sqrtf( peak / (float)nframes); */

/* since the GUI only updates at 20 or 30hz, there's no point in doing this more often than necessary. */

/* need to store this separately from other peaks as it must be reset each time we do a round of smoothing output */
/* store peak value */
if ( peak > ((float*)control_output[0].buffer())[i] )
((float*)control_output[0].buffer())[i] = peak;

((float*)control_output[0].buffer())[i] = dB;
if (dB > control_value[i])
control_value[i] = dB;
if ( peak > control_value[i] )
control_value[i] = peak;
}
}

+ 13
- 0
mixer/src/Meter_Module.H View File

@@ -20,6 +20,8 @@
#pragma once

#include "Module.H"
#include "dsp.h"
#include <vector>

class Fl_Scalepack;

@@ -27,8 +29,19 @@ class Meter_Module : public Module
{
Fl_Scalepack *dpm_pack;

std::vector <Value_Smoothing_Filter> smoothing;
volatile float *control_value;
volatile float *peaks;

int meter_sample_periods; /* no need to do computations every
* buffer when the gui only updates at
* 30Hz. So only do it every n
* buffers */
int meter_sample_period_count;

void set_smoothing_sample_rate ( nframes_t nframes, nframes_t sample_rate );
public:

Meter_Module ( );


+ 2
- 2
mixer/src/Mixer.C View File

@@ -416,7 +416,7 @@ Mixer::update_cb ( void )
{
Fl::repeat_timeout( _update_interval, &Mixer::update_cb, this );

if ( active_r() && visible_r() )
/* if ( active_r() && visible_r() ) */
{
for ( int i = 0; i < mixer_strips->children(); i++ )
{
@@ -591,7 +591,7 @@ Mixer::Mixer ( int X, int Y, int W, int H, const char *L ) :

resize( X,Y,W,H );

update_frequency( 30 );
update_frequency( 24 );

Fl::add_timeout( FEEDBACK_UPDATE_FREQ, send_feedback_cb, this );



+ 8
- 5
mixer/src/Module.H View File

@@ -46,10 +46,10 @@ class Module : public Fl_Group, public Loggable {
int _ins;
int _outs;
int _instances;
nframes_t _nframes;
Chain *_chain;
bool _is_default;

nframes_t _nframes;
static nframes_t _sample_rate;
static Module *_copied_module_empty;
static char *_copied_module_settings;
@@ -181,12 +181,14 @@ public:
_by_number_path = NULL;
}


nframes_t nframes ( void ) const { return _nframes; }
void nframes ( nframes_t n) { _nframes = n; }
const char *name ( void ) const { return _name; }
Type type ( void ) const { return _type; }
Direction direction ( void ) const { return _direction; }

Module * module ( void ) const { return _module; }
nframes_t nframes ( void ) const { return _nframes; }

void buffer ( void *buf, nframes_t nframes ) { _buf = buf; _nframes = nframes; };
void *buffer ( void ) const { return _buf; }
@@ -368,7 +370,6 @@ public:

LOG_NAME_FUNC( Module );

nframes_t nframes ( void ) const { return _nframes; }
virtual void resize_buffers ( nframes_t v ) { _nframes = v; }


@@ -548,7 +549,9 @@ protected:
bool add_aux_port ( bool input, const char *prefix, int n , JACK::Port::type_e type );

public:
nframes_t sample_rate ( void ) const { return Module::_sample_rate; }
static nframes_t sample_rate ( void ) { return Module::_sample_rate; }
nframes_t nframes ( void ) { return _nframes; }


void auto_connect_outputs();
@@ -561,7 +564,7 @@ public:
bool add_aux_audio_input ( const char *prefix, int n );
bool add_aux_cv_input ( const char *prefix, int n );

static void set_sample_rate ( nframes_t srate ) { _sample_rate = srate; }
static void sample_rate ( nframes_t srate ) { _sample_rate = srate; }

void command_open_parameter_editor();
virtual void command_activate ( void );


+ 7
- 12
nonlib/dsp.C View File

@@ -199,24 +199,17 @@ buffer_get_peak ( const sample_t * __restrict__ buf, nframes_t nframes )
{
const sample_t * buf_ = (const sample_t*) assume_aligned(buf);

float pmax = 0.0f;
float pmin = 0.0f;
float p = 0.0f;
while (nframes--)
{
const float v = *buf_++;
const float v = fabsf( *buf_++ );

if ( v > pmax )
pmax = v;
if ( v < pmin )
pmin = v;
if ( v > p )
p = v;
}

pmax = fabsf(pmax);
pmin = fabsf(pmin);
return pmax > pmin ? pmax : pmin;
return p;
}

void
@@ -266,6 +259,8 @@ Value_Smoothing_Filter::apply( sample_t * __restrict__ dst, nframes_t nframes, f
dst_[i] = g2;
}

g2 += 1e-10f; /* denormal protection */

if ( fabsf( gt - g2 ) < 0.0001f )
g2 = gt;



Loading…
Cancel
Save