+int
+MidiTimeAxisView::step_add_note (uint8_t channel, uint8_t pitch, uint8_t velocity, Evoral::MusicalTime beat_duration)
+{
+ if (step_edit_region && step_edit_region_view) {
+
+ if (beat_duration == 0.0) {
+ bool success;
+ beat_duration = _editor.get_grid_type_as_beats (success, step_edit_insert_position);
+
+ if (!success) {
+ return -1;
+ }
+ }
+
+ MidiStreamView* msv = midi_view();
+
+ /* make sure its visible on the vertical axis */
+
+ if (pitch < msv->lowest_note() || pitch > msv->highest_note()) {
+ msv->update_note_range (pitch);
+ msv->set_note_range (MidiStreamView::ContentsRange);
+ }
+
+ /* make sure its visible on the horizontal axis */
+
+ nframes64_t fpos = step_edit_region->position() +
+ step_edit_region_view->beats_to_frames (step_edit_beat_pos + beat_duration);
+
+ if (fpos >= (_editor.leftmost_position() + _editor.current_page_frames())) {
+ _editor.reset_x_origin (fpos - (_editor.current_page_frames()/4));
+ }
+
+ step_edit_region_view->step_add_note (channel, pitch, velocity, step_edit_beat_pos, beat_duration);
+
+ if (_step_edit_triplet_countdown > 0) {
+ _step_edit_triplet_countdown--;
+
+ if (_step_edit_triplet_countdown == 0) {
+ _step_edit_triplet_countdown = 3;
+ }
+ }
+
+ if (!_step_edit_within_chord) {
+ step_edit_beat_pos += beat_duration;
+ step_edit_region_view->move_step_edit_cursor (step_edit_beat_pos);
+ } else {
+ step_edit_beat_pos += 1.0/Meter::ticks_per_beat; // tiny, but no longer overlapping
+ _step_edit_chord_duration = max (_step_edit_chord_duration, beat_duration);
+ }
+ }
+
+ return 0;
+}