diff options
author | Carl Hetherington <carl@carlh.net> | 2010-12-07 19:16:23 +0000 |
---|---|---|
committer | Carl Hetherington <carl@carlh.net> | 2010-12-07 19:16:23 +0000 |
commit | f3fc6195bc6136a31b08ffe8c260a64efe77f9dc (patch) | |
tree | c9d98183fc9d14cd22ff7d076c593fef9bc9fa2f /libs/ardour | |
parent | f8e16276d9a598eb6425ae393dc0bd62cd2df05b (diff) |
Allow trim of midi regions to before the start of the source. Fixes #3156.
git-svn-id: svn://localhost/ardour2/branches/3.0@8212 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/midi_region.h | 9 | ||||
-rw-r--r-- | libs/ardour/ardour/region.h | 4 | ||||
-rw-r--r-- | libs/ardour/midi_region.cc | 17 | ||||
-rw-r--r-- | libs/ardour/region.cc | 27 |
4 files changed, 36 insertions, 21 deletions
diff --git a/libs/ardour/ardour/midi_region.h b/libs/ardour/ardour/midi_region.h index 853272d349..dae984c331 100644 --- a/libs/ardour/ardour/midi_region.h +++ b/libs/ardour/ardour/midi_region.h @@ -107,13 +107,20 @@ class MidiRegion : public Region boost::shared_ptr<MidiModel> model() { return midi_source()->model(); } boost::shared_ptr<const MidiModel> model() const { return midi_source()->model(); } + void fix_negative_start (); + + protected: + + virtual bool can_trim_start_before_source_start () const { + return true; + } + private: friend class RegionFactory; MidiRegion (const SourceList&); MidiRegion (boost::shared_ptr<const MidiRegion>, frameoffset_t offset = 0, bool offset_relative = true); - private: framecnt_t _read_at (const SourceList&, Evoral::EventSink<framepos_t>& dst, framepos_t position, framecnt_t dur, diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index 3ad61919b1..ed4923bc40 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -315,6 +315,10 @@ class Region /** Constructor for derived types only */ Region (Session& s, framepos_t start, framecnt_t length, const std::string& name, DataType); + virtual bool can_trim_start_before_source_start () const { + return false; + } + protected: void send_change (const PBD::PropertyChange&); void mid_thaw (const PBD::PropertyChange&); diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc index f9fb791bad..74276ff5b6 100644 --- a/libs/ardour/midi_region.cc +++ b/libs/ardour/midi_region.cc @@ -121,7 +121,7 @@ MidiRegion::set_position_internal (framepos_t pos, bool allow_bbt_recompute) BeatsFramesConverter old_converter(_session.tempo_map(), _position - _start); double length_beats = old_converter.from(_length); - Region::set_position_internal(pos, allow_bbt_recompute); + Region::set_position_internal (pos, allow_bbt_recompute); BeatsFramesConverter new_converter(_session.tempo_map(), pos - _start); @@ -306,9 +306,22 @@ MidiRegion::model_automation_state_changed (Evoral::Parameter const & p) } /* the source will have an iterator into the model, and that iterator will have been set up - for a given set of filtered_paramters, so now that we've changed that list we must invalidate + for a given set of filtered_parameters, so now that we've changed that list we must invalidate the iterator. */ Glib::Mutex::Lock lm (midi_source(0)->mutex()); midi_source(0)->invalidate (); } + +/** This is called when a trim drag has resulted in a -ve _start time for this region. + * Fix it up by adding some empty space to the source. + */ +void +MidiRegion::fix_negative_start () +{ + BeatsFramesConverter c (_session.tempo_map(), _position); + + MidiModel::WriteLock lock (model()->edit_lock ()); + model()->insert_silence_at_start (c.from (-_start)); + _start = 0; +} diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 5c25d34c60..585689a656 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -732,13 +732,7 @@ Region::trim_start (framepos_t new_position, void */*src*/) return; } framepos_t new_start; - frameoffset_t start_shift; - - if (new_position > _position) { - start_shift = new_position - _position; - } else { - start_shift = -(_position - new_position); - } + frameoffset_t const start_shift = new_position - _position; if (start_shift > 0) { @@ -759,6 +753,7 @@ Region::trim_start (framepos_t new_position, void */*src*/) } else { new_start = _start + start_shift; } + } else { return; } @@ -813,9 +808,10 @@ Region::modify_front (framepos_t new_position, bool reset_fade, void *src) framecnt_t newlen = 0; framepos_t delta = 0; - /* can't trim it back passed where source position zero is located */ - - new_position = max (new_position, source_zero); + if (!can_trim_start_before_source_start ()) { + /* can't trim it back past where source position zero is located */ + new_position = max (new_position, source_zero); + } if (new_position > _position) { newlen = _length - (new_position - _position); @@ -887,18 +883,13 @@ Region::trim_to (framepos_t position, framecnt_t length, void *src) void Region::trim_to_internal (framepos_t position, framecnt_t length, void */*src*/) { - frameoffset_t start_shift; framepos_t new_start; if (locked()) { return; } - if (position > _position) { - start_shift = position - _position; - } else { - start_shift = -(_position - position); - } + frameoffset_t const start_shift = position - _position; if (start_shift > 0) { @@ -910,7 +901,7 @@ Region::trim_to_internal (framepos_t position, framecnt_t length, void */*src*/) } else if (start_shift < 0) { - if (_start < -start_shift) { + if (_start < -start_shift && !can_trim_start_before_source_start ()) { new_start = 0; } else { new_start = _start + start_shift; @@ -1609,7 +1600,7 @@ Region::can_trim () const ct = CanTrim (ct | FrontTrimLater | EndTrimEarlier); - if (start() != 0) { + if (start() != 0 || can_trim_start_before_source_start ()) { ct = CanTrim (ct | FrontTrimEarlier); } |