23 #include <libgnomecanvas/libgnomecanvas.h>
38 #if defined(_POSIX_VERSION) || defined(COMPILER_MINGW)
39 #define POSIX_FUNC_PTR_CAST(type, object) *((type*) &(object))
40 #endif // _POSIX_VERSION
102 GnomeCanvasItem **actual_item);
105 GnomeCanvasBuf *buf);
108 GdkDrawable *drawable,
132 static GType waveview_type;
134 if (!waveview_type) {
135 static const GTypeInfo object_info = {
137 (GBaseInitFunc) NULL,
138 (GBaseFinalizeFunc) NULL,
140 (GClassFinalizeFunc) NULL,
148 waveview_type = g_type_register_static (GNOME_TYPE_CANVAS_ITEM,
"GnomeCanvasWaveView",
152 return waveview_type;
158 GObjectClass *gobject_class;
159 GtkObjectClass *object_class;
160 GnomeCanvasItemClass *item_class;
162 gobject_class = (GObjectClass *)
class;
163 object_class = (GtkObjectClass *)
class;
164 item_class = (GnomeCanvasItemClass *)
class;
171 g_object_class_install_property
174 g_param_spec_pointer (
"data_src", NULL, NULL,
175 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
177 g_object_class_install_property
180 g_param_spec_uint (
"channel", NULL, NULL,
182 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
184 g_object_class_install_property
187 g_param_spec_pointer (
"length_function", NULL, NULL,
188 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
190 g_object_class_install_property
193 g_param_spec_pointer (
"sourcefile_length_function", NULL, NULL,
194 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
196 g_object_class_install_property
199 g_param_spec_pointer (
"peak_function", NULL, NULL,
200 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
202 g_object_class_install_property
205 g_param_spec_pointer (
"gain_function", NULL, NULL,
206 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
208 g_object_class_install_property
211 g_param_spec_pointer (
"gain_src", NULL, NULL,
212 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
214 g_object_class_install_property
217 g_param_spec_pointer (
"cache", NULL, NULL,
218 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
220 g_object_class_install_property
223 g_param_spec_boolean (
"cache_updater", NULL, NULL,
225 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
227 g_object_class_install_property
230 g_param_spec_double (
"samples_per_unit", NULL, NULL,
231 0.0, G_MAXDOUBLE, 0.0,
232 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
234 g_object_class_install_property
237 g_param_spec_double (
"amplitude_above_axis", NULL, NULL,
238 0.0, G_MAXDOUBLE, 0.0,
239 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
241 g_object_class_install_property
244 g_param_spec_double (
"x", NULL, NULL,
245 0.0, G_MAXDOUBLE, 0.0,
246 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
248 g_object_class_install_property
251 g_param_spec_double (
"y", NULL, NULL,
252 0.0, G_MAXDOUBLE, 0.0,
253 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
255 g_object_class_install_property
258 g_param_spec_double (
"height", NULL, NULL,
259 0.0, G_MAXDOUBLE, 0.0,
260 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
262 g_object_class_install_property
265 g_param_spec_uint (
"wave_color", NULL, NULL,
267 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
269 g_object_class_install_property
272 g_param_spec_uint (
"clip_color", NULL, NULL,
274 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
276 g_object_class_install_property
279 g_param_spec_uint (
"zero_color", NULL, NULL,
281 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
283 g_object_class_install_property
286 g_param_spec_uint (
"fill_color", NULL, NULL,
288 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
290 g_object_class_install_property
293 g_param_spec_boolean (
"filled", NULL, NULL,
295 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
297 g_object_class_install_property
300 g_param_spec_boolean (
"rectified", NULL, NULL,
302 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
304 g_object_class_install_property
307 g_param_spec_boolean (
"zero_line", NULL, NULL,
309 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
311 g_object_class_install_property
314 g_param_spec_boolean (
"logscaled", NULL, NULL,
316 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
318 g_object_class_install_property
321 g_param_spec_uint (
"region_start", NULL, NULL,
323 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
359 g_free (cache->
data);
397 g_return_if_fail (
object != NULL);
404 #define DEBUG_CACHE 0
405 #undef CACHE_MEMMOVE_OPTIMIZATION
411 gulong required_cache_entries;
412 gulong rf1, rf2,rf3, required_frames;
413 gulong new_cache_start, new_cache_end;
421 #ifdef CACHE_MEMMOVE_OPTIMIZATION
422 gulong present_frames;
423 gulong present_entries;
426 cache = waveview->
cache;
433 printf (
"\n\n=> 0x%x cache @ 0x%x range: %lu - %lu request: %lu - %lu (%lu frames)\n",
436 start_sample, end_sample, end_sample - start_sample);
439 if (cache->
start <= start_sample && cache->
end >= end_sample) {
455 if (start_sample < half_width) {
458 new_cache_start = start_sample - half_width;
463 rf1 = end_sample - start_sample + 1;
465 required_frames =
MAX(rf1,rf2);
470 if (rf3 < new_cache_start) {
473 rf3 -= new_cache_start;
477 fprintf (stderr,
"AVAILABLE FRAMES = %lu of %lu, start = %lu, sstart = %lu, cstart = %lu\n",
482 required_frames =
MIN(required_frames,rf3);
484 new_cache_end = new_cache_start + required_frames - 1;
486 required_cache_entries = (gulong) floor (required_frames / waveview->
samples_per_unit );
489 fprintf (stderr,
"new cache = %lu - %lu\n", new_cache_start, new_cache_end);
490 fprintf(stderr,
"required_cach_entries = %lu, samples_per_unit = %f req frames = %lu\n",
494 if (required_cache_entries > cache->
allocated) {
496 cache->
allocated = required_cache_entries;
501 ostart = new_cache_start;
503 #ifdef CACHE_MEMMOVE_OPTIMIZATION
511 if (cache->
start < new_cache_start && new_cache_start < cache->end) {
526 present_frames = cache->
end - new_cache_start;
527 present_entries = (gulong) floor (present_frames / waveview->
samples_per_unit);
530 fprintf (stderr,
"existing material at end of current cache, move to start of new cache\n"
531 "\tcopy from %lu to start\n", cache->
data_size - present_entries);
534 memmove (&cache->
data[0],
539 fprintf (stderr,
"satisfied %lu of %lu frames, offset = %lu, will start at %lu (ptr = 0x%x)\n",
540 present_frames, required_frames, present_entries, new_cache_start + present_entries,
541 cache->
data + present_entries);
544 copied = present_entries;
545 offset = present_entries;
546 new_cache_start += present_frames;
547 required_frames -= present_frames;
549 }
else if (new_cache_end > cache->
start && new_cache_end < cache->end) {
562 present_frames = new_cache_end - cache->
start;
563 present_entries = (gulong) floor (present_frames / waveview->
samples_per_unit);
570 fprintf (stderr,
"existing material at start of current cache, move to start of end cache\n");
574 fprintf (stderr,
"satisfied %lu of %lu frames, offset = %lu, will start at %lu (ptr = 0x%x)\n",
575 present_entries, required_frames, present_entries, new_cache_start + present_entries,
576 cache->
data + present_entries);
579 copied = present_entries;
581 required_frames -= present_frames;
605 printf (
"requesting %lu/%f to cover %lu-%lu at %f spu (request was %lu-%lu) into cache + %lu\n",
606 required_frames, required_frames/waveview->
samples_per_unit, new_cache_start, new_cache_end,
616 if (required_frames) {
626 if (npeaks < cache->allocated) {
628 fprintf (stderr,
"zero fill cache for %lu at %lu\n", cache->
allocated - npeaks, npeaks);
639 gain = (
float*) malloc (
sizeof (
float) * cache->
data_size);
660 if (buf[n].max > 0.0
f) {
662 }
else if (buf[n].max < 0.0
f) {
666 if (buf[n].min > 0.0
f) {
668 }
else if (buf[n].min < 0.0
f) {
674 cache->
start = ostart;
675 cache->
end = new_cache_end;
679 fprintf (stderr,
"return cache index = %d\n",
682 return (guint32) floor ((((
double) (start_sample - cache->
start)) / waveview->
samples_per_unit) + 0.5);
691 if (waveview->
data_src == data_src) {
706 if (waveview->
channel == chan) {
717 double x1, x2, y1, y2;
720 int Ix1, Ix2, Iy1, Iy2;
730 gnome_canvas_item_i2w_affine (item, i2w);
731 art_affine_point (&w1, &i1, i2w);
732 art_affine_point (&w2, &i2, i2w);
734 Ix1 = (int) rint(w1.x);
735 Ix2 = (int) rint(w2.x);
736 Iy1 = (int) rint(w1.y);
737 Iy2 = (int) rint(w2.y);
739 gnome_canvas_update_bbox (item, Ix1, Iy1, Ix2, Iy2);
755 GnomeCanvasItem *item;
758 int calc_bounds = FALSE;
760 g_return_if_fail (
object != NULL);
763 item = GNOME_CANVAS_ITEM (
object);
779 ptr = g_value_get_pointer(value);
785 ptr = g_value_get_pointer(value);
791 ptr = g_value_get_pointer(value);
797 ptr = g_value_get_pointer(value);
803 waveview->
gain_src = g_value_get_pointer(value);
813 waveview->
cache = g_value_get_pointer(value);
841 if (waveview->
x != g_value_get_double (value)) {
842 waveview->
x = g_value_get_double (value);
848 if (waveview->
y != g_value_get_double (value)) {
849 waveview->
y = g_value_get_double (value);
855 if (waveview->
height != fabs (g_value_get_double (value))) {
856 waveview->
height = fabs (g_value_get_double (value));
862 if (waveview->
wave_color != g_value_get_uint(value)) {
863 waveview->
wave_color = g_value_get_uint(value);
869 if (waveview->
clip_color != g_value_get_uint(value)) {
870 waveview->
clip_color = g_value_get_uint(value);
876 if (waveview->
zero_color != g_value_get_uint(value)) {
877 waveview->
zero_color = g_value_get_uint(value);
883 if (waveview->
fill_color != g_value_get_uint(value)) {
884 waveview->
fill_color = g_value_get_uint(value);
890 if (waveview->
filled != g_value_get_boolean(value)) {
891 waveview->
filled = g_value_get_boolean(value);
897 if (waveview->
rectified != g_value_get_boolean(value)) {
898 waveview->
rectified = g_value_get_boolean(value);
904 if (waveview->
zero_line != g_value_get_boolean(value)) {
905 waveview->
zero_line = g_value_get_boolean(value);
911 if (waveview->
logscaled != g_value_get_boolean(value)) {
912 waveview->
logscaled = g_value_get_boolean(value);
937 gnome_canvas_item_request_update (item);
951 g_return_if_fail (
object != NULL);
958 g_value_set_pointer(value, waveview->
data_src);
962 g_value_set_uint(value, waveview->
channel);
966 g_value_set_pointer(value, POSIX_FUNC_PTR_CAST(
void*, waveview->
length_function));
974 g_value_set_pointer(value, POSIX_FUNC_PTR_CAST(
void*, waveview->
peak_function));
982 g_value_set_pointer(value, waveview->
gain_src);
986 g_value_set_pointer(value, waveview->
cache);
1002 g_value_set_double (value, waveview->
x);
1006 g_value_set_double (value, waveview->
y);
1010 g_value_set_double (value, waveview->
height);
1014 g_value_set_uint (value, waveview->
wave_color);
1018 g_value_set_uint (value, waveview->
clip_color);
1022 g_value_set_uint (value, waveview->
zero_color);
1026 g_value_set_uint (value, waveview->
fill_color);
1030 g_value_set_boolean (value, waveview->
filled);
1034 g_value_set_boolean (value, waveview->
rectified);
1038 g_value_set_boolean (value, waveview->
zero_line);
1042 g_value_set_boolean (value, waveview->
logscaled);
1050 G_OBJECT_WARN_INVALID_PROPERTY_ID (
object, prop_id, pspec);
1066 (*
parent_class->update) (item, affine, clip_path, flags);
1078 gnome_canvas_item_i2w (item, &x, &y);
1079 gnome_canvas_w2c (GNOME_CANVAS(item->canvas), x, y, &waveview->
bbox_ulx, &waveview->
bbox_uly);
1084 y = waveview->
y + waveview->
height;
1086 gnome_canvas_item_i2w (item, &x, &y);
1087 gnome_canvas_w2c (GNOME_CANVAS(item->canvas), x, y, &waveview->
bbox_lrx, &waveview->
bbox_lry);
1107 GnomeCanvasBuf *buf)
1111 int clip_length = 0;
1127 gnome_canvas_buf_ensure_buf (buf);
1134 int const begin =
MAX (waveview->
bbox_ulx, buf->rect.x0);
1137 int const zbegin = (begin == waveview->
bbox_ulx) ? (begin + 1) : begin;
1140 int const end = (waveview->
bbox_lrx >= 0) ?
MIN (waveview->
bbox_lrx,buf->rect.x1) : buf->rect.x1;
1143 int const zend = (end == waveview->
bbox_lrx) ? (end - 1) : end;
1167 printf (
"0x%x r (%d..%d)(%d..%d) bbox (%d..%d)(%d..%d)"
1168 " b/e %d..%d s= %lu..%lu @ %f\n",
1204 clip_length =
MIN(5,(waveview->
height/4));
1214 #define origin half_height
1216 if (waveview->
filled && !rectify) {
1221 int next_pymin, next_pymax;
1223 int next_clip_max = 0;
1224 int next_clip_min = 0;
1226 int wave_middle = (int) rint ((item->y1 +
origin) * item->canvas->pixels_per_unit);
1227 int wave_top = (int) rint ((item->y1) * item->canvas->pixels_per_unit);
1229 if (s1 < waveview->samples_per_unit) {
1231 prev_pymax = (int) rint ((item->y1 +
origin) * item->canvas->pixels_per_unit);
1232 prev_pymin = prev_pymax;
1240 last_pymax = (int) rint ((item->y1 +
origin) * item->canvas->pixels_per_unit);
1241 last_pymin = last_pymax;
1252 if(prev_pymax != prev_pymin) {
1254 prev_pymax = (int) rint ((item->y1 +
origin -
MIN(waveview->
cache->
data[cache_index].
max, 1.0) * half_height) * item->canvas->pixels_per_unit);
1255 prev_pymin = (int) rint ((item->y1 +
origin -
MAX(waveview->
cache->
data[cache_index].
min, -1.0) * half_height) * item->canvas->pixels_per_unit);
1258 if(last_pymax != last_pymin) {
1260 guint index = cache_index + (end - begin);
1266 last_pymax = (int) rint ((item->y1 +
origin) * item->canvas->pixels_per_unit);
1267 last_pymin = (int) rint ((item->y1 +
origin) * item->canvas->pixels_per_unit);
1271 last_pymax = (int) rint ((item->y1 +
origin -
MIN(waveview->
cache->
data[index].
max, 1.0) * half_height) * item->canvas->pixels_per_unit);
1272 last_pymin = (int) rint ((item->y1 +
origin -
MAX(waveview->
cache->
data[index].
min, -1.0) * half_height) * item->canvas->pixels_per_unit);
1297 next_pymax = (int) rint ((item->y1 +
origin - max) * item->canvas->pixels_per_unit);
1298 next_pymin = (int) rint ((item->y1 +
origin - min) * item->canvas->pixels_per_unit);
1303 for(x = begin; x < end; ++x) {
1304 int clip_max = next_clip_max;
1305 int clip_min = next_clip_min;
1306 int fill_max, fill_min;
1314 next_pymax = last_pymax;
1315 next_pymin = last_pymin;
1320 if (cache_index < waveview->cache->data_size) {
1343 next_pymax = (int) rint ((item->y1 +
origin - max) * item->canvas->pixels_per_unit);
1344 next_pymin = (int) rint ((item->y1 +
origin - min) * item->canvas->pixels_per_unit);
1348 if (pymax == pymin) {
1351 if((prev_pymax < pymax && next_pymax < pymax) ||
1352 (prev_pymax == pymax && next_pymax == pymax)) {
1353 fill_max = pymax + 1;
1357 fill_max =
MAX(prev_pymax, next_pymax);
1358 if(pymax == fill_max) {
1367 if((prev_pymin > pymin && next_pymin > pymin) ||
1368 (prev_pymin == pymin && next_pymin == pymin)) {
1369 fill_min = pymin - 1;
1373 fill_min =
MIN(prev_pymin, next_pymin);
1374 if(pymin == fill_min) {
1382 if(fill_max < fill_min) {
1385 else if(fill_max == fill_min) {
1407 }
else if (waveview->
filled && rectify) {
1409 int prev_pymax = -1;
1410 int last_pymax = -1;
1413 int next_clip_max = 0;
1414 int next_clip_min = 0;
1416 int wave_middle = (int) rint ((item->y1 + waveview->
height) * item->canvas->pixels_per_unit);
1417 int wave_top = (int) rint ((item->y1) * item->canvas->pixels_per_unit);
1420 pymin = (int) rint ((item->y1 + waveview->
height) * item->canvas->pixels_per_unit);
1422 if(s1 < waveview->samples_per_unit) {
1443 if(prev_pymax < 0) {
1447 if (fabs (min) > fabs (max)) {
1451 prev_pymax = (int) rint ((item->y1 + waveview->
height - max * waveview->
height) * item->canvas->pixels_per_unit);
1454 if(last_pymax < 0) {
1456 int index = cache_index + (end - begin);
1461 if (fabs (min) > fabs (max)) {
1465 last_pymax = (int) rint ((item->y1 + waveview->
height - max * waveview->
height) * item->canvas->pixels_per_unit);
1484 if (fabs (min) > fabs (max)) {
1488 next_pymax = (int) rint ((item->y1 + waveview->
height - max * waveview->
height) * item->canvas->pixels_per_unit);
1493 for(x = begin; x < end; ++x) {
1494 int clip_max = next_clip_max;
1495 int clip_min = next_clip_min;
1503 next_pymax = last_pymax;
1521 if (fabs (min) > fabs (max)) {
1525 next_pymax = (int) rint ((item->y1 + waveview->
height - max * waveview->
height) * item->canvas->pixels_per_unit);
1529 if (pymax == pymin) {
1532 if((prev_pymax < pymax && next_pymax < pymax) ||
1533 (prev_pymax == pymax && next_pymax == pymax)) {
1534 fill_max = pymax + 1;
1538 fill_max =
MAX(prev_pymax, next_pymax);
1539 if(pymax == fill_max) {
1548 if(fill_max < pymin) {
1551 else if(fill_max == pymin) {
1574 for (x = begin; x < end; x++) {
1577 int clip_max, clip_min;
1597 if (fabs (min) > fabs (max)) {
1601 max = max * waveview->
height;
1603 pymax = (int) rint ((item->y1 + waveview->
height - max) * item->canvas->pixels_per_unit);
1604 pymin = (int) rint ((item->y1 + waveview->
height) * item->canvas->pixels_per_unit);
1608 max = max * half_height;
1609 min = min * half_height;
1611 pymax = (int) rint ((item->y1 +
origin - max) * item->canvas->pixels_per_unit);
1612 pymin = (int) rint ((item->y1 +
origin - min) * item->canvas->pixels_per_unit);
1619 if (pymax == pymin) {
1644 unsigned char zero_r, zero_g, zero_b, zero_a;
1646 int zeroline_y = (int) rint ((item->y1 +
origin) * item->canvas->pixels_per_unit);
1647 PAINT_HORIZA(buf, zero_r, zero_g, zero_b, zero_a, zbegin, zend, zeroline_y);
1655 GnomeCanvasBuf *buf)
1659 int clip_length = 0;
1675 gnome_canvas_buf_ensure_buf (buf);
1682 int const begin =
MAX (waveview->
bbox_ulx, buf->rect.x0);
1685 int const zbegin = (begin == waveview->
bbox_ulx) ? (begin + 1) : begin;
1688 int const end = (waveview->
bbox_lrx >= 0) ?
MIN (waveview->
bbox_lrx,buf->rect.x1) : buf->rect.x1;
1691 int const zend = (end == waveview->
bbox_lrx) ? (end - 1) : end;
1715 printf (
"0x%x r (%d..%d)(%d..%d) bbox (%d..%d)(%d..%d)"
1716 " b/e %d..%d s= %lu..%lu @ %f\n",
1752 clip_length =
MIN(5,(waveview->
height/4));
1762 #define origin half_height
1764 if (waveview->
filled && !rectify) {
1769 int next_pymin, next_pymax;
1771 int next_clip_max = 0;
1772 int next_clip_min = 0;
1774 if (s1 < waveview->samples_per_unit) {
1776 prev_pymax = (int) rint ((item->y1 +
origin) * item->canvas->pixels_per_unit);
1777 prev_pymin = prev_pymax;
1785 last_pymax = (int) rint ((item->y1 +
origin) * item->canvas->pixels_per_unit);
1786 last_pymin = last_pymax;
1797 if(prev_pymax != prev_pymin) {
1799 prev_pymax = (int) rint ((item->y1 +
origin -
MIN(waveview->
cache->
data[cache_index].
max, 1.0) * half_height) * item->canvas->pixels_per_unit);
1800 prev_pymin = (int) rint ((item->y1 +
origin -
MAX(waveview->
cache->
data[cache_index].
min, -1.0) * half_height) * item->canvas->pixels_per_unit);
1803 if(last_pymax != last_pymin) {
1805 guint index = cache_index + (end - begin);
1811 last_pymax = (int) rint ((item->y1 +
origin) * item->canvas->pixels_per_unit);
1812 last_pymin = (int) rint ((item->y1 +
origin) * item->canvas->pixels_per_unit);
1816 last_pymax = (int) rint ((item->y1 +
origin -
MIN(waveview->
cache->
data[index].
max, 1.0) * half_height) * item->canvas->pixels_per_unit);
1817 last_pymin = (int) rint ((item->y1 +
origin -
MAX(waveview->
cache->
data[index].
min, -1.0) * half_height) * item->canvas->pixels_per_unit);
1842 next_pymax = (int) rint ((item->y1 +
origin - max) * item->canvas->pixels_per_unit);
1843 next_pymin = (int) rint ((item->y1 +
origin - min) * item->canvas->pixels_per_unit);
1848 for(x = begin; x < end; ++x) {
1849 int clip_max = next_clip_max;
1850 int clip_min = next_clip_min;
1851 int fill_max, fill_min;
1859 next_pymax = last_pymax;
1860 next_pymin = last_pymin;
1865 if (cache_index < waveview->cache->data_size) {
1888 next_pymax = (int) rint ((item->y1 +
origin - max) * item->canvas->pixels_per_unit);
1889 next_pymin = (int) rint ((item->y1 +
origin - min) * item->canvas->pixels_per_unit);
1893 if (pymax == pymin) {
1896 if((prev_pymax < pymax && next_pymax < pymax) ||
1897 (prev_pymax == pymax && next_pymax == pymax)) {
1898 fill_max = pymax + 1;
1902 fill_max =
MAX(prev_pymax, next_pymax);
1903 if(pymax == fill_max) {
1912 if((prev_pymin > pymin && next_pymin > pymin) ||
1913 (prev_pymin == pymin && next_pymin == pymin)) {
1914 fill_min = pymin - 1;
1918 fill_min =
MIN(prev_pymin, next_pymin);
1919 if(pymin == fill_min) {
1927 if(fill_max < fill_min) {
1930 else if(fill_max == fill_min) {
1947 }
else if (waveview->
filled && rectify) {
1949 int prev_pymax = -1;
1950 int last_pymax = -1;
1953 int next_clip_max = 0;
1954 int next_clip_min = 0;
1957 pymin = (int) rint ((item->y1 + waveview->
height) * item->canvas->pixels_per_unit);
1959 if(s1 < waveview->samples_per_unit) {
1980 if(prev_pymax < 0) {
1984 if (fabs (min) > fabs (max)) {
1988 prev_pymax = (int) rint ((item->y1 + waveview->
height - max * waveview->
height) * item->canvas->pixels_per_unit);
1991 if(last_pymax < 0) {
1993 int index = cache_index + (end - begin);
1998 if (fabs (min) > fabs (max)) {
2002 last_pymax = (int) rint ((item->y1 + waveview->
height - max * waveview->
height) * item->canvas->pixels_per_unit);
2021 if (fabs (min) > fabs (max)) {
2025 next_pymax = (int) rint ((item->y1 + waveview->
height - max * waveview->
height) * item->canvas->pixels_per_unit);
2030 for(x = begin; x < end; ++x) {
2031 int clip_max = next_clip_max;
2032 int clip_min = next_clip_min;
2040 next_pymax = last_pymax;
2058 if (fabs (min) > fabs (max)) {
2062 next_pymax = (int) rint ((item->y1 + waveview->
height - max * waveview->
height) * item->canvas->pixels_per_unit);
2066 if (pymax == pymin) {
2069 if((prev_pymax < pymax && next_pymax < pymax) ||
2070 (prev_pymax == pymax && next_pymax == pymax)) {
2071 fill_max = pymax + 1;
2075 fill_max =
MAX(prev_pymax, next_pymax);
2076 if(pymax == fill_max) {
2085 if(fill_max < pymin) {
2088 else if(fill_max == pymin) {
2107 for (x = begin; x < end; x++) {
2110 int clip_max, clip_min;
2130 if (fabs (min) > fabs (max)) {
2134 max = max * waveview->
height;
2136 pymax = (int) rint ((item->y1 + waveview->
height - max) * item->canvas->pixels_per_unit);
2137 pymin = (int) rint ((item->y1 + waveview->
height) * item->canvas->pixels_per_unit);
2141 max = max * half_height;
2142 min = min * half_height;
2144 pymax = (int) rint ((item->y1 +
origin - max) * item->canvas->pixels_per_unit);
2145 pymin = (int) rint ((item->y1 +
origin - min) * item->canvas->pixels_per_unit);
2152 if (pymax == pymin) {
2177 unsigned char zero_r, zero_g, zero_b, zero_a;
2179 int zeroline_y = (int) rint ((item->y1 +
origin) * item->canvas->pixels_per_unit);
2180 PAINT_HORIZA(buf, zero_r, zero_g, zero_b, zero_a, zbegin, zend, zeroline_y);
2187 GnomeCanvasBuf *buf)
2198 GdkDrawable *drawable,
2200 int width,
int height)
2233 if (x + width > waveview->
bbox_lrx) {
2239 if (y + height > waveview->
bbox_lry) {
2272 cr = gdk_cairo_create (drawable);
2273 cairo_set_line_width (cr, 0.5);
2277 cairo_rectangle (cr, ulx, uly, lrx - ulx, lry - uly);
2289 printf (
"%p r (%d,%d)(%d,%d)[%d x %d] bbox (%d,%d)(%d,%d)[%d x %d]"
2290 " draw (%.1f,%.1f)(%.1f,%.1f)[%.1f x %.1f] s= %lu..%lu\n",
2312 for (xoff = ulx; xoff < lrx; xoff++) {
2327 if (fabs (min) > fabs (max)) {
2332 yoff = origin - (waveview->
half_height * max) + 0.5;
2336 cairo_move_to (cr, xoff+0.5, yoff);
2338 cairo_line_to (cr, xoff+0.5, yoff);
2346 cairo_line_to (cr, xoff + 10, yoff);
2350 for (--xoff, --cache_index; xoff >= ulx; --xoff) {
2359 yoff = origin - (waveview->
half_height * min) + 0.5;
2361 cairo_line_to (cr, xoff+0.5, yoff);
2367 cairo_line_to (cr, xoff - 10, yoff);
2371 cairo_close_path (cr);
2375 cairo_set_source_rgba (cr,
2376 (waveview->
fill_r/255.0),
2377 (waveview->
fill_g/255.0),
2378 (waveview->
fill_b/255.0),
2379 (waveview->
fill_a/255.0));
2380 cairo_fill_preserve (cr);
2381 cairo_set_source_rgba (cr,
2382 (waveview->
wave_r/255.0),
2383 (waveview->
wave_g/255.0),
2384 (waveview->
wave_b/255.0),
2385 (waveview->
wave_a/255.0));
2392 if (clip_max || clip_min) {
2393 cairo_set_source_rgba (cr, waveview->clip_r, waveview->clip_g, waveview->clip_b, waveview->clip_a);
2397 cairo_move_to (cr, xoff, yoff1);
2398 cairo_line_to (cr, xoff, yoff1 + clip_length);
2403 cairo_move_to (cr, xoff, yoff2);
2404 cairo_line_to (cr, xoff, yoff2 - clip_length);
2419 *y2 = *y1 + waveview->
height;
2423 gnome_canvas_item_i2w (item, &x, &y);
2424 gnome_canvas_w2c_d (GNOME_CANVAS(item->canvas), x, y, &a, &b);
2427 gnome_canvas_item_i2w (item, &x, &y);
2428 gnome_canvas_w2c_d (GNOME_CANVAS(item->canvas), x, y, &c, &d);
2429 printf (
"item bounds now (%g,%g),(%g,%g)\n", a, b, c, d);
2455 *actual_item = item;
2463 if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) {
2483 return sqrt (dx * dx + dy * dy);
static double gnome_canvas_waveview_point(GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item)
GType gnome_canvas_waveview_get_type(void)
static float fast_coefficient_to_dB(float coeff)
GnomeCanvasWaveViewCache * gnome_canvas_waveview_cache_new(void)
static void gnome_canvas_waveview_set_data_src(GnomeCanvasWaveView *, void *)
void(* waveview_gain_curve_function_t)(void *arg, double start, double end, float *vector, gint64 veclen)
void gnome_canvas_waveview_cache_destroy(GnomeCanvasWaveViewCache *cache)
static void gnome_canvas_waveview_update(GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
static void gnome_canvas_waveview_render(GnomeCanvasItem *item, GnomeCanvasBuf *buf)
static GnomeCanvasItemClass * parent_class
#define PAINT_VERTA_GR(inbuf, colr, colg, colb, cola, ptx, pty0, pty1, origin_y, obj_top)
double amplitude_above_axis
waveview_peak_function_t peak_function
static void gnome_canvas_waveview_destroy(GtkObject *object)
LIBARDOUR_API PBD::PropertyDescriptor< bool > gain
#define UINT_TO_RGBA(u, r, g, b, a)
GnomeCanvasWaveViewCacheEntry * data
gulong(* waveview_length_function_t)(void *)
waveview_length_function_t length_function
static void gnome_canvas_waveview_init(GnomeCanvasWaveView *waveview)
static void gnome_canvas_waveview_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
#define PAINT_HORIZA(inbuf, colr, colg, colb, cola, ptx0, ptx1, pty)
static int _gradient_rendering
#define GNOME_CANVAS_WAVEVIEW(obj)
struct _GnomeCanvasWaveViewClass GnomeCanvasWaveViewClass
void gnome_canvas_waveview_set_gradient_waveforms(int yn)
#define GNOME_IS_CANVAS_WAVEVIEW(obj)
static void gnome_canvas_waveview_reset_bounds(GnomeCanvasItem *item)
static float alt_log_meter(float power)
static void gnome_canvas_waveview_set_channel(GnomeCanvasWaveView *, guint32)
#define PAINT_VERTA(inbuf, colr, colg, colb, cola, ptx, pty0, pty1)
static void gnome_canvas_waveview_flat_render(GnomeCanvasItem *item, GnomeCanvasBuf *buf)
static guint32 gnome_canvas_waveview_ensure_cache(GnomeCanvasWaveView *waveview, gulong start_sample, gulong end_sample)
gulong(* waveview_sourcefile_length_function_t)(void *, double)
static void gnome_canvas_waveview_gradient_render(GnomeCanvasItem *item, GnomeCanvasBuf *buf)
waveview_sourcefile_length_function_t sourcefile_length_function
static void gnome_canvas_waveview_bounds(GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
void(* waveview_peak_function_t)(void *, gulong, gulong, gulong, gpointer, guint32, double)
GnomeCanvasWaveViewCache * cache
#define PAINT_DOTA(inbuf, colr, colg, colb, cola, ptx, pty)
int32_t reload_cache_in_render
waveview_gain_curve_function_t gain_curve_function
static void gnome_canvas_waveview_class_init(GnomeCanvasWaveViewClass *class)
static void gnome_canvas_waveview_draw(GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int w, int h)
static void gnome_canvas_waveview_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)