mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 07:14:56 +01:00
beat slicing patch #1 from lincoln spiteri
git-svn-id: svn://localhost/ardour2/branches/3.0@7381 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
2f11b367ca
commit
2f9184d653
24 changed files with 828 additions and 193 deletions
|
|
@ -172,12 +172,13 @@
|
||||||
<menuitem action='editor-delete'/>
|
<menuitem action='editor-delete'/>
|
||||||
<menuitem action='editor-crop'/>
|
<menuitem action='editor-crop'/>
|
||||||
<menuitem action='split-region'/>
|
<menuitem action='split-region'/>
|
||||||
|
<menuitem action='split-region-at-transients'/>
|
||||||
<menu action="SeparateMenu">
|
<menu action="SeparateMenu">
|
||||||
|
<menuitem action='separate-under-region'/>
|
||||||
<menuitem action='editor-separate'/>
|
<menuitem action='editor-separate'/>
|
||||||
<menuitem action='separate-from-loop'/>
|
<menuitem action='separate-from-loop'/>
|
||||||
<menuitem action='separate-from-punch'/>
|
<menuitem action='separate-from-punch'/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<menuitem action='split-region-at-transients'/>
|
|
||||||
</menu>
|
</menu>
|
||||||
<menu action="AlignMenu">
|
<menu action="AlignMenu">
|
||||||
<menuitem action='align-regions-start'/>
|
<menuitem action='align-regions-start'/>
|
||||||
|
|
@ -272,8 +273,14 @@
|
||||||
<menuitem action='set-punch-from-region'/>
|
<menuitem action='set-punch-from-region'/>
|
||||||
<menuitem action='add-range-marker-from-region'/>
|
<menuitem action='add-range-marker-from-region'/>
|
||||||
<menuitem action='add-range-markers-from-region'/>
|
<menuitem action='add-range-markers-from-region'/>
|
||||||
|
|
||||||
<separator/>
|
<separator/>
|
||||||
|
<menuitem action='snap-regions-to-grid'/>
|
||||||
|
<menuitem action='close-region-gaps'/>
|
||||||
|
<separator/>
|
||||||
|
<menuitem action='place-transient' />
|
||||||
<menuitem action='toggle-rhythm-ferret'/>
|
<menuitem action='toggle-rhythm-ferret'/>
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
<menu action='TrackMenu'>
|
<menu action='TrackMenu'>
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,10 @@ AudioRegionView::~AudioRegionView ()
|
||||||
delete *i;
|
delete *i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> >::iterator i = feature_lines.begin(); i != feature_lines.end(); ++i) {
|
||||||
|
delete ((*i).second);
|
||||||
|
}
|
||||||
|
|
||||||
/* all waveviews etc will be destroyed when the group is destroyed */
|
/* all waveviews etc will be destroyed when the group is destroyed */
|
||||||
|
|
||||||
delete gain_line;
|
delete gain_line;
|
||||||
|
|
@ -292,6 +296,9 @@ AudioRegionView::region_changed (const PropertyChange& what_changed)
|
||||||
if (what_changed.contains (ARDOUR::Properties::envelope_active)) {
|
if (what_changed.contains (ARDOUR::Properties::envelope_active)) {
|
||||||
envelope_active_changed ();
|
envelope_active_changed ();
|
||||||
}
|
}
|
||||||
|
if (what_changed.contains (ARDOUR::Properties::valid_transients)) {
|
||||||
|
transients_changed ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -388,13 +395,26 @@ AudioRegionView::region_resized (const PropertyChange& what_changed)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
|
for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
|
||||||
if((agr = dynamic_cast<AudioGhostRegion*>(*i)) != 0) {
|
if ((agr = dynamic_cast<AudioGhostRegion*>(*i)) != 0) {
|
||||||
|
|
||||||
for (vector<WaveView*>::iterator w = agr->waves.begin(); w != agr->waves.end(); ++w) {
|
for (vector<WaveView*>::iterator w = agr->waves.begin(); w != agr->waves.end(); ++w) {
|
||||||
(*w)->property_region_start() = _region->start();
|
(*w)->property_region_start() = _region->start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* hide transient lines that extend beyond the region end */
|
||||||
|
|
||||||
|
list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> >::iterator l;
|
||||||
|
|
||||||
|
for (l = feature_lines.begin(); l != feature_lines.end(); ++l) {
|
||||||
|
if ((*l).first > _region->length()- 1){
|
||||||
|
(*l).second->hide();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(*l).second->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -425,6 +445,15 @@ AudioRegionView::reset_width_dependent_items (double pixel_width)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnalysisFeatureList analysis_features = _region->transients();
|
||||||
|
AnalysisFeatureList::const_iterator i;
|
||||||
|
list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> >::iterator l;
|
||||||
|
|
||||||
|
for (i = analysis_features.begin(), l = feature_lines.begin(); i != analysis_features.end() && l != feature_lines.end(); ++i, ++l) {
|
||||||
|
(*l).second->property_x1() = trackview.editor().frame_to_pixel (*i);
|
||||||
|
(*l).second->property_x2() = trackview.editor().frame_to_pixel (*i);
|
||||||
|
}
|
||||||
|
|
||||||
reset_fade_shapes ();
|
reset_fade_shapes ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -502,6 +531,13 @@ AudioRegionView::set_height (gdouble height)
|
||||||
manage_zero_line ();
|
manage_zero_line ();
|
||||||
reset_fade_shapes ();
|
reset_fade_shapes ();
|
||||||
|
|
||||||
|
/* Update hights for any active feature lines */
|
||||||
|
list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> >::iterator l;
|
||||||
|
|
||||||
|
for (l = feature_lines.begin(); l != feature_lines.end(); ++l) {
|
||||||
|
(*l).second->property_y2() = _height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (name_pixbuf) {
|
if (name_pixbuf) {
|
||||||
name_pixbuf->raise_to_top();
|
name_pixbuf->raise_to_top();
|
||||||
}
|
}
|
||||||
|
|
@ -583,7 +619,7 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
|
||||||
float curve[npoints];
|
float curve[npoints];
|
||||||
audio_region()->fade_in()->curve().get_vector (0, audio_region()->fade_in()->back()->when, curve, npoints);
|
audio_region()->fade_in()->curve().get_vector (0, audio_region()->fade_in()->back()->when, curve, npoints);
|
||||||
|
|
||||||
points = get_canvas_points ("fade in shape", npoints+3);
|
points = get_canvas_points ("fade in shape", npoints + 3);
|
||||||
|
|
||||||
if (_height >= NAME_HIGHLIGHT_THRESH) {
|
if (_height >= NAME_HIGHLIGHT_THRESH) {
|
||||||
h = _height - NAME_HIGHLIGHT_SIZE;
|
h = _height - NAME_HIGHLIGHT_SIZE;
|
||||||
|
|
@ -682,7 +718,7 @@ AudioRegionView::reset_fade_out_shape_width (nframes_t width)
|
||||||
|
|
||||||
/* points *MUST* be in anti-clockwise order */
|
/* points *MUST* be in anti-clockwise order */
|
||||||
|
|
||||||
points = get_canvas_points ("fade out shape", npoints+3);
|
points = get_canvas_points ("fade out shape", npoints + 3);
|
||||||
|
|
||||||
uint32_t pi, pc;
|
uint32_t pi, pc;
|
||||||
double xdelta = pwidth/npoints;
|
double xdelta = pwidth/npoints;
|
||||||
|
|
@ -1380,3 +1416,72 @@ AudioRegionView::show_region_editor ()
|
||||||
editor->present ();
|
editor->present ();
|
||||||
editor->show_all();
|
editor->show_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioRegionView::transients_changed ()
|
||||||
|
{
|
||||||
|
AnalysisFeatureList analysis_features = _region->transients();
|
||||||
|
|
||||||
|
while (feature_lines.size() < analysis_features.size()) {
|
||||||
|
ArdourCanvas::SimpleLine* l = new ArdourCanvas::SimpleLine (*group);
|
||||||
|
l->property_color_rgba() = (guint) ARDOUR_UI::config()->canvasvar_ZeroLine.get();
|
||||||
|
feature_lines.push_back (make_pair(0, l));
|
||||||
|
}
|
||||||
|
|
||||||
|
while (feature_lines.size() > analysis_features.size()) {
|
||||||
|
ArdourCanvas::SimpleLine *line = feature_lines.back().second;
|
||||||
|
feature_lines.pop_back ();
|
||||||
|
delete line;
|
||||||
|
}
|
||||||
|
|
||||||
|
AnalysisFeatureList::const_iterator i;
|
||||||
|
list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> >::iterator l;
|
||||||
|
|
||||||
|
for (i = analysis_features.begin(), l = feature_lines.begin(); i != analysis_features.end() && l != feature_lines.end(); ++i, ++l) {
|
||||||
|
(*l).first = *i;
|
||||||
|
(*l).second->property_x1() = trackview.editor().frame_to_pixel (*i);
|
||||||
|
(*l).second->property_x2() = trackview.editor().frame_to_pixel (*i);
|
||||||
|
(*l).second->property_y1() = 2;
|
||||||
|
(*l).second->property_y2() = _height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 1;
|
||||||
|
(*l).second->set_data("regionview", this);
|
||||||
|
(*l).second->show ();
|
||||||
|
(*l).second->raise_to_top ();
|
||||||
|
|
||||||
|
(*l).second->signal_event().connect (sigc::bind (sigc::mem_fun (PublicEditor::instance(), &PublicEditor::canvas_feature_line_event), (*l).second, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioRegionView::update_transient(float old_pos, float new_pos)
|
||||||
|
{
|
||||||
|
/* Find frame at old pos, calulate new frame then update region transients*/
|
||||||
|
list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> >::iterator l;
|
||||||
|
|
||||||
|
for (l = feature_lines.begin(); l != feature_lines.end(); ++l) {
|
||||||
|
/* Simple line x1 has been updated in drag so we compare to new_pos */
|
||||||
|
if (rint(new_pos) == rint((*l).second->property_x1())) {
|
||||||
|
|
||||||
|
nframes64_t old_frame = (*l).first;
|
||||||
|
nframes64_t new_frame = trackview.editor().pixel_to_frame (new_pos);
|
||||||
|
|
||||||
|
_region->update_transient (old_frame, new_frame);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioRegionView::remove_transient(float pos)
|
||||||
|
{
|
||||||
|
/* Find frame at old pos, calulate new frame then update region transients*/
|
||||||
|
list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> >::iterator l;
|
||||||
|
|
||||||
|
for (l = feature_lines.begin(); l != feature_lines.end(); ++l) {
|
||||||
|
/* Simple line x1 has been updated in drag so we compare to new_pos */
|
||||||
|
if (rint(pos) == rint((*l).second->property_x1())) {
|
||||||
|
_region->remove_transient ((*l).first);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -106,6 +106,9 @@ class AudioRegionView : public RegionView
|
||||||
void set_fade_visibility (bool);
|
void set_fade_visibility (bool);
|
||||||
void update_coverage_frames (LayerDisplay);
|
void update_coverage_frames (LayerDisplay);
|
||||||
|
|
||||||
|
void update_transient(float old_pos, float new_pos);
|
||||||
|
void remove_transient(float pos);
|
||||||
|
|
||||||
void show_region_editor ();
|
void show_region_editor ();
|
||||||
|
|
||||||
virtual void entered ();
|
virtual void entered ();
|
||||||
|
|
@ -127,6 +130,9 @@ class AudioRegionView : public RegionView
|
||||||
|
|
||||||
std::vector<ArdourCanvas::WaveView *> waves;
|
std::vector<ArdourCanvas::WaveView *> waves;
|
||||||
std::vector<ArdourCanvas::WaveView *> tmp_waves; ///< see ::create_waves()
|
std::vector<ArdourCanvas::WaveView *> tmp_waves; ///< see ::create_waves()
|
||||||
|
|
||||||
|
std::list<std::pair<nframes64_t, ArdourCanvas::SimpleLine*> > feature_lines;
|
||||||
|
|
||||||
ArdourCanvas::Polygon* sync_mark; ///< polgyon for sync position
|
ArdourCanvas::Polygon* sync_mark; ///< polgyon for sync position
|
||||||
ArdourCanvas::SimpleLine* zero_line;
|
ArdourCanvas::SimpleLine* zero_line;
|
||||||
ArdourCanvas::Polygon* fade_in_shape;
|
ArdourCanvas::Polygon* fade_in_shape;
|
||||||
|
|
@ -170,6 +176,8 @@ class AudioRegionView : public RegionView
|
||||||
|
|
||||||
std::vector<GnomeCanvasWaveViewCache*> wave_caches;
|
std::vector<GnomeCanvasWaveViewCache*> wave_caches;
|
||||||
|
|
||||||
|
void transients_changed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void setup_fade_handle_positions ();
|
void setup_fade_handle_positions ();
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||||
void new_region_from_selection ();
|
void new_region_from_selection ();
|
||||||
void separate_regions_between (const TimeSelection&);
|
void separate_regions_between (const TimeSelection&);
|
||||||
void separate_region_from_selection ();
|
void separate_region_from_selection ();
|
||||||
|
void separate_under_selected_regions ();
|
||||||
void separate_region_from_punch ();
|
void separate_region_from_punch ();
|
||||||
void separate_region_from_loop ();
|
void separate_region_from_loop ();
|
||||||
void separate_regions_using_location (ARDOUR::Location&);
|
void separate_regions_using_location (ARDOUR::Location&);
|
||||||
|
|
@ -921,10 +922,10 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||||
void select_all_selectables_between (bool within);
|
void select_all_selectables_between (bool within);
|
||||||
void select_range_between ();
|
void select_range_between ();
|
||||||
|
|
||||||
boost::shared_ptr<ARDOUR::Region> find_next_region (nframes64_t, ARDOUR::RegionPoint, int32_t dir, TrackViewList&, TimeAxisView ** = 0);
|
boost::shared_ptr<ARDOUR::Region> find_next_region (ARDOUR::framepos_t, ARDOUR::RegionPoint, int32_t dir, TrackViewList&, TimeAxisView ** = 0);
|
||||||
nframes64_t find_next_region_boundary (nframes64_t, int32_t dir, const TrackViewList&);
|
ARDOUR::framepos_t find_next_region_boundary (ARDOUR::framepos_t, int32_t dir, const TrackViewList&);
|
||||||
|
|
||||||
std::vector<nframes64_t> region_boundary_cache;
|
std::vector<ARDOUR::framepos_t> region_boundary_cache;
|
||||||
void build_region_boundary_cache ();
|
void build_region_boundary_cache ();
|
||||||
|
|
||||||
Gtk::HBox top_hbox;
|
Gtk::HBox top_hbox;
|
||||||
|
|
@ -1125,6 +1126,11 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||||
void copy ();
|
void copy ();
|
||||||
void paste (float times);
|
void paste (float times);
|
||||||
|
|
||||||
|
void place_transient ();
|
||||||
|
void remove_transient (ArdourCanvas::Item* item);
|
||||||
|
void snap_regions_to_grid ();
|
||||||
|
void close_region_gaps ();
|
||||||
|
|
||||||
int get_prefix (float&, bool&);
|
int get_prefix (float&, bool&);
|
||||||
|
|
||||||
void keyboard_paste ();
|
void keyboard_paste ();
|
||||||
|
|
@ -1364,6 +1370,7 @@ public:
|
||||||
bool canvas_frame_handle_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
|
bool canvas_frame_handle_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
|
||||||
bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
|
bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
|
||||||
bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
|
bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
|
||||||
|
bool canvas_feature_line_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*);
|
||||||
bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, RouteTimeAxisView*);
|
bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, RouteTimeAxisView*);
|
||||||
bool canvas_marker_event (GdkEvent* event,ArdourCanvas::Item*, Marker*);
|
bool canvas_marker_event (GdkEvent* event,ArdourCanvas::Item*, Marker*);
|
||||||
bool canvas_zoom_rect_event (GdkEvent* event,ArdourCanvas::Item*);
|
bool canvas_zoom_rect_event (GdkEvent* event,ArdourCanvas::Item*);
|
||||||
|
|
@ -2064,6 +2071,7 @@ public:
|
||||||
friend class EditorGroupTabs;
|
friend class EditorGroupTabs;
|
||||||
|
|
||||||
friend class EditorRoutes;
|
friend class EditorRoutes;
|
||||||
|
friend class RhythmFerret;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __ardour_editor_h__ */
|
#endif /* __ardour_editor_h__ */
|
||||||
|
|
|
||||||
|
|
@ -476,6 +476,15 @@ Editor::register_actions ()
|
||||||
act = ActionManager::register_action (editor_actions, "mute-unmute-region", _("Mute/Unmute Region"), sigc::mem_fun(*this, &Editor::kbd_mute_unmute_region));
|
act = ActionManager::register_action (editor_actions, "mute-unmute-region", _("Mute/Unmute Region"), sigc::mem_fun(*this, &Editor::kbd_mute_unmute_region));
|
||||||
ActionManager::session_sensitive_actions.push_back (act);
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
ActionManager::region_selection_sensitive_actions.push_back (act);
|
ActionManager::region_selection_sensitive_actions.push_back (act);
|
||||||
|
act = ActionManager::register_action (editor_actions, "snap-regions-to-grid", _("Snap Regions to Grid"), sigc::mem_fun(*this, &Editor::snap_regions_to_grid));
|
||||||
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
|
ActionManager::region_selection_sensitive_actions.push_back (act);
|
||||||
|
act = ActionManager::register_action (editor_actions, "close-region-gaps", _("Close Region Gaps"), sigc::mem_fun(*this, &Editor::close_region_gaps));
|
||||||
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
|
ActionManager::region_selection_sensitive_actions.push_back (act);
|
||||||
|
act = ActionManager::register_action (editor_actions, "place-transient", _("Place Transient"), sigc::mem_fun(*this, &Editor::place_transient));
|
||||||
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
|
ActionManager::region_selection_sensitive_actions.push_back (act);
|
||||||
|
|
||||||
undo_action = act = ActionManager::register_action (editor_actions, "undo", _("Undo"), sigc::bind (sigc::mem_fun(*this, &Editor::undo), 1U));
|
undo_action = act = ActionManager::register_action (editor_actions, "undo", _("Undo"), sigc::bind (sigc::mem_fun(*this, &Editor::undo), 1U));
|
||||||
ActionManager::session_sensitive_actions.push_back (act);
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
|
|
@ -487,20 +496,28 @@ Editor::register_actions ()
|
||||||
act = ActionManager::register_action (editor_actions, "export-range", _("Export Range"), sigc::mem_fun(*this, &Editor::export_range));
|
act = ActionManager::register_action (editor_actions, "export-range", _("Export Range"), sigc::mem_fun(*this, &Editor::export_range));
|
||||||
ActionManager::session_sensitive_actions.push_back (act);
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
|
|
||||||
|
act = ActionManager::register_action (editor_actions, "separate-under-region", _("Separate Under Selected Regions"), sigc::mem_fun(*this, &Editor::separate_under_selected_regions));
|
||||||
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
|
|
||||||
act = ActionManager::register_action (editor_actions, "editor-separate", _("Separate"), sigc::mem_fun(*this, &Editor::separate_region_from_selection));
|
act = ActionManager::register_action (editor_actions, "editor-separate", _("Separate"), sigc::mem_fun(*this, &Editor::separate_region_from_selection));
|
||||||
ActionManager::session_sensitive_actions.push_back (act);
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
|
ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
|
||||||
|
|
||||||
act = ActionManager::register_action (editor_actions, "separate-from-punch", _("Separate Using Punch Range"), sigc::mem_fun(*this, &Editor::separate_region_from_punch));
|
act = ActionManager::register_action (editor_actions, "separate-from-punch", _("Separate Using Punch Range"), sigc::mem_fun(*this, &Editor::separate_region_from_punch));
|
||||||
ActionManager::session_sensitive_actions.push_back (act);
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
|
ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
|
||||||
|
|
||||||
act = ActionManager::register_action (editor_actions, "separate-from-loop", _("Separate Using Loop Range"), sigc::mem_fun(*this, &Editor::separate_region_from_loop));
|
act = ActionManager::register_action (editor_actions, "separate-from-loop", _("Separate Using Loop Range"), sigc::mem_fun(*this, &Editor::separate_region_from_loop));
|
||||||
ActionManager::session_sensitive_actions.push_back (act);
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
|
ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
|
||||||
|
|
||||||
act = ActionManager::register_action (editor_actions, "editor-crop", _("Crop"), sigc::mem_fun(*this, &Editor::crop_region_to_selection));
|
act = ActionManager::register_action (editor_actions, "editor-crop", _("Crop"), sigc::mem_fun(*this, &Editor::crop_region_to_selection));
|
||||||
ActionManager::session_sensitive_actions.push_back (act);
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
|
ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
|
||||||
|
|
||||||
act = ActionManager::register_action (editor_actions, "editor-cut", _("Cut"), sigc::mem_fun(*this, &Editor::cut));
|
act = ActionManager::register_action (editor_actions, "editor-cut", _("Cut"), sigc::mem_fun(*this, &Editor::cut));
|
||||||
ActionManager::session_sensitive_actions.push_back (act);
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
|
|
||||||
/* Note: for now, editor-delete does the exact same thing as editor-cut */
|
/* Note: for now, editor-delete does the exact same thing as editor-cut */
|
||||||
act = ActionManager::register_action (editor_actions, "editor-delete", _("Delete"), sigc::mem_fun(*this, &Editor::cut));
|
act = ActionManager::register_action (editor_actions, "editor-delete", _("Delete"), sigc::mem_fun(*this, &Editor::cut));
|
||||||
ActionManager::session_sensitive_actions.push_back (act);
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
|
|
|
||||||
|
|
@ -899,6 +899,45 @@ Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Editor::canvas_feature_line_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView *rv)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
switch (event->type) {
|
||||||
|
case GDK_BUTTON_PRESS:
|
||||||
|
case GDK_2BUTTON_PRESS:
|
||||||
|
case GDK_3BUTTON_PRESS:
|
||||||
|
clicked_regionview = 0;
|
||||||
|
clicked_control_point = 0;
|
||||||
|
clicked_axisview = 0;
|
||||||
|
clicked_routeview = 0; //dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
|
||||||
|
ret = button_press_handler (item, event, FeatureLineItem);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GDK_BUTTON_RELEASE:
|
||||||
|
ret = button_release_handler (item, event, FeatureLineItem);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GDK_MOTION_NOTIFY:
|
||||||
|
ret = motion_handler (item, event);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GDK_ENTER_NOTIFY:
|
||||||
|
ret = enter_handler (item, event, FeatureLineItem);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GDK_LEAVE_NOTIFY:
|
||||||
|
ret = leave_handler (item, event, FeatureLineItem);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* /*marker*/)
|
Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* /*marker*/)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2935,6 +2935,76 @@ LineDrag::aborted ()
|
||||||
_line->reset ();
|
_line->reset ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FeatureLineDrag::FeatureLineDrag (Editor* e, ArdourCanvas::Item* i)
|
||||||
|
: Drag (e, i),
|
||||||
|
_line (0),
|
||||||
|
_cumulative_x_drag (0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void
|
||||||
|
FeatureLineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
|
||||||
|
{
|
||||||
|
|
||||||
|
Drag::start_grab (event);
|
||||||
|
|
||||||
|
_line = reinterpret_cast<SimpleLine*> (_item);
|
||||||
|
assert (_line);
|
||||||
|
|
||||||
|
/* need to get x coordinate in terms of parent (AudioRegionView) origin. */
|
||||||
|
|
||||||
|
double cx = event->button.x;
|
||||||
|
double cy = event->button.y;
|
||||||
|
|
||||||
|
_item->property_parent().get_value()->w2i(cx, cy);
|
||||||
|
|
||||||
|
/* store grab start in parent frame */
|
||||||
|
_region_view_grab_x = cx;
|
||||||
|
|
||||||
|
_before = _line->property_x1();
|
||||||
|
|
||||||
|
_arv = reinterpret_cast<AudioRegionView*> (_item->get_data ("regionview"));
|
||||||
|
|
||||||
|
_max_x = _editor->frame_to_pixel(_arv->get_duration());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FeatureLineDrag::motion (GdkEvent* event, bool)
|
||||||
|
{
|
||||||
|
double dx = _drags->current_pointer_x() - last_pointer_x();
|
||||||
|
|
||||||
|
double cx = _region_view_grab_x + _cumulative_x_drag + dx;
|
||||||
|
|
||||||
|
_cumulative_x_drag += dx;
|
||||||
|
|
||||||
|
/* Clamp the min and max extent of the drag to keep it within the region view bounds */
|
||||||
|
|
||||||
|
if (cx > _max_x){
|
||||||
|
cx = _max_x;
|
||||||
|
}
|
||||||
|
else if(cx < 0){
|
||||||
|
cx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_line->property_x1() = cx;
|
||||||
|
_line->property_x2() = cx;
|
||||||
|
|
||||||
|
_before = _line->property_x1();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FeatureLineDrag::finished (GdkEvent* event, bool)
|
||||||
|
{
|
||||||
|
_arv = reinterpret_cast<AudioRegionView*> (_item->get_data ("regionview"));
|
||||||
|
_arv->update_transient(_before, _line->property_x1());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FeatureLineDrag::aborted ()
|
||||||
|
{
|
||||||
|
//_line->reset ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RubberbandSelectDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
|
RubberbandSelectDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -604,6 +604,33 @@ private:
|
||||||
double _cumulative_y_drag;
|
double _cumulative_y_drag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Transient feature line drags*/
|
||||||
|
class FeatureLineDrag : public Drag
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FeatureLineDrag (Editor *e, ArdourCanvas::Item *i);
|
||||||
|
|
||||||
|
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
|
||||||
|
void motion (GdkEvent *, bool);
|
||||||
|
void finished (GdkEvent *, bool);
|
||||||
|
void aborted ();
|
||||||
|
|
||||||
|
bool active (Editing::MouseMode) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ArdourCanvas::SimpleLine* _line;
|
||||||
|
AudioRegionView* _arv;
|
||||||
|
|
||||||
|
double _region_view_grab_x;
|
||||||
|
double _cumulative_x_drag;
|
||||||
|
|
||||||
|
uint32_t _before;
|
||||||
|
uint32_t _max_x;
|
||||||
|
};
|
||||||
|
|
||||||
/** Dragging of a rubberband rectangle for selecting things */
|
/** Dragging of a rubberband rectangle for selecting things */
|
||||||
class RubberbandSelectDrag : public Drag
|
class RubberbandSelectDrag : public Drag
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ enum ItemType {
|
||||||
FadeOutItem,
|
FadeOutItem,
|
||||||
FadeOutHandleItem,
|
FadeOutHandleItem,
|
||||||
NoteItem,
|
NoteItem,
|
||||||
|
FeatureLineItem,
|
||||||
LeftFrameHandle,
|
LeftFrameHandle,
|
||||||
RightFrameHandle,
|
RightFrameHandle,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -735,10 +735,23 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case FeatureLineItem:
|
||||||
|
{
|
||||||
|
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::TertiaryModifier)) {
|
||||||
|
remove_transient(item);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_drags->set (new FeatureLineDrag (this, item), event);
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case RegionItem:
|
case RegionItem:
|
||||||
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
|
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
|
||||||
add_region_copy_drag (item, event, clicked_regionview);
|
add_region_copy_drag (item, event, clicked_regionview);
|
||||||
} else if (Keyboard::the_keyboard().key_is_down (GDK_b)) {
|
}
|
||||||
|
else if (Keyboard::the_keyboard().key_is_down (GDK_b)) {
|
||||||
add_region_brush_drag (item, event, clicked_regionview);
|
add_region_brush_drag (item, event, clicked_regionview);
|
||||||
} else {
|
} else {
|
||||||
add_region_drag (item, event, clicked_regionview);
|
add_region_drag (item, event, clicked_regionview);
|
||||||
|
|
@ -1616,7 +1629,12 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
|
||||||
track_canvas->get_window()->set_cursor (*fade_out_cursor);
|
track_canvas->get_window()->set_cursor (*fade_out_cursor);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case FeatureLineItem:
|
||||||
|
{
|
||||||
|
ArdourCanvas::SimpleLine *line = dynamic_cast<ArdourCanvas::SimpleLine *> (item);
|
||||||
|
line->property_color_rgba() = 0xFF0000FF;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1761,6 +1779,12 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
|
||||||
Glib::signal_idle().connect (sigc::mem_fun(*this, &Editor::left_automation_track));
|
Glib::signal_idle().connect (sigc::mem_fun(*this, &Editor::left_automation_track));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case FeatureLineItem:
|
||||||
|
{
|
||||||
|
ArdourCanvas::SimpleLine *line = dynamic_cast<ArdourCanvas::SimpleLine *> (item);
|
||||||
|
line->property_color_rgba() = (guint) ARDOUR_UI::config()->canvasvar_ZeroLine.get();;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -552,7 +552,7 @@ Editor::move_to_end ()
|
||||||
void
|
void
|
||||||
Editor::build_region_boundary_cache ()
|
Editor::build_region_boundary_cache ()
|
||||||
{
|
{
|
||||||
nframes64_t pos = 0;
|
framepos_t pos = 0;
|
||||||
vector<RegionPoint> interesting_points;
|
vector<RegionPoint> interesting_points;
|
||||||
boost::shared_ptr<Region> r;
|
boost::shared_ptr<Region> r;
|
||||||
TrackViewList tracks;
|
TrackViewList tracks;
|
||||||
|
|
@ -595,8 +595,8 @@ Editor::build_region_boundary_cache ()
|
||||||
|
|
||||||
while (pos < _session->current_end_frame() && !at_end) {
|
while (pos < _session->current_end_frame() && !at_end) {
|
||||||
|
|
||||||
nframes64_t rpos;
|
framepos_t rpos;
|
||||||
nframes64_t lpos = max_frames;
|
framepos_t lpos = max_frames;
|
||||||
|
|
||||||
for (vector<RegionPoint>::iterator p = interesting_points.begin(); p != interesting_points.end(); ++p) {
|
for (vector<RegionPoint>::iterator p = interesting_points.begin(); p != interesting_points.end(); ++p) {
|
||||||
|
|
||||||
|
|
@ -645,7 +645,7 @@ Editor::build_region_boundary_cache ()
|
||||||
to sort later.
|
to sort later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vector<nframes64_t>::iterator ri;
|
vector<framepos_t>::iterator ri;
|
||||||
|
|
||||||
for (ri = region_boundary_cache.begin(); ri != region_boundary_cache.end(); ++ri) {
|
for (ri = region_boundary_cache.begin(); ri != region_boundary_cache.end(); ++ri) {
|
||||||
if (*ri == rpos) {
|
if (*ri == rpos) {
|
||||||
|
|
@ -664,23 +664,29 @@ Editor::build_region_boundary_cache ()
|
||||||
/* finally sort to be sure that the order is correct */
|
/* finally sort to be sure that the order is correct */
|
||||||
|
|
||||||
sort (region_boundary_cache.begin(), region_boundary_cache.end());
|
sort (region_boundary_cache.begin(), region_boundary_cache.end());
|
||||||
|
|
||||||
|
cerr << "RBC contains " << region_boundary_cache.size() << endl;
|
||||||
|
|
||||||
|
for (vector<framepos_t>::iterator x = region_boundary_cache.begin(); x != region_boundary_cache.end(); ++x) {
|
||||||
|
cerr << "Region boundary @ " << *x << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Region>
|
boost::shared_ptr<Region>
|
||||||
Editor::find_next_region (nframes64_t frame, RegionPoint point, int32_t dir, TrackViewList& tracks, TimeAxisView **ontrack)
|
Editor::find_next_region (framepos_t frame, RegionPoint point, int32_t dir, TrackViewList& tracks, TimeAxisView **ontrack)
|
||||||
{
|
{
|
||||||
TrackViewList::iterator i;
|
TrackViewList::iterator i;
|
||||||
nframes64_t closest = max_frames;
|
nframes64_t closest = max_frames;
|
||||||
boost::shared_ptr<Region> ret;
|
boost::shared_ptr<Region> ret;
|
||||||
nframes64_t rpos = 0;
|
framepos_t rpos = 0;
|
||||||
|
|
||||||
float track_speed;
|
float track_speed;
|
||||||
nframes64_t track_frame;
|
framepos_t track_frame;
|
||||||
RouteTimeAxisView *rtav;
|
RouteTimeAxisView *rtav;
|
||||||
|
|
||||||
for (i = tracks.begin(); i != tracks.end(); ++i) {
|
for (i = tracks.begin(); i != tracks.end(); ++i) {
|
||||||
|
|
||||||
nframes64_t distance;
|
framecnt_t distance;
|
||||||
boost::shared_ptr<Region> r;
|
boost::shared_ptr<Region> r;
|
||||||
|
|
||||||
track_speed = 1.0f;
|
track_speed = 1.0f;
|
||||||
|
|
@ -730,16 +736,15 @@ Editor::find_next_region (nframes64_t frame, RegionPoint point, int32_t dir, Tra
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
nframes64_t
|
framepos_t
|
||||||
Editor::find_next_region_boundary (nframes64_t pos, int32_t dir, const TrackViewList& tracks)
|
Editor::find_next_region_boundary (framepos_t pos, int32_t dir, const TrackViewList& tracks)
|
||||||
{
|
{
|
||||||
nframes64_t distance = max_frames;
|
framecnt_t distance = max_frames;
|
||||||
nframes64_t current_nearest = -1;
|
framepos_t current_nearest = -1;
|
||||||
|
|
||||||
|
|
||||||
for (TrackViewList::const_iterator i = tracks.begin(); i != tracks.end(); ++i) {
|
for (TrackViewList::const_iterator i = tracks.begin(); i != tracks.end(); ++i) {
|
||||||
nframes64_t contender;
|
framepos_t contender;
|
||||||
nframes64_t d;
|
framecnt_t d;
|
||||||
|
|
||||||
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
|
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
|
||||||
|
|
||||||
|
|
@ -762,10 +767,10 @@ Editor::find_next_region_boundary (nframes64_t pos, int32_t dir, const TrackView
|
||||||
return current_nearest;
|
return current_nearest;
|
||||||
}
|
}
|
||||||
|
|
||||||
nframes64_t
|
framepos_t
|
||||||
Editor::get_region_boundary (nframes64_t pos, int32_t dir, bool with_selection, bool only_onscreen)
|
Editor::get_region_boundary (framepos_t pos, int32_t dir, bool with_selection, bool only_onscreen)
|
||||||
{
|
{
|
||||||
nframes64_t target;
|
framepos_t target;
|
||||||
TrackViewList tvl;
|
TrackViewList tvl;
|
||||||
|
|
||||||
if (with_selection && Config->get_region_boundaries_from_selected_tracks()) {
|
if (with_selection && Config->get_region_boundaries_from_selected_tracks()) {
|
||||||
|
|
@ -2793,6 +2798,7 @@ Editor::separate_regions_between (const TimeSelection& ts)
|
||||||
|
|
||||||
sigc::connection c = rtv->view()->RegionViewAdded.connect (
|
sigc::connection c = rtv->view()->RegionViewAdded.connect (
|
||||||
sigc::mem_fun(*this, &Editor::collect_new_region_view));
|
sigc::mem_fun(*this, &Editor::collect_new_region_view));
|
||||||
|
|
||||||
latest_regionviews.clear ();
|
latest_regionviews.clear ();
|
||||||
|
|
||||||
playlist->partition ((nframes64_t)((*t).start * speed),
|
playlist->partition ((nframes64_t)((*t).start * speed),
|
||||||
|
|
@ -2838,6 +2844,11 @@ Editor::separate_regions_between (const TimeSelection& ts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PlaylistState {
|
||||||
|
boost::shared_ptr<Playlist> playlist;
|
||||||
|
XMLNode* before;
|
||||||
|
};
|
||||||
|
|
||||||
/** Take tracks from get_tracks_for_range_action and cut any regions
|
/** Take tracks from get_tracks_for_range_action and cut any regions
|
||||||
* on those tracks so that the tracks are empty over the time
|
* on those tracks so that the tracks are empty over the time
|
||||||
* selection.
|
* selection.
|
||||||
|
|
@ -2903,6 +2914,85 @@ Editor::separate_regions_using_location (Location& loc)
|
||||||
separate_regions_between (ts);
|
separate_regions_between (ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Separate regions under the selected region */
|
||||||
|
void
|
||||||
|
Editor::separate_under_selected_regions ()
|
||||||
|
{
|
||||||
|
RegionSelection rs;
|
||||||
|
get_regions_for_action (rs);
|
||||||
|
|
||||||
|
vector<PlaylistState> playlists;
|
||||||
|
|
||||||
|
if (!_session) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rs.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
begin_reversible_command (_("separate region under"));
|
||||||
|
|
||||||
|
list<boost::shared_ptr<Region> > regions_to_remove;
|
||||||
|
|
||||||
|
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
|
||||||
|
// we can't just remove the region(s) in this loop because
|
||||||
|
// this removes them from the RegionSelection, and they thus
|
||||||
|
// disappear from underneath the iterator, and the ++i above
|
||||||
|
// SEGVs in a puzzling fashion.
|
||||||
|
|
||||||
|
// so, first iterate over the regions to be removed from rs and
|
||||||
|
// add them to the regions_to_remove list, and then
|
||||||
|
// iterate over the list to actually remove them.
|
||||||
|
|
||||||
|
regions_to_remove.push_back ((*i)->region());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (list<boost::shared_ptr<Region> >::iterator rl = regions_to_remove.begin(); rl != regions_to_remove.end(); ++rl) {
|
||||||
|
|
||||||
|
boost::shared_ptr<Playlist> playlist = (*rl)->playlist();
|
||||||
|
|
||||||
|
if (!playlist) {
|
||||||
|
// is this check necessary?
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<PlaylistState>::iterator i;
|
||||||
|
|
||||||
|
//only take state if this is a new playlist.
|
||||||
|
for (i = playlists.begin(); i != playlists.end(); ++i) {
|
||||||
|
if ((*i).playlist == playlist) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == playlists.end()) {
|
||||||
|
|
||||||
|
PlaylistState before;
|
||||||
|
before.playlist = playlist;
|
||||||
|
before.before = &playlist->get_state();
|
||||||
|
|
||||||
|
playlist->freeze ();
|
||||||
|
playlists.push_back(before);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Partition on the region bounds
|
||||||
|
playlist->partition ((*rl)->first_frame() - 1, (*rl)->last_frame() + 1, true);
|
||||||
|
|
||||||
|
//Re-add region that was just removed due to the partition operation
|
||||||
|
playlist->add_region( (*rl), (*rl)->first_frame() );
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<PlaylistState>::iterator pl;
|
||||||
|
|
||||||
|
for (pl = playlists.begin(); pl != playlists.end(); ++pl) {
|
||||||
|
(*pl).playlist->thaw ();
|
||||||
|
_session->add_command(new MementoCommand<Playlist>(*(*pl).playlist, (*pl).before, &(*pl).playlist->get_state()));
|
||||||
|
}
|
||||||
|
|
||||||
|
commit_reversible_command ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::crop_region_to_selection ()
|
Editor::crop_region_to_selection ()
|
||||||
{
|
{
|
||||||
|
|
@ -3354,12 +3444,15 @@ Editor::trim_region (bool front)
|
||||||
|
|
||||||
for (list<RegionView*>::const_iterator i = rs.by_layer().begin(); i != rs.by_layer().end(); ++i) {
|
for (list<RegionView*>::const_iterator i = rs.by_layer().begin(); i != rs.by_layer().end(); ++i) {
|
||||||
if (!(*i)->region()->locked()) {
|
if (!(*i)->region()->locked()) {
|
||||||
(*i)->region()->clear_history ();
|
|
||||||
|
(*i)->region()->clear_history ();
|
||||||
|
|
||||||
if (front) {
|
if (front) {
|
||||||
(*i)->region()->trim_front (where, this);
|
(*i)->region()->trim_front (where, this);
|
||||||
} else {
|
} else {
|
||||||
(*i)->region()->trim_end (where, this);
|
(*i)->region()->trim_end (where, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
_session->add_command (new StatefulDiffCommand ((*i)->region()));
|
_session->add_command (new StatefulDiffCommand ((*i)->region()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3564,7 +3657,7 @@ Editor::trim_to_region(bool forward)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
region->trim_end((nframes64_t) (next_region->first_frame() * speed), this);
|
region->trim_end((nframes64_t) ( (next_region->first_frame() - 1) * speed), this);
|
||||||
arv->region_changed (PropertyChange (ARDOUR::Properties::length));
|
arv->region_changed (PropertyChange (ARDOUR::Properties::length));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -3892,6 +3985,14 @@ Editor::cut_copy_midi (CutCopyOp op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct lt_playlist {
|
||||||
|
bool operator () (const PlaylistState& a, const PlaylistState& b) {
|
||||||
|
return a.playlist < b.playlist;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct PlaylistMapping {
|
struct PlaylistMapping {
|
||||||
TimeAxisView* tv;
|
TimeAxisView* tv;
|
||||||
boost::shared_ptr<Playlist> pl;
|
boost::shared_ptr<Playlist> pl;
|
||||||
|
|
@ -4263,7 +4364,7 @@ Editor::duplicate_some_regions (RegionSelection& regions, float times)
|
||||||
|
|
||||||
playlist = (*i)->region()->playlist();
|
playlist = (*i)->region()->playlist();
|
||||||
playlist->clear_history ();
|
playlist->clear_history ();
|
||||||
playlist->duplicate (r, end_frame + (r->first_frame() - start_frame) + 1, times);
|
playlist->duplicate (r, end_frame + (r->first_frame() - start_frame), times);
|
||||||
_session->add_command(new StatefulDiffCommand (playlist));
|
_session->add_command(new StatefulDiffCommand (playlist));
|
||||||
|
|
||||||
c.disconnect ();
|
c.disconnect ();
|
||||||
|
|
@ -5872,6 +5973,7 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
|
||||||
|
|
||||||
int response = msg.run();
|
int response = msg.run();
|
||||||
msg.hide ();
|
msg.hide ();
|
||||||
|
|
||||||
switch (response) {
|
switch (response) {
|
||||||
case RESPONSE_OK:
|
case RESPONSE_OK:
|
||||||
break;
|
break;
|
||||||
|
|
@ -5890,19 +5992,10 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
|
||||||
|
|
||||||
AnalysisFeatureList::const_iterator x;
|
AnalysisFeatureList::const_iterator x;
|
||||||
|
|
||||||
nframes64_t pos = r->position();
|
|
||||||
|
|
||||||
pl->clear_history ();
|
pl->clear_history ();
|
||||||
|
|
||||||
x = positions.begin();
|
x = positions.begin();
|
||||||
|
|
||||||
while (x != positions.end()) {
|
|
||||||
if ((*x) > pos) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x == positions.end()) {
|
if (x == positions.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -5910,12 +6003,20 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
|
||||||
pl->freeze ();
|
pl->freeze ();
|
||||||
pl->remove_region (r);
|
pl->remove_region (r);
|
||||||
|
|
||||||
|
nframes64_t pos = 0;
|
||||||
|
|
||||||
while (x != positions.end()) {
|
while (x != positions.end()) {
|
||||||
|
|
||||||
|
/* deal with positons that are out of scope of present region bounds */
|
||||||
|
if (*x <= 0 || *x > r->length()){
|
||||||
|
++x;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* file start = original start + how far we from the initial position ?
|
/* file start = original start + how far we from the initial position ?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nframes64_t file_start = r->start() + (pos - r->position());
|
nframes64_t file_start = r->start() + pos;
|
||||||
|
|
||||||
/* length = next position - current position
|
/* length = next position - current position
|
||||||
*/
|
*/
|
||||||
|
|
@ -5946,37 +6047,192 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
|
||||||
plist.add (ARDOUR::Properties::layer, 0);
|
plist.add (ARDOUR::Properties::layer, 0);
|
||||||
|
|
||||||
boost::shared_ptr<Region> nr = RegionFactory::create (r->sources(), plist, false);
|
boost::shared_ptr<Region> nr = RegionFactory::create (r->sources(), plist, false);
|
||||||
pl->add_region (nr, pos);
|
pl->add_region (nr, r->position() + pos);
|
||||||
|
|
||||||
pos += len;
|
pos += len;
|
||||||
++x;
|
++x;
|
||||||
|
|
||||||
if (*x > r->last_frame()) {
|
|
||||||
|
|
||||||
/* add final fragment */
|
|
||||||
|
|
||||||
file_start = r->start() + (pos - r->position());
|
|
||||||
len = r->last_frame() - pos;
|
|
||||||
|
|
||||||
PropertyList plist2;
|
|
||||||
|
|
||||||
plist2.add (ARDOUR::Properties::start, file_start);
|
|
||||||
plist2.add (ARDOUR::Properties::length, len);
|
|
||||||
plist2.add (ARDOUR::Properties::name, new_name);
|
|
||||||
plist2.add (ARDOUR::Properties::layer, 0);
|
|
||||||
|
|
||||||
nr = RegionFactory::create (r->sources(), plist2);
|
|
||||||
pl->add_region (nr, pos);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string new_name;
|
||||||
|
|
||||||
|
RegionFactory::region_name (new_name, r->name());
|
||||||
|
|
||||||
|
/* Add the final region */
|
||||||
|
PropertyList plist;
|
||||||
|
|
||||||
|
plist.add (ARDOUR::Properties::start, r->start() + pos);
|
||||||
|
plist.add (ARDOUR::Properties::length, r->last_frame() - (r->position() + pos) + 1);
|
||||||
|
plist.add (ARDOUR::Properties::name, new_name);
|
||||||
|
plist.add (ARDOUR::Properties::layer, 0);
|
||||||
|
|
||||||
|
boost::shared_ptr<Region> nr = RegionFactory::create (r->sources(), plist, false);
|
||||||
|
pl->add_region (nr, r->position() + pos);
|
||||||
|
|
||||||
|
|
||||||
pl->thaw ();
|
pl->thaw ();
|
||||||
|
|
||||||
_session->add_command (new StatefulDiffCommand (pl));
|
_session->add_command (new StatefulDiffCommand (pl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Editor::place_transient()
|
||||||
|
{
|
||||||
|
if (!_session) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionSelection rs;
|
||||||
|
|
||||||
|
get_regions_for_action (rs);
|
||||||
|
|
||||||
|
if (rs.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nframes64_t where = get_preferred_edit_position();
|
||||||
|
|
||||||
|
_session->begin_reversible_command (_("place transient"));
|
||||||
|
|
||||||
|
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
|
||||||
|
framepos_t position = (*r)->region()->position();
|
||||||
|
(*r)->region()->add_transient(where - position);
|
||||||
|
}
|
||||||
|
|
||||||
|
_session->commit_reversible_command ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Editor::remove_transient(ArdourCanvas::Item* item)
|
||||||
|
{
|
||||||
|
if (!_session) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArdourCanvas::SimpleLine* _line = reinterpret_cast<ArdourCanvas::SimpleLine*> (item);
|
||||||
|
assert (_line);
|
||||||
|
|
||||||
|
AudioRegionView* _arv = reinterpret_cast<AudioRegionView*> (item->get_data ("regionview"));
|
||||||
|
_arv->remove_transient(_line->property_x1());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Editor::snap_regions_to_grid()
|
||||||
|
{
|
||||||
|
if (!_session) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionSelection rs;
|
||||||
|
|
||||||
|
get_regions_for_action (rs);
|
||||||
|
|
||||||
|
if (rs.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_session->begin_reversible_command (_("snap regions to grid"));
|
||||||
|
|
||||||
|
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
|
||||||
|
framepos_t start_frame = (*r)->region()->first_frame ();
|
||||||
|
snap_to (start_frame);
|
||||||
|
(*r)->region()->set_position (start_frame, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
_session->commit_reversible_command ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Editor::close_region_gaps()
|
||||||
|
{
|
||||||
|
if (!_session) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionSelection rs;
|
||||||
|
|
||||||
|
get_regions_for_action (rs);
|
||||||
|
|
||||||
|
if (rs.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dialog dialog (rs.size() > 1 ? _("Conform regions") : _("Conform region"));
|
||||||
|
|
||||||
|
HBox hbox_crossfade;
|
||||||
|
hbox_crossfade.set_spacing (10);
|
||||||
|
//hbox_crossfade.set_border_width (3);
|
||||||
|
hbox_crossfade.pack_start (*manage (new Label (_("Crossfade length:"))));
|
||||||
|
|
||||||
|
SpinButton spin_crossfade (1, 0);
|
||||||
|
spin_crossfade.set_range (0, 15);
|
||||||
|
spin_crossfade.set_increments (1, 1);
|
||||||
|
spin_crossfade.set_value (3);
|
||||||
|
|
||||||
|
hbox_crossfade.pack_start (spin_crossfade);
|
||||||
|
hbox_crossfade.pack_start (*manage (new Label (_("ms"))));
|
||||||
|
hbox_crossfade.show_all ();
|
||||||
|
|
||||||
|
HBox hbox_pullback;
|
||||||
|
|
||||||
|
hbox_pullback.set_spacing (10);
|
||||||
|
//hbox_pullback.set_border_width (3);
|
||||||
|
hbox_pullback.pack_start (*manage (new Label (_("Pull-back length:"))));
|
||||||
|
|
||||||
|
SpinButton spin_pullback (1, 0);
|
||||||
|
spin_pullback.set_range (0, 15);
|
||||||
|
spin_pullback.set_increments (1, 1);
|
||||||
|
spin_pullback.set_value (5);
|
||||||
|
|
||||||
|
hbox_pullback.pack_start (spin_pullback);
|
||||||
|
hbox_pullback.pack_start (*manage (new Label (_("ms"))));
|
||||||
|
hbox_pullback.show_all ();
|
||||||
|
|
||||||
|
dialog.get_vbox()->set_spacing (6);
|
||||||
|
dialog.get_vbox()->pack_start (hbox_crossfade);
|
||||||
|
dialog.get_vbox()->pack_start (hbox_pullback);
|
||||||
|
dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL);
|
||||||
|
dialog.add_button (_("Ok"), RESPONSE_ACCEPT);
|
||||||
|
|
||||||
|
if (dialog.run () == RESPONSE_CANCEL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nframes64_t crossfade_len = spin_crossfade.get_value();
|
||||||
|
nframes64_t pull_back_frames = spin_pullback.get_value();
|
||||||
|
|
||||||
|
crossfade_len = lrintf (crossfade_len * _session->frame_rate()/1000);
|
||||||
|
pull_back_frames = lrintf (pull_back_frames * _session->frame_rate()/1000);
|
||||||
|
|
||||||
|
/* Iterate over the region list and make adjacent regions overlap by crossfade_len_ms */
|
||||||
|
|
||||||
|
_session->begin_reversible_command (_("close region gaps"));
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
boost::shared_ptr<Region> last_region;
|
||||||
|
|
||||||
|
rs.sort_by_position_and_track();
|
||||||
|
|
||||||
|
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
|
||||||
|
|
||||||
|
nframes64_t position = (*r)->region()->position();
|
||||||
|
|
||||||
|
if (idx == 0 || position < last_region->position()){
|
||||||
|
last_region = (*r)->region();
|
||||||
|
idx++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*r)->region()->trim_front( (position - pull_back_frames), this );
|
||||||
|
last_region->trim_end( (position - pull_back_frames + crossfade_len), this );
|
||||||
|
|
||||||
|
last_region = (*r)->region();
|
||||||
|
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
_session->commit_reversible_command ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::tab_to_transient (bool forward)
|
Editor::tab_to_transient (bool forward)
|
||||||
{
|
{
|
||||||
|
|
@ -6053,6 +6309,7 @@ Editor::tab_to_transient (bool forward)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::playhead_forward_to_grid ()
|
Editor::playhead_forward_to_grid ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ MidiStreamView::MidiStreamView (MidiTimeAxisView& tv)
|
||||||
, _highest_note(71)
|
, _highest_note(71)
|
||||||
, _data_note_min(60)
|
, _data_note_min(60)
|
||||||
, _data_note_max(71)
|
, _data_note_max(71)
|
||||||
|
, _note_lines (0)
|
||||||
{
|
{
|
||||||
/* use a group dedicated to MIDI underlays. Audio underlays are not in this group. */
|
/* use a group dedicated to MIDI underlays. Audio underlays are not in this group. */
|
||||||
midi_underlay_group = new ArdourCanvas::Group (*_canvas_group);
|
midi_underlay_group = new ArdourCanvas::Group (*_canvas_group);
|
||||||
|
|
@ -617,11 +618,23 @@ MidiStreamView::update_rec_regions (boost::shared_ptr<MidiModel> data, nframes_t
|
||||||
|
|
||||||
const boost::shared_ptr<MidiRegionView::NoteType>& note = *i;
|
const boost::shared_ptr<MidiRegionView::NoteType>& note = *i;
|
||||||
|
|
||||||
|
cerr << "New note arrived, length = " << note->length()
|
||||||
|
<< " num " << note->note()
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
if (note->length() == 0) {
|
||||||
|
/* we got NoteOn but not NoteOff (yet)
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
nframes_t note_start_frames = tconv.to(note->time());
|
nframes_t note_start_frames = tconv.to(note->time());
|
||||||
nframes_t note_end_frames = tconv.to(note->end_time());
|
nframes_t note_end_frames = tconv.to(note->end_time());
|
||||||
|
|
||||||
if (note->length() > 0 && note_end_frames + region->position() > start)
|
|
||||||
|
if (note->length() > 0 && note_end_frames + region->position() > start) {
|
||||||
mrv->resolve_note(note->note(), note_end_frames);
|
mrv->resolve_note(note->note(), note_end_frames);
|
||||||
|
}
|
||||||
|
|
||||||
if (note_start_frames + region->position() < start) {
|
if (note_start_frames + region->position() < start) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,9 @@ This mode provides many different operations on both regions and control points,
|
||||||
@eep|Editor/trim-from-start|<@TERTIARY@>braceleft|trim region start to edit point
|
@eep|Editor/trim-from-start|<@TERTIARY@>braceleft|trim region start to edit point
|
||||||
@eep|Editor/trim-to-end|<@TERTIARY@>braceright|trim region end to edit point
|
@eep|Editor/trim-to-end|<@TERTIARY@>braceright|trim region end to edit point
|
||||||
|
|
||||||
|
@eep|Editor/trim-to-previous-region|<@PRIMARY@>j|trim region to end of previous region
|
||||||
|
@eep|Editor/trim-to-next-region|<@PRIMARY@>k|trim region to start of next region
|
||||||
|
|
||||||
@ranges|Editor/set-loop-from-edit-range|bracketright|set loop range from edit range
|
@ranges|Editor/set-loop-from-edit-range|bracketright|set loop range from edit range
|
||||||
@ranges|Editor/set-loop-from-region|<@SECONDARY@>bracketright|set loop range from region(s)
|
@ranges|Editor/set-loop-from-region|<@SECONDARY@>bracketright|set loop range from region(s)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -304,6 +304,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible {
|
||||||
virtual bool canvas_frame_handle_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
|
virtual bool canvas_frame_handle_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
|
||||||
virtual bool canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
|
virtual bool canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
|
||||||
virtual bool canvas_region_view_name_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
|
virtual bool canvas_region_view_name_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
|
||||||
|
virtual bool canvas_feature_line_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
|
||||||
virtual bool canvas_stream_view_event (GdkEvent* event, ArdourCanvas::Item*, RouteTimeAxisView*) = 0;
|
virtual bool canvas_stream_view_event (GdkEvent* event, ArdourCanvas::Item*, RouteTimeAxisView*) = 0;
|
||||||
virtual bool canvas_marker_event (GdkEvent* event, ArdourCanvas::Item*, Marker*) = 0;
|
virtual bool canvas_marker_event (GdkEvent* event, ArdourCanvas::Item*, Marker*) = 0;
|
||||||
virtual bool canvas_zoom_rect_event (GdkEvent* event, ArdourCanvas::Item*) = 0;
|
virtual bool canvas_zoom_rect_event (GdkEvent* event, ArdourCanvas::Item*) = 0;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#include "rhythm_ferret.h"
|
#include "rhythm_ferret.h"
|
||||||
#include "audio_region_view.h"
|
#include "audio_region_view.h"
|
||||||
#include "public_editor.h"
|
#include "editor.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "time_axis_view.h"
|
#include "time_axis_view.h"
|
||||||
|
|
||||||
|
|
@ -53,7 +53,7 @@ static const gchar * _operation_strings[] = {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
RhythmFerret::RhythmFerret (PublicEditor& e)
|
RhythmFerret::RhythmFerret (Editor& e)
|
||||||
: ArdourDialog (_("Rhythm Ferret"))
|
: ArdourDialog (_("Rhythm Ferret"))
|
||||||
, editor (e)
|
, editor (e)
|
||||||
, detection_threshold_adjustment (3, 0, 20, 1, 4)
|
, detection_threshold_adjustment (3, 0, 20, 1, 4)
|
||||||
|
|
@ -206,12 +206,9 @@ RhythmFerret::run_analysis ()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(*i)->region()->set_transients (current_results);
|
||||||
|
current_results.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) {
|
|
||||||
(*i)->get_time_axis_view().show_feature_lines (current_results);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -233,9 +230,9 @@ RhythmFerret::run_percussion_onset_analysis (boost::shared_ptr<Readable> readabl
|
||||||
|
|
||||||
/* translate all transients to give absolute position */
|
/* translate all transients to give absolute position */
|
||||||
|
|
||||||
for (AnalysisFeatureList::iterator x = these_results.begin(); x != these_results.end(); ++x) {
|
//for (AnalysisFeatureList::iterator x = these_results.begin(); x != these_results.end(); ++x) {
|
||||||
(*x) += offset;
|
// (*x) += offset;
|
||||||
}
|
//}
|
||||||
|
|
||||||
/* merge */
|
/* merge */
|
||||||
|
|
||||||
|
|
@ -289,9 +286,9 @@ RhythmFerret::run_note_onset_analysis (boost::shared_ptr<Readable> readable, nfr
|
||||||
|
|
||||||
/* translate all transients to give absolute position */
|
/* translate all transients to give absolute position */
|
||||||
|
|
||||||
for (AnalysisFeatureList::iterator x = these_results.begin(); x != these_results.end(); ++x) {
|
//for (AnalysisFeatureList::iterator x = these_results.begin(); x != these_results.end(); ++x) {
|
||||||
(*x) += offset;
|
// (*x) += offset;
|
||||||
}
|
//}
|
||||||
|
|
||||||
/* merge */
|
/* merge */
|
||||||
|
|
||||||
|
|
@ -314,7 +311,7 @@ RhythmFerret::run_note_onset_analysis (boost::shared_ptr<Readable> readable, nfr
|
||||||
void
|
void
|
||||||
RhythmFerret::do_action ()
|
RhythmFerret::do_action ()
|
||||||
{
|
{
|
||||||
if (!_session || current_results.empty()) {
|
if (!_session) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -322,7 +319,9 @@ RhythmFerret::do_action ()
|
||||||
case SplitRegion:
|
case SplitRegion:
|
||||||
do_split_action ();
|
do_split_action ();
|
||||||
break;
|
break;
|
||||||
|
case ConformRegion:
|
||||||
|
editor.close_region_gaps();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -333,7 +332,9 @@ RhythmFerret::do_split_action ()
|
||||||
{
|
{
|
||||||
/* this can/will change the current selection, so work with a copy */
|
/* this can/will change the current selection, so work with a copy */
|
||||||
|
|
||||||
RegionSelection& regions (editor.get_selection().regions);
|
//RegionSelection& regions (editor.get_selection().regions);
|
||||||
|
RegionSelection regions;
|
||||||
|
editor.get_regions_for_action(regions);
|
||||||
|
|
||||||
if (regions.empty()) {
|
if (regions.empty()) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -341,6 +342,20 @@ RhythmFerret::do_split_action ()
|
||||||
|
|
||||||
_session->begin_reversible_command (_("split regions (rhythm ferret)"));
|
_session->begin_reversible_command (_("split regions (rhythm ferret)"));
|
||||||
|
|
||||||
|
/* Merge the transient positions for regions in consideration */
|
||||||
|
AnalysisFeatureList merged_features;
|
||||||
|
|
||||||
|
for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) {
|
||||||
|
|
||||||
|
AnalysisFeatureList features;
|
||||||
|
features = (*i)->region()->transients();
|
||||||
|
|
||||||
|
merged_features.insert (merged_features.end(), features.begin(), features.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
merged_features.sort();
|
||||||
|
merged_features.unique();
|
||||||
|
|
||||||
for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ) {
|
for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ) {
|
||||||
|
|
||||||
RegionSelection::iterator tmp;
|
RegionSelection::iterator tmp;
|
||||||
|
|
@ -348,9 +363,9 @@ RhythmFerret::do_split_action ()
|
||||||
tmp = i;
|
tmp = i;
|
||||||
++tmp;
|
++tmp;
|
||||||
|
|
||||||
(*i)->get_time_axis_view().hide_feature_lines ();
|
AnalysisFeatureList features;
|
||||||
|
features = (*i)->region()->transients();
|
||||||
editor.split_region_at_points ((*i)->region(), current_results, false);
|
editor.split_region_at_points ((*i)->region(), merged_features, false);
|
||||||
|
|
||||||
/* i is invalid at this point */
|
/* i is invalid at this point */
|
||||||
|
|
||||||
|
|
@ -367,15 +382,9 @@ RhythmFerret::set_session (Session* s)
|
||||||
current_results.clear ();
|
current_results.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hide_time_axis_features (TimeAxisView& tav)
|
|
||||||
{
|
|
||||||
tav.hide_feature_lines ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RhythmFerret::on_hide ()
|
RhythmFerret::on_hide ()
|
||||||
{
|
{
|
||||||
editor.foreach_time_axis_view (sigc::ptr_fun (hide_time_axis_features));
|
|
||||||
ArdourDialog::on_hide ();
|
ArdourDialog::on_hide ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ namespace ARDOUR {
|
||||||
class Readable;
|
class Readable;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PublicEditor;
|
class Editor;
|
||||||
class RegionView;
|
class RegionView;
|
||||||
|
|
||||||
class RhythmFerret : public ArdourDialog {
|
class RhythmFerret : public ArdourDialog {
|
||||||
|
|
@ -36,7 +36,7 @@ class RhythmFerret : public ArdourDialog {
|
||||||
ConformRegion
|
ConformRegion
|
||||||
};
|
};
|
||||||
|
|
||||||
RhythmFerret (PublicEditor&);
|
RhythmFerret (Editor&);
|
||||||
|
|
||||||
void set_session (ARDOUR::Session*);
|
void set_session (ARDOUR::Session*);
|
||||||
|
|
||||||
|
|
@ -44,7 +44,7 @@ class RhythmFerret : public ArdourDialog {
|
||||||
void on_hide ();
|
void on_hide ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PublicEditor& editor;
|
Editor& editor;
|
||||||
|
|
||||||
Gtk::ComboBoxText operation_selector;
|
Gtk::ComboBoxText operation_selector;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -203,10 +203,6 @@ TimeAxisView::~TimeAxisView()
|
||||||
delete (*i)->end_trim;
|
delete (*i)->end_trim;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (list<SimpleLine*>::iterator i = feature_lines.begin(); i != feature_lines.end(); ++i) {
|
|
||||||
delete (*i);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete selection_group;
|
delete selection_group;
|
||||||
selection_group = 0;
|
selection_group = 0;
|
||||||
|
|
||||||
|
|
@ -426,8 +422,6 @@ TimeAxisView::set_height(uint32_t h)
|
||||||
/* resize the selection rect */
|
/* resize the selection rect */
|
||||||
show_selection (_editor.get_selection().time);
|
show_selection (_editor.get_selection().time);
|
||||||
}
|
}
|
||||||
|
|
||||||
reshow_feature_lines ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -652,11 +646,6 @@ TimeAxisView::set_samples_per_unit (double spu)
|
||||||
|
|
||||||
AnalysisFeatureList::const_iterator i;
|
AnalysisFeatureList::const_iterator i;
|
||||||
list<ArdourCanvas::SimpleLine*>::iterator l;
|
list<ArdourCanvas::SimpleLine*>::iterator l;
|
||||||
|
|
||||||
for (i = analysis_features.begin(), l = feature_lines.begin(); i != analysis_features.end() && l != feature_lines.end(); ++i, ++l) {
|
|
||||||
(*l)->property_x1() = _editor.frame_to_pixel (*i);
|
|
||||||
(*l)->property_x2() = _editor.frame_to_pixel (*i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1188,51 +1177,6 @@ TimeAxisView::covers_y_position (double y)
|
||||||
return std::make_pair ( (TimeAxisView *) 0, 0);
|
return std::make_pair ( (TimeAxisView *) 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
TimeAxisView::show_feature_lines (const AnalysisFeatureList& pos)
|
|
||||||
{
|
|
||||||
analysis_features = pos;
|
|
||||||
reshow_feature_lines ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TimeAxisView::hide_feature_lines ()
|
|
||||||
{
|
|
||||||
list<ArdourCanvas::SimpleLine*>::iterator l;
|
|
||||||
|
|
||||||
for (l = feature_lines.begin(); l != feature_lines.end(); ++l) {
|
|
||||||
(*l)->hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
TimeAxisView::reshow_feature_lines ()
|
|
||||||
{
|
|
||||||
while (feature_lines.size()< analysis_features.size()) {
|
|
||||||
ArdourCanvas::SimpleLine* l = new ArdourCanvas::SimpleLine (*_canvas_display);
|
|
||||||
l->property_color_rgba() = (guint) ARDOUR_UI::config()->canvasvar_ZeroLine.get();
|
|
||||||
feature_lines.push_back (l);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (feature_lines.size() > analysis_features.size()) {
|
|
||||||
ArdourCanvas::SimpleLine *line = feature_lines.back();
|
|
||||||
feature_lines.pop_back ();
|
|
||||||
delete line;
|
|
||||||
}
|
|
||||||
|
|
||||||
AnalysisFeatureList::const_iterator i;
|
|
||||||
list<ArdourCanvas::SimpleLine*>::iterator l;
|
|
||||||
|
|
||||||
for (i = analysis_features.begin(), l = feature_lines.begin(); i != analysis_features.end() && l != feature_lines.end(); ++i, ++l) {
|
|
||||||
(*l)->property_x1() = _editor.frame_to_pixel (*i);
|
|
||||||
(*l)->property_x2() = _editor.frame_to_pixel (*i);
|
|
||||||
(*l)->property_y1() = 0;
|
|
||||||
(*l)->property_y2() = current_height();
|
|
||||||
(*l)->show ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TimeAxisView::resizer_button_press (GdkEventButton* event)
|
TimeAxisView::resizer_button_press (GdkEventButton* event)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -165,9 +165,6 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
|
||||||
virtual ARDOUR::RouteGroup* route_group() const { return 0; }
|
virtual ARDOUR::RouteGroup* route_group() const { return 0; }
|
||||||
virtual boost::shared_ptr<ARDOUR::Playlist> playlist() const { return boost::shared_ptr<ARDOUR::Playlist> (); }
|
virtual boost::shared_ptr<ARDOUR::Playlist> playlist() const { return boost::shared_ptr<ARDOUR::Playlist> (); }
|
||||||
|
|
||||||
virtual void show_feature_lines (const ARDOUR::AnalysisFeatureList&);
|
|
||||||
virtual void hide_feature_lines ();
|
|
||||||
|
|
||||||
virtual void set_samples_per_unit (double);
|
virtual void set_samples_per_unit (double);
|
||||||
virtual void show_selection (TimeSelection&);
|
virtual void show_selection (TimeSelection&);
|
||||||
virtual void hide_selection ();
|
virtual void hide_selection ();
|
||||||
|
|
@ -310,10 +307,6 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
|
||||||
void set_heights (uint32_t h);
|
void set_heights (uint32_t h);
|
||||||
void color_handler ();
|
void color_handler ();
|
||||||
|
|
||||||
std::list<ArdourCanvas::SimpleLine*> feature_lines;
|
|
||||||
ARDOUR::AnalysisFeatureList analysis_features;
|
|
||||||
void reshow_feature_lines ();
|
|
||||||
|
|
||||||
void conditionally_add_to_selection ();
|
void conditionally_add_to_selection ();
|
||||||
|
|
||||||
ArdourCanvas::Group* _canvas_display;
|
ArdourCanvas::Group* _canvas_display;
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,13 @@ class AudioRegion : public Region
|
||||||
void resume_fade_in ();
|
void resume_fade_in ();
|
||||||
void resume_fade_out ();
|
void resume_fade_out ();
|
||||||
|
|
||||||
|
void add_transient (nframes64_t where);
|
||||||
|
void remove_transient (nframes64_t where);
|
||||||
|
int set_transients (AnalysisFeatureList&);
|
||||||
int get_transients (AnalysisFeatureList&, bool force_new = false);
|
int get_transients (AnalysisFeatureList&, bool force_new = false);
|
||||||
|
int update_transient (nframes64_t old_position, nframes64_t new_position);
|
||||||
|
int adjust_transients (nframes64_t delta);
|
||||||
|
|
||||||
std::list<std::pair<frameoffset_t, framecnt_t> > find_silence (Sample, framecnt_t, InterThreadInfo&) const;
|
std::list<std::pair<frameoffset_t, framecnt_t> > find_silence (Sample, framecnt_t, InterThreadInfo&) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ namespace Properties {
|
||||||
extern PBD::PropertyDescriptor<bool> right_of_split;
|
extern PBD::PropertyDescriptor<bool> right_of_split;
|
||||||
extern PBD::PropertyDescriptor<bool> hidden;
|
extern PBD::PropertyDescriptor<bool> hidden;
|
||||||
extern PBD::PropertyDescriptor<bool> position_locked;
|
extern PBD::PropertyDescriptor<bool> position_locked;
|
||||||
|
extern PBD::PropertyDescriptor<bool> valid_transients;
|
||||||
extern PBD::PropertyDescriptor<framepos_t> start;
|
extern PBD::PropertyDescriptor<framepos_t> start;
|
||||||
extern PBD::PropertyDescriptor<framecnt_t> length;
|
extern PBD::PropertyDescriptor<framecnt_t> length;
|
||||||
extern PBD::PropertyDescriptor<framepos_t> position;
|
extern PBD::PropertyDescriptor<framepos_t> position;
|
||||||
|
|
@ -96,6 +97,8 @@ class Region
|
||||||
|
|
||||||
const DataType& data_type() const { return _type; }
|
const DataType& data_type() const { return _type; }
|
||||||
|
|
||||||
|
AnalysisFeatureList transients () { return _transients; };
|
||||||
|
|
||||||
/** How the region parameters play together:
|
/** How the region parameters play together:
|
||||||
*
|
*
|
||||||
* POSITION: first frame of the region along the timeline
|
* POSITION: first frame of the region along the timeline
|
||||||
|
|
@ -137,6 +140,7 @@ class Region
|
||||||
bool opaque () const { return _opaque; }
|
bool opaque () const { return _opaque; }
|
||||||
bool locked() const { return _locked; }
|
bool locked() const { return _locked; }
|
||||||
bool position_locked() const { return _position_locked; }
|
bool position_locked() const { return _position_locked; }
|
||||||
|
bool valid_transients() const { return _valid_transients; }
|
||||||
bool automatic() const { return _automatic; }
|
bool automatic() const { return _automatic; }
|
||||||
bool whole_file() const { return _whole_file; }
|
bool whole_file() const { return _whole_file; }
|
||||||
bool captured() const { return !(_import || _external); }
|
bool captured() const { return !(_import || _external); }
|
||||||
|
|
@ -245,12 +249,35 @@ class Region
|
||||||
|
|
||||||
virtual int exportme (ARDOUR::Session&, ARDOUR::ExportSpecification&) = 0;
|
virtual int exportme (ARDOUR::Session&, ARDOUR::ExportSpecification&) = 0;
|
||||||
|
|
||||||
|
virtual void add_transient (nframes64_t where) {
|
||||||
|
// no transients, but its OK
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int update_transient (nframes64_t old_position, nframes64_t new_position) {
|
||||||
|
// no transients, but its OK
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void remove_transient (nframes64_t where) {
|
||||||
|
// no transients, but its OK
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int set_transients (AnalysisFeatureList&) {
|
||||||
|
// no transients, but its OK
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
virtual int get_transients (AnalysisFeatureList&, bool force_new = false) {
|
virtual int get_transients (AnalysisFeatureList&, bool force_new = false) {
|
||||||
(void) force_new;
|
(void) force_new;
|
||||||
// no transients, but its OK
|
// no transients, but its OK
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int adjust_transients (nframes64_t delta) {
|
||||||
|
// no transients, but its OK
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
virtual int separate_by_channel (ARDOUR::Session&,
|
virtual int separate_by_channel (ARDOUR::Session&,
|
||||||
std::vector< boost::shared_ptr<Region> >&) const {
|
std::vector< boost::shared_ptr<Region> >&) const {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -317,6 +344,7 @@ class Region
|
||||||
PBD::Property<bool> _right_of_split;
|
PBD::Property<bool> _right_of_split;
|
||||||
PBD::Property<bool> _hidden;
|
PBD::Property<bool> _hidden;
|
||||||
PBD::Property<bool> _position_locked;
|
PBD::Property<bool> _position_locked;
|
||||||
|
PBD::Property<bool> _valid_transients;
|
||||||
PBD::Property<framepos_t> _start;
|
PBD::Property<framepos_t> _start;
|
||||||
PBD::Property<framecnt_t> _length;
|
PBD::Property<framecnt_t> _length;
|
||||||
PBD::Property<framepos_t> _position;
|
PBD::Property<framepos_t> _position;
|
||||||
|
|
@ -333,7 +361,7 @@ class Region
|
||||||
mutable RegionEditState _first_edit;
|
mutable RegionEditState _first_edit;
|
||||||
BBT_Time _bbt_time;
|
BBT_Time _bbt_time;
|
||||||
AnalysisFeatureList _transients;
|
AnalysisFeatureList _transients;
|
||||||
bool _valid_transients;
|
|
||||||
mutable uint64_t _read_data_count; ///< modified in read()
|
mutable uint64_t _read_data_count; ///< modified in read()
|
||||||
uint64_t _last_layer_op; ///< timestamp
|
uint64_t _last_layer_op; ///< timestamp
|
||||||
SourceList _sources;
|
SourceList _sources;
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,6 @@ AudioRegion::register_properties ()
|
||||||
, _fade_in_active (other->_fade_in_active) \
|
, _fade_in_active (other->_fade_in_active) \
|
||||||
, _fade_out_active (other->_fade_out_active) \
|
, _fade_out_active (other->_fade_out_active) \
|
||||||
, _scale_amplitude (other->_scale_amplitude)
|
, _scale_amplitude (other->_scale_amplitude)
|
||||||
|
|
||||||
/* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
|
/* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1265,6 +1264,63 @@ AudioRegion::audio_source (uint32_t n) const
|
||||||
return boost::dynamic_pointer_cast<AudioSource>(source(n));
|
return boost::dynamic_pointer_cast<AudioSource>(source(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
AudioRegion::adjust_transients (nframes64_t delta)
|
||||||
|
{
|
||||||
|
for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
|
||||||
|
(*x) = (*x) + delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
send_change (PropertyChange (Properties::valid_transients));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
AudioRegion::update_transient (nframes64_t old_position, nframes64_t new_position)
|
||||||
|
{
|
||||||
|
for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
|
||||||
|
if ((*x) == old_position) {
|
||||||
|
(*x) = new_position;
|
||||||
|
send_change (PropertyChange (Properties::valid_transients));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioRegion::add_transient (nframes64_t where)
|
||||||
|
{
|
||||||
|
_transients.push_back(where);
|
||||||
|
_valid_transients = true;
|
||||||
|
|
||||||
|
send_change (PropertyChange (Properties::valid_transients));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioRegion::remove_transient (nframes64_t where)
|
||||||
|
{
|
||||||
|
_transients.remove(where);
|
||||||
|
_valid_transients = true;
|
||||||
|
|
||||||
|
send_change (PropertyChange (Properties::valid_transients));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
AudioRegion::set_transients (AnalysisFeatureList& results)
|
||||||
|
{
|
||||||
|
_transients.clear();
|
||||||
|
_transients = results;
|
||||||
|
_valid_transients = true;
|
||||||
|
|
||||||
|
send_change (PropertyChange (Properties::valid_transients));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
|
AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -696,7 +696,7 @@ Playlist::add_region (boost::shared_ptr<Region> region, framepos_t position, flo
|
||||||
framepos_t pos = position;
|
framepos_t pos = position;
|
||||||
|
|
||||||
if (times == 1 && auto_partition){
|
if (times == 1 && auto_partition){
|
||||||
partition(pos, (pos + region->length()), true);
|
partition((nframes_t) pos - 1, (nframes_t) (pos + region->length()), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itimes >= 1) {
|
if (itimes >= 1) {
|
||||||
|
|
@ -869,9 +869,7 @@ Playlist::remove_region_internal (boost::shared_ptr<Region> region)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX and thaw ... */
|
return -1;
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1284,7 +1282,7 @@ Playlist::duplicate (boost::shared_ptr<Region> region, framepos_t position, floa
|
||||||
|
|
||||||
RegionLock rl (this);
|
RegionLock rl (this);
|
||||||
int itimes = (int) floor (times);
|
int itimes = (int) floor (times);
|
||||||
framepos_t pos = position;
|
nframes_t pos = position + 1;
|
||||||
|
|
||||||
while (itimes--) {
|
while (itimes--) {
|
||||||
boost::shared_ptr<Region> copy = RegionFactory::create (region);
|
boost::shared_ptr<Region> copy = RegionFactory::create (region);
|
||||||
|
|
@ -2094,6 +2092,7 @@ Playlist::find_next_region_boundary (framepos_t frame, int dir)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2300,7 +2299,7 @@ XMLNode&
|
||||||
Playlist::state (bool full_state)
|
Playlist::state (bool full_state)
|
||||||
{
|
{
|
||||||
XMLNode *node = new XMLNode (X_("Playlist"));
|
XMLNode *node = new XMLNode (X_("Playlist"));
|
||||||
char buf[64];
|
char buf[64] = "";
|
||||||
|
|
||||||
node->add_property (X_("id"), id().to_s());
|
node->add_property (X_("id"), id().to_s());
|
||||||
node->add_property (X_("name"), _name);
|
node->add_property (X_("name"), _name);
|
||||||
|
|
@ -2312,6 +2311,7 @@ Playlist::state (bool full_state)
|
||||||
|
|
||||||
if (full_state) {
|
if (full_state) {
|
||||||
RegionLock rlock (this, false);
|
RegionLock rlock (this, false);
|
||||||
|
|
||||||
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
|
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
|
||||||
node->add_child_nocopy ((*i)->get_state());
|
node->add_child_nocopy ((*i)->get_state());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ namespace ARDOUR {
|
||||||
PBD::PropertyDescriptor<bool> right_of_split;
|
PBD::PropertyDescriptor<bool> right_of_split;
|
||||||
PBD::PropertyDescriptor<bool> hidden;
|
PBD::PropertyDescriptor<bool> hidden;
|
||||||
PBD::PropertyDescriptor<bool> position_locked;
|
PBD::PropertyDescriptor<bool> position_locked;
|
||||||
|
PBD::PropertyDescriptor<bool> valid_transients;
|
||||||
PBD::PropertyDescriptor<framepos_t> start;
|
PBD::PropertyDescriptor<framepos_t> start;
|
||||||
PBD::PropertyDescriptor<framecnt_t> length;
|
PBD::PropertyDescriptor<framecnt_t> length;
|
||||||
PBD::PropertyDescriptor<framepos_t> position;
|
PBD::PropertyDescriptor<framepos_t> position;
|
||||||
|
|
@ -101,6 +102,8 @@ Region::make_property_quarks ()
|
||||||
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for hidden = %1\n", Properties::hidden.property_id));
|
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for hidden = %1\n", Properties::hidden.property_id));
|
||||||
Properties::position_locked.property_id = g_quark_from_static_string (X_("position-locked"));
|
Properties::position_locked.property_id = g_quark_from_static_string (X_("position-locked"));
|
||||||
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position-locked = %1\n", Properties::position_locked.property_id));
|
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position-locked = %1\n", Properties::position_locked.property_id));
|
||||||
|
Properties::valid_transients.property_id = g_quark_from_static_string (X_("valid-transients"));
|
||||||
|
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for valid-transients = %1\n", Properties::valid_transients.property_id));
|
||||||
Properties::start.property_id = g_quark_from_static_string (X_("start"));
|
Properties::start.property_id = g_quark_from_static_string (X_("start"));
|
||||||
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for start = %1\n", Properties::start.property_id));
|
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for start = %1\n", Properties::start.property_id));
|
||||||
Properties::length.property_id = g_quark_from_static_string (X_("length"));
|
Properties::length.property_id = g_quark_from_static_string (X_("length"));
|
||||||
|
|
@ -140,6 +143,7 @@ Region::register_properties ()
|
||||||
add_property (_right_of_split);
|
add_property (_right_of_split);
|
||||||
add_property (_hidden);
|
add_property (_hidden);
|
||||||
add_property (_position_locked);
|
add_property (_position_locked);
|
||||||
|
add_property (_valid_transients);
|
||||||
add_property (_start);
|
add_property (_start);
|
||||||
add_property (_length);
|
add_property (_length);
|
||||||
add_property (_position);
|
add_property (_position);
|
||||||
|
|
@ -165,6 +169,7 @@ Region::register_properties ()
|
||||||
, _right_of_split (Properties::right_of_split, false) \
|
, _right_of_split (Properties::right_of_split, false) \
|
||||||
, _hidden (Properties::hidden, false) \
|
, _hidden (Properties::hidden, false) \
|
||||||
, _position_locked (Properties::position_locked, false) \
|
, _position_locked (Properties::position_locked, false) \
|
||||||
|
, _valid_transients (Properties::valid_transients, false) \
|
||||||
, _start (Properties::start, (s)) \
|
, _start (Properties::start, (s)) \
|
||||||
, _length (Properties::length, (l)) \
|
, _length (Properties::length, (l)) \
|
||||||
, _position (Properties::position, 0) \
|
, _position (Properties::position, 0) \
|
||||||
|
|
@ -189,6 +194,7 @@ Region::register_properties ()
|
||||||
, _right_of_split (other->_right_of_split) \
|
, _right_of_split (other->_right_of_split) \
|
||||||
, _hidden (other->_hidden) \
|
, _hidden (other->_hidden) \
|
||||||
, _position_locked (other->_position_locked) \
|
, _position_locked (other->_position_locked) \
|
||||||
|
, _valid_transients (other->_valid_transients) \
|
||||||
, _start(other->_start) \
|
, _start(other->_start) \
|
||||||
, _length(other->_length) \
|
, _length(other->_length) \
|
||||||
, _position(other->_position) \
|
, _position(other->_position) \
|
||||||
|
|
@ -225,7 +231,6 @@ Region::Region (const SourceList& srcs)
|
||||||
, _last_length (0)
|
, _last_length (0)
|
||||||
, _last_position (0)
|
, _last_position (0)
|
||||||
, _first_edit (EditChangesNothing)
|
, _first_edit (EditChangesNothing)
|
||||||
, _valid_transients(false)
|
|
||||||
, _read_data_count(0)
|
, _read_data_count(0)
|
||||||
, _last_layer_op (0)
|
, _last_layer_op (0)
|
||||||
, _pending_explicit_relayer (false)
|
, _pending_explicit_relayer (false)
|
||||||
|
|
@ -254,7 +259,6 @@ Region::Region (boost::shared_ptr<const Region> other, frameoffset_t offset, boo
|
||||||
, _last_length (other->_last_length)
|
, _last_length (other->_last_length)
|
||||||
, _last_position(other->_last_position) \
|
, _last_position(other->_last_position) \
|
||||||
, _first_edit (EditChangesNothing)
|
, _first_edit (EditChangesNothing)
|
||||||
, _valid_transients(false)
|
|
||||||
, _read_data_count(0)
|
, _read_data_count(0)
|
||||||
, _last_layer_op (0)
|
, _last_layer_op (0)
|
||||||
, _pending_explicit_relayer (false)
|
, _pending_explicit_relayer (false)
|
||||||
|
|
@ -360,7 +364,6 @@ Region::Region (boost::shared_ptr<const Region> other, const SourceList& srcs)
|
||||||
, _last_length (other->_last_length)
|
, _last_length (other->_last_length)
|
||||||
, _last_position (other->_last_position)
|
, _last_position (other->_last_position)
|
||||||
, _first_edit (EditChangesID)
|
, _first_edit (EditChangesID)
|
||||||
, _valid_transients (false)
|
|
||||||
, _read_data_count (0)
|
, _read_data_count (0)
|
||||||
, _last_layer_op (other->_last_layer_op)
|
, _last_layer_op (other->_last_layer_op)
|
||||||
, _pending_explicit_relayer (false)
|
, _pending_explicit_relayer (false)
|
||||||
|
|
@ -390,7 +393,6 @@ Region::Region (boost::shared_ptr<const Region> other)
|
||||||
, _last_length (other->_last_length)
|
, _last_length (other->_last_length)
|
||||||
, _last_position (other->_last_position)
|
, _last_position (other->_last_position)
|
||||||
, _first_edit (EditChangesID)
|
, _first_edit (EditChangesID)
|
||||||
, _valid_transients(false)
|
|
||||||
, _read_data_count(0)
|
, _read_data_count(0)
|
||||||
, _last_layer_op(other->_last_layer_op)
|
, _last_layer_op(other->_last_layer_op)
|
||||||
, _pending_explicit_relayer (false)
|
, _pending_explicit_relayer (false)
|
||||||
|
|
@ -609,13 +611,12 @@ Region::set_position_internal (framepos_t pos, bool allow_bbt_recompute)
|
||||||
recompute_position_from_lock_style ();
|
recompute_position_from_lock_style ();
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidate_transients ();
|
//invalidate_transients ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do this even if the position is the same. this helps out
|
/* do this even if the position is the same. this helps out
|
||||||
a GUI that has moved its representation already.
|
a GUI that has moved its representation already.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
send_change (Properties::position);
|
send_change (Properties::position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -802,7 +803,8 @@ Region::modify_front (nframes_t new_position, bool reset_fade, void *src)
|
||||||
|
|
||||||
if (new_position < end) { /* can't trim it zero or negative length */
|
if (new_position < end) { /* can't trim it zero or negative length */
|
||||||
|
|
||||||
nframes_t newlen;
|
nframes_t newlen = 0;
|
||||||
|
nframes64_t delta = 0;
|
||||||
|
|
||||||
/* can't trim it back passed where source position zero is located */
|
/* can't trim it back passed where source position zero is located */
|
||||||
|
|
||||||
|
|
@ -810,11 +812,14 @@ Region::modify_front (nframes_t new_position, bool reset_fade, void *src)
|
||||||
|
|
||||||
if (new_position > _position) {
|
if (new_position > _position) {
|
||||||
newlen = _length - (new_position - _position);
|
newlen = _length - (new_position - _position);
|
||||||
|
delta = -1 * (new_position - _position);
|
||||||
} else {
|
} else {
|
||||||
newlen = _length + (_position - new_position);
|
newlen = _length + (_position - new_position);
|
||||||
|
delta = _position - new_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
trim_to_internal (new_position, newlen, src);
|
trim_to_internal (new_position, newlen, src);
|
||||||
|
|
||||||
if (reset_fade) {
|
if (reset_fade) {
|
||||||
_right_of_split = true;
|
_right_of_split = true;
|
||||||
}
|
}
|
||||||
|
|
@ -822,6 +827,10 @@ Region::modify_front (nframes_t new_position, bool reset_fade, void *src)
|
||||||
if (!property_changes_suspended()) {
|
if (!property_changes_suspended()) {
|
||||||
recompute_at_start ();
|
recompute_at_start ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_transients.size() > 0){
|
||||||
|
adjust_transients(delta);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -892,7 +901,6 @@ Region::trim_to_internal (framepos_t position, framecnt_t length, void */*src*/)
|
||||||
new_start = _start + start_shift;
|
new_start = _start + start_shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} else if (start_shift < 0) {
|
} else if (start_shift < 0) {
|
||||||
|
|
||||||
if (_start < -start_shift) {
|
if (_start < -start_shift) {
|
||||||
|
|
@ -900,6 +908,7 @@ Region::trim_to_internal (framepos_t position, framecnt_t length, void */*src*/)
|
||||||
} else {
|
} else {
|
||||||
new_start = _start + start_shift;
|
new_start = _start + start_shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
new_start = _start;
|
new_start = _start;
|
||||||
}
|
}
|
||||||
|
|
@ -1528,6 +1537,8 @@ Region::invalidate_transients ()
|
||||||
{
|
{
|
||||||
_valid_transients = false;
|
_valid_transients = false;
|
||||||
_transients.clear ();
|
_transients.clear ();
|
||||||
|
|
||||||
|
send_change (PropertyChange (Properties::valid_transients));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -957,25 +957,33 @@ Session::handle_locations_changed (Locations::LocationList& locations)
|
||||||
void
|
void
|
||||||
Session::enable_record ()
|
Session::enable_record ()
|
||||||
{
|
{
|
||||||
/* XXX really atomic compare+swap here */
|
while (1) {
|
||||||
if (g_atomic_int_get (&_record_status) != Recording) {
|
RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
|
||||||
g_atomic_int_set (&_record_status, Recording);
|
|
||||||
_last_record_location = _transport_frame;
|
|
||||||
_mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
|
|
||||||
|
|
||||||
if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
|
if (rs == Recording) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
boost::shared_ptr<RouteList> rl = routes.reader ();
|
if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
|
||||||
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
|
|
||||||
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
|
|
||||||
if (tr && tr->record_enabled ()) {
|
|
||||||
tr->monitor_input (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RecordStateChanged ();
|
_last_record_location = _transport_frame;
|
||||||
}
|
_mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
|
||||||
|
|
||||||
|
if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
|
||||||
|
|
||||||
|
boost::shared_ptr<RouteList> rl = routes.reader ();
|
||||||
|
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
|
||||||
|
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
|
||||||
|
if (tr && tr->record_enabled ()) {
|
||||||
|
tr->monitor_input (true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RecordStateChanged ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue