diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2013-08-05 14:22:32 -0400 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2013-08-05 14:22:32 -0400 |
commit | 616f2a0370a10dcc7372a95f6bca9f5a45698980 (patch) | |
tree | b07badccad237cc66d0668482ad65cedefdee23f /libs/ardour | |
parent | 499b7fcfa9f3e8535a4500143a9d7af7b67c6984 (diff) | |
parent | 38e4f7bd1ba2ec9ae37dbb384da449f894cd8564 (diff) |
fix conflicts after merge with master
Diffstat (limited to 'libs/ardour')
59 files changed, 611 insertions, 193 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); |