ardour
region.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2000-2003 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 #include <iostream>
21 #include <cmath>
22 #include <climits>
23 #include <algorithm>
24 #include <sstream>
25 
26 #include <glibmm/threads.h>
27 #include "pbd/xml++.h"
28 
29 #include "ardour/debug.h"
30 #include "ardour/filter.h"
31 #include "ardour/playlist.h"
32 #include "ardour/playlist_source.h"
33 #include "ardour/profile.h"
34 #include "ardour/region.h"
35 #include "ardour/region_factory.h"
36 #include "ardour/session.h"
37 #include "ardour/source.h"
38 #include "ardour/tempo.h"
39 
40 #include "i18n.h"
41 
42 using namespace std;
43 using namespace ARDOUR;
44 using namespace PBD;
45 
46 namespace ARDOUR {
47  class Progress;
48  namespace Properties {
74  }
75 }
76 
77 PBD::Signal2<void,boost::shared_ptr<ARDOUR::Region>,const PropertyChange&> Region::RegionPropertyChanged;
78 
79 void
81 {
82  Properties::muted.property_id = g_quark_from_static_string (X_("muted"));
83  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for muted = %1\n", Properties::muted.property_id));
84  Properties::opaque.property_id = g_quark_from_static_string (X_("opaque"));
85  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for opaque = %1\n", Properties::opaque.property_id));
86  Properties::locked.property_id = g_quark_from_static_string (X_("locked"));
87  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for locked = %1\n", Properties::locked.property_id));
88  Properties::video_locked.property_id = g_quark_from_static_string (X_("video-locked"));
89  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for video-locked = %1\n", Properties::video_locked.property_id));
90  Properties::automatic.property_id = g_quark_from_static_string (X_("automatic"));
91  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for automatic = %1\n", Properties::automatic.property_id));
92  Properties::whole_file.property_id = g_quark_from_static_string (X_("whole-file"));
93  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for whole-file = %1\n", Properties::whole_file.property_id));
94  Properties::import.property_id = g_quark_from_static_string (X_("import"));
95  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for import = %1\n", Properties::import.property_id));
96  Properties::external.property_id = g_quark_from_static_string (X_("external"));
97  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for external = %1\n", Properties::external.property_id));
98  Properties::sync_marked.property_id = g_quark_from_static_string (X_("sync-marked"));
99  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for sync-marked = %1\n", Properties::sync_marked.property_id));
100  Properties::left_of_split.property_id = g_quark_from_static_string (X_("left-of-split"));
101  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for left-of-split = %1\n", Properties::left_of_split.property_id));
102  Properties::right_of_split.property_id = g_quark_from_static_string (X_("right-of-split"));
103  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for right-of-split = %1\n", Properties::right_of_split.property_id));
104  Properties::hidden.property_id = g_quark_from_static_string (X_("hidden"));
105  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for hidden = %1\n", Properties::hidden.property_id));
106  Properties::position_locked.property_id = g_quark_from_static_string (X_("position-locked"));
107  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position-locked = %1\n", Properties::position_locked.property_id));
108  Properties::valid_transients.property_id = g_quark_from_static_string (X_("valid-transients"));
109  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for valid-transients = %1\n", Properties::valid_transients.property_id));
110  Properties::start.property_id = g_quark_from_static_string (X_("start"));
111  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for start = %1\n", Properties::start.property_id));
112  Properties::length.property_id = g_quark_from_static_string (X_("length"));
113  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for length = %1\n", Properties::length.property_id));
114  Properties::position.property_id = g_quark_from_static_string (X_("position"));
115  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position = %1\n", Properties::position.property_id));
116  Properties::sync_position.property_id = g_quark_from_static_string (X_("sync-position"));
117  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for sync-position = %1\n", Properties::sync_position.property_id));
118  Properties::layer.property_id = g_quark_from_static_string (X_("layer"));
119  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for layer = %1\n", Properties::layer.property_id));
120  Properties::ancestral_start.property_id = g_quark_from_static_string (X_("ancestral-start"));
121  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for ancestral-start = %1\n", Properties::ancestral_start.property_id));
122  Properties::ancestral_length.property_id = g_quark_from_static_string (X_("ancestral-length"));
123  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for ancestral-length = %1\n", Properties::ancestral_length.property_id));
124  Properties::stretch.property_id = g_quark_from_static_string (X_("stretch"));
125  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for stretch = %1\n", Properties::stretch.property_id));
126  Properties::shift.property_id = g_quark_from_static_string (X_("shift"));
127  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for shift = %1\n", Properties::shift.property_id));
128  Properties::position_lock_style.property_id = g_quark_from_static_string (X_("positional-lock-style"));
129  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position_lock_style = %1\n", Properties::position_lock_style.property_id));
130  Properties::layering_index.property_id = g_quark_from_static_string (X_("layering-index"));
131  DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for layering_index = %1\n", Properties::layering_index.property_id));
132 }
133 
134 void
135 Region::register_properties ()
136 {
137  _xml_node_name = X_("Region");
138 
139  add_property (_muted);
140  add_property (_opaque);
141  add_property (_locked);
142  add_property (_video_locked);
143  add_property (_automatic);
144  add_property (_whole_file);
145  add_property (_import);
146  add_property (_external);
147  add_property (_sync_marked);
148  add_property (_left_of_split);
149  add_property (_right_of_split);
150  add_property (_hidden);
151  add_property (_position_locked);
152  add_property (_valid_transients);
153  add_property (_start);
154  add_property (_length);
155  add_property (_position);
156  add_property (_sync_position);
157  add_property (_ancestral_start);
158  add_property (_ancestral_length);
159  add_property (_stretch);
160  add_property (_shift);
161  add_property (_position_lock_style);
162  add_property (_layering_index);
163 }
164 
165 #define REGION_DEFAULT_STATE(s,l) \
166  _sync_marked (Properties::sync_marked, false) \
167  , _left_of_split (Properties::left_of_split, false) \
168  , _right_of_split (Properties::right_of_split, false) \
169  , _valid_transients (Properties::valid_transients, false) \
170  , _start (Properties::start, (s)) \
171  , _length (Properties::length, (l)) \
172  , _position (Properties::position, 0) \
173  , _sync_position (Properties::sync_position, (s)) \
174  , _muted (Properties::muted, false) \
175  , _opaque (Properties::opaque, true) \
176  , _locked (Properties::locked, false) \
177  , _video_locked (Properties::video_locked, false) \
178  , _automatic (Properties::automatic, false) \
179  , _whole_file (Properties::whole_file, false) \
180  , _import (Properties::import, false) \
181  , _external (Properties::external, false) \
182  , _hidden (Properties::hidden, false) \
183  , _position_locked (Properties::position_locked, false) \
184  , _ancestral_start (Properties::ancestral_start, (s)) \
185  , _ancestral_length (Properties::ancestral_length, (l)) \
186  , _stretch (Properties::stretch, 1.0) \
187  , _shift (Properties::shift, 1.0) \
188  , _position_lock_style (Properties::position_lock_style, _type == DataType::AUDIO ? AudioTime : MusicTime) \
189  , _layering_index (Properties::layering_index, 0)
190 
191 #define REGION_COPY_STATE(other) \
192  _sync_marked (Properties::sync_marked, other->_sync_marked) \
193  , _left_of_split (Properties::left_of_split, other->_left_of_split) \
194  , _right_of_split (Properties::right_of_split, other->_right_of_split) \
195  , _valid_transients (Properties::valid_transients, other->_valid_transients) \
196  , _start(Properties::start, other->_start) \
197  , _length(Properties::length, other->_length) \
198  , _position(Properties::position, other->_position) \
199  , _sync_position(Properties::sync_position, other->_sync_position) \
200  , _muted (Properties::muted, other->_muted) \
201  , _opaque (Properties::opaque, other->_opaque) \
202  , _locked (Properties::locked, other->_locked) \
203  , _video_locked (Properties::video_locked, other->_video_locked) \
204  , _automatic (Properties::automatic, other->_automatic) \
205  , _whole_file (Properties::whole_file, other->_whole_file) \
206  , _import (Properties::import, other->_import) \
207  , _external (Properties::external, other->_external) \
208  , _hidden (Properties::hidden, other->_hidden) \
209  , _position_locked (Properties::position_locked, other->_position_locked) \
210  , _ancestral_start (Properties::ancestral_start, other->_ancestral_start) \
211  , _ancestral_length (Properties::ancestral_length, other->_ancestral_length) \
212  , _stretch (Properties::stretch, other->_stretch) \
213  , _shift (Properties::shift, other->_shift) \
214  , _position_lock_style (Properties::position_lock_style, other->_position_lock_style) \
215  , _layering_index (Properties::layering_index, other->_layering_index)
216 
217 /* derived-from-derived constructor (no sources in constructor) */
218 Region::Region (Session& s, framepos_t start, framecnt_t length, const string& name, DataType type)
219  : SessionObject(s, name)
220  , _type(type)
221  , REGION_DEFAULT_STATE(start,length)
222  , _last_length (length)
223  , _last_position (0)
224  , _first_edit (EditChangesNothing)
225  , _layer (0)
226 {
227  register_properties ();
228 
229  /* no sources at this point */
230 }
231 
233 Region::Region (const SourceList& srcs)
234  : SessionObject(srcs.front()->session(), "toBeRenamed")
235  , _type (srcs.front()->type())
236  , REGION_DEFAULT_STATE(0,0)
237  , _last_length (0)
238  , _last_position (0)
239  , _first_edit (EditChangesNothing)
240  , _layer (0)
241 {
243 
244  _type = srcs.front()->type();
245 
246  use_sources (srcs);
247 
248  assert(_sources.size() > 0);
249  assert (_type == srcs.front()->type());
250 }
251 
254  : SessionObject(other->session(), other->name())
255  , _type (other->data_type())
256  , REGION_COPY_STATE (other)
257  , _last_length (other->_last_length)
258  , _last_position(other->_last_position) \
259  , _first_edit (EditChangesNothing)
260  , _layer (other->_layer)
261 {
263 
264  /* override state that may have been incorrectly inherited from the other region
265  */
266 
267  _position = 0;
268  _locked = false;
269  _whole_file = false;
270  _hidden = false;
271 
272  use_sources (other->_sources);
273 
275  _first_edit = other->_first_edit;
276 
277  _start = 0; // It seems strange _start is not inherited here?
278 
279  /* sync pos is relative to start of file. our start-in-file is now zero,
280  so set our sync position to whatever the the difference between
281  _start and _sync_pos was in the other region.
282 
283  result is that our new sync pos points to the same point in our source(s)
284  as the sync in the other region did in its source(s).
285 
286  since we start at zero in our source(s), it is not possible to use a sync point that
287  is before the start. reset it to _start if that was true in the other region.
288  */
289 
290  if (other->sync_marked()) {
291  if (other->_start < other->_sync_position) {
292  /* sync pos was after the start point of the other region */
293  _sync_position = other->_sync_position - other->_start;
294  } else {
295  /* sync pos was before the start point of the other region. not possible here. */
296  _sync_marked = false;
298  }
299  } else {
300  _sync_marked = false;
302  }
303 
304  if (Profile->get_sae()) {
305  /* reset sync point to start if its ended up
306  outside region bounds.
307  */
308 
309  if (_sync_position < _start || _sync_position >= _start + _length) {
310  _sync_marked = false;
312  }
313  }
314 
315  assert (_type == other->data_type());
316 }
317 
324  : SessionObject(other->session(), other->name())
325  , _type (other->data_type())
326  , REGION_COPY_STATE (other)
327  , _last_length (other->_last_length)
328  , _last_position(other->_last_position) \
329  , _first_edit (EditChangesNothing)
330  , _layer (other->_layer)
331 {
333 
334  /* override state that may have been incorrectly inherited from the other region
335  */
336 
337  _position = 0;
338  _locked = false;
339  _whole_file = false;
340  _hidden = false;
341 
342  use_sources (other->_sources);
343 
344  _start = other->_start + offset;
345 
346  /* if the other region had a distinct sync point
347  set, then continue to use it as best we can.
348  otherwise, reset sync point back to start.
349  */
350 
351  if (other->sync_marked()) {
352  if (other->_sync_position < _start) {
353  _sync_marked = false;
355  } else {
357  }
358  } else {
359  _sync_marked = false;
361  }
362 
363  if (Profile->get_sae()) {
364  /* reset sync point to start if its ended up
365  outside region bounds.
366  */
367 
368  if (_sync_position < _start || _sync_position >= _start + _length) {
369  _sync_marked = false;
371  }
372  }
373 
374  assert (_type == other->data_type());
375 }
376 
379  : SessionObject (other->session(), other->name())
380  , _type (srcs.front()->type())
381  , REGION_COPY_STATE (other)
382  , _last_length (other->_last_length)
383  , _last_position (other->_last_position)
384  , _first_edit (EditChangesID)
385  , _layer (other->_layer)
386 {
388 
389  _locked = false;
390  _position_locked = false;
391 
392  other->_first_edit = EditChangesName;
393 
394  if (other->_extra_xml) {
395  _extra_xml = new XMLNode (*other->_extra_xml);
396  } else {
397  _extra_xml = 0;
398  }
399 
400  use_sources (srcs);
401  assert(_sources.size() > 0);
402 }
403 
405 {
406  DEBUG_TRACE (DEBUG::Destruction, string_compose ("Region %1 destructor @ %2\n", _name, this));
407  drop_sources ();
408 }
409 
410 void
412 {
413  _playlist = wpl.lock();
414 }
415 
416 bool
417 Region::set_name (const std::string& str)
418 {
419  if (_name != str) {
420  SessionObject::set_name(str); // EMIT SIGNAL NameChanged()
421  assert(_name == str);
422 
424  }
425 
426  return true;
427 }
428 
429 void
431 {
432  //cerr << "Region::set_length() len = " << len << endl;
433  if (locked()) {
434  return;
435  }
436 
437  if (_length != len && len != 0) {
438 
439  /* check that the current _position wouldn't make the new
440  length impossible.
441  */
442 
443  if (max_framepos - len < _position) {
444  return;
445  }
446 
447  if (!verify_length (len)) {
448  return;
449  }
450 
451 
453  set_length_internal (len);
454  _whole_file = false;
455  first_edit ();
456  maybe_uncopy ();
458 
460  recompute_at_end ();
461  }
462 
464  }
465 }
466 
467 void
469 {
470  _length = len;
471 }
472 
473 void
475 {
476  /* this does nothing but marked a semantic moment once upon a time */
477 }
478 
479 void
481 {
483 
484  if (_first_edit != EditChangesNothing && pl) {
485 
488 
490 
491  RegionFactory::CheckNewRegion (shared_from_this());
492  }
493 }
494 
495 bool
497 {
499 
500  if (!pl) {
501  return false;
502  }
503 
504  boost::shared_ptr<Region> whole_file_region = get_parent();
505 
506  if (whole_file_region) {
507  if (_position == whole_file_region->position() + _start) {
508  return true;
509  }
510  }
511 
512  return false;
513 }
514 
515 void
517 {
519 
520  if (!pl) {
521  return;
522  }
523 
524  boost::shared_ptr<Region> whole_file_region = get_parent();
525 
526  if (whole_file_region) {
527  set_position (whole_file_region->position() + _start);
528  }
529 }
530 
531 void
533 {
534  /* this is used when creating a whole file region as
535  a way to store its "natural" or "captured" position.
536  */
537 
539  _position = pos;
540 }
541 
542 void
544 {
545  if (_position_lock_style != ps) {
546 
548 
550 
553  }
554 
556  }
557 }
558 
559 void
561 {
563 
564  if (!pl || _position_lock_style != MusicTime) {
565  return;
566  }
567 
568  TempoMap& map (_session.tempo_map());
569  framepos_t pos = map.frame_time (_bbt_time);
570  set_position_internal (pos, false);
571 
572  /* do this even if the position is the same. this helps out
573  a GUI that has moved its representation already.
574  */
576 }
577 
578 void
580 {
581  if (!can_move()) {
582  return;
583  }
584 
585  set_position_internal (pos, true);
586 
587  /* do this even if the position is the same. this helps out
588  a GUI that has moved its representation already.
589  */
591 
592 }
593 
594 void
595 Region::set_position_internal (framepos_t pos, bool allow_bbt_recompute)
596 {
597  /* We emit a change of Properties::position even if the position hasn't changed
598  (see Region::set_position), so we must always set this up so that
599  e.g. Playlist::notify_region_moved doesn't use an out-of-date last_position.
600  */
602 
603  if (_position != pos) {
604  _position = pos;
605 
606  /* check that the new _position wouldn't make the current
607  length impossible - if so, change the length.
608 
609  XXX is this the right thing to do?
610  */
611 
612  if (max_framepos - _length < _position) {
615  }
616 
617  if (allow_bbt_recompute) {
619  }
620 
621  //invalidate_transients ();
622  }
623 }
624 
625 void
627 {
630  }
631 }
632 
633 void
635 {
636  if (locked() || video_locked()) {
637  return;
638  }
639 
640  if (n == 0) {
641  return;
642  }
643 
644  framepos_t new_position = _position;
645 
646  if (n > 0) {
647  if (_position > max_framepos - n) {
648  new_position = max_framepos;
649  } else {
650  new_position += n;
651  }
652  } else {
653  if (_position < -n) {
654  new_position = 0;
655  } else {
656  new_position += n;
657  }
658  }
659 
660  set_position_internal (new_position, true);
661 
663 }
664 
665 void
667 {
668  _ancestral_length = l;
669  _ancestral_start = s;
670  _stretch = st;
671  _shift = sh;
672 }
673 
674 void
676 {
677  if (locked() || position_locked() || video_locked()) {
678  return;
679  }
680  /* This just sets the start, nothing else. It effectively shifts
681  the contents of the Region within the overall extent of the Source,
682  without changing the Region's position or length
683  */
684 
685  if (_start != pos) {
686 
687  if (!verify_start (pos)) {
688  return;
689  }
690 
691  set_start_internal (pos);
692  _whole_file = false;
693  first_edit ();
695 
697  }
698 }
699 
700 void
702 {
703  if (locked() || position_locked() || video_locked()) {
704  return;
705  }
706 
707  framepos_t new_start;
708 
709  if (distance > 0) {
710 
711  if (_start > max_framepos - distance) {
712  new_start = max_framepos; // makes no sense
713  } else {
714  new_start = _start + distance;
715  }
716 
717  if (!verify_start (new_start)) {
718  return;
719  }
720 
721  } else if (distance < 0) {
722 
723  if (_start < -distance) {
724  new_start = 0;
725  } else {
726  new_start = _start + distance;
727  }
728 
729  } else {
730  return;
731  }
732 
733  if (new_start == _start) {
734  return;
735  }
736 
737  set_start_internal (new_start);
738 
739  _whole_file = false;
740  first_edit ();
741 
743 }
744 
745 void
747 {
748  modify_front (new_position, false);
749 }
750 
751 void
753 {
754  modify_front (new_position, true);
755 }
756 
757 void
759 {
760  modify_end (new_endpoint, true);
761 }
762 
763 void
764 Region::modify_front (framepos_t new_position, bool reset_fade)
765 {
766  if (locked()) {
767  return;
768  }
769 
770  framepos_t end = last_frame();
771  framepos_t source_zero;
772 
773  if (_position > _start) {
774  source_zero = _position - _start;
775  } else {
776  source_zero = 0; // its actually negative, but this will work for us
777  }
778 
779  if (new_position < end) { /* can't trim it zero or negative length */
780 
781  framecnt_t newlen = 0;
782  framepos_t delta = 0;
783 
785  /* can't trim it back past where source position zero is located */
786  new_position = max (new_position, source_zero);
787  }
788 
789  if (new_position > _position) {
790  newlen = _length - (new_position - _position);
791  delta = -1 * (new_position - _position);
792  } else {
793  newlen = _length + (_position - new_position);
794  delta = _position - new_position;
795  }
796 
797  trim_to_internal (new_position, newlen);
798 
799  if (reset_fade) {
800  _right_of_split = true;
801  }
802 
805  }
806 
807  if (_transients.size() > 0){
808  adjust_transients(delta);
809  }
810  }
811 }
812 
813 void
814 Region::modify_end (framepos_t new_endpoint, bool reset_fade)
815 {
816  if (locked()) {
817  return;
818  }
819 
820  if (new_endpoint > _position) {
821  trim_to_internal (_position, new_endpoint - _position);
822  if (reset_fade) {
823  _left_of_split = true;
824  }
826  recompute_at_end ();
827  }
828  }
829 }
830 
835 void
837 {
838  modify_end (new_endpoint, false);
839 }
840 
841 void
843 {
844  if (locked()) {
845  return;
846  }
847 
848  trim_to_internal (position, length);
849 
852  recompute_at_end ();
853  }
854 }
855 
856 void
858 {
859  framepos_t new_start;
860 
861  if (locked()) {
862  return;
863  }
864 
865  frameoffset_t const start_shift = position - _position;
866 
867  if (start_shift > 0) {
868 
869  if (_start > max_framepos - start_shift) {
870  new_start = max_framepos;
871  } else {
872  new_start = _start + start_shift;
873  }
874 
875  } else if (start_shift < 0) {
876 
877  if (_start < -start_shift && !can_trim_start_before_source_start ()) {
878  new_start = 0;
879  } else {
880  new_start = _start + start_shift;
881  }
882 
883  } else {
884  new_start = _start;
885  }
886 
887  if (!verify_start_and_length (new_start, length)) {
888  return;
889  }
890 
891  PropertyChange what_changed;
892 
893  if (_start != new_start) {
894  set_start_internal (new_start);
895  what_changed.add (Properties::start);
896  }
897 
898  /* Set position before length, otherwise for MIDI regions this bad thing happens:
899  * 1. we call set_length_internal; length in beats is computed using the region's current
900  * (soon-to-be old) position
901  * 2. we call set_position_internal; position is set and length in frames re-computed using
902  * length in beats from (1) but at the new position, which is wrong if the region
903  * straddles a tempo/meter change.
904  */
905 
906  if (_position != position) {
909  }
910  set_position_internal (position, true);
911  what_changed.add (Properties::position);
912  }
913 
914  if (_length != length) {
917  }
918  set_length_internal (length);
919  what_changed.add (Properties::length);
920  }
921 
922  _whole_file = false;
923 
924  PropertyChange start_and_length;
925 
926  start_and_length.add (Properties::start);
927  start_and_length.add (Properties::length);
928 
929  if (what_changed.contains (start_and_length)) {
930  first_edit ();
931  }
932 
933  if (!what_changed.empty()) {
934  send_change (what_changed);
935  }
936 }
937 
938 void
940 {
941  if (hidden() != yn) {
942  _hidden = yn;
944  }
945 }
946 
947 void
949 {
950  _whole_file = yn;
951  /* no change signal */
952 }
953 
954 void
956 {
957  _automatic = yn;
958  /* no change signal */
959 }
960 
961 void
963 {
964  if (muted() != yn) {
965  _muted = yn;
967  }
968 }
969 
970 void
972 {
973  if (opaque() != yn) {
974  _opaque = yn;
976  }
977 }
978 
979 void
981 {
982  if (locked() != yn) {
983  _locked = yn;
985  }
986 }
987 
988 void
990 {
991  if (video_locked() != yn) {
992  _video_locked = yn;
994  }
995 }
996 
997 void
999 {
1000  if (position_locked() != yn) {
1001  _position_locked = yn;
1003  }
1004 }
1005 
1009 void
1011 {
1012  /* position within our file */
1013  framepos_t const file_pos = _start + (absolute_pos - _position);
1014 
1015  if (file_pos != _sync_position) {
1016  _sync_marked = true;
1017  _sync_position = file_pos;
1018  if (!property_changes_suspended()) {
1019  maybe_uncopy ();
1020  }
1021 
1023  }
1024 }
1025 
1026 void
1028 {
1029  if (sync_marked()) {
1030  _sync_marked = false;
1031  if (!property_changes_suspended()) {
1032  maybe_uncopy ();
1033  }
1034 
1036  }
1037 }
1038 
1039 /* @return the sync point relative the first frame of the region */
1041 Region::sync_offset (int& dir) const
1042 {
1043  if (sync_marked()) {
1044  if (_sync_position > _start) {
1045  dir = 1;
1046  return _sync_position - _start;
1047  } else {
1048  dir = -1;
1049  return _start - _sync_position;
1050  }
1051  } else {
1052  dir = 0;
1053  return 0;
1054  }
1055 }
1056 
1057 framepos_t
1059 {
1060  int sync_dir;
1061  frameoffset_t offset = sync_offset (sync_dir);
1062 
1063  // cerr << "adjusting pos = " << pos << " to sync at " << _sync_position << " offset = " << offset << " with dir = " << sync_dir << endl;
1064 
1065  if (sync_dir > 0) {
1066  if (pos > offset) {
1067  pos -= offset;
1068  } else {
1069  pos = 0;
1070  }
1071  } else {
1072  if (max_framepos - pos > offset) {
1073  pos += offset;
1074  }
1075  }
1076 
1077  return pos;
1078 }
1079 
1081 framepos_t
1083 {
1084  if (sync_marked()) {
1085  return _position - _start + _sync_position;
1086  } else {
1087  /* if sync has not been marked, use the start of the region */
1088  return _position;
1089  }
1090 }
1091 
1092 void
1094 {
1096  if (pl) {
1097  pl->raise_region (shared_from_this ());
1098  }
1099 }
1100 
1101 void
1103 {
1105  if (pl) {
1106  pl->lower_region (shared_from_this ());
1107  }
1108 }
1109 
1110 
1111 void
1113 {
1115  if (pl) {
1116  pl->raise_region_to_top (shared_from_this());
1117  }
1118 }
1119 
1120 void
1122 {
1124  if (pl) {
1125  pl->lower_region_to_bottom (shared_from_this());
1126  }
1127 }
1128 
1129 void
1131 {
1132  _layer = l;
1133 }
1134 
1135 XMLNode&
1137 {
1138  XMLNode *node = new XMLNode ("Region");
1139  char buf[64];
1140  char buf2[64];
1141  LocaleGuard lg (X_("C"));
1142  const char* fe = NULL;
1143 
1144  /* custom version of 'add_properties (*node);'
1145  * skip values that have have dedicated save functions
1146  * in AudioRegion::state()
1147  */
1148  for (OwnedPropertyList::iterator i = _properties->begin(); i != _properties->end(); ++i) {
1149  if (!strcmp(i->second->property_name(), (const char*)"Envelope")) continue;
1150  if (!strcmp(i->second->property_name(), (const char*)"FadeIn")) continue;
1151  if (!strcmp(i->second->property_name(), (const char*)"FadeOut")) continue;
1152  if (!strcmp(i->second->property_name(), (const char*)"InverseFadeIn")) continue;
1153  if (!strcmp(i->second->property_name(), (const char*)"InverseFadeOut")) continue;
1154  i->second->get_value (*node);
1155  }
1156 
1157  id().print (buf, sizeof (buf));
1158  node->add_property ("id", buf);
1159  node->add_property ("type", _type.to_string());
1160 
1161  switch (_first_edit) {
1162  case EditChangesNothing:
1163  fe = X_("nothing");
1164  break;
1165  case EditChangesName:
1166  fe = X_("name");
1167  break;
1168  case EditChangesID:
1169  fe = X_("id");
1170  break;
1171  default: /* should be unreachable but makes g++ happy */
1172  fe = X_("nothing");
1173  break;
1174  }
1175 
1176  node->add_property ("first-edit", fe);
1177 
1178  /* note: flags are stored by derived classes */
1179 
1181  stringstream str;
1182  str << _bbt_time;
1183  node->add_property ("bbt-position", str.str());
1184  }
1185 
1186  for (uint32_t n=0; n < _sources.size(); ++n) {
1187  snprintf (buf2, sizeof(buf2), "source-%d", n);
1188  _sources[n]->id().print (buf, sizeof(buf));
1189  node->add_property (buf2, buf);
1190  }
1191 
1192  for (uint32_t n=0; n < _master_sources.size(); ++n) {
1193  snprintf (buf2, sizeof(buf2), "master-source-%d", n);
1194  _master_sources[n]->id().print (buf, sizeof (buf));
1195  node->add_property (buf2, buf);
1196  }
1197 
1198  /* Only store nested sources for the whole-file region that acts
1199  as the parent/root of all regions using it.
1200  */
1201 
1202  if (_whole_file && max_source_level() > 0) {
1203 
1204  XMLNode* nested_node = new XMLNode (X_("NestedSource"));
1205 
1206  /* region is compound - get its playlist and
1207  store that before we list the region that
1208  needs it ...
1209  */
1210 
1211  for (SourceList::const_iterator s = _sources.begin(); s != _sources.end(); ++s) {
1212  nested_node->add_child_nocopy ((*s)->get_state ());
1213  }
1214 
1215  if (nested_node) {
1216  node->add_child_nocopy (*nested_node);
1217  }
1218  }
1219 
1220  if (_extra_xml) {
1221  node->add_child_copy (*_extra_xml);
1222  }
1223 
1224  return *node;
1225 }
1226 
1227 XMLNode&
1229 {
1230  return state ();
1231 }
1232 
1233 int
1234 Region::set_state (const XMLNode& node, int version)
1235 {
1236  PropertyChange what_changed;
1237  return _set_state (node, version, what_changed, true);
1238 }
1239 
1240 int
1241 Region::_set_state (const XMLNode& node, int /*version*/, PropertyChange& what_changed, bool send)
1242 {
1243  const XMLProperty* prop;
1244 
1245  Stateful::save_extra_xml (node);
1246 
1247  what_changed = set_values (node);
1248 
1249  set_id (node);
1250 
1252  if ((prop = node.property ("bbt-position")) == 0) {
1253  /* missing BBT info, revert to audio time locking */
1255  } else {
1256  if (sscanf (prop->value().c_str(), "%d|%d|%d",
1257  &_bbt_time.bars,
1258  &_bbt_time.beats,
1259  &_bbt_time.ticks) != 3) {
1261  }
1262  }
1263  }
1264 
1265  /* fix problems with old sessions corrupted by impossible
1266  values for _stretch or _shift
1267  */
1268  if (_stretch == 0.0f) {
1269  _stretch = 1.0f;
1270  }
1271 
1272  if (_shift == 0.0f) {
1273  _shift = 1.0f;
1274  }
1275 
1276  if (send) {
1277  send_change (what_changed);
1278  }
1279 
1280  /* Quick fix for 2.x sessions when region is muted */
1281  if ((prop = node.property (X_("flags")))) {
1282  if (string::npos != prop->value().find("Muted")){
1283  set_muted (true);
1284  }
1285  }
1286 
1287 
1288  return 0;
1289 }
1290 
1291 void
1293 {
1297 }
1298 
1299 void
1300 Region::mid_thaw (const PropertyChange& what_changed)
1301 {
1302  if (what_changed.contains (Properties::length)) {
1303  if (what_changed.contains (Properties::position)) {
1304  recompute_at_start ();
1305  }
1306  recompute_at_end ();
1307  }
1308 }
1309 
1310 void
1312 {
1313  if (what_changed.empty()) {
1314  return;
1315  }
1316 
1317  Stateful::send_change (what_changed);
1318 
1320 
1321  /* Try and send a shared_pointer unless this is part of the constructor.
1322  If so, do nothing.
1323  */
1324 
1325  try {
1326  boost::shared_ptr<Region> rptr = shared_from_this();
1327  RegionPropertyChanged (rptr, what_changed);
1328  } catch (...) {
1329  /* no shared_ptr available, relax; */
1330  }
1331  }
1332 }
1333 
1334 bool
1336 {
1337  return coverage (other->first_frame(), other->last_frame()) != Evoral::OverlapNone;
1338 }
1339 
1340 bool
1342 {
1343  return _start == other->_start &&
1344  _position == other->_position &&
1345  _length == other->_length;
1346 }
1347 
1348 bool
1350 {
1351  return _start == other->_start &&
1352  _length == other->_length;
1353 }
1354 
1355 bool
1357 {
1358  return size_equivalent (other) && source_equivalent (other) && _name == other->_name;
1359 }
1360 
1361 void
1363 {
1364  drop_sources ();
1365 
1366  if (!_session.deletion_in_progress()) {
1367  /* this is a very special case: at least one of the region's
1368  sources has bee deleted, so invalidate all references to
1369  ourselves. Do NOT do this during session deletion, because
1370  then we run the risk that this will actually result
1371  in this object being deleted (as refcnt goes to zero)
1372  while emitting DropReferences.
1373  */
1374 
1375  drop_references ();
1376  }
1377 }
1378 
1379 vector<string>
1381 {
1382  SourceList::iterator i;
1383 
1384  vector<string> names;
1385  for (i = _master_sources.begin(); i != _master_sources.end(); ++i) {
1386  names.push_back((*i)->name());
1387  }
1388 
1389  return names;
1390 }
1391 
1392 void
1394 {
1395  for (SourceList::const_iterator i = _master_sources.begin (); i != _master_sources.end(); ++i) {
1396  (*i)->dec_use_count ();
1397  }
1398 
1399  _master_sources = srcs;
1400  assert (_sources.size() == _master_sources.size());
1401 
1402  for (SourceList::const_iterator i = _master_sources.begin (); i != _master_sources.end(); ++i) {
1403  (*i)->inc_use_count ();
1404  }
1405 }
1406 
1407 bool
1409 {
1410  if (!other)
1411  return false;
1412 
1413  if ((_sources.size() != other->_sources.size()) ||
1414  (_master_sources.size() != other->_master_sources.size())) {
1415  return false;
1416  }
1417 
1418  SourceList::const_iterator i;
1419  SourceList::const_iterator io;
1420 
1421  for (i = _sources.begin(), io = other->_sources.begin(); i != _sources.end() && io != other->_sources.end(); ++i, ++io) {
1422  if ((*i)->id() != (*io)->id()) {
1423  return false;
1424  }
1425  }
1426 
1427  for (i = _master_sources.begin(), io = other->_master_sources.begin(); i != _master_sources.end() && io != other->_master_sources.end(); ++i, ++io) {
1428  if ((*i)->id() != (*io)->id()) {
1429  return false;
1430  }
1431  }
1432 
1433  return true;
1434 }
1435 
1436 bool
1438 {
1439  if (!other) {
1440  return false;
1441  }
1442 
1443  SourceList::const_iterator i;
1444  SourceList::const_iterator io;
1445 
1446  for (i = _sources.begin(), io = other->_sources.begin(); i != _sources.end() && io != other->_sources.end(); ++i, ++io) {
1447  if ((*i)->id() == (*io)->id()) {
1448  return true;
1449  }
1450  }
1451 
1452  return false;
1453 }
1454 
1455 std::string
1457 {
1458  //string res = itos(_sources.size());
1459 
1460  stringstream res;
1461  res << _sources.size() << ":";
1462 
1463  SourceList::const_iterator i;
1464 
1465  for (i = _sources.begin(); i != _sources.end(); ++i) {
1466  res << (*i)->id() << ":";
1467  }
1468 
1469  for (i = _master_sources.begin(); i != _master_sources.end(); ++i) {
1470  res << (*i)->id() << ":";
1471  }
1472 
1473  return res.str();
1474 }
1475 
1476 bool
1478 {
1479  for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
1480  if (*i == source) {
1481  return true;
1482  }
1483 
1485 
1486  if (ps) {
1487  if (ps->playlist()->uses_source (source)) {
1488  return true;
1489  }
1490  }
1491  }
1492 
1493  for (SourceList::const_iterator i = _master_sources.begin(); i != _master_sources.end(); ++i) {
1494  if (*i == source) {
1495  return true;
1496  }
1497 
1499 
1500  if (ps) {
1501  if (ps->playlist()->uses_source (source)) {
1502  return true;
1503  }
1504  }
1505  }
1506 
1507  return false;
1508 }
1509 
1510 framecnt_t
1511 Region::source_length(uint32_t n) const
1512 {
1513  assert (n < _sources.size());
1514  return _sources[n]->length (_position - _start);
1515 }
1516 
1517 bool
1519 {
1520  if (source() && (source()->destructive() || source()->length_mutable())) {
1521  return true;
1522  }
1523 
1524  framecnt_t maxlen = 0;
1525 
1526  for (uint32_t n = 0; n < _sources.size(); ++n) {
1527  maxlen = max (maxlen, source_length(n) - _start);
1528  }
1529 
1530  len = min (len, maxlen);
1531 
1532  return true;
1533 }
1534 
1535 bool
1537 {
1538  if (source() && (source()->destructive() || source()->length_mutable())) {
1539  return true;
1540  }
1541 
1542  framecnt_t maxlen = 0;
1543 
1544  for (uint32_t n = 0; n < _sources.size(); ++n) {
1545  maxlen = max (maxlen, source_length(n) - new_start);
1546  }
1547 
1548  new_length = min (new_length, maxlen);
1549 
1550  return true;
1551 }
1552 
1553 bool
1555 {
1556  if (source() && (source()->destructive() || source()->length_mutable())) {
1557  return true;
1558  }
1559 
1560  for (uint32_t n = 0; n < _sources.size(); ++n) {
1561  if (pos > source_length(n) - _length) {
1562  return false;
1563  }
1564  }
1565  return true;
1566 }
1567 
1568 bool
1570 {
1571  if (source() && (source()->destructive() || source()->length_mutable())) {
1572  return true;
1573  }
1574 
1575  for (uint32_t n = 0; n < _sources.size(); ++n) {
1576  if (new_start > source_length(n) - _length) {
1577  new_start = source_length(n) - _length;
1578  }
1579  }
1580  return true;
1581 }
1582 
1585 {
1587 
1588  if (pl) {
1590  boost::shared_ptr<Region const> grrr2 = boost::dynamic_pointer_cast<Region const> (shared_from_this());
1591 
1592  if (grrr2 && (r = _session.find_whole_file_parent (grrr2))) {
1593  return boost::static_pointer_cast<Region> (r);
1594  }
1595  }
1596 
1597  return boost::shared_ptr<Region>();
1598 }
1599 
1600 int
1601 Region::apply (Filter& filter, Progress* progress)
1602 {
1603  return filter.run (shared_from_this(), progress);
1604 }
1605 
1606 
1607 void
1609 {
1610  _valid_transients = false;
1611  _transients.clear ();
1612 
1614 }
1615 
1616 void
1618 {
1619  for (SourceList::const_iterator i = _sources.begin (); i != _sources.end(); ++i) {
1620  (*i)->dec_use_count ();
1621  }
1622 
1623  _sources.clear ();
1624 
1625  for (SourceList::const_iterator i = _master_sources.begin (); i != _master_sources.end(); ++i) {
1626  (*i)->dec_use_count ();
1627  }
1628 
1629  _master_sources.clear ();
1630 }
1631 
1632 void
1634 {
1635  set<boost::shared_ptr<Source> > unique_srcs;
1636 
1637  for (SourceList::const_iterator i = s.begin (); i != s.end(); ++i) {
1638 
1639  _sources.push_back (*i);
1640  (*i)->inc_use_count ();
1641  _master_sources.push_back (*i);
1642  (*i)->inc_use_count ();
1643 
1644  /* connect only once to DropReferences, even if sources are replicated
1645  */
1646 
1647  if (unique_srcs.find (*i) == unique_srcs.end ()) {
1648  unique_srcs.insert (*i);
1649  (*i)->DropReferences.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(*i)));
1650  }
1651  }
1652 }
1653 
1656 {
1657  CanTrim ct = CanTrim (0);
1658 
1659  if (locked()) {
1660  return ct;
1661  }
1662 
1663  /* if not locked, we can always move the front later, and the end earlier
1664  */
1665 
1666  ct = CanTrim (ct | FrontTrimLater | EndTrimEarlier);
1667 
1668  if (start() != 0 || can_trim_start_before_source_start ()) {
1669  ct = CanTrim (ct | FrontTrimEarlier);
1670  }
1671 
1672  if (!_sources.empty()) {
1673  if ((start() + length()) < _sources.front()->length (0)) {
1674  ct = CanTrim (ct | EndTrimLater);
1675  }
1676  }
1677 
1678  return ct;
1679 }
1680 
1681 uint32_t
1683 {
1684  uint32_t lvl = 0;
1685 
1686  for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
1687  lvl = max (lvl, (*i)->level());
1688  }
1689 
1690  return lvl;
1691 }
1692 
1693 bool
1695 {
1696  return max_source_level() > 0;
1697 }
1698 
1699 void
1701 {
1702  if (pc.contains (Properties::position)) {
1704  }
1705 }
1706 
1707 void
1709 {
1710  _start = s;
1711 }
1712 
1713 framepos_t
1715 {
1716  if (_start > _position) {
1717  return 0;
1718  } else {
1719  return _position - _start;
1720  }
1721 }
1722 
1723 framecnt_t
1725 {
1726  framecnt_t minlen = max_framecnt;
1727 
1728  for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
1729  /* non-audio regions have a length that may vary based on their
1730  * position, so we have to pass it in the call.
1731  */
1732  minlen = min (minlen, (*i)->length (_position));
1733  }
1734 
1735  /* the latest possible last frame is determined by the current
1736  * position, plus the shortest source extent past _start.
1737  */
1738 
1739  return _position + (minlen - _start) - 1;
1740 }
1741 
virtual void set_playlist(boost::weak_ptr< ARDOUR::Playlist >)
Definition: region.cc:411
AnalysisFeatureList _transients
Definition: region.h:374
PBD::Property< bool > _automatic
Definition: region.h:400
ARDOUR::Session & _session
PBD::Property< bool > _muted
Definition: region.h:396
bool property_changes_suspended() const
Definition: stateful.h:95
void trim_front(framepos_t new_position)
Definition: region.cc:746
bool get_sae() const
Definition: profile.h:48
virtual void send_change(const PropertyChange &)
Definition: stateful.cc:278
bool verify_start_and_length(framepos_t, framecnt_t &)
Definition: region.cc:1536
XMLNode & get_state()
Definition: region.cc:1228
void set_position_locked(bool yn)
Definition: region.cc:998
const std::string & value() const
Definition: xml++.h:159
PBD::Property< bool > _position_locked
Definition: region.h:405
PBD::Property< framepos_t > _ancestral_start
Definition: region.h:406
void save_extra_xml(const XMLNode &)
Definition: stateful.cc:94
virtual void suspend_property_changes()
Definition: stateful.cc:296
void set_ancestral_data(framepos_t start, framecnt_t length, float stretch, float shift)
Definition: region.cc:666
LIBARDOUR_API PBD::PropertyDescriptor< layer_t > layer
Definition: region.cc:67
void cut_end(framepos_t new_position)
Definition: region.cc:758
LIBARDOUR_API uint64_t Destruction
Definition: debug.cc:38
LIBARDOUR_API PBD::PropertyDescriptor< bool > hidden
Definition: route_group.h:50
void set_hidden(bool yn)
Definition: region.cc:939
framepos_t _last_position
Definition: region.h:414
framepos_t latest_possible_frame() const
Definition: region.cc:1724
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > ancestral_start
Definition: region.cc:68
EditChangesName
Definition: region.h:78
LIBARDOUR_API PBD::PropertyDescriptor< bool > video_locked
Definition: region.cc:52
bool uses_source(boost::shared_ptr< const Source >) const
Definition: region.cc:1477
void special_set_position(framepos_t)
Definition: region.cc:532
const char * to_string() const
Definition: data_type.h:77
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
LIBARDOUR_API PBD::PropertyDescriptor< std::string > name
bool equivalent(boost::shared_ptr< const Region >) const
Definition: region.cc:1341
void post_set(const PBD::PropertyChange &)
Definition: region.cc:1700
void move_start(frameoffset_t distance)
Definition: region.cc:701
void raise_region(boost::shared_ptr< Region >)
Definition: playlist.cc:2503
TempoMap & tempo_map()
Definition: session.h:596
void source_deleted(boost::weak_ptr< Source >)
Definition: region.cc:1362
EditChangesNothing
Definition: region.h:77
bool set_name(const std::string &str)
Definition: region.cc:417
boost::shared_ptr< Region > find_whole_file_parent(boost::shared_ptr< Region const >) const
Definition: session.cc:3502
tuple f
Definition: signals.py:35
XMLNode * add_child_copy(const XMLNode &)
Definition: xml++.cc:363
virtual int run(boost::shared_ptr< ARDOUR::Region >, Progress *progress=0)=0
Definition: Beats.hpp:239
layer_t _layer
Definition: region.h:417
#define REGION_DEFAULT_STATE(s, l)
Definition: region.cc:165
bool verify_length(framecnt_t &)
Definition: region.cc:1518
PBD::Property< bool > _whole_file
Definition: region.h:401
PBD::Property< framepos_t > _sync_position
Definition: region.h:368
boost::shared_ptr< Source > source(uint32_t n=0) const
Definition: region.h:258
void set_video_locked(bool yn)
Definition: region.cc:989
void modify_end(framepos_t new_position, bool reset_fade)
Definition: region.cc:814
PropertyChange set_values(XMLNode const &)
Definition: stateful.cc:209
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
Definition: region.cc:63
virtual int _set_state(const XMLNode &, int version, PBD::PropertyChange &what_changed, bool send_signal)
Definition: region.cc:1241
PBD::Property< bool > _left_of_split
Definition: region.h:361
LIBARDOUR_API PBD::PropertyDescriptor< float > stretch
Definition: region.cc:70
void set_sync_position(framepos_t n)
Definition: region.cc:1010
framepos_t frame_time(const Timecode::BBT_Time &)
Definition: tempo.cc:1218
bool can_move() const
Definition: region.h:171
OwnedPropertyList * _properties
Definition: stateful.h:117
PBD::Property< float > _stretch
Definition: region.h:408
framepos_t sync_position() const
Definition: region.cc:1082
PBD::Property< bool > _valid_transients
Definition: region.h:363
void raise_to_top()
Definition: region.cc:1112
void maybe_uncopy()
Definition: region.cc:474
PBD::Property< bool > _right_of_split
Definition: region.h:362
PBD::Property< bool > _locked
Definition: region.h:398
bool source_equivalent(boost::shared_ptr< const Region >) const
Definition: region.cc:1408
void use_sources(SourceList const &)
Definition: region.cc:1633
void trim_end(framepos_t new_position)
Definition: region.cc:836
void trim_to_internal(framepos_t position, framecnt_t length)
Definition: region.cc:857
virtual void update_after_tempo_map_change()
Definition: region.cc:560
XMLNode * _extra_xml
Definition: stateful.h:109
virtual void recompute_at_start()=0
void invalidate_transients()
Definition: region.cc:1608
static std::string new_region_name(std::string)
SourceList _master_sources
Definition: region.h:372
virtual int set_state(const XMLNode &, int version)
Definition: region.cc:1234
Region(const SourceList &srcs)
Definition: region.cc:233
Trimmable::CanTrim can_trim() const
Definition: region.cc:1655
SourceList _sources
Definition: region.h:370
const DataType & data_type() const
Definition: region.h:102
#define X_(Text)
Definition: i18n.h:13
LIBARDOUR_API PBD::PropertyDescriptor< bool > automatic
Definition: region.cc:53
PBD::Property< framepos_t > _start
Definition: region.h:364
void set_master_sources(const SourceList &)
Definition: region.cc:1393
int64_t framecnt_t
Definition: types.h:76
boost::shared_ptr< const Playlist > playlist() const
void set_layer(layer_t l)
Definition: region.cc:1130
virtual bool can_trim_start_before_source_start() const
Definition: region.h:345
XMLProperty * property(const char *)
Definition: xml++.cc:413
void set_position(framepos_t)
Definition: region.cc:579
bool video_locked() const
Definition: region.h:166
RegionEditState _first_edit
Definition: region.h:415
void cut_front(framepos_t new_position)
Definition: region.cc:752
PBD::Property< bool > _sync_marked
Definition: region.h:360
virtual void set_position_internal(framepos_t pos, bool allow_bbt_recompute)
Definition: region.cc:595
bool overlap_equivalent(boost::shared_ptr< const Region >) const
Definition: region.cc:1335
void first_edit()
Definition: region.cc:480
LIBARDOUR_API PBD::PropertyDescriptor< float > shift
Definition: region.cc:71
void mid_thaw(const PBD::PropertyChange &)
Definition: region.cc:1300
void lower_region(boost::shared_ptr< Region >)
Definition: playlist.cc:2510
Definition: amp.h:29
virtual void recompute_at_end()=0
const PBD::ID & id() const
Definition: stateful.h:68
bool position_locked() const
Definition: region.h:165
virtual bool set_name(const std::string &str)
std::vector< std::string > master_source_names()
Definition: region.cc:1380
bool verify_start(framepos_t)
Definition: region.cc:1554
bool muted() const
Definition: region.h:162
LIBARDOUR_API PBD::PropertyDescriptor< bool > locked
Definition: region.cc:51
void print(char *buf, uint32_t bufsize) const
Definition: id.cc:73
bool is_compound() const
Definition: region.cc:1694
bool set_id(const XMLNode &)
Definition: stateful.cc:381
void lower_region_to_bottom(boost::shared_ptr< Region >)
Definition: playlist.cc:2524
std::vector< boost::shared_ptr< Source > > SourceList
Definition: region.h:91
PBD::EnumProperty< PositionLockStyle > _position_lock_style
Definition: region.h:410
bool deletion_in_progress() const
Definition: session.h:179
PBD::Property< bool > _opaque
Definition: region.h:397
Evoral::OverlapType coverage(framepos_t start, framepos_t end) const
Definition: region.h:195
LIBARDOUR_API PBD::PropertyDescriptor< bool > opaque
Definition: region.cc:50
void drop_sources()
Definition: region.cc:1617
uint32_t layer_t
Definition: types.h:59
frameoffset_t sync_offset(int &dir) const
Definition: region.cc:1041
#define DEBUG_TRACE(bits, str)
Definition: debug.h:55
std::string source_string() const
Definition: region.cc:1456
LIBARDOUR_API void make_property_quarks()
int64_t framepos_t
Definition: types.h:66
LIBARDOUR_API PBD::PropertyDescriptor< bool > external
Definition: region.cc:56
RouteGroup::RouteGroup(Session &s, const string &n) add_property(_relative)
Definition: route_group.cc:101
shared_ptr< T > static_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:386
LIBARDOUR_API PBD::PropertyDescriptor< bool > right_of_split
Definition: region.cc:59
bool region_list_equivalent(boost::shared_ptr< const Region >) const
Definition: region.cc:1356
void drop_references()
Definition: destructible.h:36
framepos_t earliest_possible_position() const
Definition: region.cc:1714
int64_t frameoffset_t
Definition: types.h:71
static PBD::Signal1< void, boost::shared_ptr< Region > > CheckNewRegion
PBD::Property< std::string > _name
#define REGION_COPY_STATE(other)
Definition: region.cc:191
virtual int adjust_transients(frameoffset_t)
Definition: region.h:313
void raise()
Definition: region.cc:1093
framepos_t adjust_to_sync(framepos_t) const
Definition: region.cc:1058
void set_whole_file(bool yn)
Definition: region.cc:948
LIBARDOUR_API RuntimeProfile * Profile
Definition: globals.cc:120
void set_muted(bool yn)
Definition: region.cc:962
framecnt_t source_length(uint32_t n) const
Definition: region.cc:1511
framepos_t position() const
Definition: region.h:112
LIBPBD_API uint64_t Properties
Definition: debug.cc:47
Timecode::BBT_Time _bbt_time
Definition: region.h:416
bool verify_start_mutable(framepos_t &_start)
Definition: region.cc:1569
void lower()
Definition: region.cc:1102
void register_properties()
Definition: region.cc:135
XMLProperty * add_property(const char *name, const std::string &value)
void trim_to(framepos_t position, framecnt_t length)
Definition: region.cc:842
void raise_region_to_top(boost::shared_ptr< Region >)
Definition: playlist.cc:2517
LIBARDOUR_API PBD::PropertyDescriptor< uint64_t > layering_index
Definition: region.cc:73
LIBARDOUR_API PBD::PropertyDescriptor< bool > import
Definition: region.cc:55
const char * name
virtual XMLNode & state()
Definition: region.cc:1136
void add_child_nocopy(XMLNode &)
Definition: xml++.cc:357
bool locked() const
Definition: region.h:164
void set_opaque(bool yn)
Definition: region.cc:971
void set_length(framecnt_t)
Definition: region.cc:430
Definition: xml++.h:95
void recompute_position_from_lock_style()
Definition: region.cc:626
DataType _type
Definition: region.h:358
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > position
Definition: region.cc:65
LIBARDOUR_API PBD::PropertyDescriptor< framecnt_t > ancestral_length
Definition: region.cc:69
LIBARDOUR_API PBD::PropertyDescriptor< framecnt_t > sync_position
Definition: region.cc:66
virtual ~Region()
Definition: region.cc:404
virtual void set_start_internal(framecnt_t)
Definition: region.cc:1708
Definition: debug.h:30
void send_change(const PBD::PropertyChange &)
Definition: region.cc:1311
LIBARDOUR_API PBD::PropertyDescriptor< bool > sync_marked
Definition: region.cc:57
PBD::Property< float > _shift
Definition: region.h:409
bool opaque() const
Definition: region.h:163
void set_automatic(bool yn)
Definition: region.cc:955
bool contains(PropertyDescriptor< T > p) const
void clear_sync_position()
Definition: region.cc:1027
void modify_front(framepos_t new_position, bool reset_fade)
Definition: region.cc:764
framecnt_t length() const
Definition: region.h:114
static const framepos_t max_framepos
Definition: types.h:78
PositionLockStyle
Definition: types.h:553
framepos_t first_frame() const
Definition: region.h:141
void set_position_lock_style(PositionLockStyle ps)
Definition: region.cc:543
void lower_to_bottom()
Definition: region.cc:1121
PBD::Property< bool > _hidden
Definition: region.h:404
framepos_t start() const
Definition: region.h:113
void nudge_position(frameoffset_t)
Definition: region.cc:634
static const framecnt_t max_framecnt
Definition: types.h:79
LIBARDOUR_API PBD::PropertyDescriptor< PositionLockStyle > position_lock_style
Definition: region.cc:72
virtual void set_length_internal(framecnt_t)
Definition: region.cc:468
uint32_t max_source_level() const
Definition: region.cc:1682
bool size_equivalent(boost::shared_ptr< const Region >) const
Definition: region.cc:1349
int apply(Filter &, Progress *progress=0)
Definition: region.cc:1601
bool sync_marked() const
Definition: region.h:172
PBD::Property< framecnt_t > _ancestral_length
Definition: region.h:407
bool at_natural_position() const
Definition: region.cc:496
static PBD::Signal2< void, boost::shared_ptr< ARDOUR::Region >, const PBD::PropertyChange & > RegionPropertyChanged
Definition: region.h:95
LIBARDOUR_API PBD::PropertyDescriptor< bool > valid_transients
Definition: region.cc:62
void bbt_time(framepos_t when, Timecode::BBT_Time &)
Definition: session_time.cc:47
LIBARDOUR_API PBD::PropertyDescriptor< bool > muted
Definition: region.cc:49
LIBARDOUR_API PBD::PropertyDescriptor< bool > position_locked
Definition: region.cc:61
LIBARDOUR_API PBD::PropertyDescriptor< bool > whole_file
Definition: region.cc:54
void add(PropertyID id)
PBD::Property< bool > _video_locked
Definition: region.h:399
virtual boost::shared_ptr< Region > get_parent() const
Definition: region.cc:1584
void move_to_natural_position()
Definition: region.cc:516
void set_start(framepos_t)
Definition: region.cc:675
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
LIBARDOUR_API PBD::PropertyDescriptor< bool > left_of_split
Definition: region.cc:58
framecnt_t _last_length
Definition: region.h:413
void set_locked(bool yn)
Definition: region.cc:980
boost::shared_ptr< ARDOUR::Playlist > playlist() const
Definition: region.h:251
boost::weak_ptr< ARDOUR::Playlist > _playlist
Definition: region.h:376
PBD::Property< framepos_t > _position
Definition: region.h:366
void suspend_property_changes()
Definition: region.cc:1292
PBD::Property< framecnt_t > _length
Definition: region.h:365
framepos_t last_frame() const
Definition: region.h:142
LIBARDOUR_API PBD::PropertyDescriptor< framecnt_t > length
Definition: region.cc:64
bool any_source_equivalent(boost::shared_ptr< const Region >) const
Definition: region.cc:1437
bool hidden() const
Definition: region.h:161