Revert "Revert new meter types (postponed until after 3.3 release)"

This reverts commit d80f672e84.
This commit is contained in:
Robin Gareus 2013-07-22 18:42:01 +02:00
parent e294e78fef
commit 72aa1cd86c
16 changed files with 570 additions and 27 deletions

View File

@ -64,6 +64,15 @@ ArdourMeter::meter_type_string (ARDOUR::MeterType mt)
case MeterKrms:
return _("RMS + Peak");
break;
case MeterIEC1:
return _("DIN");
break;
case MeterIEC2:
return _("EBU/BBC");
break;
case MeterVU:
return _("VU");
break;
default:
return _("???");
break;

View File

@ -573,6 +573,9 @@ MeterStrip::popup_level_meter_menu (GdkEventButton* ev)
_suspend_menu_callbacks = true;
add_level_meter_item (items, group, ArdourMeter::meter_type_string(MeterPeak), MeterPeak);
add_level_meter_item (items, group, ArdourMeter::meter_type_string(MeterKrms), MeterKrms);
add_level_meter_item (items, group, ArdourMeter::meter_type_string(MeterIEC1), MeterIEC1);
add_level_meter_item (items, group, ArdourMeter::meter_type_string(MeterIEC2), MeterIEC2);
add_level_meter_item (items, group, ArdourMeter::meter_type_string(MeterVU), MeterVU);
MeterType cmt = _route->meter_type();
const std::string cmn = ArdourMeter::meter_type_string(cmt);

View File

@ -2135,6 +2135,9 @@ MixerStrip::popup_level_meter_menu (GdkEventButton* ev)
add_level_meter_item_type (items, tgroup, ArdourMeter::meter_type_string(MeterPeak), MeterPeak);
add_level_meter_item_type (items, tgroup, ArdourMeter::meter_type_string(MeterKrms), MeterKrms);
add_level_meter_item_type (items, tgroup, ArdourMeter::meter_type_string(MeterIEC1), MeterIEC1);
add_level_meter_item_type (items, tgroup, ArdourMeter::meter_type_string(MeterIEC2), MeterIEC2);
add_level_meter_item_type (items, tgroup, ArdourMeter::meter_type_string(MeterVU), MeterVU);
int _strip_type;
if (_route->is_master()) {

View File

@ -0,0 +1,51 @@
/*
Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
Adopted for Ardour 2013 by Robin Gareus <robin@gareus.org>
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; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __IEC1PPMDSP_H
#define __IEC1PPMDSP_H
class Iec1ppmdsp
{
public:
Iec1ppmdsp (void);
~Iec1ppmdsp (void);
void process (float *p, int n);
float read (void);
void reset ();
static void init (float fsamp);
private:
float _z1; // filter state
float _z2; // filter state
float _m; // max value since last read()
bool _res; // flag to reset m
static float _w1; // attack filter coefficient
static float _w2; // attack filter coefficient
static float _w3; // release filter coefficient
static float _g; // gain factor
};
#endif

View File

@ -0,0 +1,51 @@
/*
Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
Adopted for Ardour 2013 by Robin Gareus <robin@gareus.org>
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; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __IEC2PPMDSP_H
#define __IEC2PPMDSP_H
class Iec2ppmdsp
{
public:
Iec2ppmdsp (void);
~Iec2ppmdsp (void);
void process (float *p, int n);
float read (void);
void reset ();
static void init (float fsamp);
private:
float _z1; // filter state
float _z2; // filter state
float _m; // max value since last read()
bool _res; // flag to reset m
static float _w1; // attack filter coefficient
static float _w2; // attack filter coefficient
static float _w3; // release filter coefficient
static float _g; // gain factor
};
#endif

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2008-2011 Fons Adriaensen <fons@linuxaudio.org>
Adopted for Ardour 2013 by Robin Gareus <robin@gareus.org>
Adopted for Ardour 2013 by Robin Gareus <robin@gareus.org>
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
@ -29,9 +29,10 @@ public:
void process (float *p, int n);
float read ();
static void init (int fsamp);
void reset ();
static void init (int fsamp);
private:
float _z1; // filter state

View File

@ -23,7 +23,11 @@
#include "ardour/types.h"
#include "ardour/processor.h"
#include "pbd/fastlog.h"
#include "kmeterdsp.h"
#include "ardour/kmeterdsp.h"
#include "ardour/iec1ppmdsp.h"
#include "ardour/iec2ppmdsp.h"
#include "ardour/vumeterdsp.h"
namespace ARDOUR {
@ -104,7 +108,11 @@ private:
std::vector<float> _visible_peak_power;
std::vector<float> _max_peak_signal;
std::vector<float> _max_peak_power;
std::vector<Kmeterdsp *> _kmeter;
std::vector<Iec1ppmdsp *> _iec1meter;
std::vector<Iec2ppmdsp *> _iec2meter;
std::vector<Vumeterdsp *> _vumeter;
MeterType _meter_type;
};

View File

@ -181,7 +181,10 @@ namespace ARDOUR {
MeterMaxSignal = 0x01,
MeterMaxPeak = 0x02,
MeterPeak = 0x04,
MeterKrms = 0x08
MeterKrms = 0x08,
MeterIEC1 = 0x10,
MeterIEC2 = 0x20,
MeterVU = 0x40
};
enum TrackMode {

View File

@ -0,0 +1,49 @@
/*
Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
Adopted for Ardour 2013 by Robin Gareus <robin@gareus.org>
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; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __VUMETERDSP_H
#define __VUMETERDSP_H
class Vumeterdsp
{
public:
Vumeterdsp (void);
~Vumeterdsp (void);
void process (float *p, int n);
float read (void);
void reset ();
static void init (float fsamp);
private:
float _z1; // filter state
float _z2; // filter state
float _m; // max value since last read()
bool _res; // flag to reset m
static float _w; // lowpass filter coefficient
static float _g; // gain factor
};
#endif

View File

@ -177,6 +177,9 @@ setup_enum_writer ()
REGISTER_ENUM (MeterMaxPeak);
REGISTER_ENUM (MeterPeak);
REGISTER_ENUM (MeterKrms);
REGISTER_ENUM (MeterIEC1);
REGISTER_ENUM (MeterIEC2);
REGISTER_ENUM (MeterVU);
REGISTER (_MeterType);
REGISTER_ENUM (Normal);

100
libs/ardour/iec1ppmdsp.cc Normal file
View File

@ -0,0 +1,100 @@
/*
Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
Adopted for Ardour 2013 by Robin Gareus <robin@gareus.org>
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; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <math.h>
#include "ardour/iec1ppmdsp.h"
float Iec1ppmdsp::_w1;
float Iec1ppmdsp::_w2;
float Iec1ppmdsp::_w3;
float Iec1ppmdsp::_g;
Iec1ppmdsp::Iec1ppmdsp (void) :
_z1 (0),
_z2 (0),
_m (0),
_res (true)
{
}
Iec1ppmdsp::~Iec1ppmdsp (void)
{
}
void Iec1ppmdsp::process (float *p, int n)
{
float z1, z2, m, t;
z1 = _z1;
z2 = _z2;
m = _res ? 0: _m;
_res = false;
n /= 4;
while (n--)
{
z1 *= _w3;
z2 *= _w3;
t = fabsf (*p++);
if (t > z1) z1 += _w1 * (t - z1);
if (t > z2) z2 += _w2 * (t - z2);
t = fabsf (*p++);
if (t > z1) z1 += _w1 * (t - z1);
if (t > z2) z2 += _w2 * (t - z2);
t = fabsf (*p++);
if (t > z1) z1 += _w1 * (t - z1);
if (t > z2) z2 += _w2 * (t - z2);
t = fabsf (*p++);
if (t > z1) z1 += _w1 * (t - z1);
if (t > z2) z2 += _w2 * (t - z2);
t = z1 + z2;
if (t > m) m = t;
}
_z1 = z1 + 1e-10f;
_z2 = z2 + 1e-10f;
_m = m;
}
float Iec1ppmdsp::read (void)
{
_res = true;
return _g * _m;
}
void Iec1ppmdsp::reset ()
{
_z1 = _z2 = _m = .0f;
_res = true;
}
void Iec1ppmdsp::init (float fsamp)
{
_w1 = 450.0f / fsamp;
_w2 = 1300.0f / fsamp;
_w3 = 1.0f - 5.4f / fsamp;
_g = 0.5108f;
}
/* vi:set ts=8 sts=8 sw=4: */

100
libs/ardour/iec2ppmdsp.cc Normal file
View File

@ -0,0 +1,100 @@
/*
Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
Adopted for Ardour 2013 by Robin Gareus <robin@gareus.org>
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; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <math.h>
#include "ardour/iec2ppmdsp.h"
float Iec2ppmdsp::_w1;
float Iec2ppmdsp::_w2;
float Iec2ppmdsp::_w3;
float Iec2ppmdsp::_g;
Iec2ppmdsp::Iec2ppmdsp (void) :
_z1 (0),
_z2 (0),
_m (0),
_res (true)
{
}
Iec2ppmdsp::~Iec2ppmdsp (void)
{
}
void Iec2ppmdsp::process (float *p, int n)
{
float z1, z2, m, t;
z1 = _z1;
z2 = _z2;
m = _res ? 0: _m;
_res = false;
n /= 4;
while (n--)
{
z1 *= _w3;
z2 *= _w3;
t = fabsf (*p++);
if (t > z1) z1 += _w1 * (t - z1);
if (t > z2) z2 += _w2 * (t - z2);
t = fabsf (*p++);
if (t > z1) z1 += _w1 * (t - z1);
if (t > z2) z2 += _w2 * (t - z2);
t = fabsf (*p++);
if (t > z1) z1 += _w1 * (t - z1);
if (t > z2) z2 += _w2 * (t - z2);
t = fabsf (*p++);
if (t > z1) z1 += _w1 * (t - z1);
if (t > z2) z2 += _w2 * (t - z2);
t = z1 + z2;
if (t > m) m = t;
}
_z1 = z1 + 1e-10f;
_z2 = z2 + 1e-10f;
_m = m;
}
float Iec2ppmdsp::read (void)
{
_res = true;
return _g * _m;
}
void Iec2ppmdsp::reset ()
{
_z1 = _z2 = _m = .0f;
_res = true;
}
void Iec2ppmdsp::init (float fsamp)
{
_w1 = 200.0f / fsamp;
_w2 = 860.0f / fsamp;
_w3 = 1.0f - 4.0f / fsamp;
_g = 0.5141f;
}
/* vi:set ts=8 sts=8 sw=4: */

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2008-2011 Fons Adriaensen <fons@linuxaudio.org>
Adopted for Ardour 2013 by Robin Gareus <robin@gareus.org>
Adopted for Ardour 2013 by Robin Gareus <robin@gareus.org>
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
@ -17,12 +17,13 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <math.h>
#include "kmeterdsp.h"
#include "ardour/kmeterdsp.h"
float Kmeterdsp::_omega;
Kmeterdsp::Kmeterdsp (void) :
_z1 (0),
_z2 (0),
@ -36,6 +37,10 @@ Kmeterdsp::~Kmeterdsp (void)
{
}
void Kmeterdsp::init (int fsamp)
{
_omega = 9.72f / fsamp; // ballistic filter coefficient
}
void Kmeterdsp::process (float *p, int n)
{
@ -96,7 +101,6 @@ void Kmeterdsp::process (float *p, int n)
}
}
/* Returns highest _rms value since last call */
float Kmeterdsp::read ()
{
@ -105,15 +109,10 @@ float Kmeterdsp::read ()
return rv;
}
void Kmeterdsp::init (int fsamp)
{
_omega = 9.72f / fsamp; // ballistic filter coefficient
}
void Kmeterdsp::reset ()
{
_z1 = _z2 = _rms = 0.0;
_flag=false;
_z1 = _z2 = _rms = .0f;
_flag = false;
}
/* vi:set ts=8 sts=8 sw=8: */
/* vi:set ts=8 sts=8 sw=4: */

View File

@ -40,13 +40,22 @@ PeakMeter::PeakMeter (Session& s, const std::string& name)
: Processor (s, string_compose ("meter-%1", name))
{
Kmeterdsp::init(s.nominal_frame_rate());
Iec1ppmdsp::init(s.nominal_frame_rate());
Iec2ppmdsp::init(s.nominal_frame_rate());
Vumeterdsp::init(s.nominal_frame_rate());
}
PeakMeter::~PeakMeter ()
{
while (_kmeter.size() > 0) {
delete (_kmeter.back());
delete (_iec1meter.back());
delete (_iec2meter.back());
delete (_vumeter.back());
_kmeter.pop_back();
_iec1meter.pop_back();
_iec2meter.pop_back();
_vumeter.pop_back();
}
}
@ -100,6 +109,15 @@ PeakMeter::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_fr
if (_meter_type & MeterKrms) {
_kmeter[i]->process(bufs.get_audio(i).data(), nframes);
}
if (_meter_type & MeterIEC1) {
_iec1meter[i]->process(bufs.get_audio(i).data(), nframes);
}
if (_meter_type & MeterIEC2) {
_iec2meter[i]->process(bufs.get_audio(i).data(), nframes);
}
if (_meter_type & MeterVU) {
_vumeter[i]->process(bufs.get_audio(i).data(), nframes);
}
}
// Zero any excess peaks
@ -119,6 +137,9 @@ PeakMeter::reset ()
for (size_t n = 0; n < _kmeter.size(); ++n) {
_kmeter[n]->reset();
_iec1meter[n]->reset();
_iec2meter[n]->reset();
_vumeter[n]->reset();
}
}
@ -212,12 +233,24 @@ PeakMeter::reset_max_channels (const ChanCount& chn)
/* alloc/free other audio-only meter types. */
while (_kmeter.size() > n_audio) {
delete (_kmeter.back());
delete (_iec1meter.back());
delete (_iec2meter.back());
delete (_vumeter.back());
_kmeter.pop_back();
_iec1meter.pop_back();
_iec2meter.pop_back();
_vumeter.pop_back();
}
while (_kmeter.size() < n_audio) {
_kmeter.push_back(new Kmeterdsp());
_iec1meter.push_back(new Iec1ppmdsp());
_iec2meter.push_back(new Iec2ppmdsp());
_vumeter.push_back(new Vumeterdsp());
}
assert(_kmeter.size() == n_audio);
assert(_iec1meter.size() == n_audio);
assert(_iec2meter.size() == n_audio);
assert(_vumeter.size() == n_audio);
reset();
reset_max();
@ -292,32 +325,51 @@ PeakMeter::meter_level(uint32_t n, MeterType type) {
switch (type) {
case MeterKrms:
{
const uint32_t n_midi = current_meters.n_midi();
const uint32_t n_midi = current_meters.n_midi();
if ((n - n_midi) < _kmeter.size() && (n - n_midi) >= 0) {
#if 0
return fast_coefficient_to_dB (_kmeter[n-n_midi]->read());
#else
return accurate_coefficient_to_dB (_kmeter[n-n_midi]->read());
#endif
return accurate_coefficient_to_dB (_kmeter[n - n_midi]->read());
}
return minus_infinity();
}
break;
case MeterIEC1:
{
const uint32_t n_midi = current_meters.n_midi();
if ((n - n_midi) < _iec1meter.size() && (n - n_midi) >= 0) {
return accurate_coefficient_to_dB (_iec1meter[n - n_midi]->read());
}
}
break;
case MeterIEC2:
{
const uint32_t n_midi = current_meters.n_midi();
if ((n - n_midi) < _iec2meter.size() && (n - n_midi) >= 0) {
return accurate_coefficient_to_dB (_iec2meter[n - n_midi]->read());
}
}
break;
case MeterVU:
{
const uint32_t n_midi = current_meters.n_midi();
if ((n - n_midi) < _vumeter.size() && (n - n_midi) >= 0) {
return accurate_coefficient_to_dB (_vumeter[n - n_midi]->read());
}
}
break;
case MeterPeak:
return peak_power(n);
case MeterMaxSignal:
if (n < _max_peak_signal.size()) {
return _max_peak_signal[n];
} else {
return minus_infinity();
}
break;
default:
case MeterMaxPeak:
if (n < _max_peak_power.size()) {
return _max_peak_power[n];
} else {
return minus_infinity();
}
break;
}
return minus_infinity();
}
void
@ -335,6 +387,25 @@ PeakMeter::set_type(MeterType t)
_kmeter[n]->reset();
}
}
if (t & MeterIEC1) {
const size_t n_audio = current_meters.n_audio();
for (size_t n = 0; n < n_audio; ++n) {
_iec1meter[n]->reset();
}
}
if (t & MeterIEC2) {
const size_t n_audio = current_meters.n_audio();
for (size_t n = 0; n < n_audio; ++n) {
_iec2meter[n]->reset();
}
}
if (t & MeterVU) {
const size_t n_audio = current_meters.n_audio();
for (size_t n = 0; n < n_audio; ++n) {
_vumeter[n]->reset();
}
}
TypeChanged(t);
}

89
libs/ardour/vumeterdsp.cc Normal file
View File

@ -0,0 +1,89 @@
/*
Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
Adopted for Ardour 2013 by Robin Gareus <robin@gareus.org>
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; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <math.h>
#include "ardour/vumeterdsp.h"
float Vumeterdsp::_w;
float Vumeterdsp::_g;
Vumeterdsp::Vumeterdsp (void) :
_z1 (0),
_z2 (0),
_m (0),
_res (true)
{
}
Vumeterdsp::~Vumeterdsp (void)
{
}
void Vumeterdsp::process (float *p, int n)
{
float z1, z2, m, t1, t2;
z1 = _z1;
z2 = _z2;
m = _res ? 0: _m;
_res = false;
n /= 4;
while (n--)
{
t2 = z2 / 2;
t1 = fabsf (*p++) - t2;
z1 += _w * (t1 - z1);
t1 = fabsf (*p++) - t2;
z1 += _w * (t1 - z1);
t1 = fabsf (*p++) - t2;
z1 += _w * (t1 - z1);
t1 = fabsf (*p++) - t2;
z1 += _w * (t1 - z1);
z2 += 4 * _w * (z1 - z2);
if (z2 > m) m = z2;
}
_z1 = z1;
_z2 = z2 + 1e-10f;
_m = m;
}
float Vumeterdsp::read (void)
{
_res = true;
return _g * _m;
}
void Vumeterdsp::reset ()
{
_z1 = _z2 = _m = .0f;
_res = true;
}
void Vumeterdsp::init (float fsamp)
{
_w = 11.1f / fsamp;
_g = 1.5f * 1.571f;
}

View File

@ -91,6 +91,8 @@ libardour_sources = [
'globals.cc',
'graph.cc',
'graphnode.cc',
'iec1ppmdsp.cc',
'iec2ppmdsp.cc',
'import.cc',
'instrument_info.cc',
'internal_return.cc',
@ -206,6 +208,7 @@ libardour_sources = [
'user_bundle.cc',
'utils.cc',
'version.cc',
'vumeterdsp.cc',
'worker.cc'
]