View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0005517 | ardour | features | public | 2013-06-07 09:02 | 2020-04-19 20:16 |
Reporter | colinf | Assigned To | paul | ||
Priority | normal | Severity | minor | Reproducibility | N/A |
Status | closed | Resolution | fixed | ||
Summary | 0005517: New intermediate 'Regions in active edit groups are edited together' setting | ||||
Description | I think that a setting for 'Regions in active edit groups are edited together' that considers regions equivalent when the bounds of one are either equal to or lie within the bounds of another would be useful. This would fit my workflow editing multi-track live recordings very well, where in general, all tracks are edited together, but the timing of the edits in one or two tracks occasionally has to be adjusted. Nether of the two existing region equivalency modes does exactly what I want here: 'only when identical' of course stops working as soon as any regions are edited slightly differently within the group, and 'whenever they overlap' selects regions on both sides of the edit. | ||||
Additional Information | ASCII-art examples to clarify how I think this new mode should work: |---a---| |--b--| |---a---| |--b--| |---a---| |--b--| - are equivalent. |---a---| |--b--| |---a---| |--b--| - are not. | ||||
Tags | No tags attached. | ||||
|
I like it. |
|
I started to hack this together, and it seemed like a doddle, but I got totally stumped thinking up a name for the function. The standard 'identical' equivalence mode function is Region::equivalent() and the 'overlap' mode is Region::overlap_equivalent(), but what to call this one? Also, I'm not sure whether it's a good idea to change the use_overlap_equivalency config setting from a bool to an int/enum for this third type, or to introduce a new config variable, or just change the overlap equivalency to work like this. Who uses overlap equivalency, anyway? |
|
I've implemented this now (I have it in a local branch), since I wanted it (especially in the face of 0004834). I made a new enumerated "region-equivalence" config setting, and got rid of the old "use-overlap-equivalency" boolean one, so anyone who had enabled the old one would lose their setting if the patch were to be merged as-is. I hope that's OK - I'd think that anyone who wants this setting knows they want it. There's also a discussion to be had about what the default should be - obviously I'd like it to be my new mode, but I guess there's a consistency argument in favour of making it be the 'exact' equivalence mode as at present. |
|
enclosed-equivalent-regions.patch (8,874 bytes)
commit ff2cfb306a0d46e267d5102a456fa01b086a3f4d Author: Colin Fletcher <colin.m.fletcher@googlemail.com> Date: Sun Dec 28 16:03:56 2014 +0000 Implement new 'Enclosed' region equivalence mode. diff --git a/gtk2_ardour/rc_option_editor.cc b/gtk2_ardour/rc_option_editor.cc index 421e4c56c..2f5f12d3a 100644 --- a/gtk2_ardour/rc_option_editor.cc +++ b/gtk2_ardour/rc_option_editor.cc @@ -1728,7 +1728,6 @@ RCOptionEditor::RCOptionEditor () uint32_t hwcpus = hardware_concurrency (); BoolOption* bo; - BoolComboOption* bco; if (hwcpus > 1) { add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization"))); @@ -2173,16 +2172,18 @@ if (!Profile->get_mixbus()) { add_option (_("Editor"), fadeshape); - bco = new BoolComboOption ( - "use-overlap-equivalency", + ComboOption<RegionEquivalence> *eqv = new ComboOption<RegionEquivalence> ( + "region-equivalence", _("Regions in active edit groups are edited together"), - _("whenever they overlap in time"), - _("only if they have identical length, position and origin"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency) + sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_equivalence), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_equivalence) ); - add_option (_("Editor"), bco); + eqv->add (Overlap, _("whenever they overlap in time")); + eqv->add (Enclosed, _("if either encloses the other")); + eqv->add (Exact, _("only if they have identical length, position and origin")); + + add_option (_("Editor"), eqv); ComboOption<LayerModel>* lm = new ComboOption<LayerModel> ( "layer-model", diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h index 39f770969..c48d9ee13 100644 --- a/libs/ardour/ardour/rc_configuration_vars.h +++ b/libs/ardour/ardour/rc_configuration_vars.h @@ -206,7 +206,7 @@ CONFIG_VARIABLE (bool, verify_remove_last_capture, "verify-remove-last-capture", CONFIG_VARIABLE (bool, save_history, "save-history", true) CONFIG_VARIABLE (int32_t, saved_history_depth, "save-history-depth", 20) CONFIG_VARIABLE (int32_t, history_depth, "history-depth", 20) -CONFIG_VARIABLE (bool, use_overlap_equivalency, "use-overlap-equivalency", false) +CONFIG_VARIABLE (RegionEquivalence, region_equivalence, "region-equivalence", Enclosed) CONFIG_VARIABLE (bool, periodic_safety_backups, "periodic-safety-backups", true) CONFIG_VARIABLE (uint32_t, periodic_safety_backup_interval, "periodic-safety-backup-interval", 120) CONFIG_VARIABLE (float, automation_interval_msecs, "automation-interval-msecs", 30) diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index a8a1475fb..3a86bd2e3 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -196,9 +196,10 @@ class LIBARDOUR_API Region return Evoral::coverage (first_frame(), last_frame(), start, end); } - bool equivalent (boost::shared_ptr<const Region>) const; + bool exact_equivalent (boost::shared_ptr<const Region>) const; bool size_equivalent (boost::shared_ptr<const Region>) const; bool overlap_equivalent (boost::shared_ptr<const Region>) const; + bool enclosed_equivalent (boost::shared_ptr<const Region>) const; bool region_list_equivalent (boost::shared_ptr<const Region>) const; bool source_equivalent (boost::shared_ptr<const Region>) const; bool any_source_equivalent (boost::shared_ptr<const Region>) const; diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 97dba38d7..45df5e7c1 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -568,6 +568,12 @@ namespace ARDOUR { class Bundle; typedef std::vector<boost::shared_ptr<Bundle> > BundleList; + enum RegionEquivalence { + Exact, + Enclosed, + Overlap + }; + enum WaveformScale { Linear, Logarithmic @@ -699,6 +705,7 @@ std::istream& operator>>(std::istream& o, ARDOUR::ShuttleBehaviour& sf); std::istream& operator>>(std::istream& o, ARDOUR::ShuttleUnits& sf); std::istream& operator>>(std::istream& o, Timecode::TimecodeFormat& sf); std::istream& operator>>(std::istream& o, ARDOUR::DenormalModel& sf); +std::istream& operator>>(std::istream& o, ARDOUR::RegionEquivalence& sf); std::istream& operator>>(std::istream& o, ARDOUR::PositionLockStyle& sf); std::istream& operator>>(std::istream& o, ARDOUR::FadeShape& sf); std::istream& operator>>(std::istream& o, ARDOUR::RegionSelectionAfterSplit& sf); @@ -723,6 +730,7 @@ std::ostream& operator<<(std::ostream& o, const ARDOUR::ShuttleBehaviour& sf); std::ostream& operator<<(std::ostream& o, const ARDOUR::ShuttleUnits& sf); std::ostream& operator<<(std::ostream& o, const Timecode::TimecodeFormat& sf); std::ostream& operator<<(std::ostream& o, const ARDOUR::DenormalModel& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::RegionEquivalence& sf); std::ostream& operator<<(std::ostream& o, const ARDOUR::PositionLockStyle& sf); std::ostream& operator<<(std::ostream& o, const ARDOUR::FadeShape& sf); std::ostream& operator<<(std::ostream& o, const ARDOUR::RegionSelectionAfterSplit& sf); diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc index fa8378072..8b39a7df1 100644 --- a/libs/ardour/enums.cc +++ b/libs/ardour/enums.cc @@ -124,6 +124,7 @@ setup_enum_writer () MidiModel::NoteDiffCommand::Property _MidiModel_NoteDiffCommand_Property; MidiModel::SysExDiffCommand::Property _MidiModel_SysExDiffCommand_Property; MidiModel::PatchChangeDiffCommand::Property _MidiModel_PatchChangeDiffCommand_Property; + RegionEquivalence _RegionEquivalence; WaveformScale _WaveformScale; WaveformShape _WaveformShape; Session::PostTransportWork _Session_PostTransportWork; @@ -664,6 +665,11 @@ setup_enum_writer () REGISTER_CLASS_ENUM (MidiModel::PatchChangeDiffCommand, Bank); REGISTER (_MidiModel_PatchChangeDiffCommand_Property); + REGISTER_ENUM (Exact); + REGISTER_ENUM (Enclosed); + REGISTER_ENUM (Overlap); + REGISTER(_RegionEquivalence); + REGISTER_ENUM(Linear); REGISTER_ENUM(Logarithmic); REGISTER(_WaveformScale); @@ -957,6 +963,20 @@ std::ostream& operator<<(std::ostream& o, const DenormalModel& var) std::string s = enum_2_string (var); return o << s; } +std::istream& operator>>(std::istream& o, RegionEquivalence& var) +{ + std::string s; + o >> s; + var = (RegionEquivalence) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const RegionEquivalence& var) +{ + std::string s = enum_2_string (var); + return o << s; +} + std::istream& operator>>(std::istream& o, WaveformScale& var) { std::string s; diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index 41681a73f..0a6dc48c7 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -830,18 +830,30 @@ Playlist::flush_notifications (bool from_undo) void Playlist::get_equivalent_regions (boost::shared_ptr<Region> other, vector<boost::shared_ptr<Region> >& results) { - if (Config->get_use_overlap_equivalency()) { - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - if ((*i)->overlap_equivalent (other)) { - results.push_back (*i); + switch (Config->get_region_equivalence()) { + case Exact: + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + if ((*i)->exact_equivalent (other)) { + results.push_back (*i); + } } - } - } else { - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - if ((*i)->equivalent (other)) { - results.push_back (*i); + break; + + case Enclosed: + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + if ((*i)->enclosed_equivalent (other)) { + results.push_back (*i); + } } - } + break; + + case Overlap: + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + if ((*i)->overlap_equivalent (other)) { + results.push_back (*i); + } + } + break; } } diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index bd99403cb..9745d3ac2 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -1380,7 +1380,14 @@ Region::overlap_equivalent (boost::shared_ptr<const Region> other) const } bool -Region::equivalent (boost::shared_ptr<const Region> other) const +Region::enclosed_equivalent (boost::shared_ptr<const Region> other) const +{ + return (first_frame() >= other->first_frame() && last_frame() <= other->last_frame()) || + (first_frame() <= other->first_frame() && last_frame() >= other->last_frame()) ; +} + +bool +Region::exact_equivalent (boost::shared_ptr<const Region> other) const { return _start == other->_start && _position == other->_position && |
|
enclosed-equivalent-regions-5.12.patch (7,609 bytes)
commit 019a90dbe28d0be8ad94ad8ab44734151744c89a Author: Colin Fletcher <colin.m.fletcher@googlemail.com> Date: Thu Sep 13 16:05:23 2018 +0100 Implement new 'Enclosed' region equivalence mode. Now applies to master diff --git a/gtk2_ardour/rc_option_editor.cc b/gtk2_ardour/rc_option_editor.cc index e086363a2..8cca0227f 100644 --- a/gtk2_ardour/rc_option_editor.cc +++ b/gtk2_ardour/rc_option_editor.cc @@ -2138,7 +2138,6 @@ RCOptionEditor::RCOptionEditor () uint32_t hwcpus = hardware_concurrency (); BoolOption* bo; - BoolComboOption* bco; if (hwcpus > 1) { add_option (_("General"), new OptionEditorHeading (_("DSP CPU Utilization"))); @@ -2444,16 +2443,18 @@ RCOptionEditor::RCOptionEditor () add_option (_("Editor"), fadeshape); - bco = new BoolComboOption ( - "use-overlap-equivalency", - _("Regions in edit groups are edited together"), - _("whenever they overlap in time"), - _("only if they have identical length and position"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency) + ComboOption<RegionEquivalence> *eqv = new ComboOption<RegionEquivalence> ( + "region-equivalence", + _("Regions in active edit groups are edited together"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_equivalence), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_equivalence) ); - add_option (_("Editor"), bco); + eqv->add (Overlap, _("whenever they overlap in time")); + eqv->add (Enclosed, _("if either encloses the other")); + eqv->add (Exact, _("only if they have identical length, position and origin")); + + add_option (_("Editor"), eqv); ComboOption<LayerModel>* lm = new ComboOption<LayerModel> ( "layer-model", diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h index 681c51a32..b7ee95e9e 100644 --- a/libs/ardour/ardour/rc_configuration_vars.h +++ b/libs/ardour/ardour/rc_configuration_vars.h @@ -212,7 +212,7 @@ CONFIG_VARIABLE (bool, verify_remove_last_capture, "verify-remove-last-capture", CONFIG_VARIABLE (bool, save_history, "save-history", true) CONFIG_VARIABLE (int32_t, saved_history_depth, "save-history-depth", 20) CONFIG_VARIABLE (int32_t, history_depth, "history-depth", 20) -CONFIG_VARIABLE (bool, use_overlap_equivalency, "use-overlap-equivalency", false) +CONFIG_VARIABLE (RegionEquivalence, region_equivalence, "region-equivalence", Enclosed) CONFIG_VARIABLE (bool, periodic_safety_backups, "periodic-safety-backups", true) CONFIG_VARIABLE (uint32_t, periodic_safety_backup_interval, "periodic-safety-backup-interval", 120) CONFIG_VARIABLE (float, automation_interval_msecs, "automation-interval-msecs", 30) diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index b536aa16a..5d0413beb 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -201,9 +201,10 @@ public: return Evoral::coverage (first_sample(), last_sample(), start, end); } - bool equivalent (boost::shared_ptr<const Region>) const; + bool exact_equivalent (boost::shared_ptr<const Region>) const; bool size_equivalent (boost::shared_ptr<const Region>) const; bool overlap_equivalent (boost::shared_ptr<const Region>) const; + bool enclosed_equivalent (boost::shared_ptr<const Region>) const; bool region_list_equivalent (boost::shared_ptr<const Region>) const; bool source_equivalent (boost::shared_ptr<const Region>) const; bool any_source_equivalent (boost::shared_ptr<const Region>) const; diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index f835a5ff0..366e30318 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -605,6 +605,12 @@ namespace ARDOUR { class Bundle; typedef std::vector<boost::shared_ptr<Bundle> > BundleList; + enum RegionEquivalence { + Exact, + Enclosed, + Overlap + }; + enum WaveformScale { Linear, Logarithmic diff --git a/libs/ardour/ardour/types_convert.h b/libs/ardour/ardour/types_convert.h index 831761498..dcdc49fae 100644 --- a/libs/ardour/ardour/types_convert.h +++ b/libs/ardour/ardour/types_convert.h @@ -68,6 +68,7 @@ DEFINE_ENUM_CONVERT(ARDOUR::PluginType) DEFINE_ENUM_CONVERT(ARDOUR::AlignStyle) DEFINE_ENUM_CONVERT(ARDOUR::AlignChoice) +DEFINE_ENUM_CONVERT(ARDOUR::RegionEquivalence) DEFINE_ENUM_CONVERT(ARDOUR::WaveformScale) DEFINE_ENUM_CONVERT(ARDOUR::WaveformShape) DEFINE_ENUM_CONVERT(ARDOUR::VUMeterStandard) diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc index 74e445a37..1173a99b0 100644 --- a/libs/ardour/enums.cc +++ b/libs/ardour/enums.cc @@ -127,6 +127,7 @@ setup_enum_writer () MidiModel::NoteDiffCommand::Property _MidiModel_NoteDiffCommand_Property; MidiModel::SysExDiffCommand::Property _MidiModel_SysExDiffCommand_Property; MidiModel::PatchChangeDiffCommand::Property _MidiModel_PatchChangeDiffCommand_Property; + RegionEquivalence _RegionEquivalence; WaveformScale _WaveformScale; WaveformShape _WaveformShape; Session::PostTransportWork _Session_PostTransportWork; @@ -685,6 +686,11 @@ setup_enum_writer () REGISTER_ENUM(MidiPortSelection); REGISTER_BITS(_MidiPortFlags); + REGISTER_ENUM(Exact); + REGISTER_ENUM(Enclosed); + REGISTER_ENUM(Overlap); + REGISTER(_RegionEquivalence); + REGISTER_ENUM(Linear); REGISTER_ENUM(Logarithmic); REGISTER(_WaveformScale); diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index c3b91f3f4..c992c1057 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -839,18 +839,28 @@ Playlist::remove_region_internal (boost::shared_ptr<Region> region) void Playlist::get_equivalent_regions (boost::shared_ptr<Region> other, vector<boost::shared_ptr<Region> >& results) { - if (Config->get_use_overlap_equivalency()) { - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - if ((*i)->overlap_equivalent (other)) { - results.push_back (*i); - } - } - } else { - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - if ((*i)->equivalent (other)) { - results.push_back (*i); - } - } + switch (Config->get_region_equivalence()) { + case Exact: + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + if ((*i)->exact_equivalent (other)) { + results.push_back (*i); + } + } + break; + case Enclosed: + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + if ((*i)->enclosed_equivalent (other)) { + results.push_back (*i); + } + } + break; + case Overlap: + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + if ((*i)->overlap_equivalent (other)) { + results.push_back (*i); + } + } + break; } } diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index cad32cd4d..d4afb7d9c 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -1478,7 +1478,14 @@ Region::overlap_equivalent (boost::shared_ptr<const Region> other) const } bool -Region::equivalent (boost::shared_ptr<const Region> other) const +Region::enclosed_equivalent (boost::shared_ptr<const Region> other) const +{ + return (first_sample() >= other->first_sample() && last_sample() <= other->last_sample()) || + (first_sample() <= other->first_sample() && last_sample() >= other->last_sample()) ; +} + +bool +Region::exact_equivalent (boost::shared_ptr<const Region> other) const { return _start == other->_start && _position == other->_position && |
|
Attached enclosed-equivalent-regions-5.12.patch applies on master (and 5.12), and Works For Me™. |
|
git-applied to master and committed as 9321f46c453b |
|
Issue has been closed automatically, by Trigger Close Plugin. Feel free to re-open with additional information if you think the issue is not resolved. |
Date Modified | Username | Field | Change |
---|---|---|---|
2013-06-07 09:02 | colinf | New Issue | |
2013-06-10 16:10 | paul | Note Added: 0014963 | |
2013-06-10 17:29 | colinf | Note Added: 0014973 | |
2014-09-19 18:36 | colinf | Note Added: 0015889 | |
2018-09-13 13:25 | colinf | File Added: enclosed-equivalent-regions.patch | |
2018-09-13 16:59 | colinf | File Added: enclosed-equivalent-regions-5.12.patch | |
2018-09-13 17:02 | colinf | Note Added: 0020385 | |
2018-09-13 18:18 | paul | Note Added: 0020386 | |
2018-09-13 18:18 | paul | Status | new => resolved |
2018-09-13 18:18 | paul | Resolution | open => fixed |
2018-09-13 18:18 | paul | Assigned To | => paul |
2020-04-19 20:16 | system | Note Added: 0023237 | |
2020-04-19 20:16 | system | Status | resolved => closed |