summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2010-12-07 19:16:23 +0000
committerCarl Hetherington <carl@carlh.net>2010-12-07 19:16:23 +0000
commitf3fc6195bc6136a31b08ffe8c260a64efe77f9dc (patch)
treec9d98183fc9d14cd22ff7d076c593fef9bc9fa2f /libs/ardour
parentf8e16276d9a598eb6425ae393dc0bd62cd2df05b (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.h9
-rw-r--r--libs/ardour/ardour/region.h4
-rw-r--r--libs/ardour/midi_region.cc17
-rw-r--r--libs/ardour/region.cc27
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);
}