summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2013-07-31 20:11:15 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2013-07-31 20:11:15 -0400
commit6a436fd826d1c9d88b60287696cc0836ccce35aa (patch)
tree460a08b4d46359b6b168ece26f592c75fc2fe41f /libs
parentbb59def1ca8a21f915cf636dd1e54957df981656 (diff)
parent4dc74ae2ea13d2e5a8b481961d507df1ff98df97 (diff)
fix merge conflict from master
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/iec1ppmdsp.h51
-rw-r--r--libs/ardour/ardour/iec2ppmdsp.h51
-rw-r--r--libs/ardour/ardour/kmeterdsp.h (renamed from libs/ardour/kmeterdsp.h)5
-rw-r--r--libs/ardour/ardour/meter.h13
-rw-r--r--libs/ardour/ardour/process_thread.h3
-rw-r--r--libs/ardour/ardour/rc_configuration_vars.h5
-rw-r--r--libs/ardour/ardour/session.h4
-rw-r--r--libs/ardour/ardour/session_configuration_vars.h1
-rw-r--r--libs/ardour/ardour/thread_buffers.h1
-rw-r--r--libs/ardour/ardour/ticker.h3
-rw-r--r--libs/ardour/ardour/types.h24
-rw-r--r--libs/ardour/ardour/vumeterdsp.h49
-rw-r--r--libs/ardour/audio_track.cc2
-rw-r--r--libs/ardour/audio_unit.cc7
-rw-r--r--libs/ardour/audiosource.cc2
-rw-r--r--libs/ardour/enums.cc28
-rw-r--r--libs/ardour/iec1ppmdsp.cc100
-rw-r--r--libs/ardour/iec2ppmdsp.cc100
-rw-r--r--libs/ardour/kmeterdsp.cc39
-rw-r--r--libs/ardour/ladspa_plugin.cc2
-rw-r--r--libs/ardour/lv2_plugin.cc2
-rw-r--r--libs/ardour/meter.cc173
-rw-r--r--libs/ardour/midi_track.cc2
-rw-r--r--libs/ardour/plugin_insert.cc2
-rw-r--r--libs/ardour/po/de.po105
-rw-r--r--libs/ardour/process_thread.cc37
-rw-r--r--libs/ardour/route.cc11
-rw-r--r--libs/ardour/session.cc11
-rw-r--r--libs/ardour/session_midi.cc14
-rw-r--r--libs/ardour/thread_buffers.cc2
-rw-r--r--libs/ardour/ticker.cc86
-rw-r--r--libs/ardour/track.cc10
-rw-r--r--libs/ardour/vumeterdsp.cc89
-rw-r--r--libs/ardour/wscript3
-rw-r--r--libs/gtkmm2ext/fastmeter.cc446
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/fastmeter.h39
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/keyboard.h2
-rw-r--r--libs/gtkmm2ext/keyboard.cc11
-rw-r--r--libs/pbd/pbd/ringbuffer.h1
-rw-r--r--libs/pbd/pbd/stl_delete.h11
-rw-r--r--libs/surfaces/osc/osc.h4
41 files changed, 1317 insertions, 234 deletions
diff --git a/libs/ardour/ardour/iec1ppmdsp.h b/libs/ardour/ardour/iec1ppmdsp.h
new file mode 100644
index 0000000000..58dea97555
--- /dev/null
+++ b/libs/ardour/ardour/iec1ppmdsp.h
@@ -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
diff --git a/libs/ardour/ardour/iec2ppmdsp.h b/libs/ardour/ardour/iec2ppmdsp.h
new file mode 100644
index 0000000000..3574a8bd3f
--- /dev/null
+++ b/libs/ardour/ardour/iec2ppmdsp.h
@@ -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
diff --git a/libs/ardour/kmeterdsp.h b/libs/ardour/ardour/kmeterdsp.h
index 9c2309e09c..eca3c76695 100644
--- a/libs/ardour/kmeterdsp.h
+++ b/libs/ardour/ardour/kmeterdsp.h
@@ -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
diff --git a/libs/ardour/ardour/meter.h b/libs/ardour/ardour/meter.h
index 31ebc76179..a4ad8ecff4 100644
--- a/libs/ardour/ardour/meter.h
+++ b/libs/ardour/ardour/meter.h
@@ -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 {
@@ -71,6 +75,9 @@ public:
/** Compute peaks */
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
+ void activate () { }
+ void deactivate () { }
+
ChanCount input_streams () const { return current_meters; }
ChanCount output_streams () const { return current_meters; }
@@ -104,7 +111,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;
};
diff --git a/libs/ardour/ardour/process_thread.h b/libs/ardour/ardour/process_thread.h
index 0c197e9fb2..f96595fbbf 100644
--- a/libs/ardour/ardour/process_thread.h
+++ b/libs/ardour/ardour/process_thread.h
@@ -45,7 +45,8 @@ public:
*/
static BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO);
- static BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO);
+ static BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO, bool silence = false);
+ static BufferSet& get_route_buffers (ChanCount count = ChanCount::ZERO, bool silence = false);
static BufferSet& get_mix_buffers (ChanCount count = ChanCount::ZERO);
static gain_t* gain_automation_buffer ();
static gain_t* send_gain_automation_buffer ();
diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h
index f87781c8a9..a1008df6a6 100644
--- a/libs/ardour/ardour/rc_configuration_vars.h
+++ b/libs/ardour/ardour/rc_configuration_vars.h
@@ -148,9 +148,12 @@ CONFIG_VARIABLE (bool, super_rapid_clock_update, "super-rapid-clock-update", fal
/* metering */
CONFIG_VARIABLE (float, meter_hold, "meter-hold", 100.0f)
-CONFIG_VARIABLE (float, meter_falloff, "meter-falloff", 32.0f)
+CONFIG_VARIABLE (float, meter_falloff, "meter-falloff", 13.3f)
+CONFIG_VARIABLE (VUMeterStandard, meter_vu_standard, "meter-vu-standard", MeteringVUstandard)
CONFIG_VARIABLE (MeterLineUp, meter_line_up_level, "meter-line-up-level", MeteringLineUp18)
+CONFIG_VARIABLE (MeterLineUp, meter_line_up_din, "meter-line-up-din", MeteringLineUp15)
CONFIG_VARIABLE (float, meter_peak, "meter-peak", 0.0f)
+CONFIG_VARIABLE (bool, meter_style_led, "meter-style-led", true)
/* miscellany */
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 85866f99a5..1044d9a2dc 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -200,7 +200,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void process (pframes_t nframes);
BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO);
- BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO);
+ BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO, bool silence = true );
+ BufferSet& get_route_buffers (ChanCount count = ChanCount::ZERO, bool silence = true);
BufferSet& get_mix_buffers (ChanCount count = ChanCount::ZERO);
bool have_rec_enabled_track () const;
@@ -813,6 +814,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void send_mmc_locate (framepos_t);
int send_full_time_code (framepos_t);
+ void send_song_position_pointer (framepos_t);
bool step_editing() const { return (_step_editors > 0); }
diff --git a/libs/ardour/ardour/session_configuration_vars.h b/libs/ardour/ardour/session_configuration_vars.h
index ebeebbe1fd..5e93c01b79 100644
--- a/libs/ardour/ardour/session_configuration_vars.h
+++ b/libs/ardour/ardour/session_configuration_vars.h
@@ -64,3 +64,4 @@ CONFIG_VARIABLE (bool, show_rec_on_meterbridge, "show-rec-on-meterbridge", true)
CONFIG_VARIABLE (bool, show_mute_on_meterbridge, "show-mute-on-meterbridge", false)
CONFIG_VARIABLE (bool, show_solo_on_meterbridge, "show-solo-on-meterbridge", false)
CONFIG_VARIABLE (bool, show_name_on_meterbridge, "show-name-on-meterbridge", true)
+CONFIG_VARIABLE (uint32_t, meterbridge_label_height, "meterbridge-label-height", 0)
diff --git a/libs/ardour/ardour/thread_buffers.h b/libs/ardour/ardour/thread_buffers.h
index cd0b76511a..9d92454887 100644
--- a/libs/ardour/ardour/thread_buffers.h
+++ b/libs/ardour/ardour/thread_buffers.h
@@ -38,6 +38,7 @@ public:
BufferSet* silent_buffers;
BufferSet* scratch_buffers;
+ BufferSet* route_buffers;
BufferSet* mix_buffers;
gain_t* gain_automation_buffer;
gain_t* send_gain_automation_buffer;
diff --git a/libs/ardour/ardour/ticker.h b/libs/ardour/ardour/ticker.h
index 23d2ef2fe6..da728a5d54 100644
--- a/libs/ardour/ardour/ticker.h
+++ b/libs/ardour/ardour/ticker.h
@@ -42,7 +42,7 @@ class MidiClockTicker : public SessionHandlePtr, boost::noncopyable
{
public:
MidiClockTicker ();
- virtual ~MidiClockTicker() {};
+ virtual ~MidiClockTicker() {}
void tick (const framepos_t& transport_frames);
@@ -77,6 +77,7 @@ private:
void send_start_event (pframes_t offset);
void send_continue_event (pframes_t offset);
void send_stop_event (pframes_t offset);
+ void send_position_event (framepos_t transport_position, pframes_t offset);
};
}
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index 05d6d0b27d..2115149872 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -178,10 +178,17 @@ namespace ARDOUR {
};
enum MeterType {
- MeterMaxSignal = 0x01,
- MeterMaxPeak = 0x02,
- MeterPeak = 0x04,
- MeterKrms = 0x08
+ MeterMaxSignal = 0x001,
+ MeterMaxPeak = 0x002,
+ MeterPeak = 0x004,
+ MeterKrms = 0x008,
+ MeterK20 = 0x010,
+ MeterK14 = 0x020,
+ MeterIEC1DIN = 0x040,
+ MeterIEC1NOR = 0x080,
+ MeterIEC2BBC = 0x100,
+ MeterIEC2EBU = 0x200,
+ MeterVU = 0x400
};
enum TrackMode {
@@ -376,6 +383,13 @@ namespace ARDOUR {
MeteringRoute ///< meter what is going through the route
};
+ enum VUMeterStandard {
+ MeteringVUfrench, // 0VU = -2dBu
+ MeteringVUamerican, // 0VU = 0dBu
+ MeteringVUstandard, // 0VU = +4dBu
+ MeteringVUeight // 0VU = +8dBu
+ };
+
enum MeterLineUp {
MeteringLineUp24,
MeteringLineUp20,
@@ -583,6 +597,7 @@ std::istream& operator>>(std::istream& o, ARDOUR::HeaderFormat& sf);
std::istream& operator>>(std::istream& o, ARDOUR::AutoConnectOption& sf);
std::istream& operator>>(std::istream& o, ARDOUR::EditMode& sf);
std::istream& operator>>(std::istream& o, ARDOUR::MonitorModel& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::VUMeterStandard& sf);
std::istream& operator>>(std::istream& o, ARDOUR::MeterLineUp& sf);
std::istream& operator>>(std::istream& o, ARDOUR::PFLPosition& sf);
std::istream& operator>>(std::istream& o, ARDOUR::AFLPosition& sf);
@@ -605,6 +620,7 @@ std::ostream& operator<<(std::ostream& o, const ARDOUR::HeaderFormat& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::AutoConnectOption& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::EditMode& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::MonitorModel& sf);
+std::ostream& operator<<(std::ostream& o, const ARDOUR::VUMeterStandard& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::MeterLineUp& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::PFLPosition& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::AFLPosition& sf);
diff --git a/libs/ardour/ardour/vumeterdsp.h b/libs/ardour/ardour/vumeterdsp.h
new file mode 100644
index 0000000000..86487e8e8e
--- /dev/null
+++ b/libs/ardour/ardour/vumeterdsp.h
@@ -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
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 4b33bbd4c6..6de833aeb4 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -353,7 +353,7 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram
_silent = false;
_amp->apply_gain_automation(false);
- BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers ());
+ BufferSet& bufs = _session.get_route_buffers (n_process_buffers ());
fill_buffers_with_input (bufs, _input, nframes);
diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc
index 9c86b87415..3636ebf941 100644
--- a/libs/ardour/audio_unit.cc
+++ b/libs/ardour/audio_unit.cc
@@ -1824,7 +1824,6 @@ AUPlugin::do_save_preset (string preset_name)
CFPropertyListRef propertyList;
vector<Glib::ustring> v;
Glib::ustring user_preset_path;
- bool ret = true;
std::string m = maker();
std::string n = name();
@@ -1843,12 +1842,12 @@ AUPlugin::do_save_preset (string preset_name)
if (g_mkdir_with_parents (user_preset_path.c_str(), 0775) < 0) {
error << string_compose (_("Cannot create user plugin presets folder (%1)"), user_preset_path) << endmsg;
- return false;
+ return string();
}
DEBUG_TRACE (DEBUG::AudioUnits, "get current preset\n");
if (unit->GetAUPreset (propertyList) != noErr) {
- return false;
+ return string();
}
// add the actual preset name */
@@ -1863,7 +1862,7 @@ AUPlugin::do_save_preset (string preset_name)
if (save_property_list (propertyList, user_preset_path)) {
error << string_compose (_("Saving plugin state to %1 failed"), user_preset_path) << endmsg;
- ret = false;
+ return string();
}
CFRelease(propertyList);
diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc
index e224186bd2..65540d4e3d 100644
--- a/libs/ardour/audiosource.cc
+++ b/libs/ardour/audiosource.cc
@@ -189,7 +189,7 @@ AudioSource::touch_peakfile ()
struct utimbuf tbuf;
tbuf.actime = statbuf.st_atime;
- tbuf.modtime = time ((time_t) 0);
+ tbuf.modtime = time ((time_t*) 0);
g_utime (peakpath.c_str(), &tbuf);
}
diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc
index 495ff0b4c3..ab181d2956 100644
--- a/libs/ardour/enums.cc
+++ b/libs/ardour/enums.cc
@@ -62,6 +62,7 @@ setup_enum_writer ()
ColorMode _ColorMode;
MeterFalloff _MeterFalloff;
MeterHold _MeterHold;
+ VUMeterStandard _VUMeterStandard;
MeterLineUp _MeterLineUp;
EditMode _EditMode;
RegionPoint _RegionPoint;
@@ -177,6 +178,13 @@ setup_enum_writer ()
REGISTER_ENUM (MeterMaxPeak);
REGISTER_ENUM (MeterPeak);
REGISTER_ENUM (MeterKrms);
+ REGISTER_ENUM (MeterK20);
+ REGISTER_ENUM (MeterK14);
+ REGISTER_ENUM (MeterIEC1DIN);
+ REGISTER_ENUM (MeterIEC1NOR);
+ REGISTER_ENUM (MeterIEC2BBC);
+ REGISTER_ENUM (MeterIEC2EBU);
+ REGISTER_ENUM (MeterVU);
REGISTER (_MeterType);
REGISTER_ENUM (Normal);
@@ -215,6 +223,12 @@ setup_enum_writer ()
REGISTER_ENUM (MeterHoldLong);
REGISTER (_MeterHold);
+ REGISTER_ENUM (MeteringVUfrench);
+ REGISTER_ENUM (MeteringVUamerican);
+ REGISTER_ENUM (MeteringVUstandard);
+ REGISTER_ENUM (MeteringVUeight);
+ REGISTER (_VUMeterStandard);
+
REGISTER_ENUM (MeteringLineUp24);
REGISTER_ENUM (MeteringLineUp20);
REGISTER_ENUM (MeteringLineUp18);
@@ -668,6 +682,20 @@ std::ostream& operator<<(std::ostream& o, const MonitorModel& var)
return o << s;
}
+std::istream& operator>>(std::istream& o, VUMeterStandard& var)
+{
+ std::string s;
+ o >> s;
+ var = (VUMeterStandard) string_2_enum (s, var);
+ return o;
+}
+
+std::ostream& operator<<(std::ostream& o, const VUMeterStandard& var)
+{
+ std::string s = enum_2_string (var);
+ return o << s;
+}
+
std::istream& operator>>(std::istream& o, MeterLineUp& var)
{
std::string s;
diff --git a/libs/ardour/iec1ppmdsp.cc b/libs/ardour/iec1ppmdsp.cc
new file mode 100644
index 0000000000..bed825048f
--- /dev/null
+++ b/libs/ardour/iec1ppmdsp.cc
@@ -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: */
diff --git a/libs/ardour/iec2ppmdsp.cc b/libs/ardour/iec2ppmdsp.cc
new file mode 100644
index 0000000000..76862cccd2
--- /dev/null
+++ b/libs/ardour/iec2ppmdsp.cc
@@ -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: */
diff --git a/libs/ardour/kmeterdsp.cc b/libs/ardour/kmeterdsp.cc
index afd0f71719..181378cf76 100644
--- a/libs/ardour/kmeterdsp.cc
+++ b/libs/ardour/kmeterdsp.cc
@@ -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)
{
@@ -44,45 +49,37 @@ void Kmeterdsp::process (float *p, int n)
// p : pointer to sample buffer
// n : number of samples to process
- float s, t, z1, z2;
+ float s, z1, z2;
// Get filter state.
z1 = _z1;
z2 = _z2;
- // Process n samples. Find digital peak value for this
- // period and perform filtering. The second filter is
- // evaluated only every 4th sample - this is just an
- // optimisation.
- t = 0;
+ // Perform filtering. The second filter is evaluated
+ // only every 4th sample - this is just an optimisation.
n /= 4; // Loop is unrolled by 4.
while (n--)
{
s = *p++;
s *= s;
- if (t < s) t = s; // Update digital peak.
z1 += _omega * (s - z1); // Update first filter.
s = *p++;
s *= s;
- if (t < s) t = s; // Update digital peak.
z1 += _omega * (s - z1); // Update first filter.
s = *p++;
s *= s;
- if (t < s) t = s; // Update digital peak.
z1 += _omega * (s - z1); // Update first filter.
s = *p++;
s *= s;
- if (t < s) t = s; // Update digital peak.
z1 += _omega * (s - z1); // Update first filter.
z2 += 4 * _omega * (z1 - z2); // Update second filter.
}
- t = sqrtf (t);
// Save filter state. The added constants avoid denormals.
_z1 = z1 + 1e-20f;
_z2 = z2 + 1e-20f;
- s = sqrtf (2 * z2);
+ s = sqrtf (2.0f * z2);
if (_flag) // Display thread has read the rms value.
{
@@ -96,7 +93,6 @@ void Kmeterdsp::process (float *p, int n)
}
}
-
/* Returns highest _rms value since last call */
float Kmeterdsp::read ()
{
@@ -105,15 +101,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: */
diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc
index 82bf97264f..38d0d8b944 100644
--- a/libs/ardour/ladspa_plugin.cc
+++ b/libs/ardour/ladspa_plugin.cc
@@ -574,7 +574,7 @@ LadspaPlugin::connect_and_run (BufferSet& bufs,
cycles_t then = get_cycles ();
BufferSet& silent_bufs = _session.get_silent_buffers(ChanCount(DataType::AUDIO, 1));
- BufferSet& scratch_bufs = _session.get_silent_buffers(ChanCount(DataType::AUDIO, 1));
+ BufferSet& scratch_bufs = _session.get_scratch_buffers(ChanCount(DataType::AUDIO, 1));
uint32_t audio_in_index = 0;
uint32_t audio_out_index = 0;
diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc
index 2f46db75a6..d44f9351c4 100644
--- a/libs/ardour/lv2_plugin.cc
+++ b/libs/ardour/lv2_plugin.cc
@@ -1652,7 +1652,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
}
} else if (!valid) {
// Nothing we understand or care about, connect to scratch
- _ev_buffers[port_index] = silent_bufs.get_lv2_midi(
+ _ev_buffers[port_index] = scratch_bufs.get_lv2_midi(
(flags & PORT_INPUT), 0, (flags & PORT_EVENT));
}
buf = lv2_evbuf_get_buffer(_ev_buffers[port_index]);
diff --git a/libs/ardour/meter.cc b/libs/ardour/meter.cc
index 3d1ab61bbc..490b75dcb2 100644
--- a/libs/ardour/meter.cc
+++ b/libs/ardour/meter.cc
@@ -40,13 +40,24 @@ 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());
+ _pending_active = true;
+ _meter_type = MeterPeak;
}
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();
}
}
@@ -97,9 +108,18 @@ PeakMeter::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_fr
// Meter audio in to the rest of the peaks
for (uint32_t i = 0; i < n_audio; ++i, ++n) {
_peak_signal[n] = compute_peak (bufs.get_audio(i).data(), nframes, _peak_signal[n]);
- if (_meter_type & MeterKrms) {
+ if (_meter_type & (MeterKrms | MeterK20 | MeterK14)) {
_kmeter[i]->process(bufs.get_audio(i).data(), nframes);
}
+ if (_meter_type & (MeterIEC1DIN | MeterIEC1NOR)) {
+ _iec1meter[i]->process(bufs.get_audio(i).data(), nframes);
+ }
+ if (_meter_type & (MeterIEC2BBC | MeterIEC2EBU)) {
+ _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 +139,9 @@ PeakMeter::reset ()
for (size_t n = 0; n < _kmeter.size(); ++n) {
_kmeter[n]->reset();
+ _iec1meter[n]->reset();
+ _iec2meter[n]->reset();
+ _vumeter[n]->reset();
}
}
@@ -129,6 +152,16 @@ PeakMeter::reset_max ()
_max_peak_power[i] = -INFINITY;
_max_peak_signal[i] = 0;
}
+
+ const size_t n_midi = min (_peak_signal.size(), (size_t) current_meters.n_midi());
+
+ for (size_t n = 0; n < _peak_signal.size(); ++n) {
+ if (n < n_midi) {
+ _visible_peak_power[n] = 0;
+ } else {
+ _visible_peak_power[n] = -INFINITY;
+ }
+ }
}
bool
@@ -155,24 +188,20 @@ PeakMeter::configure_io (ChanCount in, ChanCount out)
void
PeakMeter::reflect_inputs (const ChanCount& in)
{
- current_meters = in;
-
- const size_t limit = min (_peak_signal.size(), (size_t) current_meters.n_total ());
- const size_t n_midi = min (_peak_signal.size(), (size_t) current_meters.n_midi());
- const size_t n_audio = current_meters.n_audio();
-
- for (size_t n = 0; n < limit; ++n) {
- if (n < n_midi) {
- _visible_peak_power[n] = 0;
- } else {
- _visible_peak_power[n] = -INFINITY;
+ for (uint32_t i = in.n_total(); i < current_meters.n_total(); ++i) {
+ if (i < _peak_signal.size()) {
+ _peak_signal[i] = 0.0f;
}
}
-
- for (size_t n = 0; n < n_audio; ++n) {
- _kmeter[n]->reset();
+ for (uint32_t i = in.n_audio(); i < current_meters.n_audio(); ++i) {
+ if (i >= _kmeter.size()) continue;
+ _kmeter[i]->reset();
+ _iec1meter[i]->reset();
+ _iec2meter[i]->reset();
+ _vumeter[i]->reset();
}
+ current_meters = in;
reset_max();
ConfigurationChanged (in, in); /* EMIT SIGNAL */
@@ -206,12 +235,27 @@ 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();
}
/** To be driven by the Meter signal from IO.
@@ -226,11 +270,26 @@ PeakMeter::meter ()
return;
}
- assert(_visible_peak_power.size() == _peak_signal.size());
+ // TODO block this thread while PeakMeter::reset_max_channels() is
+ // reallocating channels.
+ // (may happen with Session > New: old session not yet closed,
+ // meter-thread still active while new one is initializing and
+ // maybe on other occasions, too)
+ if ( (_visible_peak_power.size() != _peak_signal.size())
+ || (_max_peak_power.size() != _peak_signal.size())
+ || (_max_peak_signal.size() != _peak_signal.size())
+ ) {
+ return;
+ }
const size_t limit = min (_peak_signal.size(), (size_t) current_meters.n_total ());
const size_t n_midi = min (_peak_signal.size(), (size_t) current_meters.n_midi());
+ /* 0.01f ^= 100 Hz update rate */
+ const float midi_meter_falloff = Config->get_meter_falloff() * 0.01f;
+ /* kmeters: 24dB / 2 sec */
+ const float audio_meter_falloff = (_meter_type & (MeterK20 | MeterK14)) ? 0.12f : midi_meter_falloff;
+
for (size_t n = 0; n < limit; ++n) {
/* grab peak since last read */
@@ -241,11 +300,11 @@ PeakMeter::meter ()
if (n < n_midi) {
_max_peak_power[n] = -INFINITY; // std::max (new_peak, _max_peak_power[n]); // XXX
_max_peak_signal[n] = 0;
- if (Config->get_meter_falloff() == 0.0f || new_peak > _visible_peak_power[n]) {
+ if (midi_meter_falloff == 0.0f || new_peak > _visible_peak_power[n]) {
;
} else {
- /* empirical WRT to falloff times , 0.01f ^= 100 Hz update rate */
- new_peak = _visible_peak_power[n] - sqrt(_visible_peak_power[n] * Config->get_meter_falloff() * 0.01f * 0.0002f);
+ /* empirical algorithm WRT to audio falloff times */
+ new_peak = _visible_peak_power[n] - sqrt(_visible_peak_power[n] * midi_meter_falloff * 0.0002f);
if (new_peak < (1.0 / 512.0)) new_peak = 0;
}
_visible_peak_power[n] = new_peak;
@@ -268,47 +327,72 @@ PeakMeter::meter ()
_max_peak_power[n] = std::max (new_peak, _max_peak_power[n]);
- if (Config->get_meter_falloff() == 0.0f || new_peak > _visible_peak_power[n]) {
+ if (audio_meter_falloff == 0.0f || new_peak > _visible_peak_power[n]) {
_visible_peak_power[n] = new_peak;
} else {
// do falloff
- new_peak = _visible_peak_power[n] - (Config->get_meter_falloff() * 0.01f);
- _visible_peak_power[n] = std::max (new_peak, (float)-INFINITY);
+ new_peak = _visible_peak_power[n] - (audio_meter_falloff);
+ _visible_peak_power[n] = std::max (new_peak, -INFINITY);
}
}
}
+#define CHECKSIZE(MTR) (n < MTR.size() + n_midi && n >= n_midi)
+
float
PeakMeter::meter_level(uint32_t n, MeterType type) {
switch (type) {
case MeterKrms:
+ case MeterK20:
+ case MeterK14:
+ {
+ const uint32_t n_midi = current_meters.n_midi();
+ if (CHECKSIZE(_kmeter)) {
+ return accurate_coefficient_to_dB (_kmeter[n - n_midi]->read());
+ }
+ }
+ break;
+ case MeterIEC1DIN:
+ case MeterIEC1NOR:
+ {
+ const uint32_t n_midi = current_meters.n_midi();
+ if (CHECKSIZE(_iec1meter)) {
+ return accurate_coefficient_to_dB (_iec1meter[n - n_midi]->read());
+ }
+ }
+ break;
+ case MeterIEC2BBC:
+ case MeterIEC2EBU:
{
- 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
+ const uint32_t n_midi = current_meters.n_midi();
+ if (CHECKSIZE(_iec2meter)) {
+ return accurate_coefficient_to_dB (_iec2meter[n - n_midi]->read());
}
- return minus_infinity();
}
+ break;
+ case MeterVU:
+ {
+ const uint32_t n_midi = current_meters.n_midi();
+ if (CHECKSIZE(_vumeter)) {
+ 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
@@ -320,12 +404,31 @@ PeakMeter::set_type(MeterType t)
_meter_type = t;
- if (t & MeterKrms) {
+ if (t & (MeterKrms | MeterK20 | MeterK14)) {
const size_t n_audio = current_meters.n_audio();
for (size_t n = 0; n < n_audio; ++n) {
_kmeter[n]->reset();
}
}
+ if (t & (MeterIEC1DIN | MeterIEC1NOR)) {
+ const size_t n_audio = current_meters.n_audio();
+ for (size_t n = 0; n < n_audio; ++n) {
+ _iec1meter[n]->reset();
+ }
+ }
+ if (t & (MeterIEC2BBC | MeterIEC2EBU)) {
+ 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);
}
diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc
index 7c4ae24a2a..415ae6210f 100644
--- a/libs/ardour/midi_track.cc
+++ b/libs/ardour/midi_track.cc
@@ -352,7 +352,7 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame
return dret;
}
- BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
+ BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
fill_buffers_with_input (bufs, _input, nframes);
diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc
index 998a03e3aa..d519dbd7a7 100644
--- a/libs/ardour/plugin_insert.cc
+++ b/libs/ardour/plugin_insert.cc
@@ -448,7 +448,7 @@ PluginInsert::silence (framecnt_t nframes)
}
for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
- (*i)->connect_and_run (_session.get_silent_buffers ((*i)->get_info()->n_inputs), in_map, out_map, nframes, 0);
+ (*i)->connect_and_run (_session.get_scratch_buffers ((*i)->get_info()->n_inputs, true), in_map, out_map, nframes, 0);
}
}
diff --git a/libs/ardour/po/de.po b/libs/ardour/po/de.po
index 579d5257e2..564cafd434 100644
--- a/libs/ardour/po/de.po
+++ b/libs/ardour/po/de.po
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-06-11 08:49-0400\n"
-"PO-Revision-Date: 2013-02-05 19:52+0100\n"
+"POT-Creation-Date: 2013-07-17 11:09+0200\n"
+"PO-Revision-Date: 2013-07-23 15:04+0200\n"
"Last-Translator: Edgar Aichinger <edogawa@aon.at>\n"
"Language-Team: German <ardour-dev@lists.ardour.org>\n"
"Language: de\n"
@@ -218,7 +218,7 @@ msgstr ""
msgid "Connect session to engine"
msgstr "Verbinde Projekt mit Engine"
-#: audioengine.cc:844
+#: audioengine.cc:843
msgid ""
"a port with the name \"%1\" already exists: check for duplicated track/bus "
"names"
@@ -226,7 +226,7 @@ msgstr ""
"Ein Port mit Namen \"%1\" existiert bereits: Prüfen Sie auf doppelte Spur/"
"Busnamen"
-#: audioengine.cc:846 session.cc:1698
+#: audioengine.cc:845 session.cc:1698
msgid ""
"No more JACK ports are available. You will need to stop %1 and restart JACK "
"with more ports if you need this many tracks."
@@ -234,35 +234,35 @@ msgstr ""
"Keine JACK-Ports mehr verfügbar. Wenn Sie so viele Spuren benötigen, müssen "
"Sie %1 stoppen und JACK mit mehr Ports neu starten."
-#: audioengine.cc:849
+#: audioengine.cc:848
msgid "AudioEngine: cannot register port \"%1\": %2"
msgstr "AudioEngine: kann Port \"%1\": %2 nicht registrieren"
-#: audioengine.cc:879
+#: audioengine.cc:878
msgid "unable to create port: %1"
msgstr "kann Port: %1 nicht erzeugen"
-#: audioengine.cc:933
+#: audioengine.cc:932
msgid "connect called before engine was started"
msgstr "Aufruf von connect vor dem Start der Engine"
-#: audioengine.cc:959
+#: audioengine.cc:958
msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)"
msgstr "AudioEngine: kann %1 (%2) nicht mit %3 (%4) verbinden"
-#: audioengine.cc:974 audioengine.cc:1005
+#: audioengine.cc:973 audioengine.cc:1004
msgid "disconnect called before engine was started"
msgstr "Aufruf von disconnect vor dem Start der Engine"
-#: audioengine.cc:1053
+#: audioengine.cc:1052
msgid "get_port_by_name() called before engine was started"
msgstr "Aufruf von get_port_by_name() vor dem Start der Engine"
-#: audioengine.cc:1105
+#: audioengine.cc:1104
msgid "get_ports called before engine was started"
msgstr "Aufruf von get_ports vor dem Start der Engine"
-#: audioengine.cc:1428
+#: audioengine.cc:1427
msgid "failed to connect to JACK"
msgstr "Verbindung zu JACK fehlgeschlagen"
@@ -316,8 +316,8 @@ msgstr "AudioSource: kann Pfad für Peaks (b) \"%1\" nicht öffnen (%2)"
msgid ""
"AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"
msgstr ""
-"AudioSource[%1]: peak read - kann %2 Samples bei Offset %3 von %4 nicht lesen"
-"(%5)"
+"AudioSource[%1]: peak read - kann %2 Samples bei Offset %3 von %4 nicht "
+"lesen(%5)"
#: audiosource.cc:667
msgid "%1: could not write read raw data for peak computation (%2)"
@@ -971,21 +971,21 @@ msgstr "R"
msgid "%d"
msgstr "%d"
-#: ladspa_plugin.cc:87
+#: ladspa_plugin.cc:88
msgid "LADSPA: module has no descriptor function."
msgstr "LADSPA: Modul hat keine Beschreibungsfunktion"
-#: ladspa_plugin.cc:92
+#: ladspa_plugin.cc:93
msgid "LADSPA: plugin has gone away since discovery!"
msgstr "LADSPA: Plugin ist nicht mehr auffindbar!"
-#: ladspa_plugin.cc:99
+#: ladspa_plugin.cc:100
msgid "LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"
msgstr ""
"LADSPA: \"%1\" kann nicht verwendet werdeen, da es kein \"inplace processing"
"\" beherrscht"
-#: ladspa_plugin.cc:296
+#: ladspa_plugin.cc:297
msgid ""
"illegal parameter number used with plugin \"%1\". This may indicate a change "
"in the plugin design, and presets may be invalid"
@@ -993,35 +993,35 @@ msgstr ""
"Falsche Parameterzahl für Plugin \"%1\". Das auf eine Änderung im Plugin-"
"Design hindeuten, und Presets sind eventuell ungültig"
-#: ladspa_plugin.cc:373 ladspa_plugin.cc:418
+#: ladspa_plugin.cc:376 ladspa_plugin.cc:426
msgid "Bad node sent to LadspaPlugin::set_state"
msgstr "Schlechter Knoten an LadspaPlugin::set_state gesendet"
-#: ladspa_plugin.cc:386 ladspa_plugin.cc:431
+#: ladspa_plugin.cc:391 ladspa_plugin.cc:440
msgid "LADSPA: no ladspa port number"
msgstr "LADSPA: keine LADSPA-Portnummer"
-#: ladspa_plugin.cc:392 ladspa_plugin.cc:437
+#: ladspa_plugin.cc:397 ladspa_plugin.cc:446
msgid "LADSPA: no ladspa port data"
msgstr "LADSPA: keine LADSPA-Portdaten"
-#: ladspa_plugin.cc:707
+#: ladspa_plugin.cc:717
msgid "LADSPA: cannot load module from \"%1\""
msgstr "LADSPA: kann Modul nicht aus \"%1\" laden"
-#: ladspa_plugin.cc:817
+#: ladspa_plugin.cc:827
msgid "Could not locate HOME. Preset not removed."
msgstr "Konnte HOME nicht eruieren. Preset nicht entfernt."
-#: ladspa_plugin.cc:854 ladspa_plugin.cc:860
+#: ladspa_plugin.cc:864 ladspa_plugin.cc:870
msgid "Could not create %1. Preset not saved. (%2)"
msgstr "Konnte %1 nicht erzeugen. Preset nicht gesichert. (%2)"
-#: ladspa_plugin.cc:867
+#: ladspa_plugin.cc:877
msgid "Error saving presets file %1."
msgstr "Fehler beim Sichern der Preset-Datei %1."
-#: ladspa_plugin.cc:905
+#: ladspa_plugin.cc:915
msgid "Could not locate HOME. Preset not saved."
msgstr "Konnte HOME nicht eruieren. Preset nicht gesichert."
@@ -1368,23 +1368,39 @@ msgstr ""
"Konnte die Wiedergabeliste nicht aus den Quelldaten des Projekts "
"konstruieren!"
+#: plugin.cc:324
+msgid ""
+"Plugin presets are not supported in this build of %1. Consider paying for a "
+"full version"
+msgstr ""
+"Pluginpresets werden in diesem %1-Binärpaket nicht unterstützt. Erwägen Sie, "
+"für die Vollversion zu bezahlen"
+
+#: plugin.cc:398
+msgid ""
+"Saving plugin settings is not supported in this build of %1. Consider paying "
+"for the full version"
+msgstr ""
+"Das Speichern von Pluginpresets werden in diesem %1-Binärpaket nicht "
+"unterstützt. Erwägen Sie, für die Vollversion zu bezahlen"
+
#: plugin_insert.cc:599
msgid "programming error: "
msgstr "Programmierfehler:"
-#: plugin_insert.cc:908
+#: plugin_insert.cc:914
msgid "XML node describing plugin is missing the `type' field"
msgstr "Dem XML-Knoten zur Beschreibung des Plugins fehlt das \"type\"-Feld"
-#: plugin_insert.cc:923
+#: plugin_insert.cc:929
msgid "unknown plugin type %1 in plugin insert state"
msgstr "Unbekannter Plugintyp %1 im Einfüge-Status des Plugins"
-#: plugin_insert.cc:951
+#: plugin_insert.cc:957
msgid "Plugin has no unique ID field"
msgstr "Das Plugin hat kein Feld für die eindeutige ID"
-#: plugin_insert.cc:960
+#: plugin_insert.cc:966
msgid ""
"Found a reference to a plugin (\"%1\") that is unknown.\n"
"Perhaps it was removed or moved since it was last used."
@@ -1392,15 +1408,15 @@ msgstr ""
"Referenz auf ein unbekanntes Plugin (\"%1\") gefunden.\n"
"Vielleicht wurde es seit der letzten Verwendung entfernt oder verschoben."
-#: plugin_insert.cc:1076
+#: plugin_insert.cc:1082
msgid "PluginInsert: Auto: no ladspa port number"
msgstr "PluginInsert: Auto: keine LADSPA Portnummer"
-#: plugin_insert.cc:1083
+#: plugin_insert.cc:1089
msgid "PluginInsert: Auto: port id out of range"
msgstr "PluginInsert: Auto: Port-ID Bereichsüberschreitung"
-#: plugin_insert.cc:1119
+#: plugin_insert.cc:1125
msgid "PluginInsert: automatable control %1 not found - ignored"
msgstr ""
"PluginInsert: automatisierbares Kontrollelement %1 nicht gefunden - ignoriert"
@@ -1550,23 +1566,23 @@ msgstr "Import: Fehler in src_new() : %1"
msgid "return %1"
msgstr "Rückgabewert: %1"
-#: route.cc:1100 route.cc:2550
+#: route.cc:1101 route.cc:2557
msgid "unknown Processor type \"%1\"; ignored"
msgstr "unbekannter Prozessortyp \"%1\"; ignoriert"
-#: route.cc:1112
+#: route.cc:1113
msgid "processor could not be created. Ignored."
msgstr "Prozessor konnte nicht erzeugt werden. Ignoriert."
-#: route.cc:1983 route.cc:2203
+#: route.cc:1986 route.cc:2210
msgid "Bad node sent to Route::set_state() [%1]"
msgstr "Schlechter Knoten an Route::set_state() gesendet [%1]"
-#: route.cc:2042
+#: route.cc:2045
msgid "Pannable state found for route (%1) without a panner!"
msgstr "Pannerziel-Status für Route (%1) ohne Panner gefunden!"
-#: route.cc:2106 route.cc:2110 route.cc:2317 route.cc:2321
+#: route.cc:2113 route.cc:2117 route.cc:2324 route.cc:2328
msgid "badly formed order key string in state file! [%1] ... ignored."
msgstr ""
"schlecht geformte Zeichenkette für den Schlüssel der Sortierreihenfolge in "
@@ -1857,18 +1873,17 @@ msgstr "Session: kann quarter-frame MTC-Nachricht nicht senden (%1)"
msgid "Session: cannot create Playlist from XML description."
msgstr "Session: kann Wiedergabeliste nicht aus der XML-Beschreibung erzeugen"
-#: session_process.cc:135
+#: session_process.cc:133
msgid "Session: error in no roll for %1"
msgstr "Session: Fehler in no_roll für %1"
-#: session_process.cc:1160
+#: session_process.cc:1158
msgid "Programming error: illegal event type in process_event (%1)"
msgstr "Programmierfehler: illegaler Ereignistyp in process_event (%1)"
#: session_state.cc:139
-#, fuzzy
msgid "Could not use path %1 (%2)"
-msgstr "Konnte Pfad %1 nicht benutzen (%s)"
+msgstr "Konnte Pfad %1 nicht benutzen (%2)"
#: session_state.cc:267
msgid "solo cut control (dB)"
@@ -2406,7 +2421,7 @@ msgstr ""
msgid "attempt to write a non-writable audio file source (%1)"
msgstr "Versuch, in eine schreibgeschützte Audio-Dateiquelle zu schreiben (%1)"
-#: sndfilesource.cc:396 utils.cc:497 utils.cc:521 utils.cc:535 utils.cc:554
+#: sndfilesource.cc:396 utils.cc:507 utils.cc:531 utils.cc:545 utils.cc:564
msgid "programming error: %1 %2"
msgstr "Programmierfehler: %1 %2"
@@ -2672,11 +2687,11 @@ msgstr "M-Clock"
msgid "LTC"
msgstr "LTC"
-#: utils.cc:589
+#: utils.cc:599
msgid "programming error: unknown native header format: %1"
msgstr "Programmierfehler: unbekanntes natives Dateikopfformat: %1"
-#: utils.cc:604
+#: utils.cc:614
msgid "cannot open directory %1 (%2)"
msgstr "kann Verzeichnis %1 nicht öffnen (%2)"
diff --git a/libs/ardour/process_thread.cc b/libs/ardour/process_thread.cc
index e10ccf160c..d4a3d2f390 100644
--- a/libs/ardour/process_thread.cc
+++ b/libs/ardour/process_thread.cc
@@ -90,7 +90,7 @@ ProcessThread::get_silent_buffers (ChanCount count)
}
BufferSet&
-ProcessThread::get_scratch_buffers (ChanCount count)
+ProcessThread::get_scratch_buffers (ChanCount count, bool silence)
{
ThreadBuffers* tb = _private_thread_buffers.get();
assert (tb);
@@ -105,6 +105,41 @@ ProcessThread::get_scratch_buffers (ChanCount count)
sb->set_count (sb->available());
}
+ if (silence) {
+ for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+ for (uint32_t i = 0; i < sb->count().get(*t); ++i) {
+ sb->get(*t, i).clear();
+ }
+ }
+ }
+
+ return *sb;
+}
+
+BufferSet&
+ProcessThread::get_route_buffers (ChanCount count, bool silence)
+{
+ ThreadBuffers* tb = _private_thread_buffers.get();
+ assert (tb);
+
+ BufferSet* sb = tb->route_buffers;
+ assert (sb);
+
+ if (count != ChanCount::ZERO) {
+ assert(sb->available() >= count);
+ sb->set_count (count);
+ } else {
+ sb->set_count (sb->available());
+ }
+
+ if (silence) {
+ for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+ for (uint32_t i = 0; i < sb->count().get(*t); ++i) {
+ sb->get(*t, i).clear();
+ }
+ }
+ }
+
return *sb;
}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 797481b7b8..671a00319d 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -101,6 +101,9 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
, _custom_meter_position_noted (false)
, _last_custom_meter_was_at_end (false)
{
+ if (is_master()) {
+ _meter_type = MeterK20;
+ }
processor_max_streams.reset();
}
@@ -568,7 +571,7 @@ void
Route::monitor_run (framepos_t start_frame, framepos_t end_frame, pframes_t nframes, int declick)
{
assert (is_monitor());
- BufferSet& bufs (_session.get_scratch_buffers (n_process_buffers()));
+ BufferSet& bufs (_session.get_route_buffers (n_process_buffers()));
passthru (bufs, start_frame, end_frame, nframes, declick);
}
@@ -594,7 +597,7 @@ Route::passthru (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
void
Route::passthru_silence (framepos_t start_frame, framepos_t end_frame, pframes_t nframes, int declick)
{
- BufferSet& bufs (_session.get_silent_buffers (n_process_buffers()));
+ BufferSet& bufs (_session.get_route_buffers (n_process_buffers(), true));
bufs.set_count (_input->n_ports());
write_out_of_band_data (bufs, start_frame, end_frame, nframes);
@@ -3017,7 +3020,7 @@ Route::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
*/
}
- BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
+ BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
fill_buffers_with_input (bufs, _input, nframes);
@@ -3056,7 +3059,7 @@ Route::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, in
_silent = false;
- BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
+ BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
fill_buffers_with_input (bufs, _input, nframes);
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 476682158f..9817f17069 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -4174,12 +4174,19 @@ Session::get_silent_buffers (ChanCount count)
}
BufferSet&
-Session::get_scratch_buffers (ChanCount count)
+Session::get_scratch_buffers (ChanCount count, bool silence)
{
- return ProcessThread::get_scratch_buffers (count);
+ return ProcessThread::get_scratch_buffers (count, silence);
}
BufferSet&
+Session::get_route_buffers (ChanCount count, bool silence)
+{
+ return ProcessThread::get_route_buffers (count, silence);
+}
+
+
+BufferSet&
Session::get_mix_buffers (ChanCount count)
{
return ProcessThread::get_mix_buffers (count);
diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc
index 5b5554be7c..e4fd58dedc 100644
--- a/libs/ardour/session_midi.cc
+++ b/libs/ardour/session_midi.cc
@@ -44,6 +44,7 @@
#include "ardour/midi_ui.h"
#include "ardour/session.h"
#include "ardour/slave.h"
+#include "ardour/ticker.h"
#include "i18n.h"
@@ -580,6 +581,19 @@ Session::mmc_step_timeout ()
return true;
}
+/***********************************************************************
+ OUTBOUND SYSTEM COMMON STUFF
+**********************************************************************/
+
+
+void
+Session::send_song_position_pointer (framepos_t t)
+{
+ if (midi_clock) {
+ midi_clock->position_changed (t);
+ }
+}
+
int
Session::start_midi_thread ()
{
diff --git a/libs/ardour/thread_buffers.cc b/libs/ardour/thread_buffers.cc
index 34f6f9828b..fd3160bb15 100644
--- a/libs/ardour/thread_buffers.cc
+++ b/libs/ardour/thread_buffers.cc
@@ -30,6 +30,7 @@ using namespace std;
ThreadBuffers::ThreadBuffers ()
: silent_buffers (new BufferSet)
, scratch_buffers (new BufferSet)
+ , route_buffers (new BufferSet)
, mix_buffers (new BufferSet)
, gain_automation_buffer (0)
, send_gain_automation_buffer (0)
@@ -64,6 +65,7 @@ ThreadBuffers::ensure_buffers (ChanCount howmany)
scratch_buffers->ensure_buffers (*t, count, size);
mix_buffers->ensure_buffers (*t, count, size);
silent_buffers->ensure_buffers (*t, count, size);
+ route_buffers->ensure_buffers (*t, count, size);
}
delete [] gain_automation_buffer;
diff --git a/libs/ardour/ticker.cc b/libs/ardour/ticker.cc
index 5d078952a1..4f66128943 100644
--- a/libs/ardour/ticker.cc
+++ b/libs/ardour/ticker.cc
@@ -40,7 +40,8 @@ MidiClockTicker::MidiClockTicker ()
{
}
-void MidiClockTicker::set_session (Session* s)
+void
+MidiClockTicker::set_session (Session* s)
{
SessionHandlePtr::set_session (s);
@@ -59,12 +60,14 @@ MidiClockTicker::session_going_away ()
_midi_port = 0;
}
-void MidiClockTicker::update_midi_clock_port()
+void
+MidiClockTicker::update_midi_clock_port()
{
_midi_port = MIDI::Manager::instance()->midi_clock_output_port();
}
-void MidiClockTicker::transport_state_changed()
+void
+MidiClockTicker::transport_state_changed()
{
if (_session->exporting()) {
/* no midi clock during export, for now */
@@ -80,8 +83,8 @@ void MidiClockTicker::transport_state_changed()
framepos_t position = _session->transport_frame();
DEBUG_TRACE (PBD::DEBUG::MidiClock,
- string_compose ("Transport state change @ %4, speed: %1 position: %2 play loop: %3\n", speed, position, _session->get_play_loop(), position)
- );
+ string_compose ("Transport state change @ %4, speed: %1 position: %2 play loop: %3\n", speed, position, _session->get_play_loop(), position)
+ );
if (speed == 1.0f) {
_last_tick = position;
@@ -109,19 +112,27 @@ void MidiClockTicker::transport_state_changed()
return;
send_stop_event(0);
+ send_position_event (position, 0);
}
tick (position);
}
-void MidiClockTicker::position_changed (framepos_t position)
+void
+MidiClockTicker::position_changed (framepos_t position)
{
- DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Position change: %1\n", position));
+ const double speed = _session->transport_speed();
+ DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Transport Position Change: %1, speed: %2\n", position, speed));
+
+ if (speed == 0.0f && Config->get_send_midi_clock()) {
+ send_position_event (position, 0);
+ }
_last_tick = position;
}
-void MidiClockTicker::transport_looped()
+void
+MidiClockTicker::transport_looped()
{
Location* loop_location = _session->locations()->auto_loop_location();
assert(loop_location);
@@ -143,7 +154,8 @@ void MidiClockTicker::transport_looped()
}
}
-void MidiClockTicker::tick (const framepos_t& transport_frame)
+void
+MidiClockTicker::tick (const framepos_t& transport_frame)
{
if (!Config->get_send_midi_clock() || _session == 0 || _session->transport_speed() != 1.0f || _midi_port == 0) {
return;
@@ -155,9 +167,11 @@ void MidiClockTicker::tick (const framepos_t& transport_frame)
MIDI::JackMIDIPort* mp = dynamic_cast<MIDI::JackMIDIPort*> (_midi_port);
+ /*
DEBUG_TRACE (PBD::DEBUG::MidiClock,
string_compose ("Transport: %1, last tick time: %2, next tick time: %3, offset: %4, cycle length: %5\n",
transport_frame, _last_tick, next_tick, next_tick_offset, mp ? mp->nframes_this_cycle() : 0));
+ */
if (!mp || (next_tick_offset >= mp->nframes_this_cycle())) {
break;
@@ -171,7 +185,8 @@ void MidiClockTicker::tick (const framepos_t& transport_frame)
}
}
-double MidiClockTicker::one_ppqn_in_frames (framepos_t transport_position)
+double
+MidiClockTicker::one_ppqn_in_frames (framepos_t transport_position)
{
const Tempo& current_tempo = _session->tempo_map().tempo_at (transport_position);
double frames_per_beat = current_tempo.frames_per_beat (_session->nominal_frame_rate());
@@ -182,47 +197,88 @@ double MidiClockTicker::one_ppqn_in_frames (framepos_t transport_position)
return frames_per_quarter_note / double (_ppqn);
}
-void MidiClockTicker::send_midi_clock_event (pframes_t offset)
+void
+MidiClockTicker::send_midi_clock_event (pframes_t offset)
{
if (!_midi_port) {
return;
}
- DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Tick with offset %1\n", offset));
+ // DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Tick with offset %1\n", offset));
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_CLOCK };
_midi_port->write (_midi_clock_tick, 1, offset);
}
-void MidiClockTicker::send_start_event (pframes_t offset)
+void
+MidiClockTicker::send_start_event (pframes_t offset)
{
if (!_midi_port) {
return;
}
+ DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Start %1\n", _last_tick));
+
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_START };
_midi_port->write (_midi_clock_tick, 1, offset);
}
-void MidiClockTicker::send_continue_event (pframes_t offset)
+void
+MidiClockTicker::send_continue_event (pframes_t offset)
{
if (!_midi_port) {
return;
}
+ DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Continue %1\n", _last_tick));
+
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_CONTINUE };
_midi_port->write (_midi_clock_tick, 1, offset);
}
-void MidiClockTicker::send_stop_event (pframes_t offset)
+void
+MidiClockTicker::send_stop_event (pframes_t offset)
{
if (!_midi_port) {
return;
}
+ DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Stop %1\n", _last_tick));
+
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_STOP };
_midi_port->write (_midi_clock_tick, 1, offset);
}
+void
+MidiClockTicker::send_position_event (framepos_t transport_position, pframes_t offset)
+{
+ if (_midi_port == 0 || _session == 0 || _session->engine().freewheeling()) {
+ return;
+ }
+
+ const TempoMap& tempo = _session->tempo_map();
+ Timecode::BBT_Time time;
+ _session->bbt_time (transport_position, time);
+ const double beats_per_bar = tempo.meter_at(transport_position).divisions_per_bar();
+ /* Midi Beats in terms of Song Position Pointer is equivalent to total
+ sixteenth notes at 'time' */
+ const uint32_t midi_beats = 4 * (((time.bars - 1) * beats_per_bar) + time.beats - 1);
+
+ /* can only use 14bits worth */
+ if (midi_beats > 0x3fff) {
+ return;
+ }
+
+ /* split midi beats into a 14bit value */
+ MIDI::byte msg[3] = {
+ MIDI_CMD_COMMON_SONG_POS,
+ midi_beats & 0x007f,
+ midi_beats & 0x3f80
+ };
+
+ DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Song Position: %1\n", midi_beats));
+
+ _midi_port->midimsg (msg, sizeof (msg), offset);
+}
diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc
index c6a348ddfb..7d90709b6f 100644
--- a/libs/ardour/track.cc
+++ b/libs/ardour/track.cc
@@ -398,6 +398,9 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
case MonitoringInput:
be_silent = false;
break;
+ default:
+ be_silent = false;
+ break;
}
}
@@ -436,7 +439,8 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
}
if (no_meter) {
- _meter->reset();
+ BufferSet& bufs (_session.get_silent_buffers (n_process_buffers()));
+ _meter->run (bufs, 0, 0, nframes, true);
_input->process_input (boost::shared_ptr<Processor>(), start_frame, end_frame, nframes);
} else {
_input->process_input (_meter, start_frame, end_frame, nframes);
@@ -447,7 +451,7 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
} else {
- BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
+ BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
fill_buffers_with_input (bufs, _input, nframes);
@@ -492,7 +496,7 @@ Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*
framecnt_t playback_distance;
- BufferSet& bufs (_session.get_silent_buffers (n_process_buffers()));
+ BufferSet& bufs (_session.get_route_buffers (n_process_buffers(), true));
int const dret = _diskstream->process (bufs, _session.transport_frame(), nframes, playback_distance, false);
need_butler = _diskstream->commit (playback_distance);
diff --git a/libs/ardour/vumeterdsp.cc b/libs/ardour/vumeterdsp.cc
new file mode 100644
index 0000000000..67d48f6c54
--- /dev/null
+++ b/libs/ardour/vumeterdsp.cc
@@ -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;
+}
diff --git a/libs/ardour/wscript b/libs/ardour/wscript
index 5e8b27d4ea..87dce06a2a 100644
--- a/libs/ardour/wscript
+++ b/libs/ardour/wscript
@@ -92,6 +92,8 @@ libardour_sources = [
'globals.cc',
'graph.cc',
'graphnode.cc',
+ 'iec1ppmdsp.cc',
+ 'iec2ppmdsp.cc',
'import.cc',
'instrument_info.cc',
'internal_return.cc',
@@ -209,6 +211,7 @@ libardour_sources = [
'user_bundle.cc',
'utils.cc',
'version.cc',
+ 'vumeterdsp.cc',
'worker.cc'
]
diff --git a/libs/gtkmm2ext/fastmeter.cc b/libs/gtkmm2ext/fastmeter.cc
index 6ea1a6dd4b..d826def7ff 100644
--- a/libs/gtkmm2ext/fastmeter.cc
+++ b/libs/gtkmm2ext/fastmeter.cc
@@ -44,6 +44,9 @@ bool FastMeter::no_rgba_overlay = false;
FastMeter::Pattern10Map FastMeter::vm_pattern_cache;
FastMeter::PatternBgMap FastMeter::vb_pattern_cache;
+FastMeter::Pattern10Map FastMeter::hm_pattern_cache;
+FastMeter::PatternBgMap FastMeter::hb_pattern_cache;
+
FastMeter::FastMeter (long hold, unsigned long dimen, Orientation o, int len,
int clr0, int clr1, int clr2, int clr3,
int clr4, int clr5, int clr6, int clr7,
@@ -51,19 +54,25 @@ FastMeter::FastMeter (long hold, unsigned long dimen, Orientation o, int len,
int bgc0, int bgc1,
int bgh0, int bgh1,
float stp0, float stp1,
- float stp2, float stp3
+ float stp2, float stp3,
+ int styleflags
)
+ : pixheight(0)
+ , pixwidth(0)
+ , _styleflags(styleflags)
+ , orientation(o)
+ , hold_cnt(hold)
+ , hold_state(0)
+ , bright_hold(false)
+ , current_level(0)
+ , current_peak(0)
+ , highlight(false)
{
- orientation = o;
- hold_cnt = hold;
- hold_state = 0;
- bright_hold = false;
- current_peak = 0;
- current_level = 0;
last_peak_rect.width = 0;
last_peak_rect.height = 0;
+ last_peak_rect.x = 0;
+ last_peak_rect.y = 0;
- highlight = false;
no_rgba_overlay = ! Glib::getenv("NO_METER_SHADE").empty();
_clr[0] = clr0;
@@ -96,10 +105,18 @@ FastMeter::FastMeter (long hold, unsigned long dimen, Orientation o, int len,
if (!len) {
len = 250;
}
- fgpattern = request_vertical_meter(dimen, len, _clr, _stp, true);
- bgpattern = request_vertical_background (dimen, len, _bgc, false);
- pixheight = len;
- pixwidth = dimen;
+ if (orientation == Vertical) {
+ pixheight = len;
+ pixwidth = dimen;
+ fgpattern = request_vertical_meter(pixwidth + 2, pixheight + 2, _clr, _stp, _styleflags);
+ bgpattern = request_vertical_background (pixwidth + 2, pixheight + 2, _bgc, false);
+
+ } else {
+ pixheight = dimen;
+ pixwidth = len;
+ fgpattern = request_horizontal_meter(pixwidth + 2, pixheight + 2, _clr, _stp, _styleflags);
+ bgpattern = request_horizontal_background (pixwidth + 2, pixheight + 2, _bgc, false);
+ }
pixrect.width = pixwidth;
pixrect.height = pixheight;
@@ -107,7 +124,7 @@ FastMeter::FastMeter (long hold, unsigned long dimen, Orientation o, int len,
request_width = pixrect.width + 2;
request_height= pixrect.height + 2;
- queue_draw ();
+ clear ();
}
FastMeter::~FastMeter ()
@@ -116,11 +133,12 @@ FastMeter::~FastMeter ()
Cairo::RefPtr<Cairo::Pattern>
FastMeter::generate_meter_pattern (
- int width, int height, int *clr, float *stp, bool shade)
+ int width, int height, int *clr, float *stp, int styleflags, bool horiz)
{
guint8 r,g,b,a;
double knee;
- double soft = 1.5 / (double) height;
+ const double soft = 3.0 / (double) height;
+ const double offs = -1.0 / (double) height;
cairo_pattern_t* pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, height);
@@ -133,54 +151,55 @@ FastMeter::generate_meter_pattern (
cairo_pattern_add_color_stop_rgb (pat, 0.0,
r/255.0, g/255.0, b/255.0);
- knee = ((float)height * stp[3] / 115.0f); // -0dB
+ knee = offs + stp[3] / 115.0f; // -0dB
UINT_TO_RGBA (clr[8], &r, &g, &b, &a);
- cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height) - soft,
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee,
r/255.0, g/255.0, b/255.0);
UINT_TO_RGBA (clr[7], &r, &g, &b, &a);
- cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height) + soft,
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee + soft,
r/255.0, g/255.0, b/255.0);
- knee = ((float)height * stp[2]/ 115.0f); // -3dB || -2dB
+ knee = offs + stp[2]/ 115.0f; // -3dB || -2dB
UINT_TO_RGBA (clr[6], &r, &g, &b, &a);
- cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height) - soft,
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee,
r/255.0, g/255.0, b/255.0);
UINT_TO_RGBA (clr[5], &r, &g, &b, &a);
- cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height) + soft,
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee + soft,
r/255.0, g/255.0, b/255.0);
- knee = ((float)height * stp[1] / 115.0f); // -9dB
+ knee = offs + stp[1] / 115.0f; // -9dB
UINT_TO_RGBA (clr[4], &r, &g, &b, &a);
- cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height) - soft,
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee,
r/255.0, g/255.0, b/255.0);
UINT_TO_RGBA (clr[3], &r, &g, &b, &a);
- cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height) + soft,
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee + soft,
r/255.0, g/255.0, b/255.0);
- knee = ((float)height * stp[0] / 115.0f); // -18dB
+ knee = offs + stp[0] / 115.0f; // -18dB
UINT_TO_RGBA (clr[2], &r, &g, &b, &a);
- cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height) - soft,
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee,
r/255.0, g/255.0, b/255.0);
UINT_TO_RGBA (clr[1], &r, &g, &b, &a);
- cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height) + soft,
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee + soft,
r/255.0, g/255.0, b/255.0);
UINT_TO_RGBA (clr[0], &r, &g, &b, &a); // bottom
cairo_pattern_add_color_stop_rgb (pat, 1.0,
r/255.0, g/255.0, b/255.0);
- if (shade && !no_rgba_overlay) {
+ if ((styleflags & 1) && !no_rgba_overlay) {
cairo_pattern_t* shade_pattern = cairo_pattern_create_linear (0.0, 0.0, width, 0.0);
- cairo_pattern_add_color_stop_rgba (shade_pattern, 0, 1.0, 1.0, 1.0, 0.2);
- cairo_pattern_add_color_stop_rgba (shade_pattern, 1, 0.0, 0.0, 0.0, 0.3);
+ cairo_pattern_add_color_stop_rgba (shade_pattern, 0, 0.0, 0.0, 0.0, 0.15);
+ cairo_pattern_add_color_stop_rgba (shade_pattern, 0.4, 1.0, 1.0, 1.0, 0.05);
+ cairo_pattern_add_color_stop_rgba (shade_pattern, 1, 0.0, 0.0, 0.0, 0.25);
cairo_surface_t* surface;
cairo_t* tc = 0;
@@ -189,19 +208,49 @@ FastMeter::generate_meter_pattern (
cairo_set_source (tc, pat);
cairo_rectangle (tc, 0, 0, width, height);
cairo_fill (tc);
+ cairo_pattern_destroy (pat);
+
cairo_set_source (tc, shade_pattern);
cairo_rectangle (tc, 0, 0, width, height);
cairo_fill (tc);
-
- cairo_pattern_destroy (pat);
cairo_pattern_destroy (shade_pattern);
- pat = cairo_pattern_create_for_surface (surface);
+ if (styleflags & 2) { // LED stripes
+ cairo_save (tc);
+ cairo_set_line_width(tc, 1.0);
+ cairo_set_source_rgba(tc, .0, .0, .0, 0.4);
+ //cairo_set_operator (tc, CAIRO_OPERATOR_SOURCE);
+ for (float y=0.5; y < height; y+= 2.0) {
+ cairo_move_to(tc, 0, y);
+ cairo_line_to(tc, width, y);
+ cairo_stroke (tc);
+ }
+ cairo_restore (tc);
+ }
+ pat = cairo_pattern_create_for_surface (surface);
cairo_destroy (tc);
cairo_surface_destroy (surface);
}
+ if (horiz) {
+ cairo_surface_t* surface;
+ cairo_t* tc = 0;
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, height, width);
+ tc = cairo_create (surface);
+
+ cairo_matrix_t m;
+ cairo_matrix_init_rotate (&m, -M_PI/2.0);
+ cairo_matrix_translate (&m, -height, 0);
+ cairo_pattern_set_matrix (pat, &m);
+ cairo_set_source (tc, pat);
+ cairo_rectangle (tc, 0, 0, height, width);
+ cairo_fill (tc);
+ cairo_pattern_destroy (pat);
+ pat = cairo_pattern_create_for_surface (surface);
+ cairo_destroy (tc);
+ cairo_surface_destroy (surface);
+ }
Cairo::RefPtr<Cairo::Pattern> p (new Cairo::Pattern (pat, false));
return p;
@@ -210,7 +259,7 @@ FastMeter::generate_meter_pattern (
Cairo::RefPtr<Cairo::Pattern>
FastMeter::generate_meter_background (
- int width, int height, int *clr, bool shade)
+ int width, int height, int *clr, bool shade, bool horiz)
{
guint8 r0,g0,b0,r1,g1,b1,a;
@@ -251,6 +300,25 @@ FastMeter::generate_meter_background (
cairo_surface_destroy (surface);
}
+ if (horiz) {
+ cairo_surface_t* surface;
+ cairo_t* tc = 0;
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, height, width);
+ tc = cairo_create (surface);
+
+ cairo_matrix_t m;
+ cairo_matrix_init_rotate (&m, -M_PI/2.0);
+ cairo_matrix_translate (&m, -height, 0);
+ cairo_pattern_set_matrix (pat, &m);
+ cairo_set_source (tc, pat);
+ cairo_rectangle (tc, 0, 0, height, width);
+ cairo_fill (tc);
+ cairo_pattern_destroy (pat);
+ pat = cairo_pattern_create_for_surface (surface);
+ cairo_destroy (tc);
+ cairo_surface_destroy (surface);
+ }
+
Cairo::RefPtr<Cairo::Pattern> p (new Cairo::Pattern (pat, false));
return p;
@@ -258,18 +326,16 @@ FastMeter::generate_meter_background (
Cairo::RefPtr<Cairo::Pattern>
FastMeter::request_vertical_meter(
- int width, int height, int *clr, float *stp, bool shade)
+ int width, int height, int *clr, float *stp, int styleflags)
{
- if (height < min_pattern_metric_size)
- height = min_pattern_metric_size;
- if (height > max_pattern_metric_size)
- height = max_pattern_metric_size;
+ height = max(height, min_pattern_metric_size);
+ height = min(height, max_pattern_metric_size);
const Pattern10MapKey key (width, height,
stp[0], stp[1], stp[2], stp[3],
clr[0], clr[1], clr[2], clr[3],
clr[4], clr[5], clr[6], clr[7],
- clr[8], clr[9]);
+ clr[8], clr[9], styleflags);
Pattern10Map::iterator i;
if ((i = vm_pattern_cache.find (key)) != vm_pattern_cache.end()) {
@@ -278,7 +344,7 @@ FastMeter::request_vertical_meter(
// TODO flush pattern cache if it gets too large
Cairo::RefPtr<Cairo::Pattern> p = generate_meter_pattern (
- width, height, clr, stp, shade);
+ width, height, clr, stp, styleflags, false);
vm_pattern_cache[key] = p;
return p;
@@ -288,12 +354,11 @@ Cairo::RefPtr<Cairo::Pattern>
FastMeter::request_vertical_background(
int width, int height, int *bgc, bool shade)
{
- if (height < min_pattern_metric_size)
- height = min_pattern_metric_size;
- if (height > max_pattern_metric_size)
- height = max_pattern_metric_size;
+ height = max(height, min_pattern_metric_size);
+ height = min(height, max_pattern_metric_size);
+ height += 2;
- const PatternBgMapKey key (width, height, bgc[0], bgc[1]);
+ const PatternBgMapKey key (width, height, bgc[0], bgc[1], shade);
PatternBgMap::iterator i;
if ((i = vb_pattern_cache.find (key)) != vb_pattern_cache.end()) {
return i->second;
@@ -301,12 +366,62 @@ FastMeter::request_vertical_background(
// TODO flush pattern cache if it gets too large
Cairo::RefPtr<Cairo::Pattern> p = generate_meter_background (
- width, height, bgc, shade);
+ width, height, bgc, shade, false);
vb_pattern_cache[key] = p;
return p;
}
+Cairo::RefPtr<Cairo::Pattern>
+FastMeter::request_horizontal_meter(
+ int width, int height, int *clr, float *stp, int styleflags)
+{
+ width = max(width, min_pattern_metric_size);
+ width = min(width, max_pattern_metric_size);
+
+ const Pattern10MapKey key (width, height,
+ stp[0], stp[1], stp[2], stp[3],
+ clr[0], clr[1], clr[2], clr[3],
+ clr[4], clr[5], clr[6], clr[7],
+ clr[8], clr[9], styleflags);
+
+ Pattern10Map::iterator i;
+ if ((i = hm_pattern_cache.find (key)) != hm_pattern_cache.end()) {
+ return i->second;
+ }
+ // TODO flush pattern cache if it gets too large
+
+ Cairo::RefPtr<Cairo::Pattern> p = generate_meter_pattern (
+ height, width, clr, stp, styleflags, true);
+
+ hm_pattern_cache[key] = p;
+ return p;
+}
+
+Cairo::RefPtr<Cairo::Pattern>
+FastMeter::request_horizontal_background(
+ int width, int height, int *bgc, bool shade)
+{
+ width = max(width, min_pattern_metric_size);
+ width = min(width, max_pattern_metric_size);
+ width += 2;
+
+ const PatternBgMapKey key (width, height, bgc[0], bgc[1], shade);
+ PatternBgMap::iterator i;
+ if ((i = hb_pattern_cache.find (key)) != hb_pattern_cache.end()) {
+ return i->second;
+ }
+ // TODO flush pattern cache if it gets too large
+
+ Cairo::RefPtr<Cairo::Pattern> p = generate_meter_background (
+ height, width, bgc, shade, true);
+
+ hb_pattern_cache[key] = p;
+
+ return p;
+}
+
+
void
FastMeter::set_hold_count (long val)
@@ -325,6 +440,16 @@ FastMeter::set_hold_count (long val)
void
FastMeter::on_size_request (GtkRequisition* req)
{
+ if (orientation == Vertical) {
+ vertical_size_request (req);
+ } else {
+ horizontal_size_request (req);
+ }
+}
+
+void
+FastMeter::vertical_size_request (GtkRequisition* req)
+{
req->height = request_height;
req->height = max(req->height, min_pattern_metric_size);
req->height = min(req->height, max_pattern_metric_size);
@@ -334,8 +459,30 @@ FastMeter::on_size_request (GtkRequisition* req)
}
void
+FastMeter::horizontal_size_request (GtkRequisition* req)
+{
+ req->width = request_width;
+ req->width = max(req->width, min_pattern_metric_size);
+ req->width = min(req->width, max_pattern_metric_size);
+ req->width += 2;
+
+ req->height = request_height;
+}
+
+void
FastMeter::on_size_allocate (Gtk::Allocation &alloc)
{
+ if (orientation == Vertical) {
+ vertical_size_allocate (alloc);
+ } else {
+ horizontal_size_allocate (alloc);
+ }
+ queue_draw ();
+}
+
+void
+FastMeter::vertical_size_allocate (Gtk::Allocation &alloc)
+{
if (alloc.get_width() != request_width) {
alloc.set_width (request_width);
}
@@ -349,7 +496,7 @@ FastMeter::on_size_allocate (Gtk::Allocation &alloc)
}
if (pixheight != h) {
- fgpattern = request_vertical_meter (request_width, h, _clr, _stp, true);
+ fgpattern = request_vertical_meter (request_width, h, _clr, _stp, _styleflags);
bgpattern = request_vertical_background (request_width, h, highlight ? _bgh : _bgc, highlight);
pixheight = h - 2;
pixwidth = request_width - 2;
@@ -358,10 +505,39 @@ FastMeter::on_size_allocate (Gtk::Allocation &alloc)
DrawingArea::on_size_allocate (alloc);
}
+void
+FastMeter::horizontal_size_allocate (Gtk::Allocation &alloc)
+{
+ if (alloc.get_height() != request_height) {
+ alloc.set_height (request_height);
+ }
+
+ int w = alloc.get_width();
+ w = max (w, min_pattern_metric_size + 2);
+ w = min (w, max_pattern_metric_size + 2);
+
+ if (w != alloc.get_width()) {
+ alloc.set_width (w);
+ }
+
+ if (pixwidth != w) {
+ fgpattern = request_horizontal_meter (w, request_height, _clr, _stp, _styleflags);
+ bgpattern = request_horizontal_background (w, request_height, highlight ? _bgh : _bgc, highlight);
+ pixwidth = w - 2;
+ pixheight = request_height - 2;
+ }
+
+ DrawingArea::on_size_allocate (alloc);
+}
+
bool
FastMeter::on_expose_event (GdkEventExpose* ev)
{
- return vertical_expose (ev);
+ if (orientation == Vertical) {
+ return vertical_expose (ev);
+ } else {
+ return horizontal_expose (ev);
+ }
}
bool
@@ -378,7 +554,7 @@ FastMeter::vertical_expose (GdkEventExpose* ev)
cairo_clip (cr);
cairo_set_source_rgb (cr, 0, 0, 0); // black
- rounded_rectangle (cr, 0, 0, pixrect.width + 2, pixheight + 2, 2);
+ rounded_rectangle (cr, 0, 0, pixwidth + 2, pixheight + 2, 2);
cairo_stroke (cr);
top_of_meter = (gint) floor (pixheight * current_level);
@@ -413,14 +589,87 @@ FastMeter::vertical_expose (GdkEventExpose* ev)
last_peak_rect.x = 1;
last_peak_rect.width = pixwidth;
last_peak_rect.y = max(1, 1 + pixheight - (gint) floor (pixheight * current_peak));
- if (bright_hold) {
- last_peak_rect.height = max(0, min(4, pixheight - last_peak_rect.y -1 ));
+ if (bright_hold || (_styleflags & 2)) {
+ last_peak_rect.height = max(0, min(3, pixheight - last_peak_rect.y - 1 ));
} else {
- last_peak_rect.height = max(0, min(2, pixheight - last_peak_rect.y -1 ));
+ last_peak_rect.height = max(0, min(2, pixheight - last_peak_rect.y - 1 ));
}
cairo_set_source (cr, fgpattern->cobj());
- cairo_rectangle (cr, 1, last_peak_rect.y, pixwidth, last_peak_rect.height);
+ cairo_rectangle (cr, last_peak_rect.x, last_peak_rect.y, last_peak_rect.width, last_peak_rect.height);
+
+ if (bright_hold && !no_rgba_overlay) {
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.3);
+ }
+ cairo_fill (cr);
+
+ } else {
+ last_peak_rect.width = 0;
+ last_peak_rect.height = 0;
+ }
+
+ cairo_destroy (cr);
+
+ return TRUE;
+}
+
+bool
+FastMeter::horizontal_expose (GdkEventExpose* ev)
+{
+ Glib::RefPtr<Gdk::Window> win = get_window ();
+ gint right_of_meter;
+ GdkRectangle intersection;
+ GdkRectangle background;
+
+ cairo_t* cr = gdk_cairo_create (get_window ()->gobj());
+
+ cairo_rectangle (cr, ev->area.x, ev->area.y, ev->area.width, ev->area.height);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0); // black
+ rounded_rectangle (cr, 0, 0, pixwidth + 2, pixheight + 2, 2);
+ cairo_stroke (cr);
+
+ right_of_meter = (gint) floor (pixwidth * current_level);
+
+ /* reset the height & origin of the rect that needs to show the pixbuf
+ */
+
+ pixrect.width = right_of_meter;
+
+ background.x = 1 + right_of_meter;
+ background.y = 1;
+ background.width = pixwidth - right_of_meter;
+ background.height = pixheight;
+
+ if (gdk_rectangle_intersect (&background, &ev->area, &intersection)) {
+ cairo_set_source (cr, bgpattern->cobj());
+ cairo_rectangle (cr, intersection.x, intersection.y, intersection.width, intersection.height);
+ cairo_fill (cr);
+ }
+
+ if (gdk_rectangle_intersect (&pixrect, &ev->area, &intersection)) {
+ cairo_set_source (cr, fgpattern->cobj());
+ cairo_rectangle (cr, intersection.x, intersection.y, intersection.width, intersection.height);
+ cairo_fill (cr);
+ }
+
+ // draw peak bar
+
+ if (hold_state) {
+ last_peak_rect.y = 1;
+ last_peak_rect.height = pixheight;
+ const int xpos = floor (pixwidth * current_peak);
+ if (bright_hold || (_styleflags & 2)) {
+ last_peak_rect.width = min(3, xpos );
+ } else {
+ last_peak_rect.width = min(2, xpos );
+ }
+ last_peak_rect.x = 1 + max(0, xpos - last_peak_rect.width);
+
+ cairo_set_source (cr, fgpattern->cobj());
+ cairo_rectangle (cr, last_peak_rect.x, last_peak_rect.y, last_peak_rect.width, last_peak_rect.height);
if (bright_hold && !no_rgba_overlay) {
cairo_fill_preserve (cr);
@@ -444,6 +693,8 @@ FastMeter::set (float lvl, float peak)
float old_level = current_level;
float old_peak = current_peak;
+ if (pixwidth <= 0 || pixheight <=0) return;
+
if (peak == -1) {
if (lvl >= current_peak) {
current_peak = lvl;
@@ -475,7 +726,11 @@ FastMeter::set (float lvl, float peak)
return;
}
- queue_vertical_redraw (win, old_level);
+ if (orientation == Vertical) {
+ queue_vertical_redraw (win, old_level);
+ } else {
+ queue_horizontal_redraw (win, old_level);
+ }
}
void
@@ -538,8 +793,8 @@ FastMeter::queue_vertical_redraw (const Glib::RefPtr<Gdk::Window>& win, float ol
}
rect.x = 1;
rect.y = max(1, 1 + pixheight - (gint) floor (pixheight * current_peak));
- if (bright_hold) {
- rect.height = max(0, min(4, pixheight - last_peak_rect.y -1 ));
+ if (bright_hold || (_styleflags & 2)) {
+ rect.height = max(0, min(3, pixheight - last_peak_rect.y -1 ));
} else {
rect.height = max(0, min(2, pixheight - last_peak_rect.y -1 ));
}
@@ -557,13 +812,88 @@ FastMeter::queue_vertical_redraw (const Glib::RefPtr<Gdk::Window>& win, float ol
}
void
+FastMeter::queue_horizontal_redraw (const Glib::RefPtr<Gdk::Window>& win, float old_level)
+{
+ GdkRectangle rect;
+
+ gint new_right = (gint) floor (pixwidth * current_level);
+
+ rect.height = pixheight;
+ rect.y = 1;
+
+ if (current_level > old_level) {
+ rect.x = 1 + pixrect.width;
+ /* colored/pixbuf got larger, just draw the new section */
+ rect.width = new_right - pixrect.width;
+ } else {
+ /* it got smaller, compute the difference */
+ rect.x = 1 + new_right;
+ /* rect.height is the old.x (smaller) minus the new.x (larger) */
+ rect.width = pixrect.width - new_right;
+ }
+
+ GdkRegion* region = 0;
+ bool queue = false;
+
+ if (rect.height != 0) {
+
+ /* ok, first region to draw ... */
+
+ region = gdk_region_rectangle (&rect);
+ queue = true;
+ }
+
+ /* redraw the last place where the last peak hold bar was;
+ the next expose will draw the new one whether its part of
+ expose region or not.
+ */
+
+ if (last_peak_rect.width * last_peak_rect.height != 0) {
+ if (!queue) {
+ region = gdk_region_new ();
+ queue = true;
+ }
+ gdk_region_union_with_rect (region, &last_peak_rect);
+ }
+
+ if (hold_state && current_peak > 0) {
+ if (!queue) {
+ region = gdk_region_new ();
+ queue = true;
+ }
+ rect.y = 1;
+ rect.height = pixheight;
+ const int xpos = floor (pixwidth * current_peak);
+ if (bright_hold || (_styleflags & 2)) {
+ rect.width = min(3, xpos);
+ } else {
+ rect.width = min(2, xpos);
+ }
+ rect.x = 1 + max(0, xpos - rect.width);
+ gdk_region_union_with_rect (region, &rect);
+ }
+
+ if (queue) {
+ gdk_window_invalidate_region (win->gobj(), region, true);
+ }
+ if (region) {
+ gdk_region_destroy(region);
+ region = 0;
+ }
+}
+
+void
FastMeter::set_highlight (bool onoff)
{
if (highlight == onoff) {
return;
}
highlight = onoff;
- bgpattern = request_vertical_background (request_width, pixheight, highlight ? _bgh : _bgc, highlight);
+ if (orientation == Vertical) {
+ bgpattern = request_vertical_background (pixwidth + 2, pixheight + 2, highlight ? _bgh : _bgc, highlight);
+ } else {
+ bgpattern = request_horizontal_background (pixwidth + 2, pixheight + 2, highlight ? _bgh : _bgc, highlight);
+ }
queue_draw ();
}
diff --git a/libs/gtkmm2ext/gtkmm2ext/fastmeter.h b/libs/gtkmm2ext/gtkmm2ext/fastmeter.h
index 15c962deb4..8070748963 100644
--- a/libs/gtkmm2ext/gtkmm2ext/fastmeter.h
+++ b/libs/gtkmm2ext/gtkmm2ext/fastmeter.h
@@ -47,7 +47,8 @@ class FastMeter : public Gtk::DrawingArea {
float stp0 = 55.0, // log_meter(-18);
float stp1 = 77.5, // log_meter(-9);
float stp2 = 92.5, // log_meter(-3); // 95.0, // log_meter(-2);
- float stp3 = 100.0
+ float stp3 = 100.0,
+ int styleflags = 3
);
virtual ~FastMeter ();
@@ -67,7 +68,6 @@ protected:
bool on_expose_event (GdkEventExpose*);
void on_size_request (GtkRequisition*);
void on_size_allocate (Gtk::Allocation&);
-
private:
Cairo::RefPtr<Cairo::Pattern> fgpattern;
@@ -79,6 +79,7 @@ private:
int _clr[10];
int _bgc[2];
int _bgh[2];
+ int _styleflags;
Orientation orientation;
GdkRectangle pixrect;
@@ -94,19 +95,30 @@ private:
bool highlight;
bool vertical_expose (GdkEventExpose*);
+ void vertical_size_request (GtkRequisition*);
+ void vertical_size_allocate (Gtk::Allocation&);
void queue_vertical_redraw (const Glib::RefPtr<Gdk::Window>&, float);
+ bool horizontal_expose (GdkEventExpose*);
+ void horizontal_size_request (GtkRequisition*);
+ void horizontal_size_allocate (Gtk::Allocation&);
+ void queue_horizontal_redraw (const Glib::RefPtr<Gdk::Window>&, float);
+
static bool no_rgba_overlay;
static Cairo::RefPtr<Cairo::Pattern> generate_meter_pattern (
- int w, int h, int *clr, float *stp, bool shade);
+ int, int, int *, float *, int, bool);
static Cairo::RefPtr<Cairo::Pattern> request_vertical_meter (
- int w, int h, int *clr, float *stp, bool shade);
+ int, int, int *, float *, int);
+ static Cairo::RefPtr<Cairo::Pattern> request_horizontal_meter (
+ int, int, int *, float *, int);
static Cairo::RefPtr<Cairo::Pattern> generate_meter_background (
- int w, int h, int *bgc, bool shade);
+ int, int, int *, bool, bool);
static Cairo::RefPtr<Cairo::Pattern> request_vertical_background (
- int w, int h, int *bgc, bool shade);
+ int, int, int *, bool);
+ static Cairo::RefPtr<Cairo::Pattern> request_horizontal_background (
+ int, int, int *, bool);
struct Pattern10MapKey {
Pattern10MapKey (
@@ -114,38 +126,45 @@ private:
float stp0, float stp1, float stp2, float stp3,
int c0, int c1, int c2, int c3,
int c4, int c5, int c6, int c7,
- int c8, int c9
+ int c8, int c9, int st
)
: dim(w, h)
, stp(stp0, stp1, stp2, stp3)
, cols(c0, c1, c2, c3, c4, c5, c6, c7, c8, c9)
+ , style(st)
{}
inline bool operator<(const Pattern10MapKey& rhs) const {
return (dim < rhs.dim)
|| (dim == rhs.dim && stp < rhs.stp)
- || (dim == rhs.dim && stp == rhs.stp && cols < rhs.cols);
+ || (dim == rhs.dim && stp == rhs.stp && cols < rhs.cols)
+ || (dim == rhs.dim && stp == rhs.stp && cols == rhs.cols && style < rhs.style);
}
boost::tuple<int, int> dim;
boost::tuple<float, float, float, float> stp;
boost::tuple<int, int, int, int, int, int, int, int, int, int> cols;
+ int style;
};
typedef std::map<Pattern10MapKey, Cairo::RefPtr<Cairo::Pattern> > Pattern10Map;
struct PatternBgMapKey {
- PatternBgMapKey (int w, int h, int c0, int c1)
+ PatternBgMapKey (int w, int h, int c0, int c1, bool shade)
: dim(w, h)
, cols(c0, c1)
+ , sh(shade)
{}
inline bool operator<(const PatternBgMapKey& rhs) const {
- return (dim < rhs.dim) || (dim == rhs.dim && cols < rhs.cols);
+ return (dim < rhs.dim) || (dim == rhs.dim && cols < rhs.cols) || (dim == rhs.dim && cols == rhs.cols && (sh && !rhs.sh));
}
boost::tuple<int, int> dim;
boost::tuple<int, int> cols;
+ bool sh;
};
typedef std::map<PatternBgMapKey, Cairo::RefPtr<Cairo::Pattern> > PatternBgMap;
static Pattern10Map vm_pattern_cache;
static PatternBgMap vb_pattern_cache;
+ static Pattern10Map hm_pattern_cache;
+ static PatternBgMap hb_pattern_cache;
static int min_pattern_metric_size; // min dimension for axis that displays the meter level
static int max_pattern_metric_size; // max dimension for axis that displays the meter level
};
diff --git a/libs/gtkmm2ext/gtkmm2ext/keyboard.h b/libs/gtkmm2ext/gtkmm2ext/keyboard.h
index 84988e1525..2c6b026a42 100644
--- a/libs/gtkmm2ext/gtkmm2ext/keyboard.h
+++ b/libs/gtkmm2ext/gtkmm2ext/keyboard.h
@@ -164,7 +164,7 @@ class Keyboard : public sigc::trackable, PBD::Stateful
}
};
- sigc::signal0<void> ShiftReleased;
+ sigc::signal0<void> ZoomVerticalModifierReleased;
protected:
static Keyboard* _the_keyboard;
diff --git a/libs/gtkmm2ext/keyboard.cc b/libs/gtkmm2ext/keyboard.cc
index f694471d9a..5087f61a23 100644
--- a/libs/gtkmm2ext/keyboard.cc
+++ b/libs/gtkmm2ext/keyboard.cc
@@ -248,12 +248,15 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event)
keyval = event->keyval;
}
- if (keyval == GDK_Shift_L) {
+ if (event->state & ScrollZoomVerticalModifier) {
/* There is a special and rather hacky situation in Editor which makes
- it useful to know when a shift key has been released, so emit a signal
- here (see Editor::_stepping_axis_view)
+ it useful to know when the modifier key for vertical zoom has been
+ released, so emit a signal here (see Editor::_stepping_axis_view).
+ Note that the state bit for the modifier key is set for the key-up
+ event when the modifier is released, but not the key-down when it
+ is pressed, so we get here on key-up, which is what we want.
*/
- ShiftReleased (); /* EMIT SIGNAL */
+ ZoomVerticalModifierReleased (); /* EMIT SIGNAL */
}
if (event->type == GDK_KEY_PRESS) {
diff --git a/libs/pbd/pbd/ringbuffer.h b/libs/pbd/pbd/ringbuffer.h
index a1a6151542..bb5485a8f3 100644
--- a/libs/pbd/pbd/ringbuffer.h
+++ b/libs/pbd/pbd/ringbuffer.h
@@ -233,6 +233,7 @@ RingBuffer<T>::get_read_vector (typename RingBuffer<T>::rw_vector *vec)
vec->buf[0] = &buf[r];
vec->len[0] = free_cnt;
+ vec->buf[1] = 0;
vec->len[1] = 0;
}
}
diff --git a/libs/pbd/pbd/stl_delete.h b/libs/pbd/pbd/stl_delete.h
index ac2161560c..bca0ea9e21 100644
--- a/libs/pbd/pbd/stl_delete.h
+++ b/libs/pbd/pbd/stl_delete.h
@@ -21,17 +21,10 @@
#define __libmisc_stl_delete_h__
-#if __clang__ && __APPLE__ && __cplusplus >= 201103L
-#include <vector>
-#ifndef _CPP_VECTOR
-#define _CPP_VECTOR
-#endif
-#endif
-
/* To actually use any of these deletion functions, you need to
first include the revelant container type header.
*/
-#if defined(_CPP_VECTOR) || defined(_GLIBCXX_VECTOR) || defined(__SGI_STL_VECTOR)
+#if defined(_CPP_VECTOR) || defined(_GLIBCXX_VECTOR) || defined(__SGI_STL_VECTOR) || defined(_LIBCPP_VECTOR)
template<class T> void vector_delete (std::vector<T *> *vec)
{
typename std::vector<T *>::iterator i;
@@ -41,7 +34,7 @@ template<class T> void vector_delete (std::vector<T *> *vec)
}
vec->clear ();
}
-#endif // _CPP_VECTOR || _GLIBCXX_VECTOR || __SGI_STL_VECTOR
+#endif // _CPP_VECTOR || _GLIBCXX_VECTOR || __SGI_STL_VECTOR || _LIBCPP_VECTOR
#if defined(_CPP_MAP) || defined(_GLIBCXX_MAP) || defined(__SGI_STL_MAP)
template<class K, class T> void map_delete (std::map<K, T *> *m)
diff --git a/libs/surfaces/osc/osc.h b/libs/surfaces/osc/osc.h
index 5c3422799b..84dd0d9c86 100644
--- a/libs/surfaces/osc/osc.h
+++ b/libs/surfaces/osc/osc.h
@@ -188,7 +188,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { \
return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, data); \
} \
- int cb_ ## name (const char *, const char *, lo_arg **argv, int argc, void *data) { \
+ int cb_ ## name (const char *, const char *, lo_arg **argv, int argc, void *) { \
if (argc > 1) { \
name (argv[0]->arg1type, argv[1]->arg2type,argv[2]->arg3type); \
} \
@@ -199,7 +199,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { \
return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, data); \
} \
- int cb_ ## name (const char *, const char *, lo_arg **argv, int argc, void *data) { \
+ int cb_ ## name (const char *, const char *, lo_arg **argv, int argc, void *) { \
if (argc > 1) { \
name (argv[0]->arg1type, argv[1]->arg2type,argv[2]->arg3type,argv[3]->arg4type); \
} \