View Issue Details

IDProjectCategoryView StatusLast Update
0001841ardourbugspublic2007-11-06 13:42
Reporteroofus Assigned Tocth103  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
PlatformCentrino 1.6GHz LaptopOSLinuxOS VersionMandriva 2007
Product Version2.0 
Summary0001841: It's not possible to drag a region gain line to 0dB with the gain tool, it jumps from -0.1dB to 0.1dB missing out 0dB.
DescriptionIt's not possible to drag a region gain line to 0dB with the gain tool, it jumps from -0.1dB to 0.1dB missing out 0dB.
TagsNo tags attached.

Activities

jdavisp3

2007-10-26 02:56

reporter   ~0004507

If you expand the region to a large height you could probably do it, since the larger height means a smaller change for the same drag distance. However, I think
that it would be possible to implement the same sort of fine-grained control that you can do with faders by pressing control and control-alt. control is currently
used to turn on 'push' mode for dragging control points, so perhaps just alt.

I'm attaching patches to implement this. Try pressing 'Alt' while dragging
and you get much finer-grained control over the gain.

2007-10-26 02:56

 

ardour-2.0.patch (3,561 bytes)   
Index: gtk2_ardour/draginfo.h
===================================================================
--- gtk2_ardour/draginfo.h	(revision 2563)
+++ gtk2_ardour/draginfo.h	(working copy)
@@ -49,6 +49,8 @@
     double cumulative_y_drag;
     double current_pointer_x;
     double current_pointer_y;
+    double last_pointer_x;
+    double last_pointer_y;
     void (Editor::*motion_callback)(ArdourCanvas::Item*, GdkEvent*);
     void (Editor::*finished_callback)(ArdourCanvas::Item*, GdkEvent*);
     TimeAxisView* last_trackview;
Index: gtk2_ardour/editor_mouse.cc
===================================================================
--- gtk2_ardour/editor_mouse.cc	(revision 2563)
+++ gtk2_ardour/editor_mouse.cc	(working copy)
@@ -1461,6 +1461,8 @@
 	}
 
 	drag_info.item_type = item_type;
+	drag_info.last_pointer_x = drag_info.current_pointer_x;
+	drag_info.last_pointer_y = drag_info.current_pointer_y;
 	drag_info.current_pointer_frame = event_frame (event, &drag_info.current_pointer_x,
 						       &drag_info.current_pointer_y);
 
@@ -1647,6 +1649,8 @@
 	drag_info.current_pointer_frame = drag_info.grab_frame;
 	drag_info.current_pointer_x = drag_info.grab_x;
 	drag_info.current_pointer_y = drag_info.grab_y;
+	drag_info.last_pointer_x = drag_info.current_pointer_x;
+	drag_info.last_pointer_y = drag_info.current_pointer_y;
 	drag_info.cumulative_x_drag = 0;
 	drag_info.cumulative_y_drag = 0;
 	drag_info.first_move = true;
@@ -1705,6 +1709,8 @@
 	drag_info.item->ungrab (event->button.time);
 
 	if (drag_info.finished_callback) {
+		drag_info.last_pointer_x = drag_info.current_pointer_x;
+		drag_info.last_pointer_y = drag_info.current_pointer_y;
 		(this->*(drag_info.finished_callback)) (item, event);
 	}
 
@@ -2569,12 +2575,17 @@
 {
 	ControlPoint* cp = reinterpret_cast<ControlPoint *> (drag_info.data);
 
-	double cx = drag_info.current_pointer_x;
-	double cy = drag_info.current_pointer_y;
+	double dx = drag_info.current_pointer_x - drag_info.last_pointer_x;
+	double dy = drag_info.current_pointer_y - drag_info.last_pointer_y;
 
-	drag_info.cumulative_x_drag = cx - drag_info.grab_x ;
-	drag_info.cumulative_y_drag = cy - drag_info.grab_y ;
+	if (event->button.state & Keyboard::Alt) {
+		dx *= 0.1;
+		dy *= 0.1;
+	}
 
+	double cx = drag_info.grab_x + drag_info.cumulative_x_drag + dx;
+	double cy = drag_info.grab_y + drag_info.cumulative_y_drag + dy;
+
 	if (drag_info.x_constrained) {
 		cx = drag_info.grab_x;
 	}
@@ -2582,6 +2593,9 @@
 		cy = drag_info.grab_y;
 	}
 
+	drag_info.cumulative_x_drag = cx - drag_info.grab_x;
+	drag_info.cumulative_y_drag = cy - drag_info.grab_y;
+
 	cp->line.parent_group().w2i (cx, cy);
 
 	cx = max (0.0, cx);
@@ -2596,7 +2610,7 @@
 	}
 
 	float fraction = 1.0 - (cy / cp->line.height());
-	
+
 	bool push;
 
 	if (Keyboard::modifier_state_contains (event->button.state, Keyboard::Control)) {
@@ -2699,11 +2713,23 @@
 Editor::line_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 {
 	AutomationLine* line = reinterpret_cast<AutomationLine *> (drag_info.data);
+
+	double dy = drag_info.current_pointer_y - drag_info.last_pointer_y;
+
+	if (event->button.state & Keyboard::Alt) {
+		dy *= 0.1;
+	}
+
 	double cx = drag_info.current_pointer_x;
-	double cy = drag_info.current_pointer_y;
+	double cy = drag_info.grab_y + drag_info.cumulative_y_drag + dy;
 
+	drag_info.cumulative_y_drag = cy - drag_info.grab_y;
+
 	line->parent_group().w2i (cx, cy);
-	
+
+	cy = max (0.0, cy);
+	cy = min ((double) line->height(), cy);
+
 	double fraction;
 	fraction = 1.0 - (cy / line->height());
 
ardour-2.0.patch (3,561 bytes)   

2007-10-26 02:56

 

ardour-trunk.patch (3,419 bytes)   
Index: gtk2_ardour/draginfo.h
===================================================================
--- gtk2_ardour/draginfo.h	(revision 2575)
+++ gtk2_ardour/draginfo.h	(working copy)
@@ -49,6 +49,8 @@
     double cumulative_y_drag;
     double current_pointer_x;
     double current_pointer_y;
+    double last_pointer_x;
+    double last_pointer_y;
     void (Editor::*motion_callback)(ArdourCanvas::Item*, GdkEvent*);
     void (Editor::*finished_callback)(ArdourCanvas::Item*, GdkEvent*);
     TimeAxisView* last_trackview;
Index: gtk2_ardour/editor_mouse.cc
===================================================================
--- gtk2_ardour/editor_mouse.cc	(revision 2575)
+++ gtk2_ardour/editor_mouse.cc	(working copy)
@@ -1500,6 +1500,8 @@
 	}
 
 	drag_info.item_type = item_type;
+	drag_info.last_pointer_x = drag_info.current_pointer_x;
+	drag_info.last_pointer_y = drag_info.current_pointer_y;
 	drag_info.current_pointer_frame = event_frame (event, &drag_info.current_pointer_x,
 						       &drag_info.current_pointer_y);
 
@@ -1685,6 +1687,8 @@
 	drag_info.current_pointer_frame = drag_info.grab_frame;
 	drag_info.current_pointer_x = drag_info.grab_x;
 	drag_info.current_pointer_y = drag_info.grab_y;
+	drag_info.last_pointer_x = drag_info.current_pointer_x;
+	drag_info.last_pointer_y = drag_info.current_pointer_y;
 	drag_info.cumulative_x_drag = 0;
 	drag_info.cumulative_y_drag = 0;
 	drag_info.first_move = true;
@@ -1743,6 +1747,8 @@
 	drag_info.item->ungrab (event->button.time);
 
 	if (drag_info.finished_callback) {
+		drag_info.last_pointer_x = drag_info.current_pointer_x;
+		drag_info.last_pointer_y = drag_info.current_pointer_y;
 		(this->*(drag_info.finished_callback)) (item, event);
 	}
 
@@ -2607,12 +2613,17 @@
 {
 	ControlPoint* cp = reinterpret_cast<ControlPoint *> (drag_info.data);
 
-	double cx = drag_info.current_pointer_x;
-	double cy = drag_info.current_pointer_y;
+	double dx = drag_info.current_pointer_x - drag_info.last_pointer_x;
+	double dy = drag_info.current_pointer_y - drag_info.last_pointer_y;
 
-	drag_info.cumulative_x_drag = cx - drag_info.grab_x ;
-	drag_info.cumulative_y_drag = cy - drag_info.grab_y ;
+	if (event->button.state & Keyboard::Alt) {
+		dx *= 0.1;
+		dy *= 0.1;
+	}
 
+	double cx = drag_info.grab_x + drag_info.cumulative_x_drag + dx;
+	double cy = drag_info.grab_y + drag_info.cumulative_y_drag + dy;
+
 	if (drag_info.x_constrained) {
 		cx = drag_info.grab_x;
 	}
@@ -2620,6 +2631,9 @@
 		cy = drag_info.grab_y;
 	}
 
+	drag_info.cumulative_x_drag = cx - drag_info.grab_x;
+	drag_info.cumulative_y_drag = cy - drag_info.grab_y;
+
 	cp->line().parent_group().w2i (cx, cy);
 
 	cx = max (0.0, cx);
@@ -2737,11 +2751,23 @@
 Editor::line_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 {
 	AutomationLine* line = reinterpret_cast<AutomationLine *> (drag_info.data);
+
+	double dy = drag_info.current_pointer_y - drag_info.last_pointer_y;
+
+	if (event->button.state & Keyboard::Alt) {
+		dy *= 0.1;
+	}
+
 	double cx = drag_info.current_pointer_x;
-	double cy = drag_info.current_pointer_y;
+	double cy = drag_info.grab_y + drag_info.cumulative_y_drag + dy;
 
+	drag_info.cumulative_y_drag = cy - drag_info.grab_y;
+
 	line->parent_group().w2i (cx, cy);
-	
+
+	cy = max (0.0, cy);
+	cy = min ((double) line->height(), cy);
+
 	const double fraction = 1.0 - ((cy - line->y_position()) / (double)line->height());
 
 	bool push;

ardour-trunk.patch (3,419 bytes)   

nowhiskey

2007-10-26 10:13

reporter   ~0004510

i just applied the patch to ongoing-rev2575 and it works very well not just for the fader automation but for the region-gain-automation too.
very, very useful, the patch - thanks for sharing it!!

cheers,
doc

cth103

2007-11-05 15:39

administrator   ~0004540

Applied to trunk, many thanks for the patch!

cth103

2007-11-05 16:22

administrator   ~0004541

Also applied to 2.0-ongoing. Many thanks!

oofus

2007-11-05 16:29

developer   ~0004542

This is a nice addition, but not sure is the correct solution to the problem. Why can't the line be dragged to zero in normal mode. Unity is a very common level to want to get to !

There is also another small problem here as well. Make the track as high as it can be, drag the line to 0db. Now make the track smaller. Click on the line as if to move it, the cursor indicates that it is not at 0db even though it hasn't been moved yet. Which track height is lying ? Was it placed at 0db or is it really at the new position ?

oofus

2007-11-05 16:34

developer   ~0004543

That would suggest to me that the indicated gain has as much to to with graphical rendering as it does to the actual gain that is applied to the audio. Surely this can't be right ?

jdavisp3

2007-11-05 16:47

reporter   ~0004544

I see what you mean -- you want to hit zero instead of just crossing
it no matter what the sensitivity mode. I'll see about a patch for that.

The graphical rendering is related to the gain while you are dragging the
control points & lines. I'll look into the change when you change line
height too.

2007-11-06 02:45

 

ardour-2.0-2.patch (2,422 bytes)   
Index: gtk2_ardour/editor_mouse.cc
===================================================================
--- gtk2_ardour/editor_mouse.cc	(revision 2595)
+++ gtk2_ardour/editor_mouse.cc	(working copy)
@@ -69,6 +69,8 @@
 using namespace Gtk;
 using namespace Editing;
 
+const static double ZERO_GAIN_FRACTION = gain_to_slider_position(dB_to_coefficient(0.0));
+
 bool
 Editor::mouse_frame (nframes64_t& where, bool& in_track_canvas)
 {
@@ -2587,6 +2589,16 @@
 
 	start_grab (event, fader_cursor);
 
+	// start the grab at the center of the control point so
+	// the point doesn't 'jump' to the mouse after the first drag
+	drag_info.grab_x = control_point->get_x();
+	drag_info.grab_y = control_point->get_y();
+	control_point->line.parent_group().i2w(drag_info.grab_x, drag_info.grab_y);
+	track_canvas.w2c(drag_info.grab_x, drag_info.grab_y,
+									 drag_info.grab_x, drag_info.grab_y);
+
+	drag_info.grab_frame = pixel_to_frame(drag_info.grab_x);
+
 	control_point->line.start_drag (control_point, drag_info.grab_frame, 0);
 
 	float fraction = 1.0 - (control_point->get_y() / control_point->line.height());
@@ -2612,6 +2624,18 @@
 	double cx = drag_info.grab_x + drag_info.cumulative_x_drag + dx;
 	double cy = drag_info.grab_y + drag_info.cumulative_y_drag + dy;
 
+	// calculate zero crossing point. back off by .01 to stay on the
+	// positive side of zero
+	double _unused = 0;
+	double zero_gain_y = (1.0 - ZERO_GAIN_FRACTION) * cp->line.height() - .01;
+	cp->line.parent_group().i2w(_unused, zero_gain_y);
+
+	// make sure we hit zero when passing through
+	if ((cy < zero_gain_y and (cy - dy) > zero_gain_y)
+			or (cy > zero_gain_y and (cy - dy) < zero_gain_y)) {
+		cy = zero_gain_y;
+	}
+
 	if (drag_info.x_constrained) {
 		cx = drag_info.grab_x;
 	}
@@ -2749,6 +2773,18 @@
 	double cx = drag_info.current_pointer_x;
 	double cy = drag_info.grab_y + drag_info.cumulative_y_drag + dy;
 
+	// calculate zero crossing point. back off by .01 to stay on the
+	// positive side of zero
+	double _unused = 0;
+	double zero_gain_y = (1.0 - ZERO_GAIN_FRACTION) * line->height() - .01;
+	line->parent_group().i2w(_unused, zero_gain_y);
+
+	// make sure we hit zero when passing through
+	if ((cy < zero_gain_y and (cy - dy) > zero_gain_y)
+			or (cy > zero_gain_y and (cy - dy) < zero_gain_y)) {
+		cy = zero_gain_y;
+	}
+
 	drag_info.cumulative_y_drag = cy - drag_info.grab_y;
 
 	line->parent_group().w2i (cx, cy);
ardour-2.0-2.patch (2,422 bytes)   

2007-11-06 02:46

 

ardour-trunk-2.patch (2,485 bytes)   
Index: gtk2_ardour/editor_mouse.cc
===================================================================
--- gtk2_ardour/editor_mouse.cc	(revision 2595)
+++ gtk2_ardour/editor_mouse.cc	(working copy)
@@ -74,6 +74,8 @@
 using namespace Gtk;
 using namespace Editing;
 
+const static double ZERO_GAIN_FRACTION = gain_to_slider_position(dB_to_coefficient(0.0));
+
 nframes_t
 Editor::event_frame (GdkEvent* event, double* pcx, double* pcy)
 {
@@ -2599,6 +2601,16 @@
 
 	start_grab (event, fader_cursor);
 
+	// start the grab at the center of the control point so
+	// the point doesn't 'jump' to the mouse after the first drag
+	drag_info.grab_x = control_point->get_x();
+	drag_info.grab_y = control_point->get_y();
+	control_point->line().parent_group().i2w(drag_info.grab_x, drag_info.grab_y);
+	track_canvas.w2c(drag_info.grab_x, drag_info.grab_y,
+									 drag_info.grab_x, drag_info.grab_y);
+
+	drag_info.grab_frame = pixel_to_frame(drag_info.grab_x);
+
 	control_point->line().start_drag (control_point, drag_info.grab_frame, 0);
 
 	double fraction = 1.0 - ((control_point->get_y() - control_point->line().y_position()) / (double)control_point->line().height());
@@ -2624,6 +2636,18 @@
 	double cx = drag_info.grab_x + drag_info.cumulative_x_drag + dx;
 	double cy = drag_info.grab_y + drag_info.cumulative_y_drag + dy;
 
+	// calculate zero crossing point. back off by .01 to stay on the
+	// positive side of zero
+	double _unused = 0;
+	double zero_gain_y = (1.0 - ZERO_GAIN_FRACTION) * cp->line().height() - .01;
+	cp->line().parent_group().i2w(_unused, zero_gain_y);
+
+	// make sure we hit zero when passing through
+	if ((cy < zero_gain_y and (cy - dy) > zero_gain_y)
+			or (cy > zero_gain_y and (cy - dy) < zero_gain_y)) {
+		cy = zero_gain_y;
+	}
+
 	if (drag_info.x_constrained) {
 		cx = drag_info.grab_x;
 	}
@@ -2761,6 +2785,18 @@
 	double cx = drag_info.current_pointer_x;
 	double cy = drag_info.grab_y + drag_info.cumulative_y_drag + dy;
 
+	// calculate zero crossing point. back off by .01 to stay on the
+	// positive side of zero
+	double _unused = 0;
+	double zero_gain_y = (1.0 - ZERO_GAIN_FRACTION) * line->height() - .01;
+	line->parent_group().i2w(_unused, zero_gain_y);
+
+	// make sure we hit zero when passing through
+	if ((cy < zero_gain_y and (cy - dy) > zero_gain_y)
+			or (cy > zero_gain_y and (cy - dy) < zero_gain_y)) {
+		cy = zero_gain_y;
+	}
+
 	drag_info.cumulative_y_drag = cy - drag_info.grab_y;
 
 	line->parent_group().w2i (cx, cy);
ardour-trunk-2.patch (2,485 bytes)   

jdavisp3

2007-11-06 02:46

reporter   ~0004548

Here's a patch for you to check out.

oofus

2007-11-06 13:07

developer   ~0004550

Thanks for the patches. Tested both.
In trunk, region automation lines seem very broken. The context menu for enabling/making visible etc doesn't appear. But I don't think that's your patch that has done that.

In 2-ongoing this patch works really well. It's possible to stop on 0db at any track height. Obviously the resolution changes with track height, but that's expected. Also fixed is the position of points. If I set a point at an arbitrary level and then change the track height, on hovering over the point the cursor reports the correct/same db level/position at all track heights.

Great patch thanks. Maybe you'd like to look at 0001840 and 0001842 as well :)

cth103

2007-11-06 13:35

administrator   ~0004551

Great stuff, thanks to you both! Applied to 2.0-ongoing and trunk.

oofus

2007-11-06 13:42

developer   ~0004552

fixed in SVN 2600

Issue History

Date Modified Username Field Change
2007-08-24 21:30 oofus New Issue
2007-10-26 02:56 jdavisp3 Note Added: 0004507
2007-10-26 02:56 jdavisp3 File Added: ardour-2.0.patch
2007-10-26 02:56 jdavisp3 File Added: ardour-trunk.patch
2007-10-26 10:13 nowhiskey Note Added: 0004510
2007-11-05 15:39 cth103 Note Added: 0004540
2007-11-05 16:22 cth103 Status new => resolved
2007-11-05 16:22 cth103 Resolution open => fixed
2007-11-05 16:22 cth103 Assigned To => cth103
2007-11-05 16:22 cth103 Note Added: 0004541
2007-11-05 16:29 oofus Status resolved => feedback
2007-11-05 16:29 oofus Resolution fixed => reopened
2007-11-05 16:29 oofus Note Added: 0004542
2007-11-05 16:34 oofus Note Added: 0004543
2007-11-05 16:47 jdavisp3 Note Added: 0004544
2007-11-06 02:45 jdavisp3 File Added: ardour-2.0-2.patch
2007-11-06 02:46 jdavisp3 File Added: ardour-trunk-2.patch
2007-11-06 02:46 jdavisp3 Note Added: 0004548
2007-11-06 13:07 oofus Note Added: 0004550
2007-11-06 13:35 cth103 Status feedback => resolved
2007-11-06 13:35 cth103 Resolution reopened => fixed
2007-11-06 13:35 cth103 Note Added: 0004551
2007-11-06 13:42 oofus Status resolved => closed
2007-11-06 13:42 oofus Note Added: 0004552