Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add grid filter to rhythm ferret and grouped transient lines #388

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions gtk2_ardour/audio_region_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1750,6 +1750,30 @@ AudioRegionView::remove_transient (float pos)
}
}

samplepos_t
AudioRegionView::get_transient_position(float pos){
list<std::pair<samplepos_t, ArdourCanvas::Line*> >::iterator l;
for (l = feature_lines.begin(); l != feature_lines.end(); ++l) {
float *line_pos = (float*) (*l).second->get_data ("position");
if (rint(pos) == (rint(*line_pos))) {
return (*l).first;
}
}
return 0;
}

void
AudioRegionView::get_transient_feature_line(samplepos_t pos, std::list<ArdourCanvas::Item*>& equivalent_transient_items)
{
list<std::pair<samplepos_t, ArdourCanvas::Line*> >::iterator l;
for (l = feature_lines.begin(); l != feature_lines.end(); ++l) {
if (pos == (*l).first) {
equivalent_transient_items.push_back((*l).second);
break;
}
}
}

void
AudioRegionView::thaw_after_trim ()
{
Expand Down
2 changes: 2 additions & 0 deletions gtk2_ardour/audio_region_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ class AudioRegionView : public RegionView

void update_transient(float old_pos, float new_pos);
void remove_transient(float pos);
samplepos_t get_transient_position(float pos);
void get_transient_feature_line(samplepos_t pos, std::list<ArdourCanvas::Item*>& equivalent_transient_items);

void show_region_editor ();

Expand Down
33 changes: 29 additions & 4 deletions gtk2_ardour/editor_mouse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -964,14 +964,39 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT

case FeatureLineItem:
{
std::list<ArdourCanvas::Item*> equivalent_transient_items;
ArdourCanvas::Line* line = reinterpret_cast<ArdourCanvas::Line*> (item);
assert (line);

RegionView* tmp_rv = reinterpret_cast<RegionView*> (item->get_data ("regionview"));

vector<RegionView*> all_equivalent_regions;
get_equivalent_regions(tmp_rv, all_equivalent_regions, ARDOUR::Properties::group_select.property_id);

AudioRegionView* tmp_arv = dynamic_cast<AudioRegionView*> (tmp_rv);
samplepos_t transient_position = tmp_arv->get_transient_position(*(float*) line->get_data("position"));
// boost::shared_ptr<AudioRegionView> arv;
for (vector<RegionView*>::iterator i = all_equivalent_regions.begin(); i != all_equivalent_regions.end(); ++i){
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (*i);
arv->get_transient_feature_line(transient_position, equivalent_transient_items);
}

if (Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier)) {
equivalent_transient_items.clear();
equivalent_transient_items.push_back(item);
}

if (Keyboard::modifier_state_contains (event->button.state, Keyboard::TertiaryModifier)) {
remove_transient(item);
for (std::list<ArdourCanvas::Item*>::iterator i = equivalent_transient_items.begin(); i != equivalent_transient_items.end(); ++i){
remove_transient(*i);
}
return true;
}

_drags->set (new FeatureLineDrag (this, item), event);

for (std::list<ArdourCanvas::Item*>::iterator i = equivalent_transient_items.begin(); i != equivalent_transient_items.end(); ++i){
_drags->set (new FeatureLineDrag (this, *i), event);
}
return true;
break;
}

case RegionItem:
Expand Down
68 changes: 64 additions & 4 deletions gtk2_ardour/rhythm_ferret.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ RhythmFerret::RhythmFerret (Editor& e)
*/
onset_detection_function_selector.set_active_text (onset_function_strings[3]);
detection_threshold_scale.set_digits (3);
filter_to_grid.set_active(true);

Table* t = manage (new Table (7, 3));
t->set_spacings (12);
Expand Down Expand Up @@ -153,7 +154,11 @@ RhythmFerret::RhythmFerret (Editor& e)
t->attach (detection_threshold_scale, 1, 2, n, n + 1, FILL);
t->attach (*manage (new Label (_("dB"))), 2, 3, n, n + 1, FILL);
++n;


t->attach (*manage (new Label (_("Filter results on grid"), 1, 0.5)), 0, 1, n, n + 1, FILL);
t->attach (filter_to_grid, 1, 2, n, n + 1, FILL);
++n;

t->attach (*manage (new Label (_("Operation"), 1, 0.5)), 0, 1, n, n + 1, FILL);
t->attach (operation_selector, 1, 2, n, n + 1, FILL);
++n;
Expand Down Expand Up @@ -235,7 +240,10 @@ RhythmFerret::run_analysis ()
if (regions_with_transients.empty()) {
return;
}


bool active_filter = filter_to_grid.get_active();
vector<GridFilterElement> filter_list;

for (RegionSelection::iterator i = regions_with_transients.begin(); i != regions_with_transients.end(); ++i) {

boost::shared_ptr<Readable> rd = boost::static_pointer_cast<AudioRegion> ((*i)->region());
Expand All @@ -250,10 +258,56 @@ RhythmFerret::run_analysis ()
default:
break;
}

(*i)->region()->set_onsets (current_results);
for (AnalysisFeatureList::iterator j = current_results.begin(); j != current_results.end(); ++j) {
MusicSample snaped_transient(*j + (*i)->region()->position(), 0);
editor.snap_to(snaped_transient, ARDOUR::RoundNearest, false, true);

GridFilterElement gfe((*i), *j, snaped_transient.sample);
filter_list.push_back(gfe);
}
current_results.clear();
}

std::sort(begin(filter_list), end(filter_list), [](GridFilterElement const &gf1,
GridFilterElement const &gf2 ) {
if (gf1.snaped_sample != gf2.snaped_sample){
return gf1.snaped_sample < gf2.snaped_sample;
}

return gf1.distance < gf2.distance;
}
);

for (RegionSelection::iterator r = regions_with_transients.begin(); r != regions_with_transients.end(); ++r) {
current_results.clear();
samplepos_t last_snaped_sample = -1;

for (vector<GridFilterElement>::iterator f = filter_list.begin(); f != filter_list.end(); ++f){
if (active_filter && (*f).snaped_sample == last_snaped_sample){
continue;
}
last_snaped_sample = (*f).snaped_sample;

if ((*f).region_view == (*r)) {
current_results.push_back((*f).sample);
} else {
// if onset is on an equivalent region, we put it on this region too.
vector<RegionView*> all_equivalent_regions;
editor.get_equivalent_regions((*f).region_view, all_equivalent_regions, ARDOUR::Properties::group_select.property_id);

for (vector<RegionView*>::iterator eqr = all_equivalent_regions.begin(); eqr!= all_equivalent_regions.end(); ++eqr){
if ((*eqr) == (*r)){
current_results.push_back((*f).sample + ((*f).region_view->region()->position() - (*r)->region()->position()));
break;
}
}
}
}

(*r)->region()->set_onsets (current_results);
}
current_results.clear();

}

int
Expand Down Expand Up @@ -452,3 +506,9 @@ RhythmFerret::clear_transients ()
regions_with_transients.clear ();
}

GridFilterElement::GridFilterElement(RegionView* reg_view, samplepos_t onset, samplepos_t snaped){
region_view = reg_view;
sample = onset;
snaped_sample = snaped;
distance = std::abs((region_view->region()->position() + sample) - snaped_sample);
}
11 changes: 10 additions & 1 deletion gtk2_ardour/rhythm_ferret.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ class RhythmFerret : public ArdourDialog

Gtk::Adjustment trigger_gap_adjustment;
Gtk::SpinButton trigger_gap_spinner;

Gtk::CheckButton filter_to_grid;

Gtk::Button action_button;

std::vector<std::string> analysis_mode_strings;
Expand All @@ -123,4 +124,12 @@ class RhythmFerret : public ArdourDialog
void do_region_split (RegionView* rv, const ARDOUR::AnalysisFeatureList&);
};

struct GridFilterElement {
GridFilterElement(RegionView* reg_view, samplepos_t onset, samplepos_t snaped);
samplepos_t snaped_sample;
samplepos_t sample;
samplepos_t distance;
RegionView* region_view;
};

#endif /* __gtk2_ardour_rhythm_ferret_h__ */