another redirect dialog fix
[ardour.git] / gtk2_ardour / canvas-waveview.c
index 080f6871fa1705bb6f1d9231a17fb8881365400c..b78bf63ea712aa37c18954e44c7adaf7c4288836 100644 (file)
 
 #include <ardour/dB.h>
 
+#include "logmeter.h"
 #include "canvas-waveview.h"
 #include "rgb_macros.h"
 
+
 extern void c_stacktrace();
 
 enum {
@@ -48,8 +50,11 @@ enum {
         PROP_Y,
         PROP_HEIGHT,
         PROP_WAVE_COLOR,
+        PROP_CLIP_COLOR,
+        PROP_ZERO_COLOR,
         PROP_RECTIFIED,
-        PROP_REGION_START
+        PROP_REGION_START,
+        PROP_LOGSCALED,
 };
 
 static void gnome_canvas_waveview_class_init     (GnomeCanvasWaveViewClass *class);
@@ -247,12 +252,33 @@ gnome_canvas_waveview_class_init (GnomeCanvasWaveViewClass *class)
                                     0, G_MAXUINT, 0,
                                     (G_PARAM_READABLE | G_PARAM_WRITABLE)));
         
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_CLIP_COLOR,
+                 g_param_spec_uint ("clip_color", NULL, NULL,
+                                    0, G_MAXUINT, 0,
+                                    (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+        
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_ZERO_COLOR,
+                 g_param_spec_uint ("zero_color", NULL, NULL,
+                                    0, G_MAXUINT, 0,
+                                    (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+        
         g_object_class_install_property
                 (gobject_class,
                  PROP_RECTIFIED,
                  g_param_spec_boolean ("rectified", NULL, NULL,
                                        FALSE,
                                        (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_LOGSCALED,
+                 g_param_spec_boolean ("logscaled", NULL, NULL,
+                                       FALSE,
+                                       (G_PARAM_READABLE | G_PARAM_WRITABLE)));
         
         g_object_class_install_property
                 (gobject_class,
@@ -308,6 +334,7 @@ gnome_canvas_waveview_init (GnomeCanvasWaveView *waveview)
        waveview->gain_curve_function = NULL;
        waveview->gain_src = NULL;
        waveview->rectified = FALSE;
+       waveview->logscaled = FALSE;
        waveview->region_start = 0;
        waveview->samples_per_unit = 1.0;
        waveview->amplitude_above_axis = 1.0;
@@ -316,6 +343,8 @@ gnome_canvas_waveview_init (GnomeCanvasWaveView *waveview)
        waveview->reload_cache_in_render = FALSE;
 
        waveview->wave_color = RGBA_TO_UINT(44,35,126,255);
+       waveview->clip_color = RGBA_TO_UINT(44,0,0,100);
+       waveview->zero_color = RGBA_TO_UINT(44,0,128,100);
 }
 
 static void
@@ -359,7 +388,8 @@ gnome_canvas_waveview_ensure_cache (GnomeCanvasWaveView *waveview, gulong start_
        end_sample = end_sample + waveview->region_start;
 #if DEBUG_CACHE
        // printf("waveview->region_start == %lu\n",waveview->region_start);
-       printf ("=> 0x%x cache @ 0x%x range: %lu - %lu request: %lu - %lu (%lu frames)\n", 
+       // c_stacktrace ();
+       printf ("\n\n=> 0x%x cache @ 0x%x range: %lu - %lu request: %lu - %lu (%lu frames)\n", 
                waveview, cache,
                cache->start, cache->end,
                start_sample, end_sample, end_sample - start_sample);
@@ -403,7 +433,7 @@ gnome_canvas_waveview_ensure_cache (GnomeCanvasWaveView *waveview, gulong start_
        }
 
 #if DEBUG_CACHE
-       fprintf (stderr, "\n\nAVAILABLE FRAMES = %lu of %lu, start = %lu, sstart = %lu, cstart = %lu\n", 
+       fprintf (stderr, "AVAILABLE FRAMES = %lu of %lu, start = %lu, sstart = %lu, cstart = %lu\n", 
                 rf3, waveview->sourcefile_length_function (waveview->data_src, waveview->samples_per_unit),
                 waveview->region_start, start_sample, new_cache_start);
 #endif
@@ -577,7 +607,29 @@ gnome_canvas_waveview_ensure_cache (GnomeCanvasWaveView *waveview, gulong start_
                free (gain);
        
        }
+
+       /* do optional log scaling.  this implementation is not particularly efficient */
        
+       if (waveview->logscaled) {
+               guint32 n;
+               GnomeCanvasWaveViewCacheEntry* buf = cache->data;
+               
+               for (n = 0; n < cache->data_size; ++n) {
+
+                       if (buf[n].max > 0.0f) {
+                               buf[n].max = alt_log_meter(coefficient_to_dB(buf[n].max));
+                       } else if (buf[n].max < 0.0f) {
+                               buf[n].max = -alt_log_meter(coefficient_to_dB(-buf[n].max));
+                       }
+                       
+                       if (buf[n].min > 0.0f) {
+                               buf[n].min = alt_log_meter(coefficient_to_dB(buf[n].min));
+                       } else if (buf[n].min < 0.0f) {
+                               buf[n].min = -alt_log_meter(coefficient_to_dB(-buf[n].min));
+                       }
+               }
+       }
+
        cache->start = ostart;
        cache->end = new_cache_end;
 
@@ -764,12 +816,37 @@ gnome_canvas_waveview_set_property (GObject      *object,
                }
                break;
 
+       case PROP_CLIP_COLOR:
+               if (waveview->clip_color != g_value_get_uint(value)) {
+                       waveview->clip_color = g_value_get_uint(value);
+                       redraw = TRUE;
+               }
+               break;
+
+       case PROP_ZERO_COLOR:
+               if (waveview->zero_color != g_value_get_uint(value)) {
+                       waveview->zero_color = g_value_get_uint(value);
+                       redraw = TRUE;
+               }
+               break;
+
        case PROP_RECTIFIED:
                if (waveview->rectified != g_value_get_boolean(value)) {
                        waveview->rectified = g_value_get_boolean(value);
                        redraw = TRUE;
                }
                break;
+       case PROP_LOGSCALED:
+               if (waveview->logscaled != g_value_get_boolean(value)) {
+                       waveview->logscaled = g_value_get_boolean(value);
+                       if (waveview->cache_updater) {
+                               waveview->cache->start = 0;
+                               waveview->cache->end = 0;
+                       }
+                       redraw = TRUE;
+                       calc_bounds = TRUE;
+               }
+               break;
        case PROP_REGION_START:
                waveview->region_start = g_value_get_uint(value);
                redraw = TRUE;
@@ -865,10 +942,22 @@ gnome_canvas_waveview_get_property (GObject      *object,
                g_value_set_uint (value, waveview->wave_color);
                break;
 
+       case PROP_CLIP_COLOR:
+               g_value_set_uint (value, waveview->clip_color);
+               break;
+
+       case PROP_ZERO_COLOR:
+               g_value_set_uint (value, waveview->zero_color);
+               break;
+
        case PROP_RECTIFIED:
                g_value_set_boolean (value, waveview->rectified);
                break;
 
+       case PROP_LOGSCALED:
+               g_value_set_boolean (value, waveview->logscaled);
+               break;
+
        case PROP_REGION_START:
                g_value_set_uint (value, waveview->region_start);
                break;
@@ -921,6 +1010,8 @@ gnome_canvas_waveview_update (GnomeCanvasItem *item, double *affine, ArtSVP *cli
 
        UINT_TO_RGBA (waveview->wave_color, &waveview->wave_r, &waveview->wave_g, &waveview->wave_b,
                      &waveview->wave_a);
+       UINT_TO_RGBA (waveview->clip_color, &waveview->clip_r, &waveview->clip_g, &waveview->clip_b,
+                     &waveview->clip_a);
 
 //     check_cache (waveview, "end of update");
 }
@@ -936,6 +1027,7 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item,
        int cache_index;
        double half_height;
        int x, end, begin;
+       int zbegin, zend;
 
        waveview = GNOME_CANVAS_WAVEVIEW (item);
 
@@ -950,7 +1042,13 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item,
                buf->is_bg = FALSE;
        }
 
-       begin = MAX(waveview->bbox_ulx,buf->rect.x0);
+       begin = MAX(waveview->bbox_ulx, buf->rect.x0);
+
+       if (begin == waveview->bbox_ulx) {
+               zbegin = begin + 1;
+       } else {
+               zbegin = begin;
+       }
 
        if (waveview->bbox_lrx >= 0) {
                end = MIN(waveview->bbox_lrx,buf->rect.x1);
@@ -958,6 +1056,12 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item,
                end = buf->rect.x1;
        }
 
+       if (end == waveview->bbox_lrx) {
+               zend = end - 1;
+       } else {
+               zend = end;
+       }
+
        if (begin == end) {
                return;
        }
@@ -1018,6 +1122,7 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item,
 
 #define origin half_height
 
+
        for (x = begin; x < end; x++) {
 
                double max, min;
@@ -1078,11 +1183,11 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item,
                }
 
                if (clip_max) {
-                       PAINT_VERT(buf, 255, 0, 0, x, pymax, pymax+clip_length);
+                       PAINT_VERTA(buf, waveview->clip_r, waveview->clip_g, waveview->clip_b, waveview->clip_a, x, pymax, pymax+clip_length);
                }
 
                if (clip_min) {
-                       PAINT_VERT(buf, 255, 0, 0, x, pymin-clip_length, pymin);
+                       PAINT_VERTA(buf, waveview->clip_r, waveview->clip_g, waveview->clip_b, waveview->clip_a, x, pymin-clip_length, pymin);
                }
 
                /* presto, we're done */
@@ -1090,6 +1195,15 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item,
                cache_index++;
        }
 
+       if (!waveview->rectified) {
+               // Paint zeroline.
+               //PAINT_HORIZA(buf, waveview->zero_r, waveview->zero_g, waveview->zero_b, waveview->zero_a, begin, endi-1, origin );
+               
+               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);
+       }
 #undef origin
 
 }