Expose MIDI Strum using operator in libardour

This commit is contained in:
Robin Gareus
2025-09-26 00:00:19 +02:00
parent 44097cdd6a
commit 82bdb3f05f
4 changed files with 61 additions and 0 deletions

View File

@@ -28,6 +28,7 @@
#include "ardour/rc_configuration.h"
#include "ardour/transpose.h"
#include "ardour/quantize.h"
#include "ardour/strum.h"
#include "gtkmm2ext/bindings.h"
@@ -632,6 +633,9 @@ EditingContext::register_midi_actions (Bindings* midi_bindings, std::string cons
ActionManager::register_action (_midi_actions, X_("split-notes-less"), _("Split Selected Notes into less pieces"), sigc::bind (sigc::mem_fun (*this, &EditingContext::midi_action), &MidiView::split_notes_less));
ActionManager::register_action (_midi_actions, X_("join-notes"), _("Join Selected Notes"), sigc::bind (sigc::mem_fun (*this, &EditingContext::midi_action), &MidiView::join_notes));
ActionManager::register_action (_midi_actions, X_("strum-forward"), _("Strum notes forward"), sigc::bind (sigc::mem_fun (*this, &EditingContext::midi_action), &MidiView::strum_notes_forward));
ActionManager::register_action (_midi_actions, X_("strum-backward"), _("Strum notes backward"), sigc::bind (sigc::mem_fun (*this, &EditingContext::midi_action), &MidiView::strum_notes_backward));
ActionManager::register_action (_midi_actions, X_("edit-channels"), _("Edit Note Channels"), sigc::bind (sigc::mem_fun (*this, &EditingContext::midi_action), &MidiView::channel_edit));
ActionManager::register_action (_midi_actions, X_("edit-velocities"), _("Edit Note Velocities"), sigc::bind (sigc::mem_fun (*this, &EditingContext::midi_action), &MidiView::velocity_edit));
@@ -1813,6 +1817,14 @@ EditingContext::get_quantize_op ()
quantize_dialog->threshold());
}
Strum*
EditingContext::get_strum_op (bool forward, bool fine)
{
EC_LOCAL_TEMPO_SCOPE;
return new Strum (forward, fine);
}
timecnt_t
EditingContext::relative_distance (timepos_t const & origin, timecnt_t const & duration, Temporal::TimeDomain domain)
{
@@ -1938,6 +1950,9 @@ EditingContext::popup_note_context_menu (ArdourCanvas::Item* item, GdkEvent* eve
items.back().set_sensitive (false);
}
items.push_back(MenuElem(_("Transform..."), sigc::bind(sigc::mem_fun(*this, &EditingContext::transform_regions), mvs)));
items.push_back (SeparatorElem());
items.push_back(MenuElem(_("Strum forward"), sigc::bind(sigc::mem_fun(*this, &EditingContext::strum_notes), mvs, true)));
items.push_back(MenuElem(_("Strum backward"), sigc::bind(sigc::mem_fun(*this, &EditingContext::strum_notes), mvs, false)));
_note_context_menu.popup (event->button.button, event->button.time);
}
@@ -2128,6 +2143,19 @@ EditingContext::transpose_regions (const MidiViews& rs)
}
}
void
EditingContext::strum_notes (const MidiViews& rs, bool forward)
{
EC_LOCAL_TEMPO_SCOPE;
if (rs.empty()) {
return;
}
Strum strum (forward, false);
apply_midi_note_edit_op (strum, rs);
}
void
EditingContext::edit_notes (MidiView* mrv)
{

View File

@@ -59,6 +59,10 @@ namespace Temporal {
class TempoMap;
}
namespace ARDOUR {
class Strum;
}
class XMLNode;
class ControlPoint;
@@ -388,6 +392,7 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
/* MIDI actions, proxied to selected MidiRegionView(s) */
ARDOUR::Quantize* get_quantize_op ();
ARDOUR::Strum* get_strum_op (bool, bool);
void apply_midi_note_edit_op (ARDOUR::MidiOperator& op, const RegionSelection& rs);
void apply_midi_note_edit_op (ARDOUR::MidiOperator& op, const MidiViews& rs);
PBD::Command* apply_midi_note_edit_op_to_region (ARDOUR::MidiOperator& op, MidiView& mrv);
@@ -402,6 +407,7 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
void quantize_regions (const MidiViews& rs);
void legatize_regions (const MidiViews& rs, bool shrink_only);
void strum_notes (const MidiViews& rs, bool forward);
void transform_regions (const MidiViews& rs);
void transpose_regions (const MidiViews& rs);

View File

@@ -47,6 +47,7 @@
#include "ardour/operations.h"
#include "ardour/quantize.h"
#include "ardour/session.h"
#include "ardour/strum.h"
#include "evoral/Parameter.h"
#include "evoral/Event.h"
@@ -5010,6 +5011,28 @@ MidiView::quantize_selected_notes ()
delete quant;
}
void
MidiView::strum_notes (bool forward, bool fine)
{
Strum* strum = _editing_context.get_strum_op (forward, fine);
if (!strum) {
return;
}
PBD::Command* cmd = _editing_context.apply_midi_note_edit_op_to_region (*strum, *this);
if (cmd) {
_editing_context.begin_reversible_command (strum->name ());
(*cmd)();
_editing_context.add_command (cmd);
_editing_context.commit_reversible_command ();
_editing_context.session()->set_dirty ();
}
delete strum;
}
void
MidiView::sync_velocity_drag (double factor)
{

View File

@@ -301,6 +301,7 @@ class MidiView : public virtual sigc::trackable, public LineMerger
bool set_velocities_for_notes (std::vector<NoteBase*>& notes, std::vector<int>& velocities);
void transpose (bool up, bool fine, bool allow_smush);
void nudge_notes (bool forward, bool fine);
void strum_notes (bool forward, bool fine);
void channel_edit ();
void velocity_edit ();
@@ -431,6 +432,9 @@ class MidiView : public virtual sigc::trackable, public LineMerger
void quantize_selected_notes ();
void strum_notes_forward () { strum_notes (true, false); }
void strum_notes_backward () { strum_notes (false, false); }
protected:
friend class MidiRubberbandSelectDrag;
friend class MidiVerticalSelectDrag;