minor fixes/changes based on comparison with existing bindings
[ardour.git] / gtk2_ardour / canvas-waveview.c
index f929b3119759618a2213d38928de5ad9192e8e79..aab781081d57d124d887cb227ddb3b80069f2a3a 100644 (file)
@@ -110,7 +110,7 @@ static void gnome_canvas_waveview_set_data_src   (GnomeCanvasWaveView *,
 static void gnome_canvas_waveview_set_channel    (GnomeCanvasWaveView *,
                                                   guint32);
 
-static gint32 gnome_canvas_waveview_ensure_cache (GnomeCanvasWaveView *waveview,
+static guint32 gnome_canvas_waveview_ensure_cache (GnomeCanvasWaveView *waveview,
                                                   gulong               start_sample,
                                                   gulong               end_sample);
 
@@ -392,7 +392,8 @@ gnome_canvas_waveview_destroy (GtkObject *object)
 #define DEBUG_CACHE 0
 #undef CACHE_MEMMOVE_OPTIMIZATION
 
-static gint32
+/** @return cache index of start_sample within the cache */
+static guint32
 gnome_canvas_waveview_ensure_cache (GnomeCanvasWaveView *waveview, gulong start_sample, gulong end_sample)
 {
        gulong required_cache_entries;
@@ -438,7 +439,7 @@ gnome_canvas_waveview_ensure_cache (GnomeCanvasWaveView *waveview, gulong start_
        /* Note the assumption that we have a 1:1 units:pixel ratio for the canvas. Its everywhere ... */
        
        half_width = (gulong) floor ((waveview->screen_width * waveview->samples_per_unit)/2.0 + 0.5);
-       
+
        if (start_sample < half_width) {
                new_cache_start = 0;
        } else {
@@ -664,9 +665,9 @@ gnome_canvas_waveview_ensure_cache (GnomeCanvasWaveView *waveview, gulong start_
   out:
 #if DEBUG_CACHE
        fprintf (stderr, "return cache index = %d\n", 
-                (gint32) floor ((((double) (start_sample - cache->start)) / waveview->samples_per_unit) + 0.5));
+                (guint32) floor ((((double) (start_sample - cache->start)) / waveview->samples_per_unit) + 0.5));
 #endif
-       return (gint32) floor ((((double) (start_sample - cache->start)) / waveview->samples_per_unit) + 0.5);
+       return (guint32) floor ((((double) (start_sample - cache->start)) / waveview->samples_per_unit) + 0.5);
 
 }
 
@@ -737,6 +738,8 @@ gnome_canvas_waveview_set_property (GObject      *object,
                                    GParamSpec   *pspec)
 
 {
+       (void) pspec;
+       
        GnomeCanvasItem *item;
        GnomeCanvasWaveView *waveview;
        int redraw = FALSE;
@@ -763,6 +766,7 @@ gnome_canvas_waveview_set_property (GObject      *object,
                waveview->length_function = g_value_get_pointer(value);
                redraw = TRUE;
                break;
+
        case PROP_SOURCEFILE_LENGTH_FUNCTION:
                waveview->sourcefile_length_function = g_value_get_pointer(value);
                redraw = TRUE;
@@ -919,61 +923,62 @@ gnome_canvas_waveview_set_property (GObject      *object,
 }
 
 static void
-gnome_canvas_waveview_get_property (GObject      *object,
-                                   guint         prop_id,
-                                   GValue       *value,
-                                   GParamSpec   *pspec)
+gnome_canvas_waveview_get_property (
+               GObject      *object,
+               guint         prop_id,
+               GValue       *value,
+               GParamSpec   *pspec)
 {
        
    
        g_return_if_fail (object != NULL);
-        g_return_if_fail (GNOME_IS_CANVAS_WAVEVIEW (object));
+       g_return_if_fail (GNOME_IS_CANVAS_WAVEVIEW (object));
 
        GnomeCanvasWaveView *waveview = GNOME_CANVAS_WAVEVIEW (object);
 
        switch (prop_id) {
        case PROP_DATA_SRC:
-               g_value_set_pointer(value, waveview->data_src);
+               g_value_set_pointer(value, waveview->data_src);
                break;
 
        case PROP_CHANNEL:
-               g_value_set_uint(value, waveview->channel);
+               g_value_set_uint(value, waveview->channel);
                break;
 
        case PROP_LENGTH_FUNCTION:
-               g_value_set_pointer(value, waveview->length_function);
+               g_value_set_pointer(value, waveview->length_function);
                break;
 
        case PROP_SOURCEFILE_LENGTH_FUNCTION:
-               g_value_set_pointer(value, waveview->sourcefile_length_function);
+               g_value_set_pointer(value, waveview->sourcefile_length_function);
                break;
 
        case PROP_PEAK_FUNCTION:
-               g_value_set_pointer(value, waveview->peak_function);
+               g_value_set_pointer(value, waveview->peak_function);
                break;
 
        case PROP_GAIN_FUNCTION:
-               g_value_set_pointer(value, waveview->gain_curve_function);
+               g_value_set_pointer(value, waveview->gain_curve_function);
                break;
 
        case PROP_GAIN_SRC:
-               g_value_set_pointer(value, waveview->gain_src);
+               g_value_set_pointer(value, waveview->gain_src);
                break;
 
        case PROP_CACHE:
-               g_value_set_pointer(value, waveview->cache);
+               g_value_set_pointer(value, waveview->cache);
                break;
 
        case PROP_CACHE_UPDATER:
-               g_value_set_boolean(value, waveview->cache_updater);
+               g_value_set_boolean(value, waveview->cache_updater);
                break;
 
        case PROP_SAMPLES_PER_UNIT:
-               g_value_set_double(value, waveview->samples_per_unit);
+               g_value_set_double(value, waveview->samples_per_unit);
                break;
 
        case PROP_AMPLITUDE_ABOVE_AXIS:
-               g_value_set_double(value, waveview->amplitude_above_axis);
+               g_value_set_double(value, waveview->amplitude_above_axis);
                break;
 
        case PROP_X:
@@ -1088,10 +1093,9 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item,
        gulong s1, s2;
        int clip_length = 0;
        int pymin, pymax;
-       int cache_index;
+       guint cache_index;
        double half_height;
-       int x, end, begin;
-       int zbegin, zend;
+       int x;
        char rectify;
 
        waveview = GNOME_CANVAS_WAVEVIEW (item);
@@ -1107,31 +1111,29 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item,
                buf->is_bg = FALSE;
        }
 
-       begin = MAX(waveview->bbox_ulx, buf->rect.x0);
+       /* a "unit" means a pixel */
 
-       if (begin == waveview->bbox_ulx) {
-               zbegin = begin + 1;
-       } else {
-               zbegin = begin;
-       }
+       /* begin: render start x (units) */
+       int const begin = MAX (waveview->bbox_ulx, buf->rect.x0);
 
-       if (waveview->bbox_lrx >= 0) {
-               end = MIN(waveview->bbox_lrx,buf->rect.x1);
-       } else {
-               end = buf->rect.x1;
-       }
+        /* zbegin: start x for zero line (units) */
+       int const zbegin = (begin == waveview->bbox_ulx) ? (begin + 1) : begin;
 
-       if (end == waveview->bbox_lrx) {
-               zend = end - 1;
-       } else {
-               zend = end;
-       }
+       /* end: render end x (units) */
+       int const end = (waveview->bbox_lrx >= 0) ? MIN (waveview->bbox_lrx,buf->rect.x1) : buf->rect.x1;
+
+       /* zend: end x for zero-line (units) */
+       int const zend = (end == waveview->bbox_lrx) ? (end - 1) : end;
 
        if (begin == end) {
                return;
        }
 
-       s1 = floor ((begin - waveview->bbox_ulx) * waveview->samples_per_unit) ;
+       /* s1: start sample
+          s2: end sample
+       */
+
+       s1 = floor ((begin - waveview->bbox_ulx) * waveview->samples_per_unit);
 
        // fprintf (stderr, "0x%x begins at sample %f\n", waveview, waveview->bbox_ulx * waveview->samples_per_unit);
 
@@ -1175,7 +1177,7 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item,
 //     check_cache (waveview, "post-ensure");
 
        /* don't rectify at single-sample zoom */
-       if(waveview->rectified && waveview->samples_per_unit > 1) {
+       if (waveview->rectified && waveview->samples_per_unit > 1) {
                rectify = TRUE;
        }
        else {
@@ -1194,7 +1196,7 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item,
 /* this makes it slightly easier to comprehend whats going on */
 #define origin half_height
 
-       if(waveview->filled && !rectify) {
+       if (waveview->filled && !rectify) {
                int prev_pymin = 1;
                int prev_pymax = 0;
                int last_pymin = 1;
@@ -1204,7 +1206,7 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item,
                int next_clip_max = 0;
                int next_clip_min = 0;
 
-               if(s1 < waveview->samples_per_unit) {
+               if (s1 < waveview->samples_per_unit) {
                        /* we haven't got a prev vars to compare with, so outline the whole line here */
                        prev_pymax = (int) rint ((item->y1 + origin) * item->canvas->pixels_per_unit);
                        prev_pymin = prev_pymax;
@@ -1228,16 +1230,29 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item,
                 * Compute the variables outside the rendering rect
                 */
                if(prev_pymax != prev_pymin) {
+
                        prev_pymax = (int) rint ((item->y1 + origin - MIN(waveview->cache->data[cache_index].max, 1.0) * half_height) * item->canvas->pixels_per_unit);
                        prev_pymin = (int) rint ((item->y1 + origin - MAX(waveview->cache->data[cache_index].min, -1.0) * half_height) * item->canvas->pixels_per_unit);
                        ++cache_index;
                }
                if(last_pymax != last_pymin) {
                        /* take the index of one sample right of what we render */
-                       int index = cache_index + (end - begin);
-                       
-                       last_pymax = (int) rint ((item->y1 + origin - MIN(waveview->cache->data[index].max, 1.0) * half_height) * item->canvas->pixels_per_unit);
-                       last_pymin = (int) rint ((item->y1 + origin - MAX(waveview->cache->data[index].min, -1.0) * half_height) * item->canvas->pixels_per_unit);
+                       guint index = cache_index + (end - begin);
+
+                       if (index >= waveview->cache->data_size) {
+                               
+                               /* the data we want is off the end of the cache, which must mean its beyond
+                                  the end of the region's source; hence the peak values are 0 */
+                               last_pymax = (int) rint ((item->y1 + origin) * item->canvas->pixels_per_unit);
+                               last_pymin = (int) rint ((item->y1 + origin) * item->canvas->pixels_per_unit);
+                               
+                       } else {
+                               
+                               last_pymax = (int) rint ((item->y1 + origin - MIN(waveview->cache->data[index].max, 1.0) * half_height) * item->canvas->pixels_per_unit);
+                               last_pymin = (int) rint ((item->y1 + origin - MAX(waveview->cache->data[index].min, -1.0) * half_height) * item->canvas->pixels_per_unit);
+                               
+                       }
+                               
                }
 
                /* 
@@ -1282,8 +1297,12 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item,
                        else {
                                ++cache_index;
 
-                               max = waveview->cache->data[cache_index].max;
-                               min = waveview->cache->data[cache_index].min;
+                               if (cache_index < waveview->cache->data_size) {
+                                       max = waveview->cache->data[cache_index].max;
+                                       min = waveview->cache->data[cache_index].min;
+                               } else {
+                                       max = min = 0;
+                               }
 
                                next_clip_max = 0;
                                next_clip_min = 0;
@@ -1594,7 +1613,7 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item,
                unsigned char zero_r, zero_g, zero_b, zero_a;
                UINT_TO_RGBA( waveview->zero_color, &zero_r, &zero_g, &zero_b, &zero_a );
                int zeroline_y = (int) rint ((item->y1 + origin) * item->canvas->pixels_per_unit);
-               PAINT_HORIZA(buf, zero_r, zero_g, zero_b, zero_a, zbegin, end, zeroline_y);
+               PAINT_HORIZA(buf, zero_r, zero_g, zero_b, zero_a, zbegin, zend, zeroline_y);
        }
 #undef origin
 
@@ -1610,7 +1629,6 @@ gnome_canvas_waveview_draw (GnomeCanvasItem *item,
        cairo_t* cr;
        gulong s1, s2;
        int cache_index;
-       double zbegin, zend;
        gboolean rectify;
        double origin;
        double clip_length;
@@ -1629,10 +1647,8 @@ gnome_canvas_waveview_draw (GnomeCanvasItem *item,
 
        if (x > waveview->bbox_ulx) {
                ulx = x;
-               zbegin = ulx;
        } else {
                ulx = waveview->bbox_ulx;
-               zbegin = ulx + 1;
        }
 
        if (y > waveview->bbox_uly) {
@@ -1643,10 +1659,8 @@ gnome_canvas_waveview_draw (GnomeCanvasItem *item,
 
        if (x + width > waveview->bbox_lrx) {
                lrx = waveview->bbox_lrx;
-               zend = lrx - 1;
        } else {
                lrx = x + width;
-               zend = lrx;
        }
 
        if (y + height > waveview->bbox_lry) {
@@ -1674,8 +1688,6 @@ gnome_canvas_waveview_draw (GnomeCanvasItem *item,
        uly -= y;
        lrx -= x;
        lry -= y;
-       zbegin -= x;
-       zend -= x;
 
        /* don't rectify at single-sample zoom */
        if(waveview->rectified && waveview->samples_per_unit > 1.0) {
@@ -1851,6 +1863,13 @@ gnome_canvas_waveview_bounds (GnomeCanvasItem *item, double *x1, double *y1, dou
 static double
 gnome_canvas_waveview_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item)
 {
+       (void) item;
+       (void) x;
+       (void) y;
+       (void) cx;
+       (void) cy;
+       (void) actual_item;
+       
        /* XXX for now, point is never inside the wave 
        GnomeCanvasWaveView *waveview;
        double x1, y1, x2, y2;