summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2013-08-05 14:22:32 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2013-08-05 14:22:32 -0400
commit616f2a0370a10dcc7372a95f6bca9f5a45698980 (patch)
treeb07badccad237cc66d0668482ad65cedefdee23f /libs
parent499b7fcfa9f3e8535a4500143a9d7af7b67c6984 (diff)
parent38e4f7bd1ba2ec9ae37dbb384da449f894cd8564 (diff)
fix conflicts after merge with master
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/amp.cc2
-rw-r--r--libs/ardour/ardour/amp.h2
-rw-r--r--libs/ardour/ardour/audio_diskstream.h1
-rw-r--r--libs/ardour/ardour/audio_unit.h2
-rw-r--r--libs/ardour/ardour/capturing_processor.h2
-rw-r--r--libs/ardour/ardour/delivery.h2
-rw-r--r--libs/ardour/ardour/diskstream.h1
-rw-r--r--libs/ardour/ardour/internal_return.h2
-rw-r--r--libs/ardour/ardour/internal_send.h2
-rw-r--r--libs/ardour/ardour/meter.h5
-rw-r--r--libs/ardour/ardour/midi_diskstream.h1
-rw-r--r--libs/ardour/ardour/monitor_processor.h2
-rw-r--r--libs/ardour/ardour/panner_shell.h2
-rw-r--r--libs/ardour/ardour/plugin.h2
-rw-r--r--libs/ardour/ardour/plugin_insert.h6
-rw-r--r--libs/ardour/ardour/port_insert.h2
-rw-r--r--libs/ardour/ardour/process_thread.h3
-rw-r--r--libs/ardour/ardour/processor.h2
-rw-r--r--libs/ardour/ardour/rc_configuration_vars.h7
-rw-r--r--libs/ardour/ardour/return.h2
-rw-r--r--libs/ardour/ardour/route.h3
-rw-r--r--libs/ardour/ardour/send.h2
-rw-r--r--libs/ardour/ardour/session.h5
-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.h10
-rw-r--r--libs/ardour/ardour/types.h7
-rw-r--r--libs/ardour/ardour/unknown_processor.h2
-rw-r--r--libs/ardour/audio_diskstream.cc27
-rw-r--r--libs/ardour/audio_track.cc8
-rw-r--r--libs/ardour/audio_unit.cc9
-rw-r--r--libs/ardour/audiosource.cc2
-rw-r--r--libs/ardour/capturing_processor.cc2
-rw-r--r--libs/ardour/delivery.cc2
-rw-r--r--libs/ardour/enums.cc1
-rw-r--r--libs/ardour/internal_return.cc2
-rw-r--r--libs/ardour/internal_send.cc2
-rw-r--r--libs/ardour/kmeterdsp.cc16
-rw-r--r--libs/ardour/ladspa_plugin.cc2
-rw-r--r--libs/ardour/lv2_plugin.cc4
-rw-r--r--libs/ardour/meter.cc48
-rw-r--r--libs/ardour/midi_diskstream.cc14
-rw-r--r--libs/ardour/midi_track.cc8
-rw-r--r--libs/ardour/monitor_processor.cc2
-rw-r--r--libs/ardour/playlist.cc4
-rw-r--r--libs/ardour/plugin_insert.cc30
-rw-r--r--libs/ardour/po/de.po105
-rw-r--r--libs/ardour/port_insert.cc2
-rw-r--r--libs/ardour/process_thread.cc37
-rw-r--r--libs/ardour/return.cc2
-rw-r--r--libs/ardour/route.cc57
-rw-r--r--libs/ardour/send.cc2
-rw-r--r--libs/ardour/session.cc11
-rw-r--r--libs/ardour/session_ltc.cc43
-rw-r--r--libs/ardour/session_midi.cc14
-rw-r--r--libs/ardour/session_transport.cc2
-rw-r--r--libs/ardour/thread_buffers.cc2
-rw-r--r--libs/ardour/ticker.cc249
-rw-r--r--libs/ardour/track.cc14
-rw-r--r--libs/gtkmm2ext/fastmeter.cc456
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/fastmeter.h39
-rw-r--r--libs/pbd/cocoa_open_uri.mm1
-rw-r--r--libs/pbd/pbd/ringbuffer.h1
-rw-r--r--libs/pbd/pbd/stl_delete.h11
-rw-r--r--libs/pbd/wscript5
-rw-r--r--libs/surfaces/osc/osc.h4
-rw-r--r--libs/timecode/src/time.cc4
67 files changed, 1038 insertions, 287 deletions
diff --git a/libs/ardour/amp.cc b/libs/ardour/amp.cc
index f60240fd57..c97d624440 100644
--- a/libs/ardour/amp.cc
+++ b/libs/ardour/amp.cc
@@ -61,7 +61,7 @@ Amp::display_name() const
}
bool
-Amp::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
+Amp::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in;
return true;
diff --git a/libs/ardour/ardour/amp.h b/libs/ardour/ardour/amp.h
index 23cc0ad0a8..e21cf62d62 100644
--- a/libs/ardour/ardour/amp.h
+++ b/libs/ardour/ardour/amp.h
@@ -40,7 +40,7 @@ public:
bool visible () const;
- bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
index 21efc5c20c..5a856e9b36 100644
--- a/libs/ardour/ardour/audio_diskstream.h
+++ b/libs/ardour/ardour/audio_diskstream.h
@@ -152,6 +152,7 @@ class AudioDiskstream : public Diskstream
friend class AudioTrack;
int process (BufferSet&, framepos_t transport_frame, pframes_t nframes, framecnt_t &, bool need_disk_signal);
+ frameoffset_t calculate_playback_distance (pframes_t nframes);
bool commit (framecnt_t);
private:
diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h
index 36e82da802..007390b34a 100644
--- a/libs/ardour/ardour/audio_unit.h
+++ b/libs/ardour/ardour/audio_unit.h
@@ -104,7 +104,7 @@ class AUPlugin : public ARDOUR::Plugin
bool has_editor () const;
- bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
ChanCount output_streams() const;
ChanCount input_streams() const;
bool configure_io (ChanCount in, ChanCount out);
diff --git a/libs/ardour/ardour/capturing_processor.h b/libs/ardour/ardour/capturing_processor.h
index b672d1ac07..5b9ea51557 100644
--- a/libs/ardour/ardour/capturing_processor.h
+++ b/libs/ardour/ardour/capturing_processor.h
@@ -38,7 +38,7 @@ class CapturingProcessor : public Processor
int set_block_size (pframes_t nframes);
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool result_required);
bool configure_io (ChanCount in, ChanCount out);
- bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
virtual XMLNode& state (bool);
private:
diff --git a/libs/ardour/ardour/delivery.h b/libs/ardour/ardour/delivery.h
index 314b223538..4a6d4368a6 100644
--- a/libs/ardour/ardour/delivery.h
+++ b/libs/ardour/ardour/delivery.h
@@ -67,7 +67,7 @@ public:
std::string display_name() const;
Role role() const { return _role; }
- bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index 85ca03caff..427b52b054 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/diskstream.h
@@ -193,6 +193,7 @@ class Diskstream : public SessionObject, public PublicDiskstream
friend class Track;
virtual int process (BufferSet&, framepos_t transport_frame, pframes_t nframes, framecnt_t &, bool need_disk_signal) = 0;
+ virtual frameoffset_t calculate_playback_distance (pframes_t nframes) = 0;
virtual bool commit (framecnt_t) = 0;
//private:
diff --git a/libs/ardour/ardour/internal_return.h b/libs/ardour/ardour/internal_return.h
index c7fe04cc42..4d2b32f031 100644
--- a/libs/ardour/ardour/internal_return.h
+++ b/libs/ardour/ardour/internal_return.h
@@ -39,7 +39,7 @@ class InternalReturn : public Return
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
bool configure_io (ChanCount, ChanCount);
- bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
void add_send (InternalSend *);
void remove_send (InternalSend *);
diff --git a/libs/ardour/ardour/internal_send.h b/libs/ardour/ardour/internal_send.h
index 8bfb0de887..a7f0f73e6e 100644
--- a/libs/ardour/ardour/internal_send.h
+++ b/libs/ardour/ardour/internal_send.h
@@ -42,7 +42,7 @@ class InternalSend : public Send
void cycle_start (pframes_t);
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
bool feeds (boost::shared_ptr<Route> other) const;
- bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
int set_block_size (pframes_t);
diff --git a/libs/ardour/ardour/meter.h b/libs/ardour/ardour/meter.h
index 4ac140fd04..df1e381bb4 100644
--- a/libs/ardour/ardour/meter.h
+++ b/libs/ardour/ardour/meter.h
@@ -56,7 +56,7 @@ public:
void reset ();
void reset_max ();
- bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
/* special method for meter, to ensure that it can always handle the maximum
@@ -75,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; }
diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h
index d6ad71863a..34fa0ae79a 100644
--- a/libs/ardour/ardour/midi_diskstream.h
+++ b/libs/ardour/ardour/midi_diskstream.h
@@ -125,6 +125,7 @@ class MidiDiskstream : public Diskstream
friend class MidiTrack;
int process (BufferSet&, framepos_t transport_frame, pframes_t nframes, framecnt_t &, bool need_diskstream);
+ frameoffset_t calculate_playback_distance (pframes_t nframes);
bool commit (framecnt_t nframes);
static framecnt_t midi_readahead;
diff --git a/libs/ardour/ardour/monitor_processor.h b/libs/ardour/ardour/monitor_processor.h
index 5b724b5e8d..64d3b86bfb 100644
--- a/libs/ardour/ardour/monitor_processor.h
+++ b/libs/ardour/ardour/monitor_processor.h
@@ -118,7 +118,7 @@ public:
int set_state (const XMLNode&, int /* version */);
bool configure_io (ChanCount in, ChanCount out);
- bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
void set_cut_all (bool);
void set_dim_all (bool);
diff --git a/libs/ardour/ardour/panner_shell.h b/libs/ardour/ardour/panner_shell.h
index 7d24adb46f..dba5826370 100644
--- a/libs/ardour/ardour/panner_shell.h
+++ b/libs/ardour/ardour/panner_shell.h
@@ -53,7 +53,7 @@ public:
std::string describe_parameter (Evoral::Parameter param);
- bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) const { return true; };
+ bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) { return true; };
void configure_io (ChanCount in, ChanCount out);
/// The fundamental Panner function
diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h
index 9e4f5c40fd..55b76fbb08 100644
--- a/libs/ardour/ardour/plugin.h
+++ b/libs/ardour/ardour/plugin.h
@@ -242,7 +242,7 @@ class Plugin : public PBD::StatefulDestructible, public Latent
/* specific types of plugins can overload this. As of September 2008, only
AUPlugin does this.
*/
- virtual bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) const { return false; }
+ virtual bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) { return false; }
virtual ChanCount output_streams() const;
virtual ChanCount input_streams() const;
diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h
index d80c759cff..a1b9c5a685 100644
--- a/libs/ardour/ardour/plugin_insert.h
+++ b/libs/ardour/ardour/plugin_insert.h
@@ -69,7 +69,7 @@ class PluginInsert : public Processor
bool set_count (uint32_t num);
uint32_t get_count () const { return _plugins.size(); }
- bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
bool has_no_inputs() const;
@@ -160,6 +160,8 @@ class PluginInsert : public Processor
BufferSet _signal_analysis_inputs;
BufferSet _signal_analysis_outputs;
+ ChanCount midi_bypass;
+
/** Description of how we can match our plugin's IO to our own insert IO */
struct Match {
Match () : method (Impossible), plugins (0) {}
@@ -170,7 +172,7 @@ class PluginInsert : public Processor
ChanCount hide; ///< number of channels to hide
};
- Match private_can_support_io_configuration (ChanCount const &, ChanCount &) const;
+ Match private_can_support_io_configuration (ChanCount const &, ChanCount &);
/** details of the match currently being used */
Match _match;
diff --git a/libs/ardour/ardour/port_insert.h b/libs/ardour/ardour/port_insert.h
index 657c2c0de6..abd9fb73cc 100644
--- a/libs/ardour/ardour/port_insert.h
+++ b/libs/ardour/ardour/port_insert.h
@@ -57,7 +57,7 @@ class PortInsert : public IOProcessor
bool set_name (const std::string& name);
- bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
void activate ();
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/processor.h b/libs/ardour/ardour/processor.h
index d497f56dd3..772ae3520d 100644
--- a/libs/ardour/ardour/processor.h
+++ b/libs/ardour/ardour/processor.h
@@ -82,7 +82,7 @@ class Processor : public SessionObject, public Automatable, public Latent
/* Derived classes should override these, or processor appears as an in-place pass-through */
- virtual bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const = 0;
+ virtual bool can_support_io_configuration (const ChanCount& in, ChanCount& out) = 0;
virtual ChanCount input_streams () const { return _configured_input; }
virtual ChanCount output_streams() const { return _configured_output; }
diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h
index 5716fa5105..e05efbd510 100644
--- a/libs/ardour/ardour/rc_configuration_vars.h
+++ b/libs/ardour/ardour/rc_configuration_vars.h
@@ -148,10 +148,13 @@ 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 (VUMeterStandard, meter_vu_standard, "meter-vu-standard", MeteringVUfrench)
+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)
+CONFIG_VARIABLE (bool, show_editor_meter, "show-editor-meter", true)
/* miscellany */
diff --git a/libs/ardour/ardour/return.h b/libs/ardour/ardour/return.h
index 55ca2d84f6..6dcd6ac2fc 100644
--- a/libs/ardour/ardour/return.h
+++ b/libs/ardour/ardour/return.h
@@ -56,7 +56,7 @@ public:
uint32_t pans_required() const { return _configured_input.n_audio(); }
- bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
static uint32_t how_many_returns();
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 2e44d00984..23f24cb275 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -530,6 +530,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
void silence_unlocked (framecnt_t);
ChanCount processor_max_streams;
+ ChanCount processor_out_streams;
uint32_t pans_required() const;
ChanCount n_process_buffers ();
@@ -553,8 +554,10 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
void output_change_handler (IOChange, void *src);
bool input_port_count_changing (ChanCount);
+ bool output_port_count_changing (ChanCount);
bool _in_configure_processors;
+ bool _initial_io_setup;
int configure_processors_unlocked (ProcessorStreams*);
std::list<std::pair<ChanCount, ChanCount> > try_configure_processors (ChanCount, ProcessorStreams *);
diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h
index fa023a3b68..1a21d1d050 100644
--- a/libs/ardour/ardour/send.h
+++ b/libs/ardour/ardour/send.h
@@ -56,7 +56,7 @@ class Send : public Delivery
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
- bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
void activate ();
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 4c005ffa74..a12f816c1e 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); }
@@ -1209,6 +1211,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
double ltc_enc_cnt;
framepos_t ltc_enc_off;
bool restarting;
+ framepos_t ltc_prev_cycle;
framepos_t ltc_timecode_offset;
bool ltc_timecode_negative_offset;
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..b6e5376c12 100644
--- a/libs/ardour/ardour/ticker.h
+++ b/libs/ardour/ardour/ticker.h
@@ -19,6 +19,7 @@
*/
#include <boost/noncopyable.hpp>
+#include <boost/scoped_ptr.hpp>
#include "pbd/signals.h"
@@ -42,7 +43,7 @@ class MidiClockTicker : public SessionHandlePtr, boost::noncopyable
{
public:
MidiClockTicker ();
- virtual ~MidiClockTicker() {};
+ virtual ~MidiClockTicker();
void tick (const framepos_t& transport_frames);
@@ -63,6 +64,9 @@ public:
/// slot for the signal session::TransportLooped
void transport_looped();
+ /// slot for the signal session::Located
+ void session_located();
+
/// pulses per quarter note (default 24)
void set_ppqn(int ppqn) { _ppqn = ppqn; }
@@ -71,12 +75,16 @@ private:
int _ppqn;
double _last_tick;
+ class Position;
+ boost::scoped_ptr<Position> _pos;
+
double one_ppqn_in_frames (framepos_t transport_position);
void send_midi_clock_event (pframes_t offset);
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 (uint32_t midi_clocks, pframes_t offset);
};
}
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index b00b03e060..2fb4ec9691 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -384,9 +384,10 @@ namespace ARDOUR {
};
enum VUMeterStandard {
- MeteringVUfrench, // + 2
- MeteringVUamerican, // +-0
- MeteringVUstandard // -4
+ MeteringVUfrench, // 0VU = -2dBu
+ MeteringVUamerican, // 0VU = 0dBu
+ MeteringVUstandard, // 0VU = +4dBu
+ MeteringVUeight // 0VU = +8dBu
};
enum MeterLineUp {
diff --git a/libs/ardour/ardour/unknown_processor.h b/libs/ardour/ardour/unknown_processor.h
index 36981030ce..61a5734df2 100644
--- a/libs/ardour/ardour/unknown_processor.h
+++ b/libs/ardour/ardour/unknown_processor.h
@@ -49,7 +49,7 @@ public:
return false;
}
- bool can_support_io_configuration (const ChanCount &, ChanCount &) const {
+ bool can_support_io_configuration (const ChanCount &, ChanCount &) {
return false;
}
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index 5c98271e5f..77c14de103 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -700,6 +700,31 @@ AudioDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t
return 0;
}
+frameoffset_t
+AudioDiskstream::calculate_playback_distance (pframes_t nframes)
+{
+ frameoffset_t playback_distance = nframes;
+
+ if (record_enabled()) {
+ playback_distance = nframes;
+ } else if (_actual_speed != 1.0f && _actual_speed != -1.0f) {
+ interpolation.set_speed (_target_speed);
+ boost::shared_ptr<ChannelList> c = channels.reader();
+ int channel = 0;
+ for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan, ++channel) {
+ playback_distance = interpolation.interpolate (channel, nframes, NULL, NULL);
+ }
+ } else {
+ playback_distance = nframes;
+ }
+
+ if (_actual_speed < 0.0) {
+ return -playback_distance;
+ } else {
+ return playback_distance;
+ }
+}
+
/** Update various things including playback_sample, read pointer on each channel's playback_buf
* and write pointer on each channel's capture_buf. Also wout whether the butler is needed.
* @return true if the butler is required.
@@ -900,7 +925,7 @@ AudioDiskstream::internal_playback_seek (framecnt_t distance)
boost::shared_ptr<ChannelList> c = channels.reader();
for (chan = c->begin(); chan != c->end(); ++chan) {
- (*chan)->playback_buf->increment_read_ptr (distance);
+ (*chan)->playback_buf->increment_read_ptr (llabs(distance));
}
if (first_recordable_frame < max_framepos) {
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 4b33bbd4c6..0530dbfce9 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -313,6 +313,12 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
if (!lm.locked()) {
+ boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
+ framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes);
+ if (can_internal_playback_seek(llabs(playback_distance))) {
+ /* TODO should declick */
+ internal_playback_seek(playback_distance);
+ }
return 0;
}
@@ -353,7 +359,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 20a55e49f9..538a905ca2 100644
--- a/libs/ardour/audio_unit.cc
+++ b/libs/ardour/audio_unit.cc
@@ -998,7 +998,7 @@ AUPlugin::output_streams() const
}
bool
-AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
+AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
// Note: We never attempt to multiply-instantiate plugins to meet io configurations.
@@ -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 74dd52d504..84a5b687f9 100644
--- a/libs/ardour/audiosource.cc
+++ b/libs/ardour/audiosource.cc
@@ -182,7 +182,7 @@ AudioSource::touch_peakfile ()
struct utimbuf tbuf;
tbuf.actime = statbuf.st_atime;
- tbuf.modtime = time ((time_t) 0);
+ tbuf.modtime = time ((time_t*) 0);
utime (peakpath.c_str(), &tbuf);
}
diff --git a/libs/ardour/capturing_processor.cc b/libs/ardour/capturing_processor.cc
index f14e018097..ce4a546fb4 100644
--- a/libs/ardour/capturing_processor.cc
+++ b/libs/ardour/capturing_processor.cc
@@ -62,7 +62,7 @@ CapturingProcessor::configure_io (ChanCount in, ChanCount out)
}
bool
-CapturingProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
+CapturingProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in;
return true;
diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc
index 9eaf843f7c..dfbe4c960a 100644
--- a/libs/ardour/delivery.cc
+++ b/libs/ardour/delivery.cc
@@ -124,7 +124,7 @@ Delivery::display_name () const
}
bool
-Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
+Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
if (_role == Main) {
diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc
index e60977a3e5..ab181d2956 100644
--- a/libs/ardour/enums.cc
+++ b/libs/ardour/enums.cc
@@ -226,6 +226,7 @@ setup_enum_writer ()
REGISTER_ENUM (MeteringVUfrench);
REGISTER_ENUM (MeteringVUamerican);
REGISTER_ENUM (MeteringVUstandard);
+ REGISTER_ENUM (MeteringVUeight);
REGISTER (_VUMeterStandard);
REGISTER_ENUM (MeteringLineUp24);
diff --git a/libs/ardour/internal_return.cc b/libs/ardour/internal_return.cc
index af6b6110b6..fc5963603b 100644
--- a/libs/ardour/internal_return.cc
+++ b/libs/ardour/internal_return.cc
@@ -80,7 +80,7 @@ InternalReturn::get_state()
}
bool
-InternalReturn::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
+InternalReturn::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in;
return true;
diff --git a/libs/ardour/internal_send.cc b/libs/ardour/internal_send.cc
index 4b8c469a9d..8136985e1f 100644
--- a/libs/ardour/internal_send.cc
+++ b/libs/ardour/internal_send.cc
@@ -284,7 +284,7 @@ InternalSend::connect_when_legal ()
}
bool
-InternalSend::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
+InternalSend::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in;
return true;
diff --git a/libs/ardour/kmeterdsp.cc b/libs/ardour/kmeterdsp.cc
index d4460f94cb..181378cf76 100644
--- a/libs/ardour/kmeterdsp.cc
+++ b/libs/ardour/kmeterdsp.cc
@@ -49,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.
{
diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc
index 1ab00e0b34..5a6e577f2d 100644
--- a/libs/ardour/ladspa_plugin.cc
+++ b/libs/ardour/ladspa_plugin.cc
@@ -562,7 +562,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 1f0859bc8d..95a29b7c8f 100644
--- a/libs/ardour/lv2_plugin.cc
+++ b/libs/ardour/lv2_plugin.cc
@@ -970,7 +970,7 @@ LV2Plugin::find_presets()
lilv_node_as_string(name))));
} else {
warning << string_compose(
- _("Plugin \"%1\% preset \"%2%\" is missing a label\n"),
+ _("Plugin \"%1\" preset \"%2\" is missing a label\n"),
lilv_node_as_string(lilv_plugin_get_uri(_impl->plugin)),
lilv_node_as_string(preset)) << endmsg;
}
@@ -1651,7 +1651,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 cc014caf63..a7857f5859 100644
--- a/libs/ardour/meter.cc
+++ b/libs/ardour/meter.cc
@@ -43,6 +43,8 @@ PeakMeter::PeakMeter (Session& s, const std::string& name)
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 ()
@@ -163,7 +165,7 @@ PeakMeter::reset_max ()
}
bool
-PeakMeter::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
+PeakMeter::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in;
return true;
@@ -186,20 +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());
-
- 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 (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();
+ }
- reset();
+ current_meters = in;
reset_max();
ConfigurationChanged (in, in); /* EMIT SIGNAL */
@@ -268,7 +270,17 @@ 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());
@@ -325,6 +337,8 @@ PeakMeter::meter ()
}
}
+#define CHECKSIZE(MTR) (n < MTR.size() + n_midi && n >= n_midi)
+
float
PeakMeter::meter_level(uint32_t n, MeterType type) {
switch (type) {
@@ -333,7 +347,7 @@ PeakMeter::meter_level(uint32_t n, MeterType type) {
case MeterK14:
{
const uint32_t n_midi = current_meters.n_midi();
- if ((n - n_midi) < _kmeter.size() && (n - n_midi) >= 0) {
+ if (CHECKSIZE(_kmeter)) {
return accurate_coefficient_to_dB (_kmeter[n - n_midi]->read());
}
}
@@ -342,7 +356,7 @@ PeakMeter::meter_level(uint32_t n, MeterType type) {
case MeterIEC1NOR:
{
const uint32_t n_midi = current_meters.n_midi();
- if ((n - n_midi) < _iec1meter.size() && (n - n_midi) >= 0) {
+ if (CHECKSIZE(_iec1meter)) {
return accurate_coefficient_to_dB (_iec1meter[n - n_midi]->read());
}
}
@@ -351,7 +365,7 @@ PeakMeter::meter_level(uint32_t n, MeterType type) {
case MeterIEC2EBU:
{
const uint32_t n_midi = current_meters.n_midi();
- if ((n - n_midi) < _iec2meter.size() && (n - n_midi) >= 0) {
+ if (CHECKSIZE(_iec2meter)) {
return accurate_coefficient_to_dB (_iec2meter[n - n_midi]->read());
}
}
@@ -359,7 +373,7 @@ PeakMeter::meter_level(uint32_t n, MeterType type) {
case MeterVU:
{
const uint32_t n_midi = current_meters.n_midi();
- if ((n - n_midi) < _vumeter.size() && (n - n_midi) >= 0) {
+ if (CHECKSIZE(_vumeter)) {
return accurate_coefficient_to_dB (_vumeter[n - n_midi]->read());
}
}
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index ff6147d285..e67ce9b831 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -517,6 +517,20 @@ MidiDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t
return 0;
}
+frameoffset_t
+MidiDiskstream::calculate_playback_distance (pframes_t nframes)
+{
+ frameoffset_t playback_distance = nframes;
+
+ /* XXX: should be doing varispeed stuff once it's implemented in ::process() above */
+
+ if (_actual_speed < 0.0) {
+ return -playback_distance;
+ } else {
+ return playback_distance;
+ }
+}
+
bool
MidiDiskstream::commit (framecnt_t playback_distance)
{
diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc
index c7768c7249..f88c331c2c 100644
--- a/libs/ardour/midi_track.cc
+++ b/libs/ardour/midi_track.cc
@@ -319,6 +319,12 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame
{
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
if (!lm.locked()) {
+ boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
+ framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes);
+ if (can_internal_playback_seek(llabs(playback_distance))) {
+ /* TODO should declick, and/or note-off */
+ internal_playback_seek(playback_distance);
+ }
return 0;
}
@@ -353,7 +359,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/monitor_processor.cc b/libs/ardour/monitor_processor.cc
index e55428b666..ed06647860 100644
--- a/libs/ardour/monitor_processor.cc
+++ b/libs/ardour/monitor_processor.cc
@@ -355,7 +355,7 @@ MonitorProcessor::configure_io (ChanCount in, ChanCount out)
}
bool
-MonitorProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
+MonitorProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in;
return true;
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index c5d52f7345..bb79801c9f 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -250,7 +250,7 @@ Playlist::Playlist (boost::shared_ptr<const Playlist> other, framepos_t start, f
plist.add (Properties::layer, region->layer());
plist.add (Properties::layering_index, region->layering_index());
- new_region = RegionFactory::RegionFactory::create (region, plist);
+ new_region = RegionFactory::create (region, plist);
add_region_internal (new_region, position);
}
@@ -284,7 +284,7 @@ Playlist::copy_regions (RegionList& newlist) const
RegionReadLock rlock (const_cast<Playlist *> (this));
for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
- newlist.push_back (RegionFactory::RegionFactory::create (*i, true));
+ newlist.push_back (RegionFactory::create (*i, true));
}
}
diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc
index 998a03e3aa..b191cf4890 100644
--- a/libs/ardour/plugin_insert.cc
+++ b/libs/ardour/plugin_insert.cc
@@ -145,7 +145,7 @@ PluginInsert::output_streams() const
ChanCount out = info->n_outputs;
// DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
out.set_audio (out.n_audio() * _plugins.size());
- out.set_midi (out.n_midi() * _plugins.size());
+ out.set_midi (out.n_midi() * _plugins.size() + midi_bypass.n_midi());
return out;
}
}
@@ -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);
}
}
@@ -465,7 +465,6 @@ PluginInsert::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end
}
} else {
-
if (has_no_audio_inputs()) {
/* silence all (audio) outputs. Should really declick
@@ -704,7 +703,7 @@ PluginInsert::configure_io (ChanCount in, ChanCount out)
* @return true if the given IO configuration can be supported.
*/
bool
-PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
+PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
return private_can_support_io_configuration (in, out).method != Impossible;
}
@@ -714,9 +713,11 @@ PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
* it can be.
*/
PluginInsert::Match
-PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCount& out) const
+PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out)
{
PluginInfoPtr info = _plugins.front()->get_info();
+ ChanCount in; in += inx;
+ midi_bypass.reset();
if (info->reconfigurable_io()) {
/* Plugin has flexible I/O, so delegate to it */
@@ -731,6 +732,15 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo
ChanCount inputs = info->n_inputs;
ChanCount outputs = info->n_outputs;
+ if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
+ DEBUG_TRACE ( DEBUG::Processors, string_compose ("bypassing midi-data around %1\n", name()));
+ midi_bypass.set(DataType::MIDI, 1);
+ }
+ if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
+ DEBUG_TRACE ( DEBUG::Processors, string_compose ("hiding midi-port from plugin %1\n", name()));
+ in.set(DataType::MIDI, 0);
+ }
+
bool no_inputs = true;
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
if (inputs.get (*t) != 0) {
@@ -741,13 +751,13 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo
if (no_inputs) {
/* no inputs so we can take any input configuration since we throw it away */
- out = outputs;
+ out = outputs + midi_bypass;
return Match (NoInputs, 1);
}
/* Plugin inputs match requested inputs exactly */
if (inputs == in) {
- out = outputs;
+ out = outputs + midi_bypass;
return Match (ExactMatch, 1);
}
@@ -789,6 +799,7 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
out.set (*t, outputs.get(*t) * f);
}
+ out += midi_bypass;
return Match (Replicate, f);
}
@@ -812,7 +823,7 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo
}
if (can_split) {
- out = outputs;
+ out = outputs + midi_bypass;
return Match (Split, 1);
}
@@ -836,10 +847,11 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo
}
if (could_hide && !cannot_hide) {
- out = outputs;
+ out = outputs + midi_bypass;
return Match (Hide, 1, hide_channels);
}
+ midi_bypass.reset();
return Match (Impossible, 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/port_insert.cc b/libs/ardour/port_insert.cc
index b7f74b458e..d64920b1e2 100644
--- a/libs/ardour/port_insert.cc
+++ b/libs/ardour/port_insert.cc
@@ -266,7 +266,7 @@ PortInsert::configure_io (ChanCount in, ChanCount out)
}
bool
-PortInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
+PortInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in;
return true;
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/return.cc b/libs/ardour/return.cc
index 921be6a53a..4f9e8b958a 100644
--- a/libs/ardour/return.cc
+++ b/libs/ardour/return.cc
@@ -136,7 +136,7 @@ Return::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pfra
}
bool
-Return::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
+Return::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in + _input->n_ports();
return true;
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index eabfbaacc0..8e0ac8604e 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -98,9 +98,13 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
, _default_type (default_type)
, _remote_control_id (0)
, _in_configure_processors (false)
+ , _initial_io_setup (false)
, _custom_meter_position_noted (false)
, _last_custom_meter_was_at_end (false)
{
+ if (is_master()) {
+ _meter_type = MeterK20;
+ }
processor_max_streams.reset();
}
@@ -133,6 +137,7 @@ Route::init ()
_input->PortCountChanging.connect_same_thread (*this, boost::bind (&Route::input_port_count_changing, this, _1));
_output->changed.connect_same_thread (*this, boost::bind (&Route::output_change_handler, this, _1, _2));
+ _output->PortCountChanging.connect_same_thread (*this, boost::bind (&Route::output_port_count_changing, this, _1));
/* add amp processor */
@@ -540,11 +545,10 @@ Route::process_output_buffers (BufferSet& bufs,
if (bufs.count() != (*i)->input_streams()) {
DEBUG_TRACE (
DEBUG::Processors, string_compose (
- "%1 bufs = %2 input for %3 = %4\n",
+ "input port mismatch %1 bufs = %2 input for %3 = %4\n",
_name, bufs.count(), (*i)->name(), (*i)->input_streams()
)
);
- continue;
}
}
#endif
@@ -568,7 +572,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 +598,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);
@@ -1651,7 +1655,8 @@ Route::try_configure_processors_unlocked (ChanCount in, ProcessorStreams* err)
if (boost::dynamic_pointer_cast<UnknownProcessor> (*p)) {
DEBUG_TRACE (DEBUG::Processors, "--- CONFIGURE ABORTED due to unknown processor.\n");
- break;
+ DEBUG_TRACE (DEBUG::Processors, "}\n");
+ return list<pair<ChanCount, ChanCount> > ();
}
if ((*p)->can_support_io_configuration(in, out)) {
@@ -1701,6 +1706,9 @@ Route::configure_processors_unlocked (ProcessorStreams* err)
}
ChanCount out;
+ bool seen_mains_out = false;
+ processor_out_streams = _input->n_ports();
+ processor_max_streams.reset();
list< pair<ChanCount,ChanCount> >::iterator c = configuration.begin();
for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++c) {
@@ -1713,8 +1721,21 @@ Route::configure_processors_unlocked (ProcessorStreams* err)
processor_max_streams = ChanCount::max(processor_max_streams, c->first);
processor_max_streams = ChanCount::max(processor_max_streams, c->second);
out = c->second;
+
+ if (boost::dynamic_pointer_cast<Delivery> (*p)
+ && boost::dynamic_pointer_cast<Delivery> (*p)->role() == Delivery::Main) {
+ /* main delivery will increase port count to match input.
+ * the Delivery::Main is usually the last processor - followed only by
+ * 'MeterOutput'.
+ */
+ seen_mains_out = true;
+ }
+ if (!seen_mains_out) {
+ processor_out_streams = out;
+ }
}
+
if (_meter) {
_meter->reset_max_channels (processor_max_streams);
}
@@ -1992,6 +2013,7 @@ Route::set_state (const XMLNode& node, int version)
}
set_id (node);
+ _initial_io_setup = true;
if ((prop = node.property (X_("flags"))) != 0) {
_flags = Flag (string_2_enum (prop->value(), _flags));
@@ -2059,6 +2081,8 @@ Route::set_state (const XMLNode& node, int version)
_meter_type = MeterType (string_2_enum (prop->value (), _meter_type));
}
+ _initial_io_setup = false;
+
set_processor_state (processor_state);
// this looks up the internal instrument in processors
@@ -2939,6 +2963,9 @@ void
Route::output_change_handler (IOChange change, void * /*src*/)
{
bool need_to_queue_solo_change = true;
+ if (_initial_io_setup) {
+ return;
+ }
if ((change.type & IOChange::ConfigurationChanged)) {
/* This is called with the process lock held if change
@@ -3013,7 +3040,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);
@@ -3052,7 +3079,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);
@@ -3152,9 +3179,6 @@ Route::set_meter_point (MeterPoint p, bool force)
*/
}
- _meter->reset();
- _meter->reset_max();
-
meter_change (); /* EMIT SIGNAL */
bool const meter_visibly_changed = (_meter->display_to_user() != meter_was_visible_to_user);
@@ -3754,6 +3778,19 @@ Route::input_port_count_changing (ChanCount to)
return false;
}
+/** Called when there is a proposed change to the output port count */
+bool
+Route::output_port_count_changing (ChanCount to)
+{
+ for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+ if (processor_out_streams.get(*t) > to.get(*t)) {
+ return true;
+ }
+ }
+ /* The change is ok */
+ return false;
+}
+
list<string>
Route::unknown_processors () const
{
diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc
index 107cf9862b..e74fd7f8ce 100644
--- a/libs/ardour/send.cc
+++ b/libs/ardour/send.cc
@@ -270,7 +270,7 @@ Send::set_state_2X (const XMLNode& node, int /* version */)
}
bool
-Send::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
+Send::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
/* sends have no impact at all on the channel configuration of the
streams passing through the route. so, out == in.
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index e1634db536..9667bbcd2c 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -4170,12 +4170,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_ltc.cc b/libs/ardour/session_ltc.cc
index 11c97ba147..d52d9e919a 100644
--- a/libs/ardour/session_ltc.cc
+++ b/libs/ardour/session_ltc.cc
@@ -82,6 +82,7 @@ Session::ltc_tx_initialize()
* since the fps can change and A3's min fps: 24000/1001 */
ltc_enc_buf = (ltcsnd_sample_t*) calloc((nominal_frame_rate() / 23), sizeof(ltcsnd_sample_t));
ltc_speed = 0;
+ ltc_prev_cycle = -1;
ltc_tx_reset();
ltc_tx_resync_latency();
Xrun.connect_same_thread (*this, boost::bind (&Session::ltc_tx_reset, this));
@@ -132,6 +133,7 @@ Session::ltc_tx_parse_offset() {
offset_tc.drop = timecode_drop_frames();
timecode_to_sample(offset_tc, ltc_timecode_offset, false, false);
ltc_timecode_negative_offset = !offset_tc.negative;
+ ltc_prev_cycle = -1;
}
void
@@ -214,7 +216,7 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
if (cur_timecode != ltc_enc_tcformat) {
DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX1: TC format mismatch - reinit sr: %1 fps: %2\n", nominal_frame_rate(), timecode_to_frames_per_second(cur_timecode)));
if (ltc_encoder_reinit(ltc_encoder, nominal_frame_rate(),
- timecode_to_frames_per_second(cur_timecode),
+ timecode_to_frames_per_second(cur_timecode),
TV_STANDARD(cur_timecode), 0
)) {
PBD::error << _("LTC encoder: invalid framerate - LTC encoding is disabled for the remainder of this session.") << endmsg;
@@ -244,10 +246,25 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
* The _generated timecode_ is offset by the port-latency,
* therefore the offset depends on the direction of transport.
*/
- framepos_t cycle_start_frame = (current_speed < 0) ? (start_frame - ltc_out_latency.max) : (start_frame + ltc_out_latency.max);
+ framepos_t cycle_start_frame;
+
+ if (current_speed < 0) {
+ cycle_start_frame = (start_frame - ltc_out_latency.max);
+ } else if (current_speed > 0) {
+ cycle_start_frame = (start_frame + ltc_out_latency.max);
+ } else {
+ /* There is no need to compensate for latency when not rolling
+ * rather send the accurate NOW timecode
+ * (LTC encoder compenates latency by sending earlier timecode)
+ */
+ cycle_start_frame = start_frame;
+ }
/* LTC TV standard offset */
- cycle_start_frame -= ltc_frame_alignment(frames_per_timecode_frame(), TV_STANDARD(cur_timecode));
+ if (current_speed != 0) {
+ /* ditto - send "NOW" if not rolling */
+ cycle_start_frame -= ltc_frame_alignment(frames_per_timecode_frame(), TV_STANDARD(cur_timecode));
+ }
/* cycle-start may become negative due to latency compensation */
if (cycle_start_frame < 0) { cycle_start_frame = 0; }
@@ -262,7 +279,13 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
ltc_tx_reset();
}
- if (ltc_speed != new_ltc_speed) {
+ if (ltc_speed != new_ltc_speed
+ /* but only once if, current_speed changes to 0. In that case
+ * new_ltc_speed is > 0 because (end_frame - start_frame) == jack-period for no-roll
+ * but ltc_speed will still be 0
+ */
+ && (current_speed != 0 || ltc_speed != current_speed)
+ ) {
/* check ./libs/ardour/interpolation.cc CubicInterpolation::interpolate
* if target_speed != current_speed we should interpolate, too.
*
@@ -272,7 +295,7 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
* end_frame is calculated from 'frames_moved' which includes the interpolation.
* so we're good.
*/
- DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX2: speed change old: %1 cur: %2 tgt: %3 ctd: %4\n", ltc_speed, current_speed, target_speed, fabs(current_speed) - target_speed));
+ DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX2: speed change old: %1 cur: %2 tgt: %3 ctd: %4\n", ltc_speed, current_speed, target_speed, fabs(current_speed) - target_speed, new_ltc_speed));
speed_changed = true;
ltc_encoder_set_filter(ltc_encoder, LTC_RISE_TIME(new_ltc_speed));
}
@@ -292,6 +315,10 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
ltc_speed = new_ltc_speed;
return;
}
+ if (start_frame != ltc_prev_cycle) {
+ DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX2: no-roll seek from %1 to %2 (%3)\n", ltc_prev_cycle, start_frame, cycle_start_frame));
+ ltc_tx_reset();
+ }
}
if (fabs(new_ltc_speed) > 10.0) {
@@ -375,6 +402,7 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
}
}
+ ltc_prev_cycle = start_frame;
ltc_speed = new_ltc_speed;
DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX2: transport speed %1.\n", ltc_speed));
@@ -400,6 +428,9 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
/* difference between current frame and TC frame in samples */
frameoffset_t soff = cycle_start_frame - tc_sample_start;
+ if (current_speed == 0) {
+ soff = 0;
+ }
DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX3: A3cycle: %1 = A3tc: %2 +off: %3\n",
cycle_start_frame, tc_sample_start, soff));
@@ -501,7 +532,7 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
restarting = true;
}
- if (cyc_off > 0 && cyc_off <= nframes) {
+ if (cyc_off >= 0 && cyc_off <= nframes) {
/* offset in this cycle */
txf= rint(cyc_off / fabs(ltc_speed));
memset(out, 0, cyc_off * sizeof(Sample));
diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc
index 50a7178f1b..d137e5167c 100644
--- a/libs/ardour/session_midi.cc
+++ b/libs/ardour/session_midi.cc
@@ -45,6 +45,7 @@
#include "ardour/midi_ui.h"
#include "ardour/session.h"
#include "ardour/slave.h"
+#include "ardour/ticker.h"
#include "i18n.h"
@@ -581,6 +582,19 @@ Session::mmc_step_timeout ()
return true;
}
+/***********************************************************************
+ OUTBOUND SYSTEM COMMON STUFF
+**********************************************************************/
+
+
+void
+Session::send_song_position_pointer (framepos_t t)
+{
+ if (midi_clock) {
+ /* Do nothing for the moment */
+ }
+}
+
int
Session::start_midi_thread ()
{
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 0b0351f506..08e9a89481 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -384,6 +384,7 @@ Session::butler_transport_work ()
g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
DEBUG_TRACE (DEBUG::Transport, X_("Butler transport work all done\n"));
+ DEBUG_TRACE (DEBUG::Transport, X_(string_compose ("Frame %1\n", _transport_frame)));
}
void
@@ -1007,6 +1008,7 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
send_mmc_locate (_transport_frame);
}
+ _last_roll_location = _last_roll_or_reversal_location = _transport_frame;
Located (); /* EMIT SIGNAL */
}
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..f32cdf9415 100644
--- a/libs/ardour/ticker.cc
+++ b/libs/ardour/ticker.cc
@@ -32,15 +32,84 @@
#include "ardour/debug.h"
using namespace ARDOUR;
+using namespace PBD;
+
+/** MIDI Clock Position tracking */
+class MidiClockTicker::Position : public Timecode::BBT_Time
+{
+public:
+
+ Position() : speed(0.0f), frame(0) { }
+ ~Position() { }
+
+ /** Sync timing information taken from the given Session
+ @return True if timings differed */
+ bool sync (Session* s) {
+
+ bool didit = false;
+
+ double sp = s->transport_speed();
+ framecnt_t fr = s->transport_frame();
+
+ if (speed != sp) {
+ speed = sp;
+ didit = true;
+ }
+
+ if (frame != fr) {
+ frame = fr;
+ didit = true;
+ }
+
+ /* Midi beats and clocks always gets updated for now */
+
+ s->bbt_time (this->frame, *this);
+
+ const TempoMap& tempo = s->tempo_map();
+
+ const double divisions = tempo.meter_at(frame).divisions_per_bar();
+ const double divisor = tempo.meter_at(frame).note_divisor();
+ const double qnote_scale = divisor * 0.25f;
+
+ /** Midi Beats in terms of Song Position Pointer is equivalent to total
+ sixteenth notes at 'time' */
+
+ midi_beats = (((bars - 1) * divisions) + beats - 1);
+ midi_beats += (double)ticks / (double)Position::ticks_per_beat * qnote_scale;
+ midi_beats *= 16.0f / divisor;
+
+ midi_clocks = midi_beats * 6.0f;
+
+ return didit;
+ }
+
+ double speed;
+ framecnt_t frame;
+ double midi_beats;
+ double midi_clocks;
+
+ void print (std::ostream& s) {
+ s << "frames: " << frame << " midi beats: " << midi_beats << " speed: " << speed;
+ }
+};
+
MidiClockTicker::MidiClockTicker ()
: _midi_port (0)
, _ppqn (24)
, _last_tick (0.0)
{
+ _pos.reset (new Position());
+}
+
+MidiClockTicker::~MidiClockTicker()
+{
+ _midi_port = 0;
+ _pos.reset (0);
}
-void MidiClockTicker::set_session (Session* s)
+void
+MidiClockTicker::set_session (Session* s)
{
SessionHandlePtr::set_session (s);
@@ -48,23 +117,67 @@ void MidiClockTicker::set_session (Session* s)
_session->TransportStateChange.connect_same_thread (_session_connections, boost::bind (&MidiClockTicker::transport_state_changed, this));
_session->PositionChanged.connect_same_thread (_session_connections, boost::bind (&MidiClockTicker::position_changed, this, _1));
_session->TransportLooped.connect_same_thread (_session_connections, boost::bind (&MidiClockTicker::transport_looped, this));
+ _session->Located.connect_same_thread (_session_connections, boost::bind (&MidiClockTicker::session_located, this));
+
update_midi_clock_port();
+ _pos->sync (_session);
}
}
void
+MidiClockTicker::session_located()
+{
+ DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Session Located: %1, speed: %2\n", _session->transport_frame(), _session->transport_speed()));
+
+ if (0 == _session || ! _pos->sync (_session)) {
+ return;
+ }
+
+ _last_tick = _pos->frame;
+
+ if (!Config->get_send_midi_clock()) {
+ return;
+ }
+
+ if (_pos->speed == 0.0f) {
+ uint32_t where = llrint (_pos->midi_beats);
+ send_position_event (where, 0);
+ } else if (_pos->speed == 1.0f) {
+#if 1
+ /* Experimental. To really do this and have accuracy, the
+ stop/locate/continue sequence would need queued to send immediately
+ before the next midi clock. */
+
+ send_stop_event (0);
+
+ if (_pos->frame == 0) {
+ send_start_event (0);
+ } else {
+ uint32_t where = llrint (_pos->midi_beats);
+ send_position_event (where, 0);
+ send_continue_event (0);
+ }
+#endif
+ } else {
+ /* Varispeed not supported */
+ }
+}
+
+void
MidiClockTicker::session_going_away ()
{
SessionHandlePtr::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 */
@@ -76,57 +189,70 @@ void MidiClockTicker::transport_state_changed()
return;
}
- float speed = _session->transport_speed();
- framepos_t position = _session->transport_frame();
+ if (! _pos->sync (_session)) {
+ return;
+ }
- 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)
- );
+ DEBUG_TRACE (DEBUG::MidiClock,
+ string_compose ("Transport state change @ %4, speed: %1 position: %2 play loop: %3\n",
+ _pos->speed, _pos->frame, _session->get_play_loop(), _pos->frame)
+ );
- if (speed == 1.0f) {
- _last_tick = position;
+ _last_tick = _pos->frame;
+
+ if (! Config->get_send_midi_clock()) {
+ return;
+ }
- if (!Config->get_send_midi_clock())
- return;
+ if (_pos->speed == 1.0f) {
if (_session->get_play_loop()) {
assert(_session->locations()->auto_loop_location());
- if (position == _session->locations()->auto_loop_location()->start()) {
+
+ if (_pos->frame == _session->locations()->auto_loop_location()->start()) {
send_start_event(0);
} else {
send_continue_event(0);
}
- } else if (position == 0) {
+
+ } else if (_pos->frame == 0) {
send_start_event(0);
} else {
send_continue_event(0);
}
- send_midi_clock_event(0);
+ // send_midi_clock_event (0);
- } else if (speed == 0.0f) {
- if (!Config->get_send_midi_clock())
- return;
-
- send_stop_event(0);
+ } else if (_pos->speed == 0.0f) {
+ send_stop_event (0);
+ send_position_event (llrint (_pos->midi_beats), 0);
}
- tick (position);
+ // tick (_pos->frame);
}
-void MidiClockTicker::position_changed (framepos_t position)
+void
+MidiClockTicker::position_changed (framepos_t)
{
- DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Position change: %1\n", position));
+#if 0
+ const double speed = _session->transport_speed();
+ DEBUG_TRACE (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;
+#endif
}
-void MidiClockTicker::transport_looped()
+void
+MidiClockTicker::transport_looped()
{
Location* loop_location = _session->locations()->auto_loop_location();
assert(loop_location);
- DEBUG_TRACE (PBD::DEBUG::MidiClock,
+ DEBUG_TRACE (DEBUG::MidiClock,
string_compose ("Transport looped, position: %1, loop start: %2, loop end: %3, play loop: %4\n",
_session->transport_frame(), loop_location->start(), loop_location->end(), _session->get_play_loop())
);
@@ -143,21 +269,29 @@ 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;
}
+ MIDI::JackMIDIPort* mp = dynamic_cast<MIDI::JackMIDIPort*> (_midi_port);
+ if (! mp) {
+ return;
+ }
+
+ const framepos_t end = _pos->frame + mp->nframes_this_cycle();
+ double iter = _last_tick;
+
while (true) {
- double next_tick = _last_tick + one_ppqn_in_frames (transport_frame);
- frameoffset_t next_tick_offset = llrint (next_tick) - transport_frame;
+ double clock_delta = one_ppqn_in_frames (llrint (iter));
+ double next_tick = iter + clock_delta;
+ frameoffset_t next_tick_offset = llrint (next_tick) - end;
- 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));
+ DEBUG_TRACE (DEBUG::MidiClock,
+ string_compose ("Tick: iter: %1, last tick time: %2, next tick time: %3, offset: %4, cycle length: %5\n",
+ iter, _last_tick, next_tick, next_tick_offset, mp ? mp->nframes_this_cycle() : 0));
if (!mp || (next_tick_offset >= mp->nframes_this_cycle())) {
break;
@@ -167,11 +301,16 @@ void MidiClockTicker::tick (const framepos_t& transport_frame)
send_midi_clock_event (next_tick_offset);
}
- _last_tick = next_tick;
+ iter = next_tick;
}
+
+ _last_tick = iter;
+ _pos->frame = end;
}
-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 +321,77 @@ 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 (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 (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 (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 (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 (uint32_t midi_beats, pframes_t offset)
+{
+ if (!_midi_port) {
+ return;
+ }
+ /* can only use 14bits worth */
+ if (midi_beats > 0x3fff) {
+ return;
+ }
+
+ /* split midi beats into a 14bit value */
+ MIDI::byte msg[3];
+ msg[0] = MIDI_CMD_COMMON_SONG_POS;
+ msg[1] = midi_beats & 0x007f;
+ msg[2] = midi_beats >> 7;
+ _midi_port->midimsg (msg, sizeof (msg), offset);
+
+ DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Song Position Sent: %1\n", midi_beats));
+}
diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc
index c6a348ddfb..f02863393e 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);
@@ -473,6 +477,10 @@ Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*
{
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
if (!lm.locked()) {
+ framecnt_t playback_distance = _diskstream->calculate_playback_distance(nframes);
+ if (can_internal_playback_seek(playback_distance)) {
+ internal_playback_seek(playback_distance);
+ }
return 0;
}
@@ -492,7 +500,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/gtkmm2ext/fastmeter.cc b/libs/gtkmm2ext/fastmeter.cc
index 817b11ff6c..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,31 +208,49 @@ FastMeter::generate_meter_pattern (
cairo_set_source (tc, pat);
cairo_rectangle (tc, 0, 0, width, height);
cairo_fill (tc);
-
- cairo_save (tc);
- cairo_set_line_width(tc, 1.0);
- cairo_set_source_rgba(tc, .1, .1, .1, .5);
- //cairo_set_operator (tc, CAIRO_OPERATOR_SOURCE);
- for (float y=.5; y < height; y+= 2.0) {
- cairo_move_to(tc, 0, y);
- cairo_line_to(tc, width, y);
- cairo_stroke (tc);
- }
- cairo_restore (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;
@@ -222,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;
@@ -263,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;
@@ -270,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()) {
@@ -290,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;
@@ -300,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;
@@ -313,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)
@@ -337,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);
@@ -346,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);
}
@@ -361,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;
@@ -370,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
@@ -390,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);
@@ -425,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 ));
+ }
+
+ 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);
+ 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.height = max(0, min(2, pixheight - last_peak_rect.y -1 ));
+ 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, 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);
@@ -456,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;
@@ -487,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
@@ -550,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 ));
}
@@ -569,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/pbd/cocoa_open_uri.mm b/libs/pbd/cocoa_open_uri.mm
index 2c6822ac94..90a3995d71 100644
--- a/libs/pbd/cocoa_open_uri.mm
+++ b/libs/pbd/cocoa_open_uri.mm
@@ -1,6 +1,7 @@
#include <CoreFoundation/CFLocale.h>
#import <CoreFoundation/CFString.h>
#import <Foundation/NSString.h>
+#import <Foundation/NSURL.h>
#import <Foundation/NSAutoreleasePool.h>
#import <AppKit/NSWorkspace.h>
diff --git a/libs/pbd/pbd/ringbuffer.h b/libs/pbd/pbd/ringbuffer.h
index f14fa71851..652457b493 100644
--- a/libs/pbd/pbd/ringbuffer.h
+++ b/libs/pbd/pbd/ringbuffer.h
@@ -233,6 +233,7 @@ RingBuffer<T>::get_read_vector (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/pbd/wscript b/libs/pbd/wscript
index 5c8ed194a8..0655e1ca48 100644
--- a/libs/pbd/wscript
+++ b/libs/pbd/wscript
@@ -128,12 +128,13 @@ def build(bld):
obj.uselib = 'GLIBMM SIGCPP XML UUID SNDFILE GIOMM'
if sys.platform == 'darwin':
TaskGen.task_gen.mappings['.mm'] = TaskGen.task_gen.mappings['.cc']
- obj.source += [ 'cocoa_open_uri.mm' ]
+ if 'cocoa_open_uri.mm' not in obj.source:
+ obj.source += [ 'cocoa_open_uri.mm' ]
obj.uselib += ' OSX'
obj.vnum = LIBPBD_LIB_VERSION
obj.install_path = os.path.join(bld.env['LIBDIR'], 'ardour3')
obj.defines = ['PACKAGE="' + I18N_PACKAGE + '"']
-
+
if bld.env['build_target'] == 'x86_64':
obj.defines += [ 'USE_X86_64_ASM' ]
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); \
} \
diff --git a/libs/timecode/src/time.cc b/libs/timecode/src/time.cc
index a0d56c7264..6f954a8d51 100644
--- a/libs/timecode/src/time.cc
+++ b/libs/timecode/src/time.cc
@@ -806,7 +806,7 @@ sample_to_timecode (
double timecode_frames_fraction;
int64_t timecode_frames_left;
const double frames_per_timecode_frame = sample_frame_rate / timecode_frames_per_second;
- const int64_t frames_per_hour = (int32_t)(3600 * rint(timecode_frames_per_second) * frames_per_timecode_frame);
+ const int64_t frames_per_hour = (int64_t)(3600 * rint(timecode_frames_per_second) * frames_per_timecode_frame);
timecode.hours = offset_sample / frames_per_hour;
@@ -818,7 +818,7 @@ sample_to_timecode (
timecode.subframes = (int32_t) rint(timecode_frames_fraction * subframes_per_frame);
timecode_frames_left = (int64_t) floor (timecode_frames_left_exact);
- if (timecode.subframes == subframes_per_frame) {
+ if (use_subframes && timecode.subframes == subframes_per_frame) {
timecode_frames_left++;
timecode.subframes = 0;
}