summaryrefslogtreecommitdiff
path: root/gtk2_ardour/midi_region_view.cc
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2014-12-28 19:21:07 -0500
committerDavid Robillard <d@drobilla.net>2014-12-28 19:21:46 -0500
commitb54863c8c3642a918c70f8a0ba0d36993b2f227d (patch)
tree27974c4d57cfaf91bfd510e7248c69bc360d3748 /gtk2_ardour/midi_region_view.cc
parent541705e1ee473f8e80afc81206d0ab9c3f4c9911 (diff)
Set new note velocity based on surrounding notes.
Diffstat (limited to 'gtk2_ardour/midi_region_view.cc')
-rw-r--r--gtk2_ardour/midi_region_view.cc62
1 files changed, 44 insertions, 18 deletions
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index 75b7d4693a..b690fa6649 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -917,10 +917,8 @@ MidiRegionView::create_note_at (framepos_t t, double y, Evoral::MusicalTime leng
return;
}
- MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
- MidiStreamView* const view = mtv->midi_view();
-
- const double note = view->y_to_note(y);
+ MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
+ MidiStreamView* const view = mtv->midi_view();
// Start of note in frames relative to region start
if (snap_t) {
@@ -928,11 +926,15 @@ MidiRegionView::create_note_at (framepos_t t, double y, Evoral::MusicalTime leng
t = snap_frame_to_grid_underneath (t, grid_frames);
}
- const boost::shared_ptr<NoteType> new_note (
- new NoteType (mtv->get_channel_for_add (),
- region_frames_to_region_beats(t + _region->start()),
- length,
- (uint8_t)note, 0x40));
+ const MidiModel::TimeType beat_time = region_frames_to_region_beats(
+ t + _region->start());
+
+ const double note = view->y_to_note(y);
+ const uint8_t chan = mtv->get_channel_for_add();
+ const uint8_t velocity = get_velocity_for_add(beat_time);
+
+ const boost::shared_ptr<NoteType> new_note(
+ new NoteType (chan, beat_time, length, (uint8_t)note, velocity));
if (_model->contains (new_note)) {
return;
@@ -3529,20 +3531,17 @@ MidiRegionView::update_ghost_note (double x, double y)
framecnt_t grid_frames;
framepos_t const f = snap_frame_to_grid_underneath (unsnapped_frame, grid_frames);
- /* use region_frames... because we are converting a delta within the region
- */
-
+ /* calculate time in beats relative to start of source */
const Evoral::MusicalTime length = get_grid_beats(unsnapped_frame);
+ const Evoral::MusicalTime time = std::max(
+ Evoral::MusicalTime(),
+ absolute_frames_to_source_beats (f + _region->position ()));
- /* note that this sets the time of the ghost note in beats relative to
- the start of the source; that is how all note times are stored.
- */
- _ghost_note->note()->set_time (
- std::max(Evoral::MusicalTime(),
- absolute_frames_to_source_beats (f + _region->position ())));
+ _ghost_note->note()->set_time (time);
_ghost_note->note()->set_length (length);
_ghost_note->note()->set_note (midi_stream_view()->y_to_note (y));
_ghost_note->note()->set_channel (mtv->get_channel_for_add ());
+ _ghost_note->note()->set_velocity (get_velocity_for_add (time));
/* the ghost note does not appear in ghost regions, so pass false in here */
update_note (_ghost_note, false);
@@ -3849,6 +3848,33 @@ MidiRegionView::show_verbose_cursor (string const & text, double xoffset, double
trackview.editor().verbose_cursor()->set_offset (ArdourCanvas::Duple (xoffset, yoffset));
}
+uint8_t
+MidiRegionView::get_velocity_for_add (MidiModel::TimeType time) const
+{
+ if (_model->notes().empty()) {
+ return 0x40; // No notes, use default
+ }
+
+ MidiModel::Notes::const_iterator m = _model->note_lower_bound(time);
+ if (m == _model->notes().begin()) {
+ // Before the start, use the velocity of the first note
+ return (*m)->velocity();
+ } else if (m == _model->notes().end()) {
+ // Past the end, use the velocity of the last note
+ --m;
+ return (*m)->velocity();
+ }
+
+ // Interpolate velocity of surrounding notes
+ MidiModel::Notes::const_iterator n = m;
+ --n;
+
+ const double frac = ((time - (*n)->time()).to_double() /
+ ((*m)->time() - (*n)->time()).to_double());
+
+ return (*n)->velocity() + (frac * ((*m)->velocity() - (*n)->velocity()));
+}
+
/** @param p A session framepos.
* @param grid_frames Filled in with the number of frames that a grid interval is at p.
* @return p snapped to the grid subdivision underneath it.