MIDI Draw: change behavior regarding MIDI Channel of new notes

When adding a note, use these criteria to choose the channel number:
* if the user has explicitly specified a note in the pulldown, use that
* if the user has AUTO selected and we are in a region, choose the nearest note's channel (consistent with velocity behavior)
* as a fallback, query the track for its channel-filter (old behavior)
This commit is contained in:
Ben Loftis 2021-11-18 07:32:09 -06:00
parent eebf3717e3
commit 252ae56a08
7 changed files with 38 additions and 10 deletions

View File

@ -3485,8 +3485,8 @@ Editor::setup_tooltips ()
set_tooltip (tav_shrink_button, _("Shrink Tracks"));
set_tooltip (visible_tracks_selector, _("Number of visible tracks"));
set_tooltip (draw_length_selector, _("Note Length to Draw (AUTO uses the current Grid setting)"));
set_tooltip (draw_velocity_selector, _("Note Velocity to Draw"));
set_tooltip (draw_channel_selector, _("Note Channel to Draw"));
set_tooltip (draw_velocity_selector, _("Note Velocity to Draw (AUTO uses the nearest note's velocity)"));
set_tooltip (draw_channel_selector, _("Note Channel to Draw (AUTO uses the nearest note's channel)"));
set_tooltip (grid_type_selector, _("Grid Mode"));
set_tooltip (snap_mode_button, _("Snap Mode\n\nRight-click to visit Snap preferences."));
set_tooltip (edit_point_selector, _("Edit Point"));

View File

@ -76,7 +76,7 @@ MidiAutomationLine::get_verbose_cursor_string (double fraction) const
return AutomationLine::get_verbose_cursor_string(fraction);
}
const uint8_t channel = mtv->get_channel_for_add();
const uint8_t channel = mtv->get_preferred_midi_channel();
boost::shared_ptr<const ValueNameList> value_names = mtv->route()->instrument_info().value_name_list_by_control (channel, _parameter.id());
if (!value_names) {

View File

@ -829,6 +829,7 @@ MidiRegionView::show_list_editor ()
_list_editor->present ();
}
/** Add a note to the model, and the view, at a canvas (click) coordinate.
* \param t time in samples relative to the position of the region
* \param y vertical position in pixels
@ -855,7 +856,7 @@ MidiRegionView::create_note_at (timepos_t const & t, double y, Temporal::Beats l
Temporal::Beats region_start = t.beats();
const double note = view->y_to_note(y);
const uint8_t chan = mtv->get_channel_for_add();
const uint8_t chan = get_channel_for_add(region_start);
const uint8_t velocity = get_velocity_for_add (region_start);
const boost::shared_ptr<NoteType> new_note (new NoteType (chan, region_start, length, (uint8_t)note, velocity));
@ -2002,7 +2003,7 @@ MidiRegionView::change_patch_change (MidiModel::PatchChangePtr old_change, const
/** Add a patch change to the region.
* @param t Time in samples relative to region position
* @param patch Patch to add; time and channel are ignored (time is converted from t, and channel comes from
* MidiTimeAxisView::get_channel_for_add())
* MidiTimeAxisView::get_preferred_midi_channel())
*/
void
MidiRegionView::add_patch_change (timecnt_t const & t, Evoral::PatchChange<Temporal::Beats> const & patch)
@ -3917,7 +3918,7 @@ MidiRegionView::update_ghost_note (double x, double y, uint32_t state)
_ghost_note->note()->set_time (snapped_beats);
_ghost_note->note()->set_length (length);
_ghost_note->note()->set_note (y_to_note (y));
_ghost_note->note()->set_channel (mtv->get_channel_for_add ());
_ghost_note->note()->set_channel (mtv->get_preferred_midi_channel ());
_ghost_note->note()->set_velocity (get_velocity_for_add (snapped_beats));
update_note (_ghost_note, false);
@ -4249,6 +4250,32 @@ MidiRegionView::show_verbose_cursor (string const & text, double xoffset, double
trackview.editor().verbose_cursor()->set_offset (ArdourCanvas::Duple (xoffset, yoffset));
}
uint8_t
MidiRegionView::get_channel_for_add (MidiModel::TimeType time) const
{
/* first, use the user-specified channel in the editor */
PublicEditor& editor = trackview.editor();
if (editor.draw_channel() != Editing::DRAW_CHAN_AUTO) {
return editor.draw_channel();
}
/* second, use the nearest note in the region-view (consistent with get_velocity_for_add behavior) */
if (!_model->notes().empty()) {
MidiModel::Notes::const_iterator m = _model->note_lower_bound(time);
return (*m)->channel();
}
/* lastly: query the track's channel filter */
MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
if (mtv) {
return mtv->get_preferred_midi_channel();
}
/* fallback: ch0 */
return 0;
}
uint8_t
MidiRegionView::get_velocity_for_add (MidiModel::TimeType time) const
{

View File

@ -441,6 +441,7 @@ public:
void show_verbose_cursor (boost::shared_ptr<NoteType>) const;
uint8_t get_velocity_for_add (ARDOUR::MidiModel::TimeType time) const;
uint8_t get_channel_for_add (ARDOUR::MidiModel::TimeType time) const;
uint8_t _current_range_min;
uint8_t _current_range_max;

View File

@ -1724,7 +1724,7 @@ MidiTimeAxisView::stop_step_editing ()
* of the channel selector.
*/
uint8_t
MidiTimeAxisView::get_channel_for_add () const
MidiTimeAxisView::get_preferred_midi_channel () const
{
if (_editor.draw_channel() != Editing::DRAW_CHAN_AUTO) {
return _editor.draw_channel();

View File

@ -108,7 +108,7 @@ public:
void first_idle ();
void set_note_highlight (uint8_t note);
uint8_t get_channel_for_add () const;
uint8_t get_preferred_midi_channel () const;
void get_per_region_note_selection (std::list<std::pair<PBD::ID, std::set<boost::shared_ptr<Evoral::Note<Temporal::Beats> > > > >&);
void use_midnam_info ();

View File

@ -688,7 +688,7 @@ PianoRollHeader::send_note_on (uint8_t note)
//cerr << "note on: " << (int) note << endl;
if (track) {
_event[0] = (MIDI_CMD_NOTE_ON | mtv->get_channel_for_add ());
_event[0] = (MIDI_CMD_NOTE_ON | mtv->get_preferred_midi_channel ());
_event[1] = note;
_event[2] = 100;
@ -703,7 +703,7 @@ PianoRollHeader::send_note_off (uint8_t note)
MidiTimeAxisView* mtv = dynamic_cast<MidiTimeAxisView*> (&_view.trackview ());
if (track) {
_event[0] = (MIDI_CMD_NOTE_OFF | mtv->get_channel_for_add ());
_event[0] = (MIDI_CMD_NOTE_OFF | mtv->get_preferred_midi_channel ());
_event[1] = note;
_event[2] = 100;