View Issue Details

IDProjectCategoryView StatusLast Update
0005608ardourfeaturespublic2023-11-23 10:54
ReporterLeatuspenguin Assigned Topaul  
Status resolvedResolutionfixed 
Product Version3.0 
Summary0005608: Velocity track idea
DescriptionThe one midi feature which is currently lacking is the lack of proper velocity editing. Unless there's something i'm unaware of, the only current way is to edit individual note velocity, or groups of notes together. The only visual way of telling the velocities of multiple notes is via colour intensity.

One solution to this, and without bringing a whole new window into the equation, would be to make use of an automation track to edit note velocities. I have included a mock up, influenced by qtractors velocity editing.
TagsNo tags attached.

  Users sponsoring this issue
Sponsors List Total Sponsorship = US$ 90

2018-06-19 12:22: alexmitchellmus (US$ 50)
2020-05-08 22:13: tavasti (US$ 30)
2023-02-16 02:49: Reezlaw (US$ 10)
  Users sponsoring this issue (Total Sponsorship = US$ 90)


parent of 0009072 resolvedpaul Midi Velocity Lanes 
has duplicate 0008486 resolvedpaul add event editor to piano roll 
related to 0004324 closeddrobilla A3 should have MIDI velocity editing facilities 


2013-07-21 15:55


velocity track.png (137,658 bytes)   
velocity track.png (137,658 bytes)   


2013-07-21 16:46

administrator   ~0015150

Do you have any idea how that can work with polyphony, as well?


2013-07-21 17:44

reporter   ~0015151

I never thought about that. It was just an idea i had that i thought I'd throw out there. Thinking about it now, i see what you mean. Automation tracks only works on one parameter at a time. So there's no way it could work with an automation track without a lot of work? Is it feasible at all or are there any other thoughts about velocity editing at the moment?


2013-07-23 02:46

administrator   ~0015158

its not a problem with automation track limits per se.

its a problem with conditions that involve chords. how do you edit the velocity of just one of the notes?


2013-07-23 02:48

administrator   ~0015159

i suspect lines, not bar charts, will be the likely solution to this, btw. doesn't fully solve the polyphony design problem, but it would allow editing once it was clear what line affected which notes.


2013-07-23 06:58

reporter   ~0015164

Last edited: 2013-07-23 11:06

So the issue isn't a technical one regarding polyphony on an automation track? It's to do with how it would be visually implemented? Other daws allow you to select the note with your mouse to bring it's velocity bar to the top so you can edit it, if there are multiple event notes at the same time. Would something similar not work? Or have I misunderstood?


2014-12-23 14:10

reporter   ~0016075

Good editors I've seen have a circle for each note, which can be moved up or down. You could do the same thing with a line that goes out horizontally to the end of the note.


2014-12-23 19:27

developer   ~0016080

Bars suck. If all we really need is the ability to edit in ramps and so on, seems we can add that easily enough without a clunky bar thing that's confusing as soon as any polyphony is around.

2014-12-24 02:08



2014-12-24 02:08

reporter   ~0016081

UI proposal: designed to fit with the current automation UI design.

The example doesn't include chords, but you can see how it would work for them. Just the red squares are draggable. The green lines are just indicators. If notes are selected in the actual track, then those notes are brought to the top of the stack in the velocity channel, thus allowing chord notes to be velocity-edited independently (if the chord has the same velocity on all notes, just select one note in the track, edit the velocity, select another note, repeat, etc.). If multiple notes are selected in the track, moving one of them in the velocity editor should move all of them.


2014-12-24 02:52

reporter   ~0016085

Last edited: 2014-12-24 02:53

Love this idea for 3 another reasons:
1- It helps a lot to visualize the timing of the notes.
I often have this problem when editing piano notes. e.g. there are 4 notes that are supposed to be at equal distance from each other, but not really on the tempo because plenty of emotion... and something sounds wrong in their timing but I can't hear where because they are too fast or too subtle... It helps a lot to see them on a horizontal timeline. Problems become obvious this way.
2- Currently, when scrolling for velocity, each step of scroll is an Undo/Redo action... So you have to undo 8 times to put back your 48 to the 40 it was before you scroll.
Of course this issue could be fixed another way.
3. We could get rid of the Alt+Scroll x10 velocity that is very confusing because of the Alt+Scroll for vertical zoom (which is fantastic). I bet nobody knows about this anyway, or they discovered it by mistake when trying to Y-zoom.
This way, we could simply click for large velocity steps.


2014-12-25 01:29

developer   ~0016096

? The notes *are* on a horizontal timeline. How does a velocity thing make any difference there?

I'm not fundamentally opposed to a separate velocity thing, but it's a massive mount of work completely unlike anything else we currently have for little to no mentioned benefit. I'd rather see a list of exactly what things users need to accomplish that we can't currently do (e.g. ramp up velocity from here to there) than "hey let's just blindly make a bar thing because some other programs do"...

e.g. it seems to me that a velocity tool that lets you edit the velocity of notes in linear ways might be (almost) universally superior. Perhaps we should have a bar thingie, and the benefits outweight the polyphony problems. So, what benefits?

In other words: justify with something other than "program X did it". If "we" are going to do a ton of work on velocity editing, it might as well be thought out properly first...

I am also interested in these questions because making the on-note velocity editing more powerful is something that is *way* more feasible to do relatively shortly than implementing this, and would be good regardless of whether or not we eventually have a bar thing.


2014-12-25 01:48

reporter   ~0016099

@drobilla, I don't know about the priority, there are definitely some bugs that I would consider more urgent than this. 0006055 e.g. or the fact that Ardour does not send any NoteOff in record mode. (I need to create a report for this)
But my point 1- above is clearly important. Let me show you why a horizontal view is important, what it is, and what it's not...
In this example, how do you know that the 4 piano notes following my playhead are rhythmically at equal distance from each other?
It's a piano part, not a drum, so it's not supposed to be exactly on a beat, it's just supposed to make sense emotionally.
In this example, I can hear something wrong in the timing of these notes but I can't explain it. If I could visualize these notes with vertical bars next to each other, the problem would become obvious.
In other words, with vertical bars, the visualization of the notes timing (X) is not disturbed by their frequency (Y).
Having velocity bars would help a lot to visualize the rhythmical side of the music.
I don't care what other programs use.
How urgent is it? I don't know, you judge...
I still think this x10 velocity steps with Alt+Scroll should already disappear.


2014-12-26 01:12

reporter   ~0016102

A quick solution that would work in the mean-time would be to <Modifier>+Drag changes the velocity of a note. Scrollwheel is not very precise, and it also doesn't easily let you define multiple scrolls as one event (as opposed to click and release).

But, there are good reasons that a height-based visualisation (not bars - I wouldn't describe my UI design as bars). For one, human colour perception is not that accurate - we don't really have a way of estimating the absolute value of something from the luminosity/saturation, as with the current colour scheme. You *might* be able to improve that by adding a hue change with velocity too (e.g. red->white->blue). We're better at comparing relative colours, but I don't think many people have the ability to easily tell the difference between a note at 65 velocity and one at 70 (in the current color scheme, but it's not going to be easy in any colour scheme), but that can make a big difference, depending on the synth/sampler.

The fundamental problem is that you're trying to show 3 variables (time, pitch, velocity) in 2 dimensions. There are lots of visual variables you could use (e.g. ), but size and colour are probably the only ones that might work in this situation, and size also has problems (like overlapping).

Adding a velocity bar allows you to have two correlated plots of 2 variables each. It's a pretty concise way of displaying and allowing manipulation of the information, without having too much complexity (you could make it 3D, and it'd work, but it'd get visually confusing :D ). If you add a height-guide grid behind the plot (e.g. every 32 velocity, or something), then you get *really good* absolute and relative velocity estimation.


2014-12-26 01:21

reporter   ~0016103

Last edited: 2014-12-26 01:21

Scroll is VERY precise (and very handy) One scroll step is 1 step of velocity.
Velocity upon scroll is IMO the best idea Ardour ever had... unless you have a crappy mouse.


2015-05-16 15:45

reporter   ~0016696

I think Velocity TRACK is a GREAT idea to edit velocity


2015-07-14 03:49

reporter   ~0016871

I think the goal is to achieve easy "fader rides" for crescendos etc. I propose the second mockup be approached but on a mouse drag to change velocities, apply it to all notes of the chord the same way the fader does on a midi track (scale all notes by the same factor). You can scale the highest velocity note to the new velocity or have the behavior in the preferences (highest velocity note, highest pitch note, lowest etc). Basically automating the gain fader from the mixer but applying the effect to each note event.

If an individual note is clicked and dragged in the "velocity track" it changes velocity, but you can also do quick shaping of the overall dynamics a passage through a mouse drag. Perhaps there is a better way than an extra track or bar to achieve this, but I think this is a pretty reasonable definition of the behavior for chords. I would sure appreciate a change to quickly shape drum pattern dynamics the same way I used to do in hydrogen (which does a velocity bar for whichever drum/note is currently selected).


2017-02-26 00:41

reporter   ~0019438

Last edited: 2017-02-26 00:42

*Added note from IRC discussion on Feb.25/2017

In asking about the status of this feature on IRC it was suggested that a barrier to integrating this feature was how to handle 'chords' on the MIDI timeline (or multiple notes in the same vertical timeline grid axis). In my experience with other DAW's it occurred to me that visual MIDI velocity editing where the velocity is represented by a vertical 'bar' is often handled by selecting only one group of notes at a time on the same horizontal key/note path. Below are 2 examples from screenshots:

Example 1:

Example one is a screenshot of the Hydrogen Drum Machine, as you can see in it's editor window keys/notes (or drumkit pieces) can be selected on the left hand side which highlights the horizontal grid axis and exposes the vertical visual 'bars' to change the velocity of ONLY the notes on that grid axis (or note key). This allows individual adjustment of only single notes at a time without affecting note velocities on other note keys.

Example 2:

Example two is a screenshot of EnergyXT which incidentally also shares the ideology of MIDI within a timeline track like Ardour. EnergyXT does not allow selecting note keys on it's MIDI keyboard on the left like Hydrogen does however if multiple notes are 'drag-selected' then their velocity bars appear in the 'Velocity' lane under the grid. This also allows selection of individual notes on the same horizontal grid axis without changing the velocity of other notes.

This is how 2 other Linux grid-based editors handle visual velocity editing of notes, there are more examples like Seq24...

Perhaps the addition of a new MIDI type or class of track (ie MIDI-Drum track) could incorporate the suggested visual velocity drawing features without modifying or making changes to the existing scroll wheel features in Ardours existing MIDI tracks. In my own workflow and discussion with users it seems this kind of in-depth visual velocity note editing is most often employed in drum and percussion MIDI tracks.

PLEASE consider adding this feature as it is present in almost every other MIDI-capable DAW on every platform and is very much a standard and expected method of drum sequencing, I don't think this is a feature Ardour/Mixbus should be without.

Thanks for reading,


2017-02-26 09:54

reporter   ~0019440

I would like to add that in order for the velocity track/lane to be really useful, it's should be possible to drag a line across several events to adjust the velocity.


2017-02-26 14:57

reporter   ~0019445

Last edited: 2017-02-26 20:46



Good point! Most DAW's employing vertical bars also allow to draw ramps and curves across the velocity 'bars', so this would be desirable as well.

Added Example 3:

This example is showing Reaper (Native Linux Version) and it actually combines the features shown above, so a note/key remains highlighted (in pink) and notes shown across that horizontal axis can then be edited without affecting other notes. Actually the Reaper editor is quite full-featured and also shows the numerical velocity values on the drawn note displayed on the grid as well as handling velocity bars of chords in different colors depending on the note selected.


2018-04-19 03:55

reporter   ~0020259

Last edited: 2018-04-19 06:14

I think an in-region MIDI layering system could be used to show additional information for MIDI notes. Data displayed could be selected (flags?) in a layer menu- which would show a graphical, editable overlay. (editing dependent on style and sort of data)

Such overlays could be velocity lines drawn into the notes- and paired with Color, (and a Velocity Track) could make editing of MIDI velocities clearer- and easier for the end user.

The development of a MIDI overlay system, could also be the first step to enable other data that is relevant per note (such as MPE data) to be displayed. A user could choose to enable velocity / pressure / bend etc... all at once (different color automation?) or only one at a time.

Alternatively MPE data may only be shown per selected note, however having an overview of all events that occur in a MIDI region is very powerful, and allows fast editing.

To speed up editing velocity information, it may be necessary to have a dedicated Velocity tool, allows the user to left-click onto a note, and drag while holding down the left-button, to change the velocity.

A few mockups (painted on with Krita - not accurate):

MIDI Velocity in Note:

MIDI MPE Data in Note:


2018-06-20 18:43

reporter   ~0020303

Last edited: 2018-06-20 18:44

I think that visualizes the event values nicely, but certainly doesn't provide an easy way to manipulate them. I still think that the biggest need is to be able to quickly "draw" dynamics, the same way you can with fader automation on an audio track. I think a lollipop thing to visualize AND manipulate the velocity info, be it overlay or another lane is the most logical way, though it probably needs a few editing modes like snap to value and scale to support a few use cases. I can't think of any way to do this that isn't a departure from current capabilities in ardour.

"To speed up editing velocity information, it may be necessary to have a dedicated Velocity tool, allows the user to left-click onto a note, and drag while holding down the left-button, to change the velocity."
I don't see that as much improvement over the current situation of using mousewheel and color to visualize. I think rghvdberg's point is the essence of this feature request: 1 click+drag to manipulate many notes' velocities.

The problem remains that note events have 3 degrees of freedom (4 if you include channel) and we only have 2D screens to visualize and edit on. When Ardour VR comes out we'll laugh that this was ever an issue. ;)


2018-06-21 03:38

reporter   ~0020304

As far as editing goes, a "multiplication ramp" tool might be good, and require very little in the way of new interface.

For example:

1. Select a bunch of notes
2. context menu -> velocity ramp
3. Draw a line in the current midi track, where the bottom of the track = 0, and the top = 1 (or 2?).
4. When the ramp is finished, multiply each note's current velocity value by the value at the corresponding position in the ramp.

This would be nice because it would allow you to maintain some of the relative variation between consecutive notes (rather than just over-writing the values.

The line drawing could have a couple of different options: 2 or more points (linear ramps in between), bezier curves, or free-hand draw. Hit enter to finish and apply the ramp.

If there's a tool configuration dialogue, it could include things like adding humanisation to the ramp (add a random component from 0-50%).


2018-06-25 10:22

reporter   ~0020305

Last edited: 2018-06-25 10:54

I put together a mock-up in Ardour doing this to gtk2_ardour/note_base.h:

inline static uint32_t meter_style_fill_color(uint8_t vel, bool selected) {
     if (selected) {
     return _selected_mod_col;
     } else


I experimented with other ideas:
* Dimming color of note outline
* Dimming color of note fill

However it was not clear to me when I was using Ardour which notes were selected.

If the outline can become 2 pixels then maybe these other methods would work better. However I think that 1 pixel has been chosen for a reason. (maybe only when selected the outline becomes 2 pixels?)

Also this video outlines an issue when changing multiple notes velocities. (which is already evident to any user of MIDI and Ardour) Which is that once the MIDI velocity becomes 0 or 127 there is no way to adjust the additional notes up or down.

Other software solves this issue by saturating the high and low values.

However due to Ardour using the scrollwheel for Velocity adjustment it makes it impossible to calculate 'velocity change start' events. As there can always be velocity change events.

In other software the start event is simply left click when using a dedicated velocity tool. Thus the delta of the mouse movement can be translated to velocity up and down.(Which gives the user the ability to decide how much to move the velocity without loosing too much velocity information for saturated values.)

The only issue with my solution is if the user sets one of the three velocity colors to the same as the selected color there will be no way to see selected notes. However as all colors are user changeable, this could be easily fixed by the user by selecting a 'selected color' that is not present in the velocity colors.


2018-06-26 16:32

reporter   ~0020310

Last edited: 2018-06-26 17:40

Here is a concept of placing velocity line 'inside' each MIDI note:


Also increased the outline size of all MIDI notes to 2px (originally 1px)

(out.patch above is a Git patch that contains this working concept. Not a pull request, or intended for production- only to work out ideas)


2018-06-26 17:31


out.patch (5,825 bytes)   
diff --git a/doc/classes/ b/doc/classes/
deleted file mode 100644
index d875677c0..000000000
--- a/doc/classes/
+++ /dev/null
@@ -1 +0,0 @@
-dot -Tsvg > midi.svg
diff --git a/doc/layering/ b/doc/layering/
deleted file mode 100644
index ad8d95e7b..000000000
--- a/doc/layering/
+++ /dev/null
@@ -1,10 +0,0 @@
-for f in basic-layering layering-order-1 layering-order-2; do
-    echo "$f"
-    inkscape -z --export-area-drawing -f $f.svg --export-pdf $f.pdf
-pdflatex layering.tex
-pdflatex layering.tex
diff --git a/gtk2_ardour/ b/gtk2_ardour/
index 481ac039b..b7a1bff3d 100644
--- a/gtk2_ardour/
+++ b/gtk2_ardour/
@@ -1764,7 +1764,7 @@ MidiRegionView::update_sustained (Note* ev, bool update_ghost_regions)
 	y1 = y0 + std::max(1., floor(note_height()) - 1);
-	ev->set (ArdourCanvas::Rect (x0, y0, x1, y1));
+	ev->set (ArdourCanvas::Rect (x0, y0, x1, y1), note->velocity());  //------------
 	if (!note->length()) {
 		if (_active_notes && note->note() < 128) {
@@ -1791,6 +1791,7 @@ MidiRegionView::update_sustained (Note* ev, bool update_ghost_regions)
 	const uint32_t base_col = ev->base_color();
 	ev->set_outline_color(ev->calculate_outline(base_col, ev->selected()));
+	ev->set_velocity_line_color(UINT_INTERPOLATE(base_col, 0x000000ff, 0.5));
diff --git a/gtk2_ardour/ b/gtk2_ardour/
index 6e1878afc..7770a7793 100644
--- a/gtk2_ardour/
+++ b/gtk2_ardour/
@@ -32,21 +32,28 @@ using namespace ArdourCanvas;
 Note::Note (
 	MidiRegionView& region, Item* parent, const boost::shared_ptr<NoteType> note, bool with_events)
 	: NoteBase (region, with_events, note)
-	, _rectangle (new ArdourCanvas::Rectangle (parent))
+	, _rectangle (new ArdourCanvas::Rectangle (parent)), _velocity_line (new ArdourCanvas::Rectangle (parent))
 	CANVAS_DEBUG_NAME (_rectangle, "note");
 	set_item (_rectangle);
+  //  set_item (_velocity_line);
+	_rectangle->set_outline_width(2);
 Note::~Note ()
 	delete _rectangle;
+	delete _velocity_line;
 Note::move_event (double dx, double dy)
 	_rectangle->set (_rectangle->get().translate (Duple (dx, dy)));
+	_velocity_line->set (_velocity_line->get().translate (Duple (dx, dy)));
@@ -85,28 +92,39 @@ Note::set_fill_color (uint32_t color)
 	_rectangle->set_fill_color (color);
+Note::set_velocity_line_color (uint32_t color)
+    _velocity_line->set_outline_color (color);
+    _velocity_line->set_fill_color (color);
 Note::show ()
 	_rectangle->show ();
+	_velocity_line->show ();
 Note::hide ()
 	_rectangle->hide ();
+	_velocity_line->hide ();
-Note::set (ArdourCanvas::Rect rect)
+Note::set (ArdourCanvas::Rect rect, uint8_t velocity)
 	_rectangle->set (rect);
+	_velocity_line->set (ArdourCanvas::Rect(rect.x0, rect.y0-((rect.y0-rect.y1)*.33), rect.x0 + ((rect.x1 - rect.x0) * ((float)velocity/(float)127)), ((rect.y0-rect.y1)*.33)+rect.y1));    //(rect.x0, (rect.y1-rect.y0)*.33, (rect.y1-rect.y0)*.66, rect.y1*(velocity/127)));
 Note::set_x0 (Coord x0)
 	_rectangle->set_x0 (x0);
@@ -131,16 +149,19 @@ void
 Note::set_outline_what (ArdourCanvas::Rectangle::What what)
 	_rectangle->set_outline_what (what);
+	_velocity_line->set_outline_what (what);
 Note::set_outline_all ()
 	_rectangle->set_outline_all ();
+	_velocity_line->set_outline_all ();
 Note::set_ignore_events (bool ignore)
 	_rectangle->set_ignore_events (ignore);
+	_velocity_line->set_ignore_events (ignore);
diff --git a/gtk2_ardour/note.h b/gtk2_ardour/note.h
index c002f9d3c..0cb3ff243 100644
--- a/gtk2_ardour/note.h
+++ b/gtk2_ardour/note.h
@@ -46,7 +46,7 @@ public:
 	ArdourCanvas::Coord x1 () const;
 	ArdourCanvas::Coord y1 () const;
-	void set (ArdourCanvas::Rect);
+	void set (ArdourCanvas::Rect, uint8_t);
 	void set_x0 (ArdourCanvas::Coord);
 	void set_y0 (ArdourCanvas::Coord);
 	void set_x1 (ArdourCanvas::Coord);
@@ -57,6 +57,7 @@ public:
 	void set_outline_color (uint32_t);
 	void set_fill_color (uint32_t);
+  void set_velocity_line_color (uint32_t);
 	void show ();
 	void hide ();
@@ -67,6 +68,7 @@ public:
 	ArdourCanvas::Rectangle* _rectangle;
+  ArdourCanvas::Rectangle* _velocity_line;
 #endif /* __gtk_ardour_note_h__ */
diff --git a/gtk2_ardour/note_base.h b/gtk2_ardour/note_base.h
index ebc00cbfa..d1e82327e 100644
--- a/gtk2_ardour/note_base.h
+++ b/gtk2_ardour/note_base.h
@@ -104,9 +104,10 @@ public:
 	static void set_colors ();
 	inline static uint32_t meter_style_fill_color(uint8_t vel, bool selected) {
-		if (selected) {
-			return _selected_mod_col;
-		} else if (vel < 64) {
+		//if (selected) {
+		//	return _selected_mod_col;
+		//} else
+    if (vel < 64) {
 			return UINT_INTERPOLATE(_min_col, _mid_col, (vel / (double)63.0));
 		} else {
 			return UINT_INTERPOLATE(_mid_col, _max_col, ((vel - 64) / (double)63.0));
diff --git a/libs/canvas/ b/libs/canvas/
index 488d5bf1f..ad97950d4 100644
--- a/libs/canvas/
+++ b/libs/canvas/
@@ -106,7 +106,7 @@ Rectangle::render_self (Rect const & area, Cairo::RefPtr<Cairo::Context> context
 		 * detail.
-		if (fmod (_outline_width, 2.0)  != 0.0) {
+		if (fmod (_outline_width, 2.0)  != 0.0) { //changed 2 -> 4
 			const double shift = _outline_width * 0.5;
 			self = self.translate (Duple (shift, shift));
@@ -180,7 +180,7 @@ Rectangle::compute_bounding_box () const
 		   than the rectangle itself.
-		_bounding_box = r.expand (1.0 + _outline_width * 0.5);
+		_bounding_box = r.expand (2.0 + _outline_width * 0.5);
 	_bounding_box_dirty = false;
out.patch (5,825 bytes)   


2018-06-29 05:49


Velocity_Editor.png (201,856 bytes)   
Velocity_Editor.png (201,856 bytes)   


2018-06-29 05:54

reporter   ~0020316

Last edited: 2018-06-30 12:11

+---------------------- IDEA ONLY------------------------+
                   I am not even 100% I like it myself
   posted to build a conversation around Velocity Editing
I uploaded an image of an 'In Region' Note Velocity Editor.

The idea is to be able to select notes, then right-click and be able to select from the Note menu the "Velocity Editor".

The Velocity editor would then show (as in the mock-up) the range of notes selected, and show a lollypop graph above the highest selected note.

It would be good to have a 'pen' tool, (for freehand drawing of velocities), and also a bezier curve tool (to allow any sort of velocity ramp to be drawn).

Any note that was not selected (when entering the tool would not be able to be edited. Possibly notes could be included and excluded on-the-fly while the tool is activated?

If notes overlap (as in same temporal position, then the drawn curve velocity would effect all notes (and give them all the same velocity for that time).

There would also be an exit box on the top right to close the tool, and return to normal note editing.


2018-07-03 15:29

administrator   ~0020317

alex: the master branch now has the basics of your patch, reimplemented as discussed on IRC. What's missing is color management. I think that's all.


2018-07-03 15:44

administrator   ~0020318

I set up the code to automatically compute the right color based on the fill color. I think that HSV::opposite() is probably too radical .. try playing with HSV::darker() ... ?


2018-07-03 16:55

administrator   ~0020319

color now works as it did in your patch.


2018-07-03 20:49

administrator   ~0020322

and the bars can be turned on and off.


2018-07-06 04:23

reporter   ~0020345

Last edited: 2018-07-08 11:29

Absolutely amazing work Paul! Thank you so much for taking the time to implement this.

Here are some additional thoughts (in no order) that I am thinking could help MIDI editing in Ardour work better. (some dot points are simply changing settings- or adding a preference):

* A way to edit velocity of multiple notes (as per this thread) as either an overlay or lane.
* Clearly showing MIDI regions (currently zoomed out- and in, its a bit hard to see the MIDI region from the canvas)-Theme:Cubasish does this well.
* MIDI Region (and Audio Region) end loop tool (drag end of region to loop, loop connects to same region, but can be changed in future edit.
* Making the outline of the white/black note rows able to be translucent, (like the white/black note row colors are) Currently the row outlines can become very busy visually, and actually don't help in locating which note is which as everything looks white(or the set color)
*(DONE) Velocity bar can be thinner? And also able to not show based on note vertical/horizontal height (this could already work).
* In note text (note name and velocity) and/or with velocity? EG: "A#4:127"
* Ability to change note outline thickness (currently 1px, could be 2px?) this may make a good preference.
* Smarter track zooming (when making track vertically larger) the MIDI region could expand to show more content? Instead of simply zooming in?
* When moving a note up/down highlight the whole note bar that it is currently on.
* Resound MIDI notes while changing velocity (as this is an audio software, it is good to hear the note velocity as well as see it)
* For resounding MIDI notes it may be better to have a dedicated velocity tool (or use the current 'Internal Edit Tool' to LMB a note and drag up/down to change velocity) as currently both 'DRAW MODE TOOL' and 'INTERNAL EDIT TOOL' have the same behavior when LMB clicking. (possibly we can use the middle mouse button for velocity change? MMB could be utilized more)
*(DONE) More note state colors: Currently there are 3, which only shows visually Low, Mid, High. [0,64,127] 5 Note states would show: Min, Low, Mid, High, Max. [0,32,64,96,127]


Currently RMB is not used for anything in Draw mode (when no notes are selected), it could be used to 'highlight notes' which can then also be moved with the same tool (LMB).
Then we don't need to worry about moving notes with the "Internal Edit Tool". Thus possibly we should be able to control velocity when LMB onto the selected notes in "Internal Edit". (currently both Note Edit, and Internal Edit both do same thing, and I wouldn't consider moving notes to be 'internally editing notes', rather editing 'note content' would be internal. Velocity is currently one of the only internal 'note' attributes we can edit.

If MPE is implemented, 'Internal Edit' could also be used for those values 'inside' notes as well (because LMB would no longer move the whole note):

* Note-on (strike)
* Note-off (lift)
* Aftertouch (press)
* Pitch-Bend, X-Axis (glide)
* Y-Axis (slide)

If (in the future) MPE is implemented, then showing 'internal' velocity bars is simply just one attribute of "show internal note data". Thus we should be able to select (per track) what sort of internal data we want to display (and edit).

Already there could be two modes for "show velocity bars", Note-on velocity, and Note-off.


2018-07-08 06:14


thinnervline_01.patch (1,055 bytes)   
commit e9bc4d618a585c3005cd943d7de353ecff545661
Author: alcomposer <>
Date:   Sun Jul 8 15:39:05 2018 +0930

    Make velocity lines thinner, have a 1px gap at beninning and end of

diff --git a/libs/canvas/ b/libs/canvas/
index 05c66afd4..dac9bc365 100644
--- a/libs/canvas/
+++ b/libs/canvas/
@@ -74,12 +74,12 @@ Note::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
 		   outline_width() margin on left.
 		   set width based on velocity.
-		self.y0  = self.y0 + outline_width() + 2;
-		self.y1  = self.y1 - outline_width() - 1;
+        const double centre = (self.y1 - self.y0) * 0.5;
+		self.y1  = self.y0 + centre + 2;
+		self.y0  = self.y0 + centre - 1;
 		const double width = (self.x1 - self.x0) - (2 * outline_width());
-		self.x0  = self.x0 + outline_width();
-		self.x1  = self.x0 + (width * _velocity);
+		self.x0  = self.x0 + outline_width()+1;
+		self.x1  = self.x0 + ((width-2) * _velocity);
 		const Rect draw = self.intersection (area);
thinnervline_01.patch (1,055 bytes)   


2018-07-08 06:16

reporter   ~0020350

Last edited: 2018-07-08 11:28

I attached a patch to make the in-note horizontal velocity lines thinner, with a 1px gap at either end. I think this looks a bit less visually imposing.

see: 'thinnervline_01.patch' above



2018-07-08 07:44

reporter   ~0020351

Last edited: 2018-07-08 11:35

Another idea I had for a solution to the 'lollipop' display. (Not implemented)

How about showing selected notes velocities vertically as an overlay on the piano roll editor.

User would:

1) Select multiple notes (or one note)
2) RMB notes and select from menu "Lollipop Editor"
3) Lollipop editor shows as overlay on screen, (only selected notes are displayed)
4) Freehand draw with LMB
5) Vector draw with RMB (click to create two points to draw a line between)
6) RETURN key to apply line values to note velocities
7) ESC key to leave "Lollipop Editor" mode


2018-07-13 03:38



2018-07-13 03:43

reporter   ~0020355

Last edited: 2018-07-13 03:59

Having thought about this for a while, I think that actually a simple velocity automation lane would suffice. (Simple, as in the ideas that I have proposed previous were probably quite complex- not implementation).

Mockup "Simple_Velocity_Autiomation_Lane.jpg"

To solve the 'polyphony issue' I would suggest to only be able to edit selected notes. As this is an automation lane (I know technically its not automation) but due to there being another lane, the user would be able to add or remove editable velocity lollipops by selection in the main midi region view.

Possibly a first iteration of this idea lane could simply be drawing velocity with the pen tool, or changing velocity up - down. No tools for velocity ramps - lines etc. which could come later.


2018-07-17 09:00

reporter   ~0020357

Last edited: 2018-07-17 14:17

Here is an example of a rudimentary (read Hack) change I made to Ghostregions that displays their notes as lollipops in an automation view.

Currently there is no editing, but it at least shows what it 'could' look like in Ardour. The lollipop lane is currently just an automation track, (without any automation in it).

I have attached ghostlollipop_patch.diff for anyone interested.

I can see this working such as:

* Automation header menu has 'velocity' checkbox
* When 'velocity' checkbox is toggled, a velocity layer is added
* The velocity lane will always be underneath the associated track
* If no MIDI notes are selected in a MIDI region, then all lollipops will be editable
* If there are selected MIDI notes then only those would be editable in the velocity lane (to preserve polyphonic velocity editing)
* Access to two tools: Pen (to draw velocity in) & Line (to draw lines)


2018-07-17 10:16


ghostlollipop_patch.diff (3,928 bytes)   
diff --git a/gtk2_ardour/ b/gtk2_ardour/
index 313bd22d0..06946ec7e 100644
--- a/gtk2_ardour/
+++ b/gtk2_ardour/
@@ -288,7 +288,7 @@ MidiGhostRegion::set_colors()
 static double
 note_height(TimeAxisView& trackview, MidiStreamView* mv)
-	const double tv_height  = trackview.current_height(); //ALEX_NOTE: height of each MIDI ghost note
+	const double tv_height  = trackview.current_height();
 	const double note_range = mv->contents_note_range();
 	return std::max(1.0, floor(tv_height / note_range - 1.0));
@@ -301,7 +301,7 @@ note_y(TimeAxisView& trackview, MidiStreamView* mv, uint8_t note_num)
 	const double note_range = mv->contents_note_range();
 	const double s          = tv_height / note_range;
-	return tv_height ; //- (note_num + 1 - mv->lowest_note()) * s;
+	return tv_height - (note_num + 1 - mv->lowest_note()) * s;
@@ -320,13 +320,9 @@ MidiGhostRegion::update_contents_height ()
 		double const y = note_y(trackview, mv, note_num);
-		    uint8_t const note_vel = it->second->event->note()->velocity();
-			double const track_base = trackview.current_height();
 		if (!it->second->is_hit) {
 			_tmp_rect = static_cast<ArdourCanvas::Rectangle*>(it->second->item);
-			_tmp_rect->set (ArdourCanvas::Rect (_tmp_rect->x0(), track_base-(track_base * ((float)note_vel/127)), _tmp_rect->x0()+5, track_base));
-		//  _tmp_rect->set (ArdourCanvas::Rect (_tmp_rect->x0(), y, _tmp_rect->x1(), y + h));
+			_tmp_rect->set (ArdourCanvas::Rect (_tmp_rect->x0(), y, _tmp_rect->x1(), y + h));
 		} else {
 			_tmp_poly = static_cast<ArdourCanvas::Polygon*>(it->second->item);
 			ArdourCanvas::Duple position = _tmp_poly->position();
@@ -353,22 +349,19 @@ MidiGhostRegion::add_note (NoteBase* n)
 		if (!n->item()->visible()) {
 		} else {
-		    uint8_t const note_vel = n->note()->velocity();
 			uint8_t const note_num = n->note()->note();
 			double const  h        = note_height(trackview, mv);
 			double const  y        = note_y(trackview, mv, note_num);
-			double const track_base = trackview.current_height();
-			//if (!event->is_hit) {
+			if (!event->is_hit) {
 				_tmp_rect = static_cast<ArdourCanvas::Rectangle*>(event->item);
-				_tmp_rect->set (ArdourCanvas::Rect (_tmp_rect->x0(), track_base-(track_base * ((float)note_vel/127)), _tmp_rect->x0()+5, track_base));
-			  //_tmp_rect->set (ArdourCanvas::Rect (_tmp_rect->x0(), y                       , _tmp_rect->x1() , y + h));
-			//} else {
-			//	_tmp_poly = static_cast<ArdourCanvas::Polygon*>(event->item);
-			//	Duple position = _tmp_poly->position();
-			//	position.y = y;
-			//	_tmp_poly->set_position(position);
-			//	_tmp_poly->set(Hit::points(h));
-			//}
+				_tmp_rect->set (ArdourCanvas::Rect (_tmp_rect->x0(), y, _tmp_rect->x1(), y + h));
+			} else {
+				_tmp_poly = static_cast<ArdourCanvas::Polygon*>(event->item);
+				Duple position = _tmp_poly->position();
+				position.y = y;
+				_tmp_poly->set_position(position);
+				_tmp_poly->set(Hit::points(h));
+			}
@@ -396,13 +389,10 @@ MidiGhostRegion::update_note (GhostEvent* ev)
 	_tmp_rect = static_cast<ArdourCanvas::Rectangle*>(ev->item);
 	uint8_t const note_num = ev->event->note()->note();
-	uint8_t const note_vel = ev->event->note()->velocity();
-	double const track_base = trackview.current_height();
 	double const y = note_y(trackview, mv, note_num);
 	double const h = note_height(trackview, mv);
-	_tmp_rect->set (ArdourCanvas::Rect (ev->event->x0(), track_base-(track_base * ((float)note_vel/127)), ev->event->x0()+5, trackview.current_height()));
-	//_tmp_rect->set (ArdourCanvas::Rect (ev->event->x0(), y                       , ev->event->x1()  , y + h                                ));
+	_tmp_rect->set (ArdourCanvas::Rect (ev->event->x0(), y, ev->event->x1(), y + h));
 /** Update the positions of our representation of a parent's hit.
ghostlollipop_patch.diff (3,928 bytes)   


2018-07-17 12:10

administrator   ~0020358

wow, this is brilliant.

now you need to look into the Drag code (editor_drag.{cc,h}) to see how to implement velocity dragging :)


2018-07-17 12:56

reporter   ~0020359

Last edited: 2018-07-17 13:05

@paul, I personally don't like the idea of velocity dragging for all notes. But I do think that lollipops should be able to be:

* Drawn into
* Adjusted (selected notes)
* Get value from drawn line over all selected lollipops.

In regard to 'velocity automation', enumerating lollipop should allow us to pass this as a automation track type? Which would be drawn along with all the other automation tracks?

It looks like currently global tracks are dealt with elsewhere so I am not sure if this should be the same place.


2020-08-19 05:28

reporter   ~0024940

@alexmitchellmus Is that the right patch? I may well be mistaken, but it seems to be a patch relative to another change (there is a line with an ALEX comment removed). Did you perhaps not diff against master?


2023-02-16 02:56

reporter   ~0027383

I'm really surprised that there isn't more pressure about this. Minutes ago I was drawing drum notes, I wanted a velocity curve for a roll on the toms and suddenly realised there's no other way than setting the individual velocities one by one. Coming from a well known commercial DAW that I'm determined to abandon - I want to use Linux and open source software exclusively - this is extremely weird to me and it might even be a deal breaker.


2023-02-16 03:51

administrator   ~0027384

there's less pressure than even i'd expect, and i think it is mostly because the vast majority of people rarely (if ever) do this. it is another one of those workflow things where for one set of users, this is, as you put, a dealbreaker, and for a different (and much larger) set of users, it's mostly of little consequence. that's true of almost all features already present or missing in any given DAW, including ardour.

i do have a plan for this at this point, and it will better than you see in many other DAWs, i believe. designing the details is a bit of a headache, though.


2023-02-16 09:45

reporter   ~0027387

This is awesome news. I'm learning to love your software and I really want to stick to it. I guess I'll mousewheel my velocities for a little longer, knowing you're working on something is great


2023-10-09 03:04

administrator   ~0028163

OK all you whiners :)))

Ardour 8.0 is out with your beloved lollipops implemented, along with freehand drawing.

And Leatuspenguin, I hope you're still at the same email address - this may be the first of your always excellent suggestions that we've actually implemented in a decade now.


2023-11-23 10:54

reporter   ~0028354

I finally got a chance to test it and it's amazing. Thank you so much

Issue History

Date Modified Username Field Change
2013-07-21 15:55 Leatuspenguin New Issue
2013-07-21 15:55 Leatuspenguin File Added: velocity track.png
2013-07-21 16:46 x42 Note Added: 0015150
2013-07-21 17:44 Leatuspenguin Note Added: 0015151
2013-07-23 02:46 paul Note Added: 0015158
2013-07-23 02:48 paul Note Added: 0015159
2013-07-23 06:58 Leatuspenguin Note Added: 0015164
2013-07-23 11:06 Leatuspenguin Note Edited: 0015164
2014-01-22 12:23 x42 Relationship added related to 0004324
2014-12-23 14:10 naught101 Note Added: 0016075
2014-12-23 19:27 drobilla Note Added: 0016080
2014-12-24 02:08 naught101 File Added: Ardour_MIDI_Velocity_channel.png
2014-12-24 02:08 naught101 Note Added: 0016081
2014-12-24 02:52 florianb Note Added: 0016085
2014-12-24 02:53 florianb Note Edited: 0016085
2014-12-25 01:29 drobilla Note Added: 0016096
2014-12-25 01:48 florianb Note Added: 0016099
2014-12-26 01:12 naught101 Note Added: 0016102
2014-12-26 01:21 florianb Note Added: 0016103
2014-12-26 01:21 florianb Note Edited: 0016103
2015-05-16 15:45 rgwan Note Added: 0016696
2015-07-14 03:49 ssj71 Note Added: 0016871
2017-02-26 00:41 GMaq Note Added: 0019438
2017-02-26 00:42 GMaq Note Edited: 0019438
2017-02-26 09:54 rghvdberg Note Added: 0019440
2017-02-26 14:57 GMaq Note Added: 0019445
2017-02-26 20:46 GMaq Note Edited: 0019445
2018-04-19 03:55 alexmitchellmus Note Added: 0020259
2018-04-19 03:56 alexmitchellmus Note Edited: 0020259
2018-04-19 03:56 alexmitchellmus Note Edited: 0020259
2018-04-19 04:06 alexmitchellmus Note Edited: 0020259
2018-04-19 04:06 alexmitchellmus Note Edited: 0020259
2018-04-19 04:10 alexmitchellmus Note Edited: 0020259
2018-04-19 06:14 alexmitchellmus Note Edited: 0020259
2018-06-19 12:22 alexmitchellmus Sponsorship Added alexmitchellmus: US$ 50
2018-06-19 12:22 alexmitchellmus Sponsorship Total 0 => 50
2018-06-20 18:43 ssj71 Note Added: 0020303
2018-06-20 18:44 ssj71 Note Edited: 0020303
2018-06-21 03:38 naught101 Note Added: 0020304
2018-06-25 10:22 alexmitchellmus Note Added: 0020305
2018-06-25 10:36 alexmitchellmus Note Edited: 0020305
2018-06-25 10:40 alexmitchellmus Note Edited: 0020305
2018-06-25 10:43 alexmitchellmus Note Edited: 0020305
2018-06-25 10:46 alexmitchellmus Note Edited: 0020305
2018-06-25 10:53 alexmitchellmus Note Edited: 0020305
2018-06-25 10:54 alexmitchellmus Note Edited: 0020305
2018-06-26 16:32 alexmitchellmus Note Added: 0020310
2018-06-26 16:33 alexmitchellmus Note Edited: 0020310
2018-06-26 17:31 alexmitchellmus File Added: out.patch
2018-06-26 17:40 alexmitchellmus Note Edited: 0020310
2018-06-29 05:49 alexmitchellmus File Added: Velocity_Editor.png
2018-06-29 05:54 alexmitchellmus Note Added: 0020316
2018-06-29 05:56 alexmitchellmus Note Edited: 0020316
2018-06-30 12:10 alexmitchellmus Note Edited: 0020316
2018-06-30 12:11 alexmitchellmus Note Edited: 0020316
2018-07-03 15:29 paul Note Added: 0020317
2018-07-03 15:44 paul Note Added: 0020318
2018-07-03 16:55 paul Note Added: 0020319
2018-07-03 20:49 paul Note Added: 0020322
2018-07-06 04:23 alexmitchellmus Note Added: 0020345
2018-07-06 04:25 alexmitchellmus Note Edited: 0020345
2018-07-06 04:45 alexmitchellmus Note Edited: 0020345
2018-07-06 04:47 alexmitchellmus Note Edited: 0020345
2018-07-06 04:50 alexmitchellmus Note Edited: 0020345
2018-07-06 04:55 alexmitchellmus Note Edited: 0020345
2018-07-06 04:56 alexmitchellmus Note Edited: 0020345
2018-07-06 04:58 alexmitchellmus Note Edited: 0020345
2018-07-06 04:59 alexmitchellmus Note Edited: 0020345
2018-07-06 05:04 alexmitchellmus Note Edited: 0020345
2018-07-06 05:05 alexmitchellmus Note Edited: 0020345
2018-07-06 05:08 alexmitchellmus Note Edited: 0020345
2018-07-06 05:10 alexmitchellmus Note Edited: 0020345
2018-07-06 05:33 alexmitchellmus Note Edited: 0020345
2018-07-06 08:10 alexmitchellmus Note Edited: 0020345
2018-07-06 08:25 alexmitchellmus Note Edited: 0020345
2018-07-06 08:32 alexmitchellmus Note Edited: 0020345
2018-07-06 08:34 alexmitchellmus Note Edited: 0020345
2018-07-06 08:35 alexmitchellmus Note Edited: 0020345
2018-07-07 07:27 alexmitchellmus Note Edited: 0020345
2018-07-08 06:14 alexmitchellmus File Added: thinnervline_01.patch
2018-07-08 06:16 alexmitchellmus Note Added: 0020350
2018-07-08 06:22 alexmitchellmus Note Edited: 0020350
2018-07-08 07:40 alexmitchellmus Note Edited: 0020350
2018-07-08 07:44 alexmitchellmus Note Added: 0020351
2018-07-08 07:44 alexmitchellmus Note Edited: 0020351
2018-07-08 07:48 alexmitchellmus Note Edited: 0020351
2018-07-08 07:48 alexmitchellmus Note Edited: 0020351
2018-07-08 08:00 alexmitchellmus Note Edited: 0020351
2018-07-08 11:27 alexmitchellmus Note Edited: 0020350
2018-07-08 11:28 alexmitchellmus Note Edited: 0020350
2018-07-08 11:29 alexmitchellmus Note Edited: 0020345
2018-07-08 11:35 alexmitchellmus Note Edited: 0020351
2018-07-13 03:38 alexmitchellmus File Added: Simple_Velocity_Automation_Lane.jpg
2018-07-13 03:43 alexmitchellmus Note Added: 0020355
2018-07-13 03:44 alexmitchellmus Note Edited: 0020355
2018-07-13 03:59 alexmitchellmus Note Edited: 0020355
2018-07-17 09:00 alexmitchellmus Note Added: 0020357
2018-07-17 10:16 alexmitchellmus File Added: ghostlollipop_patch.diff
2018-07-17 10:17 alexmitchellmus Note Edited: 0020357
2018-07-17 10:21 alexmitchellmus Note Edited: 0020357
2018-07-17 12:10 paul Note Added: 0020358
2018-07-17 12:56 alexmitchellmus Note Added: 0020359
2018-07-17 13:05 alexmitchellmus Note Edited: 0020359
2018-07-17 14:17 alexmitchellmus Note Edited: 0020357
2020-05-08 22:13 tavasti Sponsorship Added tavasti: US$ 30
2020-05-08 22:13 tavasti Sponsorship Total 50 => 80
2020-08-19 05:28 naught101 Note Added: 0024940
2020-12-07 17:04 x42 Relationship added has duplicate 0008486
2022-11-15 23:48 x42 Relationship added parent of 0009072
2023-02-16 02:49 Reezlaw Sponsorship Added Reezlaw: US$ 10
2023-02-16 02:49 Reezlaw Sponsorship Total 80 => 90
2023-02-16 02:56 Reezlaw Note Added: 0027383
2023-02-16 03:51 paul Note Added: 0027384
2023-02-16 09:45 Reezlaw Note Added: 0027387
2023-10-09 03:04 paul Assigned To => paul
2023-10-09 03:04 paul Status new => resolved
2023-10-09 03:04 paul Resolution open => fixed
2023-10-09 03:04 paul Note Added: 0028163
2023-11-23 10:54 Reezlaw Note Added: 0028354