1 /*
2 * Copyright (C) 2004-2005 Vadim Berezniker
3 * http://www.kryptolus.com
4 *
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with GNU Make; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 */
21
22
23 #include "stdafx.h"
24
25 #include "common.h"
26
27 #include "pavl.h"
28 #include "kry_marker.h"
29 #include "kry_region.h"
30 #include "kry_region_fixed_list.h"
31 #include "kry_waveform.h"
32 #include "kry_waveform_group_item.h"
33 #include "sound.h"
34
35 static void kry_waveform_class_init (KryWaveformClass *klass);
36 static void kry_waveform_init (KryWaveform *waveform);
37 static void kry_waveform_destroy (GtkObject *object);
38 static void kry_waveform_realize (GtkWidget *widget);
39 static void kry_waveform_find_first_region(KryWaveform *waveform, gboolean backward);
40
41 static void kry_waveform_size_request (GtkWidget *widget, GtkRequisition *requisition);
42 void kry_waveform_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
43 static gboolean kry_waveform_button_press( GtkWidget *widget, GdkEventButton *event );
44 static gboolean kry_waveform_button_release( GtkWidget *widget, GdkEventButton *event );
45 static gboolean kry_waveform_motion_notify( GtkWidget *widget, GdkEventMotion *event );
46 static void kry_waveform_adjustment_value_changed (GtkAdjustment *adjustment, gpointer data);
47 void kry_waveform_set_data(KryWaveform *waveform, struct sound_info *sound_info);
48 static gboolean kry_waveform_key_press( GtkWidget *widget, GdkEventKey *event );
49 static void kry_waveform_redraw(KryWaveform *waveform);
50 static GtkWidgetClass *parent_class = NULL;
51 static double kry_waveform_get_zoom_internal(KryWaveform *waveform);
52 static void kry_waveform_update_zoom(KryWaveform *waveform);
53
54 struct waveform_state
55 {
56 int width;
57 int height;
58 };
59
60
61 enum
62 {
63 ZOOM_CHANGED_SIGNAL,
64 SCALE_CHANGED_SIGNAL,
65 MIN_ZOOM_CHANGED_SIGNAL,
66 LAST_SIGNAL
67 };
68
69 static guint kry_waveform_signals[LAST_SIGNAL] = { 0 };
70
kry_waveform_get_type()71 GtkType kry_waveform_get_type ()
72 {
73 static GtkType waveform_type = 0;
74
75 if (!waveform_type)
76 {
77 static const GtkTypeInfo waveform_info =
78 {
79 "KryWaveform",
80 sizeof (KryWaveform),
81 sizeof (KryWaveformClass),
82 (GtkClassInitFunc) kry_waveform_class_init,
83 (GtkObjectInitFunc) kry_waveform_init,
84 /* reserved_1 */ NULL,
85 /* reserved_1 */ NULL,
86 (GtkClassInitFunc) NULL
87 };
88
89 waveform_type = gtk_type_unique (GTK_TYPE_WIDGET, &waveform_info);
90 }
91
92 return waveform_type;
93 }
94
kry_waveform_class_init(KryWaveformClass * klass)95 static void kry_waveform_class_init (KryWaveformClass *klass)
96 {
97 GtkObjectClass *object_class;
98 GtkWidgetClass *widget_class;
99
100 object_class = (GtkObjectClass*) klass;
101 widget_class = (GtkWidgetClass*) klass;
102
103 parent_class = GTK_WIDGET_CLASS(gtk_type_class (gtk_widget_get_type ()));
104
105 object_class->destroy = kry_waveform_destroy;
106
107 widget_class->realize = kry_waveform_realize;
108 widget_class->expose_event = kry_waveform_expose;
109 widget_class->size_request = kry_waveform_size_request;
110 widget_class->size_allocate = kry_waveform_size_allocate;
111 widget_class->button_press_event = kry_waveform_button_press;
112 widget_class->button_release_event = kry_waveform_button_release;
113 widget_class->motion_notify_event = kry_waveform_motion_notify;
114 widget_class->key_press_event = kry_waveform_key_press;
115
116 kry_waveform_signals[ZOOM_CHANGED_SIGNAL] =
117 g_signal_new ("zoom_changed",
118 G_OBJECT_CLASS_TYPE (klass),
119 (GSignalFlags) (G_SIGNAL_RUN_FIRST),
120 G_STRUCT_OFFSET (KryWaveformClass, zoom_changed),
121 NULL, NULL,
122 g_cclosure_marshal_VOID__DOUBLE,
123 G_TYPE_NONE, 1, G_TYPE_DOUBLE);
124
125 kry_waveform_signals[SCALE_CHANGED_SIGNAL] =
126 g_signal_new ("scale_changed",
127 G_OBJECT_CLASS_TYPE (klass),
128 (GSignalFlags) (G_SIGNAL_RUN_FIRST),
129 G_STRUCT_OFFSET (KryWaveformClass, scale_changed),
130 NULL, NULL,
131 g_cclosure_marshal_VOID__INT,
132 G_TYPE_NONE, 1, G_TYPE_INT);
133
134 kry_waveform_signals[MIN_ZOOM_CHANGED_SIGNAL] =
135 g_signal_new ("min_zoom_changed",
136 G_OBJECT_CLASS_TYPE (klass),
137 (GSignalFlags) (G_SIGNAL_RUN_FIRST),
138 G_STRUCT_OFFSET (KryWaveformClass, min_zoom_changed),
139 NULL, NULL,
140 g_cclosure_marshal_VOID__DOUBLE,
141 G_TYPE_NONE, 1, G_TYPE_DOUBLE);
142 }
143
144 static void
kry_waveform_init(KryWaveform * waveform)145 kry_waveform_init (KryWaveform *waveform)
146 {
147 waveform->button_press = FALSE;
148 waveform->data_per_pixel = 1;
149 waveform->scale = 1;
150 waveform->show_scrub_bar = TRUE;
151 waveform->show_time_bar = TRUE;
152 waveform->show_time_markers = TRUE;
153 waveform->show_keyframe = TRUE;
154 waveform->scrub_bar_height = 15;
155 waveform->scrub_bar_height_real = 15;
156 waveform->drag_selection_enabled = TRUE;
157 waveform->zoom = 3.0;
158 waveform->marker_width = 2;
159 waveform->corner_width = 8;
160 waveform->data_thread_mutex = g_mutex_new();
161 waveform->data_thread_mutex_global = g_mutex_new();
162 waveform->region_fixed_list = NULL;
163 }
164
kry_waveform_disable_draw(KryWaveform * widget)165 void kry_waveform_disable_draw(KryWaveform *widget)
166 {
167 KryWaveform *waveform;
168
169 g_return_if_fail (widget != NULL);
170 g_return_if_fail (KRY_IS_WAVEFORM (widget));
171
172 waveform = KRY_WAVEFORM(widget);
173
174 waveform->draw_disabled = TRUE;
175 }
176
kry_waveform_enable_draw(KryWaveform * widget)177 void kry_waveform_enable_draw(KryWaveform *widget)
178 {
179 KryWaveform *waveform;
180
181 g_return_if_fail (widget != NULL);
182 g_return_if_fail (KRY_IS_WAVEFORM (widget));
183
184 waveform = KRY_WAVEFORM(widget);
185
186 waveform->draw_disabled = FALSE;
187
188 kry_waveform_redraw(waveform);
189 }
190
kry_waveform_marker_draw_erase_real(KryWaveform * waveform,int pos_rel_pixel,gboolean erase)191 void kry_waveform_marker_draw_erase_real(KryWaveform *waveform, int pos_rel_pixel, gboolean erase)
192 {
193
194 GList *list = NULL;
195 struct KryWaveformMarkerInfo *info = NULL;
196 int width = waveform->marker_width;
197 if(!erase)
198 {
199 info = kry_new(struct KryWaveformMarkerInfo, 1);
200 info->marker = NULL;
201 info->pos_rel_pixel = pos_rel_pixel;
202 list = g_list_append(NULL, info);
203 waveform->markers = g_list_concat(waveform->markers, list);
204 }
205
206 kry_waveform_backbuffer_draw_final(GTK_WIDGET(waveform), pos_rel_pixel, width, TRUE, FALSE);
207
208 if(!erase)
209 {
210 waveform->markers = g_list_delete_link(waveform->markers, list);
211 kry_free(info);
212 }
213 }
214
215 /*void kry_waveform_marker_draw_erase(GtkWidget *widget, int mili, int mili_prev)
216 {
217 KryWaveform *waveform;
218
219 g_return_if_fail (widget != NULL);
220 g_return_if_fail (KRY_IS_WAVEFORM (widget));
221
222 waveform = KRY_WAVEFORM(widget);
223
224 int pos_rel_pixel = kry_waveform_rel_pixel_from_mili(waveform, mili);
225 int pos_rel_pixel_prev = kry_waveform_rel_pixel_from_mili(waveform, mili_prev);
226
227 if(mili_prev != -1)
228 kry_waveform_marker_draw_erase_real(waveform, pos_rel_pixel_prev, TRUE);
229
230 if(mili != -1)
231 kry_waveform_marker_draw_erase_real(waveform, pos_rel_pixel, FALSE);
232
233 if(mili == -1)
234 kry_waveform_update_front_buffer(waveform, pos_rel_pixel_prev, waveform->marker_width);
235 else if(mili_prev == -1)
236 kry_waveform_update_front_buffer(waveform, pos_rel_pixel, waveform->marker_width);
237 else
238 kry_waveform_update_front_buffer(waveform, pos_rel_pixel_prev, pos_rel_pixel - pos_rel_pixel_prev + waveform->marker_width);
239 }
240
241 void kry_waveform_marker_erase(GtkWidget *widget, int mili)
242 {
243 kry_waveform_marker_draw_erase(widget, mili, TRUE);
244 }*/
245
kry_waveform_redraw_partial(KryWaveform * waveform,int start,int width,gboolean redraw_time_bar,gboolean do_draw)246 static void kry_waveform_redraw_partial(KryWaveform *waveform, int start, int width, gboolean redraw_time_bar, gboolean do_draw)
247 {
248 if(!GTK_WIDGET_REALIZED(waveform))
249 return;
250
251 kry_waveform_backbuffer_draw_final(GTK_WIDGET(waveform), start, width, TRUE, redraw_time_bar);
252
253 if(do_draw)
254 kry_waveform_update_front_buffer(waveform, start, width);
255 }
256
257 // redraws the entire wave. must be used only when necessary
kry_waveform_redraw(KryWaveform * waveform)258 static void kry_waveform_redraw(KryWaveform *waveform)
259 {
260 if(!GTK_WIDGET_REALIZED(waveform) || waveform->draw_disabled)
261 return;
262
263 if(!waveform->data_pixel)
264 return;
265
266 waveform->last_draw_rect.x = kry_waveform_abs_pixel_from_rel(waveform, 0);
267 waveform->last_draw_rect.width = GTK_WIDGET(waveform)->allocation.width;
268
269 kry_waveform_backbuffer_draw_final(GTK_WIDGET(waveform), 0, GTK_WIDGET(waveform)->allocation.width, TRUE, TRUE);
270
271 kry_waveform_update_front_buffer(waveform, 0, GTK_WIDGET(waveform)->allocation.width);
272 }
273
kry_waveform_abs_pixel_from_mili(KryWaveform * waveform,long time)274 int kry_waveform_abs_pixel_from_mili(KryWaveform *waveform, long time)
275 {
276 return (int) ((((time / 1000.0) * waveform->data_info->vals_per_sec) / waveform->data_per_pixel));
277 }
278
279 // gets a relative pixel position for the given time
280 // (relative to the left side of the waveform)
kry_waveform_rel_pixel_from_mili(KryWaveform * waveform,long time)281 int kry_waveform_rel_pixel_from_mili(KryWaveform *waveform, long time)
282 {
283 return (int) ((((time / 1000.0) * waveform->data_info->vals_per_sec) / waveform->data_per_pixel) - ((waveform->left - fmod(waveform->left, waveform->data_per_pixel)) / waveform->data_per_pixel));
284 }
285
kry_waveform_abs_pixel_from_rel(KryWaveform * waveform,int pixel)286 int kry_waveform_abs_pixel_from_rel(KryWaveform *waveform, int pixel)
287 {
288 double abs = (pixel + waveform->left / waveform->data_per_pixel);
289 return (int) abs + 1;
290 }
291
kry_waveform_mili_from_rel_pixel(KryWaveform * waveform,int pixel)292 int kry_waveform_mili_from_rel_pixel(KryWaveform *waveform, int pixel)
293 {
294 return (int) (((pixel + (waveform->left - fmod(waveform->left, waveform->data_per_pixel)) / waveform->data_per_pixel) * 1000.0 * waveform->data_per_pixel) / waveform->data_info->vals_per_sec);
295 }
296
297 /*
298 * Invoked when a color in the color table used by the wave widget changes.
299 * This forces a redraw of the wave.
300 */
kry_waveform_color_changed(kryObject * obj,kryColor * color,KryWaveform * waveform)301 void kry_waveform_color_changed(kryObject *obj, kryColor *color, KryWaveform *waveform)
302 {
303 //kryColorTable *table = (kryColorTable *) obj;
304 #ifdef _WINDOWS
305 if(color->GetID() == WAVEFORM_COLOR_BACKGROUND)
306 {
307 DeleteObject(waveform->black_brush);
308 waveform->black_brush = CreateSolidBrush(RGB(color->GetRed(), color->GetGreen(), color->GetBlue()));
309 }
310
311 HPEN pen = (HPEN) color->GetUserData();
312 LOGPEN pen_info;
313 GetObject(pen, sizeof(LOGPEN), &pen_info);
314
315 if( GetRValue(pen_info.lopnColor) != color->GetRed()
316 || GetGValue(pen_info.lopnColor) != color->GetGreen()
317 || GetBValue(pen_info.lopnColor) != color->GetBlue())
318 {
319 DeleteObject(color->GetUserData());
320 color->SetUserData(CreatePen(PS_SOLID, 1, RGB(color->GetRed(), color->GetGreen(), color->GetBlue())));
321 }
322 #else
323 GdkColor *gdkcolor = (GdkColor *) color->GetUserData();
324 gdkcolor->red = color->GetRed() * 255;
325 gdkcolor->green = color->GetGreen() * 255;
326 gdkcolor->blue = color->GetBlue() * 255;
327 #endif
328
329 kry_waveform_redraw(waveform);
330 }
331
kry_waveform_new(KryWaveformDataInfo * info,GtkAdjustment * adjustment,kryColorTable * color_table)332 GtkWidget *kry_waveform_new(KryWaveformDataInfo *info, GtkAdjustment *adjustment, kryColorTable *color_table)
333 {
334 KryWaveform *waveform;
335
336 waveform = KRY_WAVEFORM(gtk_type_new (kry_waveform_get_type ()));
337
338 if(color_table)
339 {
340 waveform->color_table = color_table;
341 color_table->Ref();
342 waveform->signal_color_change =
343 color_table->ConnectSignal(kryColorTable::SIGNAL_COLOR_CHANGED, (krySignalFunc1) kry_waveform_color_changed, waveform);
344 }
345 else
346 {
347 waveform->color_table = new kryColorTable(WAVEFORM_COLOR_COUNT);
348 waveform->color_table->Set(WAVEFORM_COLOR_LINE, "WaveformLine", __("Color|Line"), 0, 0xAA, 0);
349 waveform->color_table->Set(WAVEFORM_COLOR_SELECTION_HIGHLIGHT, "WaveformSelectionHighlight", __("Color|Selection Highlight"), 0xC0, 0xFF, 0);
350 waveform->color_table->Set(WAVEFORM_COLOR_SILENCE_HIGHLIGHT, "WaveformSilenceHighlight", __("Color|Silence Highlight"), 0, 0x66, 0);
351 waveform->color_table->Set(WAVEFORM_COLOR_MARKER_START, "WaveformMarkerStart", __("Color|Start Marker"), 0xAA, 0xAA, 0);
352 waveform->color_table->Set(WAVEFORM_COLOR_MARKER_END, "WaveformMarkerEnd", __("Color|End Marker"), 0xAA, 0, 0);
353 waveform->color_table->Set(WAVEFORM_COLOR_MARKER_KEYFRAME, "WaveformMarkerKeyframe", __("Color|Keyframe Marker"), 0xAA, 0xAA, 0xAA);
354 waveform->color_table->Set(WAVEFORM_COLOR_BACKGROUND, "WaveformBackground", __("Color|Background"), 0, 0, 0);
355 waveform->color_table->Set(WAVEFORM_COLOR_MARKER_TIME, "WaveformMarkerTime", __("Color|Time Marker"), 0, 0, 0x66);
356 waveform->color_table->Set(WAVEFORM_COLOR_MARKER_CURRENT, "WaveformMarkerCurrent", __("Color|Play Marker"), 0x33, 0xFF, 0x33);
357 waveform->color_table->Set(WAVEFORM_COLOR_TEXT, "WaveformText", __("Color|Text"), 0x55, 0xBB, 0xBB);
358 waveform->color_table->Set(WAVEFORM_COLOR_MARKER_KARAOKE, "WaveformMarkerKaraoke", __("Color|Karaoke Marker"), 0x66, 0x30, 0x66);
359 waveform->color_table->Set(WAVEFORM_COLOR_SCRUB_BAR_SEPARATOR, "WaveformScrubBarSeparator", __("Color|Scrub Bar Separator"), 0xFF, 0xFF, 0xFF);
360 waveform->color_table->Set(WAVEFORM_COLOR_SCRUB_BAR_SLIDER, "WaveformScrubBarSlider", __("Color|Scrub Bar Slider"), 0x00, 0x44, 0xFF);
361 waveform->color_table->Set(WAVEFORM_COLOR_SCRUB_BAR_EXTENSION, "WaveformScrubBarExtension", __("Color|Scrub Bar Extension"), 0x00, 0x88, 0x00);
362 waveform->signal_color_change =
363 waveform->color_table->ConnectSignal(kryColorTable::SIGNAL_COLOR_CHANGED, (krySignalFunc1) kry_waveform_color_changed, waveform);
364
365 #ifdef _WINDOWS
366 for(int i = 0; i < WAVEFORM_COLOR_COUNT; i++)
367 {
368 kryColor *color = waveform->color_table->Get(i);
369 if(color->IsInitialized())
370 {
371 HPEN pen = CreatePen(PS_SOLID, 1, RGB(color->GetRed(), color->GetGreen(), color->GetBlue()));
372 color->SetUserData(pen);
373 }
374 }
375 #else
376 for(int i = 0; i < WAVEFORM_COLOR_COUNT; i++)
377 {
378 kryColor *color = waveform->color_table->Get(i);
379
380 if(color->IsInitialized())
381 {
382 GdkColor *color_gdk = kry_new0(GdkColor);
383
384 color_gdk->red = color->GetRed() * 257;
385 color_gdk->green = color->GetGreen() * 257;
386 color_gdk->blue = color->GetBlue() * 257;
387
388 gdk_rgb_find_color(gtk_widget_get_colormap(GTK_WIDGET(waveform)), color_gdk);
389
390 color->SetUserData(color_gdk);
391 }
392 }
393 #endif
394 }
395
396 #ifdef _WINDOWS
397 kryColor *background = waveform->color_table->Get(WAVEFORM_COLOR_BACKGROUND);
398 waveform->black_brush = CreateSolidBrush(RGB(background->GetRed(), background->GetGreen(), background->GetBlue()));
399
400 waveform->cursor_normal = LoadCursor(NULL, IDC_ARROW);
401 waveform->cursor_drag = LoadCursor(NULL, IDC_SIZEWE);
402 #else
403 waveform->cursor_drag = gdk_cursor_new(GDK_SB_H_DOUBLE_ARROW);
404 waveform->layout = PANGO_LAYOUT(gtk_widget_create_pango_layout(GTK_WIDGET(waveform), NULL));
405 PangoFontDescription *desc = pango_font_description_from_string("Arial 10");
406 pango_layout_set_font_description(waveform->layout, desc);
407 #endif
408
409
410 waveform->data_info = info;
411
412 if(adjustment)
413 kry_waveform_set_adjustment(waveform, adjustment);
414
415 g_object_set(waveform, "can-focus", TRUE, NULL);
416 gtk_widget_set_double_buffered(GTK_WIDGET(waveform), FALSE);
417
418 return GTK_WIDGET (waveform);
419 }
420
kry_waveform_destroy_graphics(KryWaveform * waveform)421 static void kry_waveform_destroy_graphics(KryWaveform *waveform)
422 {
423 #ifdef _WINDOWS
424 if(waveform->bitmap_backbuffer_waveonly)
425 {
426 if(!DeleteObject(waveform->bitmap_backbuffer_waveonly))
427 g_warning("failed to delete backbuffer bitmap");
428
429 waveform->bitmap_backbuffer_waveonly = NULL;
430 }
431
432 if(waveform->backbuffer_waveonly)
433 {
434 if(!DeleteDC(waveform->backbuffer_waveonly))
435 g_warning("failed to delete backbuffer");
436
437 waveform->backbuffer_waveonly = NULL;
438 }
439
440 if(waveform->bitmap_backbuffer_final)
441 {
442 if(!DeleteObject(waveform->bitmap_backbuffer_final))
443 g_warning("failed to delete backbuffer copy bitmap");
444
445 waveform->bitmap_backbuffer_final = NULL;
446 }
447
448 if(waveform->backbuffer_final)
449 {
450 if(!DeleteDC(waveform->backbuffer_final))
451 g_warning("failed to delete backbuffer copy");
452
453 waveform->backbuffer_final = NULL;
454 }
455
456 if(waveform->dc)
457 {
458 ReleaseDC(HWND(GDK_WINDOW_HWND(GTK_WIDGET(waveform)->window)), waveform->dc);
459 waveform->dc = NULL;
460 }
461
462 if(waveform->font)
463 {
464 if(!DeleteObject(waveform->font))
465 g_warning("failed to delete font");
466
467 waveform->font = NULL;
468 }
469
470 #else
471 if(waveform->backbuffer_waveonly)
472 {
473 g_object_unref(waveform->backbuffer_waveonly);
474 waveform->backbuffer_waveonly = NULL;
475 }
476
477 if(waveform->backbuffer_final)
478 {
479 g_object_unref(waveform->backbuffer_final);
480 waveform->backbuffer_final = NULL;
481 }
482
483 if(waveform->gc)
484 {
485 g_object_unref(waveform->gc);
486 waveform->gc = NULL;
487 }
488 #endif
489 }
490
kry_waveform_destroy(GtkObject * object)491 static void kry_waveform_destroy(GtkObject *object)
492 {
493 KryWaveform *waveform;
494
495 g_return_if_fail (object != NULL);
496 g_return_if_fail (KRY_IS_WAVEFORM (object));
497
498 waveform = KRY_WAVEFORM (object);
499
500 if (GTK_OBJECT_CLASS (parent_class)->destroy)
501 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
502
503
504 if(waveform->adjustment)
505 {
506 g_signal_handlers_disconnect_by_func(waveform->adjustment, (void *) kry_waveform_adjustment_value_changed, waveform);
507 g_object_unref(waveform->adjustment);
508 waveform->adjustment = NULL;
509 }
510
511 //if(waveform->mutex_markers)
512 //{
513 kry_waveform_marker_remove_all(waveform);
514
515 if(waveform->region_list)
516 {
517 kry_waveform_region_remove_all(waveform);
518 waveform->region_list = NULL;
519 }
520
521 // g_mutex_free(waveform->mutex_markers);
522 // waveform->mutex_markers = NULL;
523 //}
524
525 kry_waveform_destroy_graphics(waveform);
526
527 #ifdef _WINDOWS
528 int i;
529
530 if(waveform->color_table)
531 {
532 waveform->color_table->DisconnectSignal(kryColorTable::SIGNAL_COLOR_CHANGED, waveform->signal_color_change);
533 if(waveform->color_table->GetRefCount() == 1)
534 {
535 for(i = 0; i < WAVEFORM_COLOR_COUNT; i++)
536 {
537 if(waveform->color_table->GetUserData(i) != NULL)
538 {
539 DeleteObject(waveform->color_table->GetUserData(i));
540 waveform->color_table->SetUserData(i, NULL);
541 }
542 }
543
544 delete waveform->color_table;
545 }
546 else
547 {
548 waveform->color_table->Unref();
549 }
550
551 waveform->color_table = NULL;
552 }
553
554 if(waveform->black_brush)
555 {
556 DeleteObject(waveform->black_brush);
557 waveform->black_brush = NULL;
558 }
559 #else
560 if(waveform->layout)
561 {
562 g_object_unref(waveform->layout);
563 waveform->layout = NULL;
564 }
565 #endif
566 kry_waveform_data_thread_end(waveform);
567 if(waveform->data_pixel)
568 {
569 kry_free(waveform->data_pixel);
570 waveform->data_pixel = NULL;
571 }
572
573 if(waveform->data_time)
574 {
575 kry_free(waveform->data_time);
576 waveform->data_time = NULL;
577 }
578
579 kry_waveform_region_fixed_list_set(waveform, NULL);
580 }
581
582
583 GtkAdjustment*
kry_waveform_get_adjustment(KryWaveform * waveform)584 kry_waveform_get_adjustment (KryWaveform *waveform)
585 {
586 g_return_val_if_fail (waveform != NULL, NULL);
587 g_return_val_if_fail (KRY_IS_WAVEFORM (waveform), NULL);
588
589 return waveform->adjustment;
590 }
591
kry_waveform_marker_redraw_at_time(KryWaveform * waveform,long time_mili,gboolean no_update=FALSE)592 void kry_waveform_marker_redraw_at_time(KryWaveform *waveform, long time_mili, gboolean no_update = FALSE)
593 {
594 if(time_mili == -1 || waveform->data_info == NULL)
595 return;
596
597 int start = kry_waveform_rel_pixel_from_mili(waveform, time_mili);
598 int width = waveform->marker_width + waveform->corner_width;
599
600 kry_waveform_redraw_partial(waveform, start, width, FALSE, !no_update);
601 }
602
kry_waveform_marker_changed_cb(KryMarker * marker,int old_position,KryWaveform * waveform)603 void kry_waveform_marker_changed_cb(KryMarker *marker, int old_position, KryWaveform *waveform)
604 {
605 g_return_if_fail (waveform != NULL);
606 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
607
608 if(!waveform->data_info)
609 return;
610
611 if(g_object_get_data(G_OBJECT(marker), "highlight"))
612 return;
613
614 int pos1 = kry_waveform_rel_pixel_from_mili(waveform, kry_marker_get_value(marker));
615 int pos2 = kry_waveform_rel_pixel_from_mili(waveform, old_position);
616 int width = waveform->marker_width + 10;
617
618 kry_waveform_redraw_partial(waveform, pos1, width, FALSE, FALSE);
619 kry_waveform_redraw_partial(waveform, pos2, width, FALSE, FALSE);
620
621 kry_waveform_update_front_buffer_fast(waveform, pos1, width);
622 kry_waveform_update_front_buffer_fast(waveform, pos2, width);
623
624 if(waveform->marker_autoscroll == marker)
625 {
626 if((pos1 * 100) / GTK_WIDGET(waveform)->allocation.width > 90)
627 {
628 int page_increment = (int) waveform->adjustment->page_increment;
629 int val = (int) (gtk_adjustment_get_value(waveform->adjustment) + page_increment);
630 gtk_adjustment_set_value(waveform->adjustment, val);
631 }
632 }
633 }
634
kry_waveform_highlight_marker_changed(KryMarker * marker,long old_position,KryWaveform * waveform)635 void kry_waveform_highlight_marker_changed(KryMarker *marker, long old_position, KryWaveform *waveform)
636 {
637 GtkWidget *widget;
638 int start_pixel, end_pixel;
639
640 g_return_if_fail (waveform != NULL);
641 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
642
643 if(waveform->data_info == NULL)
644 return;
645
646 if(old_position == -1)
647 {
648 kry_waveform_redraw(waveform);
649 return;
650 }
651
652 if(kry_marker_get_value(marker) == -1)
653 start_pixel = 0;
654 else
655 start_pixel = kry_waveform_rel_pixel_from_mili(waveform, kry_marker_get_value(marker));
656
657 if(old_position == -1)
658 end_pixel = 0;
659 else
660 end_pixel = kry_waveform_rel_pixel_from_mili(waveform, old_position);
661
662 if(start_pixel > end_pixel)
663 {
664 int tmp = start_pixel;
665 start_pixel = end_pixel;
666 end_pixel = tmp;
667 }
668
669 widget = GTK_WIDGET(waveform);
670 if(start_pixel + waveform->marker_width + waveform->corner_width < 0 && end_pixel + waveform->marker_width + waveform->corner_width < 0
671 || start_pixel > widget->allocation.width && end_pixel > widget->allocation.width)
672 {
673 return;
674 }
675
676 if(start_pixel < 0)
677 start_pixel = 0;
678
679 if(end_pixel >= widget->allocation.width)
680 end_pixel = widget->allocation.width - 1;
681
682 kry_waveform_redraw_partial(waveform,
683 start_pixel - waveform->corner_width,
684 end_pixel + waveform->marker_width + waveform->corner_width * 2 - start_pixel, FALSE, TRUE);
685 }
686
kry_waveform_region_add_new(KryWaveform * waveform,KryMarker * marker_left,KryMarker * marker_right,int color_id)687 void kry_waveform_region_add_new(KryWaveform *waveform, KryMarker *marker_left, KryMarker *marker_right, int color_id)
688 {
689 g_return_if_fail (waveform != NULL);
690 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
691
692 KryRegion *region = KRY_REGION(kry_region_new(marker_left, marker_right, color_id));
693 kry_waveform_region_add(waveform, region);
694 }
695
kry_waveform_region_add(KryWaveform * waveform,KryRegion * region)696 void kry_waveform_region_add(KryWaveform *waveform, KryRegion *region)
697 {
698 g_return_if_fail (waveform != NULL);
699 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
700
701 g_object_ref(region);
702
703 int color_id = kry_region_get_colorid(region);
704 if(color_id != -1)
705 {
706 g_object_set_data(G_OBJECT(kry_region_get_marker_start(region)), "highlight", (gpointer) TRUE);
707 g_object_set_data(G_OBJECT(kry_region_get_marker_end(region)), "highlight", (gpointer) TRUE);
708
709 g_signal_connect(kry_region_get_marker_start(region), "value-changed", G_CALLBACK(kry_waveform_highlight_marker_changed), waveform);
710 g_signal_connect(kry_region_get_marker_end(region), "value-changed", G_CALLBACK(kry_waveform_highlight_marker_changed), waveform);
711 }
712
713 waveform->region_list = g_list_append(waveform->region_list, region);
714
715 if(color_id != -1 && waveform->data_info)
716 {
717 KryMarker *m1 = kry_region_get_marker_start(region);
718 KryMarker *m2 = kry_region_get_marker_end(region);
719 int px1 = kry_waveform_rel_pixel_from_mili(waveform, kry_marker_get_value(m1));
720 int px2 = kry_waveform_rel_pixel_from_mili(waveform, kry_marker_get_value(m2));
721
722 if(px1 <= GTK_WIDGET(waveform)->allocation.width - 1 && px2 >= 0 && px1 <= px2)
723 kry_waveform_redraw_partial(waveform, px1, px2 + waveform->marker_width - 1, FALSE, TRUE);
724 }
725 }
726
kry_waveform_region_fixed_added_cb(KryRegionFixedList * list,KryRegionFixed * region,KryWaveform * waveform)727 static void kry_waveform_region_fixed_added_cb(KryRegionFixedList *list, KryRegionFixed *region, KryWaveform *waveform)
728 {
729 g_return_if_fail (waveform != NULL);
730 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
731
732
733 if(!waveform->data_info)
734 return;
735
736 if(pavl_count(waveform->region_fixed_list->tree) == 1)
737 pavl_t_first(&waveform->region_fixed_list_iter, waveform->region_fixed_list->tree);
738
739 int px1 = kry_waveform_rel_pixel_from_mili(waveform, region->start);
740 int px2 = kry_waveform_rel_pixel_from_mili(waveform, region->end);
741
742 if(px1 <= GTK_WIDGET(waveform)->allocation.width - 1 && px2 >= 0 && px1 <= px2)
743 {
744 struct KryRegionFixedInfo *info = (struct KryRegionFixedInfo *) pavl_t_cur(&waveform->region_fixed_list_iter);
745 if(info)
746 {
747 struct KryRegionFixed *region_cur = (struct KryRegionFixed *) info->regions->data;
748 if(region_cur->start > region->start)
749 pavl_t_prev(&waveform->region_fixed_list_iter);
750 };
751 kry_waveform_redraw_partial(waveform, px1, px2 + waveform->marker_width - 1, FALSE, TRUE);
752 }
753 }
754
kry_waveform_region_fixed_removed_cb(KryRegionFixedList * list,KryRegionFixed * region,KryWaveform * waveform)755 static void kry_waveform_region_fixed_removed_cb(KryRegionFixedList *list, KryRegionFixed *region, KryWaveform *waveform)
756 {
757 g_return_if_fail (waveform != NULL);
758 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
759
760 if(!waveform->data_info)
761 return;
762
763 pavl_t_first(&waveform->region_fixed_list_iter, waveform->region_fixed_list->tree);
764 kry_waveform_find_first_region(waveform, FALSE);
765
766 int px1 = kry_waveform_rel_pixel_from_mili(waveform, region->start);
767 int px2 = kry_waveform_rel_pixel_from_mili(waveform, region->end);
768
769 if(px1 <= GTK_WIDGET(waveform)->allocation.width - 1 && px2 >= 0 && px1 <= px2)
770 kry_waveform_redraw_partial(waveform, px1, px2 + waveform->marker_width - 1, FALSE, TRUE);
771 }
772
kry_waveform_region_fixed_list_set(KryWaveform * waveform,KryRegionFixedList * list)773 void kry_waveform_region_fixed_list_set(KryWaveform *waveform, KryRegionFixedList *list)
774 {
775 g_return_if_fail (waveform != NULL);
776 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
777
778 if(waveform->region_fixed_list)
779 {
780 g_signal_handlers_disconnect_by_func(waveform->region_fixed_list, (void *) kry_waveform_region_fixed_added_cb, waveform);
781 g_signal_handlers_disconnect_by_func(waveform->region_fixed_list, (void *) kry_waveform_region_fixed_removed_cb, waveform);
782
783 waveform->region_fixed_list = NULL;
784 }
785
786 if(list)
787 {
788 waveform->region_fixed_list = list;
789 pavl_t_first(&waveform->region_fixed_list_iter, waveform->region_fixed_list->tree);
790
791 g_signal_connect(list, "region-added", (GCallback) kry_waveform_region_fixed_added_cb, waveform);
792 g_signal_connect(list, "region-removed", (GCallback) kry_waveform_region_fixed_removed_cb, waveform);
793 }
794
795 kry_waveform_redraw(waveform);
796 }
797
798
kry_waveform_region_remove_by_type(KryWaveform * waveform,int color_id)799 void kry_waveform_region_remove_by_type(KryWaveform *waveform, int color_id)
800 {
801 GList *ptr_next;
802 g_return_if_fail (waveform != NULL);
803 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
804
805 for(GList *ptr = waveform->region_list; ptr; ptr = ptr_next)
806 {
807 ptr_next = ptr->next;
808
809 KryRegion *region = (KryRegion *) ptr->data;
810 if(color_id != -1 && kry_region_get_colorid(region) != color_id)
811 continue;
812
813 g_signal_handlers_disconnect_by_func(kry_region_get_marker_start(region), (void *) kry_waveform_highlight_marker_changed, waveform);
814 g_signal_handlers_disconnect_by_func(kry_region_get_marker_end(region), (void *) kry_waveform_highlight_marker_changed, waveform);
815
816 g_object_set_data(G_OBJECT(kry_region_get_marker_start(region)), "highlight", (gpointer) FALSE);
817 g_object_set_data(G_OBJECT(kry_region_get_marker_end(region)), "highlight", (gpointer) FALSE);
818
819 waveform->region_list = g_list_remove(waveform->region_list, region);
820 g_object_unref(G_OBJECT(region));
821 }
822 }
823
kry_waveform_region_remove_all(KryWaveform * waveform)824 void kry_waveform_region_remove_all(KryWaveform *waveform)
825 {
826 kry_waveform_region_remove_by_type(waveform, -1);
827 }
828
kry_waveform_marker_add(KryWaveform * waveform,KryMarker * marker)829 void kry_waveform_marker_add(KryWaveform *waveform, KryMarker *marker)
830 {
831 g_return_if_fail (waveform != NULL);
832 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
833
834 struct KryWaveformMarkerInfo *marker_info = kry_new(struct KryWaveformMarkerInfo, 1);
835 marker_info->marker = marker;
836
837 //g_mutex_lock(waveform->mutex_markers);
838 waveform->markers = g_list_append(waveform->markers, marker_info);
839 g_signal_connect(marker, "value-changed", G_CALLBACK(kry_waveform_marker_changed_cb), waveform);
840
841 // this forces the marker area to be redrawn
842 kry_waveform_marker_redraw_at_time(waveform, kry_marker_get_value(marker));
843 //g_mutex_unlock(waveform->mutex_markers);
844 }
845
kry_waveform_marker_hide(KryWaveform * waveform,KryMarker * marker)846 void kry_waveform_marker_hide(KryWaveform *waveform, KryMarker *marker)
847 {
848 g_return_if_fail (waveform != NULL);
849 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
850
851 g_object_set_data(G_OBJECT(marker), "hidden", (gpointer) 1);
852
853 kry_waveform_marker_redraw_at_time(waveform, kry_marker_get_value(marker));
854 }
855
856
kry_waveform_marker_show(KryWaveform * waveform,KryMarker * marker)857 void kry_waveform_marker_show(KryWaveform *waveform, KryMarker *marker)
858 {
859 g_return_if_fail (waveform != NULL);
860 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
861
862 g_object_set_data(G_OBJECT(marker), "hidden", 0);
863
864 kry_waveform_marker_redraw_at_time(waveform, kry_marker_get_value(marker));
865 }
866
kry_waveform_marker_remove_internal(KryWaveform * waveform,KryMarker * marker_match,enum marker_type type,gboolean remove_all)867 static void kry_waveform_marker_remove_internal(KryWaveform *waveform, KryMarker *marker_match, enum marker_type type, gboolean remove_all)
868 {
869 GList *ptr;
870 GList *next = NULL;
871 g_return_if_fail (waveform != NULL);
872 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
873
874 //g_mutex_lock(waveform->mutex_markers);
875 for(ptr = waveform->markers; ptr; ptr = next)
876 {
877 struct KryWaveformMarkerInfo *info = (struct KryWaveformMarkerInfo *) ptr->data;
878 KryMarker *marker = info->marker;
879 next = ptr->next;
880 if(marker_match && marker == marker_match || kry_marker_get_marker_type(marker) == type || remove_all)
881 {
882 if(waveform->marker_active_start == marker)
883 kry_waveform_marker_set_active_start(waveform, NULL);
884
885 if(waveform->marker_active_end == marker)
886 kry_waveform_marker_set_active_end(waveform, NULL);
887
888 g_signal_handlers_disconnect_by_func(marker, (void *) kry_waveform_marker_changed_cb, waveform);
889 waveform->markers = g_list_delete_link(waveform->markers, ptr);
890
891 kry_waveform_marker_redraw_at_time(waveform, kry_marker_get_value(marker));
892 }
893 }
894 //g_mutex_unlock(waveform->mutex_markers);
895 }
896
kry_waveform_marker_remove_by_type(KryWaveform * waveform,enum marker_type type)897 void kry_waveform_marker_remove_by_type(KryWaveform *waveform, enum marker_type type)
898 {
899 kry_waveform_marker_remove_internal(waveform, NULL, type, FALSE);
900 }
901
kry_waveform_marker_remove(KryWaveform * waveform,KryMarker * marker)902 void kry_waveform_marker_remove(KryWaveform *waveform, KryMarker *marker)
903 {
904 kry_waveform_marker_remove_internal(waveform, marker, (enum marker_type) 0, FALSE);
905 }
906
kry_waveform_marker_remove_all(KryWaveform * waveform)907 void kry_waveform_marker_remove_all(KryWaveform *waveform)
908 {
909 kry_waveform_marker_remove_internal(waveform, NULL, (enum marker_type) 0, TRUE);
910 }
911
kry_waveform_marker_set_autoscroll(KryWaveform * waveform,KryMarker * marker)912 void kry_waveform_marker_set_autoscroll(KryWaveform *waveform, KryMarker *marker)
913 {
914 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
915
916 waveform->marker_autoscroll = marker;
917 }
918
kry_waveform_get_show_time_bar(KryWaveform * waveform)919 gboolean kry_waveform_get_show_time_bar(KryWaveform *waveform)
920 {
921 g_return_val_if_fail (waveform != NULL, FALSE);
922 g_return_val_if_fail (KRY_IS_WAVEFORM (waveform), FALSE);
923
924 return waveform->show_time_bar;
925 }
926
kry_waveform_get_show_keyframes(KryWaveform * waveform)927 gboolean kry_waveform_get_show_keyframes(KryWaveform *waveform)
928 {
929 g_return_val_if_fail (waveform != NULL, FALSE);
930 g_return_val_if_fail (KRY_IS_WAVEFORM (waveform), FALSE);
931
932 return waveform->show_keyframe;
933 }
934
kry_waveform_set_show_scrub_bar(KryWaveform * waveform,gboolean val)935 void kry_waveform_set_show_scrub_bar(KryWaveform *waveform, gboolean val)
936 {
937 g_return_if_fail (waveform != NULL);
938 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
939
940 if(waveform->show_scrub_bar == val)
941 return;
942
943 if(val)
944 waveform->scrub_bar_height = waveform->scrub_bar_height_real;
945 else
946 waveform->scrub_bar_height = 0;
947
948 waveform->wave_height = GTK_WIDGET(waveform)->allocation.height - waveform->time_bar_height - waveform->scrub_bar_height;
949 waveform->show_scrub_bar = val;
950
951 kry_waveform_redraw(waveform);
952 }
953
kry_waveform_set_show_time_bar(KryWaveform * waveform,gboolean val)954 void kry_waveform_set_show_time_bar(KryWaveform *waveform, gboolean val)
955 {
956 g_return_if_fail (waveform != NULL);
957 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
958
959 if(waveform->show_time_bar == val)
960 return;
961
962 if(val)
963 waveform->time_bar_height = waveform->time_bar_height_real;
964 else
965 waveform->time_bar_height = 0;
966
967 waveform->wave_height = GTK_WIDGET(waveform)->allocation.height - waveform->time_bar_height - waveform->scrub_bar_height;
968 waveform->show_time_bar = val;
969
970 kry_waveform_redraw(waveform);
971 }
972
kry_waveform_set_show_time_markers(KryWaveform * waveform,gboolean val)973 void kry_waveform_set_show_time_markers(KryWaveform *waveform, gboolean val)
974 {
975 g_return_if_fail (waveform != NULL);
976 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
977
978 if(waveform->show_time_markers == val)
979 return;
980
981 waveform->show_time_markers = val;
982
983 kry_waveform_redraw(waveform);
984 }
985
kry_waveform_set_show_keyframes(KryWaveform * waveform,gboolean val)986 void kry_waveform_set_show_keyframes(KryWaveform *waveform, gboolean val)
987 {
988 g_return_if_fail (waveform != NULL);
989 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
990
991 waveform->show_keyframe = val;
992
993 kry_waveform_redraw(waveform);
994 }
995
kry_waveform_set_adjustment(KryWaveform * waveform,GtkAdjustment * adjustment)996 void kry_waveform_set_adjustment (KryWaveform *waveform, GtkAdjustment *adjustment)
997 {
998 g_return_if_fail (waveform != NULL);
999 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
1000
1001 if(waveform->adjustment)
1002 {
1003 g_signal_handlers_disconnect_by_func(waveform->adjustment, (void *) kry_waveform_adjustment_value_changed, waveform);
1004 g_object_unref (GTK_OBJECT (waveform->adjustment));
1005 }
1006
1007 waveform->adjustment = adjustment;
1008 g_object_ref(adjustment);
1009 gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
1010 (GtkSignalFunc) kry_waveform_adjustment_value_changed,
1011 (gpointer) waveform);
1012
1013 kry_waveform_adjustment_value_changed(adjustment, waveform);
1014 }
1015
1016 static void
kry_waveform_realize(GtkWidget * widget)1017 kry_waveform_realize (GtkWidget *widget)
1018 {
1019 KryWaveform *waveform;
1020 GdkWindowAttr attributes;
1021 gint attributes_mask;
1022
1023 g_return_if_fail (widget != NULL);
1024 g_return_if_fail (KRY_IS_WAVEFORM (widget));
1025
1026 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
1027 waveform = KRY_WAVEFORM (widget);
1028
1029 attributes.x = widget->allocation.x;
1030 attributes.y = widget->allocation.y;
1031 attributes.width = widget->allocation.width;
1032 attributes.height = widget->allocation.height;
1033 attributes.wclass = GDK_INPUT_OUTPUT;
1034 attributes.window_type = GDK_WINDOW_CHILD;
1035 attributes.event_mask = gtk_widget_get_events (widget) |
1036 GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |
1037 GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK;
1038 attributes.visual = gtk_widget_get_visual (widget);
1039 attributes.colormap = gtk_widget_get_colormap (widget);
1040
1041 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
1042 widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
1043
1044 #ifdef _WINDOWS
1045 waveform->dc = GetDC(HWND(GDK_WINDOW_HWND(widget->window)));
1046 #else
1047 waveform->gc = gdk_gc_new(widget->window);
1048 #endif
1049
1050 widget->style = gtk_style_attach (widget->style, widget->window);
1051
1052 gdk_window_set_user_data (widget->window, widget);
1053
1054 gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
1055
1056 if(!waveform->backbuffer_waveonly)
1057 kry_waveform_size_allocate(widget, &widget->allocation);
1058 }
1059
1060 static void
kry_waveform_size_request(GtkWidget * widget,GtkRequisition * requisition)1061 kry_waveform_size_request (GtkWidget *widget,
1062 GtkRequisition *requisition)
1063 {
1064 requisition->width = 200;
1065 requisition->height = 80;
1066 }
1067
1068
1069
1070
kry_waveform_update_adjustment(KryWaveform * waveform)1071 void kry_waveform_update_adjustment(KryWaveform *waveform)
1072 {
1073 g_return_if_fail (waveform != NULL);
1074 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
1075
1076 waveform->adjustment->step_increment = ((GTK_WIDGET(waveform)->allocation.width - 100) * waveform->data_per_pixel) / 10;
1077 waveform->adjustment->page_increment = ((GTK_WIDGET(waveform)->allocation.width - 100) * waveform->data_per_pixel);
1078 waveform->adjustment->upper =
1079 waveform->data_info->length_seconds * waveform->data_info->vals_per_sec;
1080 waveform->adjustment->page_size =
1081 (double) waveform->adjustment->upper * waveform->data_per_pixel
1082 * GTK_WIDGET(waveform)->allocation.width
1083 / (double) (waveform->data_info->length_seconds * waveform->data_info->vals_per_sec);
1084
1085 g_signal_emit_by_name(G_OBJECT(waveform->adjustment), "changed");
1086 }
1087
1088 void
kry_waveform_size_allocate(GtkWidget * widget,GtkAllocation * allocation)1089 kry_waveform_size_allocate (GtkWidget *widget,
1090 GtkAllocation *allocation)
1091 {
1092 KryWaveform *waveform;
1093
1094 g_return_if_fail (widget != NULL);
1095 g_return_if_fail (KRY_IS_WAVEFORM (widget));
1096 g_return_if_fail (allocation != NULL);
1097
1098 widget->allocation = *allocation;
1099
1100 if (GTK_WIDGET_REALIZED (widget))
1101 {
1102 #ifdef _WINDOWS
1103 LOGFONT lfont;
1104 #endif
1105 waveform = KRY_WAVEFORM (widget);
1106
1107 gdk_window_move_resize (widget->window,
1108 allocation->x, allocation->y,
1109 allocation->width, allocation->height);
1110
1111 if(waveform->adjustment && waveform->data_info)
1112 kry_waveform_update_adjustment(waveform);
1113
1114 kry_waveform_destroy_graphics(waveform);
1115 #ifdef _WINDOWS
1116 lfont.lfHeight = 14;
1117 lfont.lfWidth = 0;
1118 lfont.lfEscapement = 0;
1119 lfont.lfOrientation = 0;
1120 lfont.lfWeight = FW_NORMAL;
1121 lfont.lfItalic = 0;
1122 lfont.lfUnderline = 0;
1123 lfont.lfStrikeOut = 0;
1124 lfont.lfCharSet = ANSI_CHARSET;
1125 lfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
1126 lfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1127 // lfQuality Specifies the output quality. Use ANTIALIASED_QUALITY!
1128 lfont.lfQuality = ANTIALIASED_QUALITY;
1129 lfont.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN;
1130 lstrcpy(lfont.lfFaceName,"Arial");
1131 waveform->font = CreateFontIndirect(&lfont);
1132
1133 if(!waveform->font)
1134 g_warning("failed to create font");
1135
1136 waveform->dc = GetDC(HWND(GDK_WINDOW_HWND(GTK_WIDGET(waveform)->window)));
1137 if(!waveform->dc)
1138 g_warning("failed to obtain waveform db");
1139
1140 waveform->backbuffer_waveonly = CreateCompatibleDC(waveform->dc);
1141 if(!waveform->backbuffer_waveonly)
1142 g_warning("failed to create backbuffer");
1143
1144 waveform->backbuffer_final = CreateCompatibleDC(waveform->dc);
1145 if(!waveform->backbuffer_final)
1146 g_warning("failed to create backbuffer copy");
1147
1148 waveform->bitmap_backbuffer_waveonly = CreateCompatibleBitmap (waveform->dc, allocation->width, allocation->height);
1149 if(!waveform->bitmap_backbuffer_waveonly)
1150 g_warning("failed to create backbuffer bitmap");
1151
1152 if(!SelectObject (waveform->backbuffer_waveonly, waveform->bitmap_backbuffer_waveonly))
1153 g_warning("failed to select backbuffer bitmap");
1154
1155 waveform->bitmap_backbuffer_final = CreateCompatibleBitmap (waveform->dc, allocation->width, allocation->height);
1156 if(!waveform->bitmap_backbuffer_final)
1157 g_warning("failed to create backbuffer copy bitmap");
1158
1159 if(!SelectObject (waveform->backbuffer_final, waveform->bitmap_backbuffer_final))
1160 g_warning("failed to select backbuffer bitmap copy");
1161
1162 if(!SelectObject(waveform->backbuffer_waveonly, waveform->font))
1163 g_warning("failed to select font");
1164
1165 if(!SetBkMode(waveform->backbuffer_waveonly, TRANSPARENT))
1166 g_warning("failed to set background mode");
1167
1168
1169 TEXTMETRIC metric;
1170 GetTextMetrics(waveform->backbuffer_final, &metric);
1171 waveform->time_bar_height_real = metric.tmHeight;
1172 #else
1173 PangoContext *context = pango_layout_get_context(waveform->layout);
1174 PangoFontDescription *desc = (PangoFontDescription *) pango_layout_get_font_description(waveform->layout);
1175 PangoFontMetrics *metrics = pango_context_get_metrics(context, desc, NULL);
1176 waveform->backbuffer_waveonly = gdk_pixmap_new(widget->window, allocation->width, allocation->height, -1);
1177 waveform->backbuffer_final = gdk_pixmap_new(waveform->backbuffer_waveonly, allocation->width, allocation->height, -1);
1178 waveform->gc = gdk_gc_new(widget->window);
1179 waveform->time_bar_height_real = (pango_font_metrics_get_ascent(metrics) + pango_font_metrics_get_descent(metrics)) / PANGO_SCALE;
1180
1181 #endif
1182 if(waveform->show_time_bar)
1183 waveform->time_bar_height = waveform->time_bar_height_real;
1184
1185 waveform->wave_height = allocation->height - waveform->time_bar_height - waveform->scrub_bar_height;
1186
1187 kry_waveform_update_zoom(waveform);
1188
1189 double min_zoom = kry_waveform_get_zoom_min(waveform);
1190 if(fabs(min_zoom - waveform->min_zoom) > 0.0001)
1191 {
1192 waveform->min_zoom = min_zoom;
1193 g_signal_emit(waveform, kry_waveform_signals[MIN_ZOOM_CHANGED_SIGNAL], 0, min_zoom);
1194 }
1195
1196 kry_waveform_redraw(waveform);
1197 }
1198 }
1199
1200
1201
1202 static gboolean
kry_waveform_key_press(GtkWidget * widget,GdkEventKey * event)1203 kry_waveform_key_press( GtkWidget *widget,
1204 GdkEventKey *event )
1205 {
1206 KryWaveform *waveform;
1207
1208 g_return_val_if_fail (widget != NULL, FALSE);
1209 g_return_val_if_fail (KRY_IS_WAVEFORM (widget), FALSE);
1210 g_return_val_if_fail (event != NULL, FALSE);
1211
1212 waveform = KRY_WAVEFORM (widget);
1213
1214 return TRUE;
1215 }
1216
kry_waveform_is_over_marker(KryWaveform * waveform,KryMarker * marker,int x)1217 static gboolean kry_waveform_is_over_marker(KryWaveform *waveform, KryMarker *marker, int x)
1218 {
1219 int marker_pos = kry_waveform_rel_pixel_from_mili(waveform, kry_marker_get_value(marker));
1220
1221 if(x >= marker_pos - 3 && x <= marker_pos + 4)
1222 return TRUE;
1223 else
1224 return FALSE;
1225 }
1226
1227
1228 static gboolean
kry_waveform_button_press(GtkWidget * widget,GdkEventButton * event)1229 kry_waveform_button_press( GtkWidget *widget,
1230 GdkEventButton *event )
1231 {
1232 KryWaveform *waveform;
1233
1234 g_return_val_if_fail (widget != NULL, FALSE);
1235 g_return_val_if_fail (KRY_IS_WAVEFORM (widget), FALSE);
1236 g_return_val_if_fail (event != NULL, FALSE);
1237
1238 waveform = KRY_WAVEFORM (widget);
1239
1240 if(!waveform->data_info)
1241 return FALSE;
1242
1243 waveform->button_press = TRUE;
1244
1245 if(event->button == 2)
1246 return FALSE;
1247
1248 if(!GTK_WIDGET_HAS_FOCUS(widget))
1249 gtk_widget_grab_focus(widget);
1250
1251 if(event->y < waveform->scrub_bar_height)
1252 {
1253 if(event->x >= waveform->scrub_bar_left_ext && event->x <= waveform->scrub_bar_right_ext)
1254 {
1255 waveform->is_scrub_bar_dragging = TRUE;
1256 waveform->scrub_bar_drag_offset = (int) event->x - waveform->scrub_bar_left;
1257 }
1258
1259 return FALSE;
1260 }
1261
1262 // user clicked on the start marker
1263 if(waveform->drag_markers_enabled && waveform->marker_active_start
1264 && kry_waveform_is_over_marker(waveform, waveform->marker_active_start, (int) event->x))
1265 {
1266 waveform->marker_dragging = waveform->marker_active_start;
1267 }
1268
1269 // user clicked on the end marker
1270 if(waveform->drag_markers_enabled && !waveform->marker_dragging
1271 && waveform->marker_active_end && kry_waveform_is_over_marker(waveform, waveform->marker_active_end, (int) event->x))
1272 {
1273 waveform->marker_dragging = waveform->marker_active_end;
1274 }
1275
1276 // user didn't click on a marker (he either wants to put the start marker there, or he wants to create a selection by dragging)
1277 if(!waveform->marker_dragging && event->button == 1 && waveform->marker_active_start)
1278 {
1279 int mili = kry_waveform_mili_from_rel_pixel(waveform, (int) event->x);
1280 kry_marker_set_value(waveform->marker_active_start, mili);
1281
1282 if(waveform->drag_selection_enabled && waveform->drag_markers_enabled)
1283 {
1284 waveform->marker_dragging = waveform->marker_active_end;
1285 waveform->drag_select = TRUE;
1286 }
1287 else
1288 {
1289 waveform->marker_dragging = waveform->marker_active_start;
1290 }
1291 }
1292
1293 if(waveform->drag_markers_enabled && waveform->marker_dragging)
1294 {
1295 #ifdef _WINDOWS
1296 SetCursor(waveform->cursor_drag);
1297 #endif
1298 return FALSE;
1299 }
1300
1301 if(event->button == 3 && waveform->marker_active_end)
1302 {
1303 int mili = kry_waveform_mili_from_rel_pixel(waveform, (int) event->x);
1304 kry_marker_set_value(waveform->marker_active_end, mili);
1305
1306 if(!waveform->drag_selection_enabled || !waveform->drag_markers_enabled)
1307 waveform->marker_dragging = waveform->marker_active_end;
1308 }
1309
1310 return FALSE;
1311 }
1312
1313 static gboolean
kry_waveform_motion_notify(GtkWidget * widget,GdkEventMotion * event)1314 kry_waveform_motion_notify( GtkWidget *widget,
1315 GdkEventMotion *event )
1316 {
1317 KryWaveform *waveform;
1318
1319 g_return_val_if_fail (widget != NULL, FALSE);
1320 g_return_val_if_fail (KRY_IS_WAVEFORM (widget), FALSE);
1321 g_return_val_if_fail (event != NULL, FALSE);
1322
1323 waveform = KRY_WAVEFORM (widget);
1324
1325 if(!waveform->data_info)
1326 return FALSE;
1327
1328 if(waveform->is_scrub_bar_dragging)
1329 {
1330 int left = (int) waveform->left;
1331 if(event->x < 0)
1332 event->x = 0;
1333
1334 if(event->x >= GTK_WIDGET(waveform)->allocation.width)
1335 event->x = GTK_WIDGET(waveform)->allocation.width - 1;
1336
1337 left = (int) ((event->x - waveform->scrub_bar_drag_offset) * (((double) waveform->data_info->length_seconds * waveform->data_info->vals_per_sec) / GTK_WIDGET(waveform)->allocation.width));
1338 if(left < 0)
1339 waveform->scrub_bar_drag_offset = (int) event->x;
1340
1341 if(left >= waveform->adjustment->upper - waveform->adjustment->page_size)
1342 {
1343 left = (int) (waveform->adjustment->upper - waveform->adjustment->page_size);
1344 waveform->scrub_bar_drag_offset = waveform->scrub_bar_width - (GTK_WIDGET(waveform)->allocation.width - (int) event->x);
1345 }
1346
1347 gtk_adjustment_set_value(waveform->adjustment, left);
1348
1349 return FALSE;
1350 }
1351
1352 // in the middle of a drag operation
1353 if(waveform->marker_dragging)
1354 {
1355 // if in the middle of a "drag to create a selection" operation
1356 if(waveform->drag_select)
1357 {
1358 // don't do anything unless the pointer has moved at least 10 pixels from the original location"
1359 int oldpx = kry_waveform_rel_pixel_from_mili(waveform, kry_marker_get_value(waveform->marker_active_start));
1360 if(abs((int) event->x - oldpx) < 10)
1361 return FALSE;
1362
1363 waveform->drag_select = FALSE;
1364 }
1365
1366 int marker_pixel = (int) event->x;
1367 int marker_mili = kry_waveform_mili_from_rel_pixel(waveform, marker_pixel);
1368
1369 // if keyframes are on, see if there are any keyframes nearby
1370 if(waveform->show_keyframe)
1371 {
1372 for(int i = 0; i < waveform->keyframes_rel_count; i++)
1373 {
1374 int val = kry_waveform_rel_pixel_from_mili(waveform, waveform->keyframes_rel[i]);
1375 if(val - marker_pixel > 20)
1376 break;
1377
1378 if(abs(val - marker_pixel) <= 20)
1379 {
1380 int mili = waveform->keyframes_rel[i];
1381
1382 if(mili % 10 != 0)
1383 mili -= (mili % 10);
1384 mili -= 10;
1385
1386 marker_mili = mili;
1387 break;
1388 }
1389 }
1390 }
1391
1392 //g_warning("set value");
1393 kry_marker_set_value(waveform->marker_dragging, marker_mili);
1394 return FALSE;
1395 }
1396
1397 if(event->y < waveform->scrub_bar_height)
1398 return FALSE;
1399
1400 if(waveform->drag_markers_enabled &&
1401 (waveform->marker_active_start && kry_waveform_is_over_marker(waveform, waveform->marker_active_start, (int) event->x)
1402 ||waveform->marker_active_end && kry_waveform_is_over_marker(waveform, waveform->marker_active_end, (int) event->x)))
1403 {
1404 #ifdef _WINDOWS
1405 SetCursor(waveform->cursor_drag);
1406 #else
1407 gdk_window_set_cursor(widget->window, waveform->cursor_drag);
1408 #endif
1409 }
1410 else
1411 {
1412 #ifdef _WINDOWS
1413 SetCursor(waveform->cursor_normal);
1414 #else
1415 gdk_window_set_cursor(widget->window, NULL);
1416 #endif
1417 }
1418
1419 return FALSE;
1420 }
1421
1422
1423 /*KryMarker *kry_waveform_get_marker(KryWaveform *waveform, enum marker_type type)
1424 {
1425 GList *ptr;
1426 g_return_val_if_fail (waveform != NULL, NULL);
1427 g_return_val_if_fail (KRY_IS_WAVEFORM (waveform), NULL);
1428
1429 for(ptr = waveform->markers; ptr; ptr = ptr->next)
1430 {
1431 KryMarker *marker = KRY_MARKER(ptr->data);
1432 if(marker->type == type)
1433 return marker;
1434 }
1435
1436 return NULL;
1437 }*/
1438
kry_waveform_button_release(GtkWidget * widget,GdkEventButton * event)1439 static gboolean kry_waveform_button_release(GtkWidget *widget, GdkEventButton *event)
1440 {
1441 KryWaveform *waveform;
1442
1443 g_return_val_if_fail (widget != NULL, FALSE);
1444 g_return_val_if_fail (KRY_IS_WAVEFORM (widget), FALSE);
1445 g_return_val_if_fail (event != NULL, FALSE);
1446
1447 waveform = KRY_WAVEFORM (widget);
1448
1449 if(waveform->button_press == FALSE)
1450 return FALSE;
1451
1452 waveform->button_press = FALSE;
1453
1454 if(!waveform->data_info)
1455 return FALSE;
1456
1457 if(waveform->is_scrub_bar_dragging)
1458 waveform->is_scrub_bar_dragging = FALSE;
1459
1460 if(waveform->marker_dragging)
1461 {
1462 waveform->marker_dragging = NULL;
1463 waveform->drag_select = FALSE;
1464
1465 return FALSE;
1466 }
1467
1468 if(event->button != 2)
1469 return FALSE;
1470
1471 struct pavl_traverser iter;
1472 kry_region_fixed_list_get_iter(waveform->region_fixed_list, &iter);
1473 while(struct KryRegionFixedInfo *info = (struct KryRegionFixedInfo *) pavl_t_next(&iter))
1474 {
1475 for(GList *ptr = info->regions; ptr; ptr = ptr->next)
1476 {
1477 KryRegion *region = (KryRegion *) ptr->data;
1478
1479 int mili = kry_waveform_mili_from_rel_pixel(waveform, (int) event->x);
1480 int start_mili = kry_marker_get_value(kry_region_get_marker_start(region));
1481 int end_mili = kry_marker_get_value(kry_region_get_marker_end(region));
1482
1483 if(mili >= start_mili && mili <= end_mili)
1484 {
1485 kry_region_selected(region);
1486 break;
1487 }
1488 }
1489 }
1490
1491 return FALSE;
1492 }
1493
kry_waveform_setup_rel_keyframe_list(KryWaveform * waveform)1494 void kry_waveform_setup_rel_keyframe_list(KryWaveform *waveform)
1495 {
1496 waveform->keyframes_rel = NULL;
1497 waveform->keyframes_rel_count = 0;
1498
1499 if(!waveform->keyframe_list || !waveform->data_info)
1500 return;
1501
1502 long left_mili = (long) (((double) waveform->left / waveform->data_info->vals_per_sec) * 1000);
1503 for(int i = 0; i < waveform->keyframe_list->count; i++)
1504 {
1505 if(waveform->keyframe_list->list[i] >= left_mili)
1506 {
1507 waveform->keyframes_rel = waveform->keyframe_list->list + i;
1508 waveform->keyframes_rel_count = waveform->keyframe_list->count - i;
1509 break;
1510 }
1511 }
1512 }
1513
kry_waveform_get_keyframe_list(KryWaveform * waveform)1514 struct KryWaveformKeyframeList *kry_waveform_get_keyframe_list(KryWaveform *waveform)
1515 {
1516 g_return_val_if_fail (waveform != NULL, NULL);
1517 g_return_val_if_fail (KRY_IS_WAVEFORM (waveform), NULL);
1518
1519 return waveform->keyframe_list;
1520 }
1521
kry_waveform_set_keyframe_list(KryWaveform * waveform,KryWaveformKeyframeList * list)1522 void kry_waveform_set_keyframe_list(KryWaveform *waveform, KryWaveformKeyframeList *list)
1523 {
1524 g_return_if_fail (waveform != NULL);
1525 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
1526
1527 waveform->keyframe_list = list;
1528
1529 kry_waveform_setup_rel_keyframe_list(waveform);
1530
1531 kry_waveform_redraw(waveform);
1532 }
1533
kry_waveform_get_zoom_internal(KryWaveform * waveform)1534 double kry_waveform_get_zoom_internal(KryWaveform *waveform)
1535 {
1536 double data_per_pixel = (waveform->data_info->vals_per_sec * waveform->zoom) / GTK_WIDGET(waveform)->allocation.width;
1537
1538 return data_per_pixel;
1539 }
1540
kry_waveform_data_process_range(KryWaveform * waveform,int sec_start,int sec_end)1541 void kry_waveform_data_process_range(KryWaveform *waveform, int sec_start, int sec_end)
1542 {
1543 int j;
1544 unsigned char *wave = (unsigned char *) waveform->data_info->waveform_data;
1545
1546 int num_data = (int) waveform->data_per_pixel;
1547 if(waveform->data_per_pixel - (int) waveform->data_per_pixel > 0.01)
1548 num_data++;
1549
1550 int pixel_start = kry_waveform_abs_pixel_from_mili(waveform, sec_start * 1000);
1551 int pixel_end = kry_waveform_abs_pixel_from_mili(waveform, sec_end * 1000);
1552
1553
1554 //g_warning("px %d - %d", pixel_start, pixel_end);
1555
1556 int max_index = waveform->data_info->vals_per_sec * waveform->data_info->length_seconds * 2;
1557 int last_index = 0;
1558 for(int pixel = pixel_start; pixel < pixel_end; pixel++)
1559 {
1560 unsigned char vpos = 0, vneg = 0;
1561 int index = kry_waveform_get_index_at_abs_pixel(waveform, pixel);
1562
1563 /*if(pixel > 0 && waveform->data_per_pixel - (int) waveform->data_per_pixel > 0.01)
1564 {
1565 int prev_end_index = kry_waveform_get_index_at_rel_pixel(waveform, pixel - 1) + (num_data - 1) * 2;
1566 if(index != prev_end_index)
1567 {
1568 num_data += (index - prev_end_index) / 2;
1569 index = prev_end_index;
1570 }
1571 }*/
1572
1573 if(index + num_data * 2 >= max_index)
1574 {
1575 vpos = 0;
1576 vneg = 0;
1577
1578 //int length_mili = waveform->data_info->length_seconds * 1000;
1579 //int pixels = kry_waveform_abs_pixel_from_mili(waveform, length_mili);
1580 //memset(waveform->data_per_pixel
1581 }
1582 else
1583 {
1584 // we find the maximum positive value of the points that represent the current pixel
1585 for(j = 0; j < num_data; j++)
1586 if(wave[index + j*2] > vpos)
1587 vpos = wave[index + j*2];
1588
1589 // we find the maximum negative value of the points that represent the current pixel
1590 for(j = 0; j < num_data; j++)
1591 if(wave[index + j*2 + 1] > vneg)
1592 vneg = wave[index + j*2 + 1];
1593 }
1594
1595 int px = pixel * 2;
1596 if(px + 1 < waveform->data_pixel_length)
1597 {
1598 waveform->data_pixel[px] = vpos;
1599 waveform->data_pixel[px + 1] = vneg;
1600 }
1601 last_index = px;
1602 }
1603
1604 //g_warning("last index: %d", last_index);
1605
1606 for(int i = sec_start; i < sec_end; i++)
1607 waveform->data_time[i] = 1;
1608 }
1609
kry_waveform_data_thread(KryWaveform * waveform)1610 void kry_waveform_data_thread(KryWaveform *waveform)
1611 {
1612 g_mutex_lock(waveform->data_thread_mutex_global);
1613 for(int i = 0; i < waveform->data_info->length_seconds; i++)
1614 {
1615 g_mutex_lock(waveform->data_thread_mutex);
1616 if(waveform->data_time[i])
1617 {
1618 g_mutex_unlock(waveform->data_thread_mutex);
1619 continue;
1620 }
1621
1622 if(waveform->data_thread_quit)
1623 {
1624 g_mutex_unlock(waveform->data_thread_mutex);
1625 break;
1626 }
1627
1628 kry_waveform_data_process_range(waveform, i, i + 1);
1629
1630 g_mutex_unlock(waveform->data_thread_mutex);
1631 }
1632
1633 g_mutex_lock(waveform->data_thread_mutex);
1634 waveform->data_thread = NULL;
1635 g_mutex_unlock(waveform->data_thread_mutex);
1636 g_mutex_unlock(waveform->data_thread_mutex_global);
1637 }
1638
kry_waveform_data_ensure_available(KryWaveform * waveform,int sec_start,int sec_end)1639 void kry_waveform_data_ensure_available(KryWaveform *waveform, int sec_start, int sec_end)
1640 {
1641 g_mutex_lock(waveform->data_thread_mutex);
1642 if(sec_start >= waveform->data_info->length_seconds)
1643 return;
1644
1645 for(int i = sec_start; i < sec_end; i++)
1646 {
1647 if(waveform->data_time[i])
1648 continue;
1649
1650 kry_waveform_data_process_range(waveform, i, i + 1);
1651 }
1652 g_mutex_unlock(waveform->data_thread_mutex);
1653 }
1654
kry_waveform_data_thread_end(KryWaveform * waveform)1655 void kry_waveform_data_thread_end(KryWaveform *waveform)
1656 {
1657 g_mutex_lock(waveform->data_thread_mutex);
1658 if(waveform->data_thread)
1659 {
1660 waveform->data_thread_quit = TRUE;
1661 g_mutex_unlock(waveform->data_thread_mutex);
1662
1663 g_mutex_lock(waveform->data_thread_mutex_global);
1664 g_mutex_unlock(waveform->data_thread_mutex_global);
1665
1666 waveform->data_thread_quit = FALSE;
1667 }
1668 else
1669 {
1670 g_mutex_unlock(waveform->data_thread_mutex);
1671 }
1672 }
1673
kry_waveform_update_zoom(KryWaveform * waveform)1674 void kry_waveform_update_zoom(KryWaveform *waveform)
1675 {
1676 if(!waveform->data_info)
1677 return;
1678
1679 kry_waveform_data_thread_end(waveform);
1680
1681 if(waveform->data_pixel)
1682 kry_free(waveform->data_pixel);
1683
1684 if(waveform->data_time)
1685 kry_free(waveform->data_time);
1686
1687 waveform->data_per_pixel = kry_waveform_get_zoom_internal(waveform);
1688
1689 if(waveform->data_per_pixel < 1)
1690 waveform->data_per_pixel = 1;
1691
1692 int length_mili = waveform->data_info->length_seconds * 1000;
1693 int pixels = kry_waveform_abs_pixel_from_mili(waveform, length_mili);
1694
1695 //g_warning("allocated: %d", pixels * 2);
1696
1697 waveform->data_pixel = kry_new(char, pixels * 2);
1698 waveform->data_pixel_length = pixels * 2;
1699 waveform->data_time = kry_new0_n(char, waveform->data_info->length_seconds);
1700 waveform->data_thread = g_thread_create((GThreadFunc) kry_waveform_data_thread, waveform, TRUE, NULL);
1701
1702 if(waveform->adjustment)
1703 {
1704 kry_waveform_update_adjustment(waveform);
1705 if(waveform->adjustment->value > waveform->adjustment->upper - waveform->adjustment->page_size)
1706 {
1707 waveform->adjustment->value = waveform->adjustment->upper - waveform->adjustment->page_size;
1708 if(waveform->adjustment->value < 0)
1709 waveform->adjustment->value = 0;
1710
1711
1712 g_signal_emit_by_name(G_OBJECT(waveform->adjustment), "value-changed");
1713 }
1714 }
1715 }
1716
kry_waveform_set_zoom(KryWaveform * waveform,double factor)1717 void kry_waveform_set_zoom(KryWaveform *waveform, double factor)
1718 {
1719 g_return_if_fail (waveform != NULL);
1720 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
1721
1722 if(fabs(factor - kry_waveform_get_zoom(waveform)) < 0.0001)
1723 return;
1724
1725 waveform->zoom = factor;
1726
1727 g_signal_emit (waveform, kry_waveform_signals[ZOOM_CHANGED_SIGNAL], 0, factor);
1728
1729 kry_waveform_update_zoom(waveform);
1730 kry_waveform_redraw(waveform);
1731 }
1732
kry_waveform_get_zoom_min(KryWaveform * waveform)1733 double kry_waveform_get_zoom_min(KryWaveform *waveform)
1734 {
1735 g_return_val_if_fail (waveform != NULL, 1);
1736 g_return_val_if_fail (KRY_IS_WAVEFORM (waveform), 1);
1737
1738 if(!waveform->data_info)
1739 return 1;
1740
1741 double width = GTK_WIDGET(waveform)->allocation.width;
1742 return (width / waveform->data_info->vals_per_sec);
1743 }
1744
kry_waveform_get_zoom_max(KryWaveform * waveform)1745 double kry_waveform_get_zoom_max(KryWaveform *waveform)
1746 {
1747 g_return_val_if_fail (waveform != NULL, 1);
1748 g_return_val_if_fail (KRY_IS_WAVEFORM (waveform), 1);
1749
1750 if(!waveform->data_info)
1751 return 1;
1752
1753 return waveform->data_info->length_seconds;
1754 }
1755
kry_waveform_get_zoom(KryWaveform * waveform)1756 double kry_waveform_get_zoom(KryWaveform *waveform)
1757 {
1758 g_return_val_if_fail (waveform != NULL, 1);
1759 g_return_val_if_fail (KRY_IS_WAVEFORM (waveform), 1);
1760
1761 if(!waveform->data_info)
1762 return 1;
1763
1764 return waveform->zoom;
1765 }
1766
kry_waveform_focus_selected(KryWaveform * waveform)1767 void kry_waveform_focus_selected(KryWaveform *waveform)
1768 {
1769 double selection_length = 0, window_length = 0;
1770 long start = 0, end = 0;
1771 long start_val = 0;
1772 long end_val = 0;
1773
1774 g_return_if_fail (waveform != NULL);
1775 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
1776
1777 if(!waveform->data_info)
1778 return;
1779
1780 KryMarker *marker_start = waveform->marker_active_start;
1781 KryMarker *marker_end = waveform->marker_active_end;
1782
1783 if(marker_start)
1784 start_val = kry_marker_get_value(marker_start);
1785
1786 if(marker_end)
1787 end_val = kry_marker_get_value(marker_end);
1788
1789 if(!marker_start || !marker_end
1790 || (start_val == -1 && end_val == -1))
1791 return;
1792
1793 if(start_val != -1)
1794 start = (long) ((kry_marker_get_value(marker_start) / 1000.0) * waveform->data_info->vals_per_sec);
1795
1796 if(end_val != -1)
1797 end = (long) ((kry_marker_get_value(marker_end) / 1000.0) * waveform->data_info->vals_per_sec);
1798
1799 if(start_val != -1 && end_val != -1)
1800 {
1801 selection_length = ((double) end - start) / waveform->data_info->vals_per_sec;
1802 window_length = (double) (GTK_WIDGET(waveform)->allocation.width * waveform->data_per_pixel) / (waveform->data_info->vals_per_sec);
1803 }
1804 // can the selected region fit in weveform?
1805 if(selection_length < window_length && start_val != -1 && end_val != -1)
1806 {
1807 double left = (GTK_WIDGET(waveform)->allocation.width - ((end - start) / (double) waveform->data_per_pixel)) / 2.0;
1808 if(left < 250)
1809 left = 250;
1810
1811 left *= waveform->data_per_pixel;
1812 waveform->adjustment->value = start - left;
1813
1814 }
1815 else
1816 {
1817 if(start_val == -1)
1818 waveform->adjustment->value = end - (250 * waveform->data_per_pixel);
1819 else
1820 waveform->adjustment->value = start - (250 * waveform->data_per_pixel);
1821 }
1822
1823 if(waveform->adjustment->value < 0)
1824 waveform->adjustment->value = 0;
1825
1826 if(waveform->adjustment->value > waveform->adjustment->upper - waveform->adjustment->page_size)
1827 waveform->adjustment->value = waveform->adjustment->upper - waveform->adjustment->page_size;
1828
1829 g_signal_emit_by_name(G_OBJECT(waveform->adjustment), "value-changed");
1830 }
1831
1832
1833 /*struct sound_info *kry_waveform_get_sound_info(KryWaveform *widget)
1834 {
1835 KryWaveform *waveform;
1836
1837 g_return_val_if_fail (widget != NULL, FALSE);
1838 g_return_val_if_fail (KRY_IS_WAVEFORM (widget), FALSE);
1839
1840 waveform = KRY_WAVEFORM (widget);
1841
1842 return waveform->data_info;
1843 }*/
1844
1845 /*void kry_waveform_set_data(KryWaveform *waveform, struct sound_info *sound_info)
1846 {
1847 g_return_if_fail (waveform != NULL);
1848 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
1849
1850 waveform->sound_info = sound_info;
1851 }*/
1852
1853 /*void kry_waveform_set_channel(KryWaveform *waveform, int channel)
1854 {
1855 g_return_if_fail (waveform != NULL);
1856 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
1857
1858 waveform->channel = channel;
1859 }*/
1860
kry_waveform_get_scale(KryWaveform * waveform)1861 double kry_waveform_get_scale(KryWaveform *waveform)
1862 {
1863 g_return_val_if_fail (waveform != NULL, 1);
1864 g_return_val_if_fail (KRY_IS_WAVEFORM (waveform), 1);
1865
1866 return waveform->scale;
1867 }
1868
kry_waveform_set_scale(KryWaveform * waveform,int value)1869 void kry_waveform_set_scale(KryWaveform *waveform, int value)
1870 {
1871 g_return_if_fail (waveform != NULL);
1872 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
1873
1874 double scale_val = value / 100.0;
1875 if(fabs(scale_val - waveform->scale) < 0.0001)
1876 return;
1877
1878 waveform->scale = scale_val;
1879
1880 g_signal_emit (waveform, kry_waveform_signals[SCALE_CHANGED_SIGNAL], 0, value);
1881
1882 kry_waveform_redraw(waveform);
1883 }
1884
kry_waveform_find_first_region(KryWaveform * waveform,gboolean backward)1885 static void kry_waveform_find_first_region(KryWaveform *waveform, gboolean backward)
1886 {
1887 int counter = 0;
1888 gboolean found = FALSE;
1889 while(!found)
1890 {
1891
1892 struct KryRegionFixedInfo *info = (struct KryRegionFixedInfo *) pavl_t_cur(&waveform->region_fixed_list_iter);
1893 if(!info)
1894 break;
1895
1896 for(GList *ptr_h = info->regions; ptr_h; ptr_h = ptr_h->next)
1897 {
1898 struct KryRegionFixed *region = (struct KryRegionFixed *) ptr_h->data;
1899 long m1val = region->start;
1900 long m2val = region->end;
1901 long m1pos = kry_waveform_rel_pixel_from_mili(waveform, m1val);
1902 long m2pos = kry_waveform_rel_pixel_from_mili(waveform, m2val);
1903
1904 counter++;
1905
1906 if(m1val == -1 || m2val == -1 || m1val >= m2val)
1907 continue;
1908
1909 gboolean region_match = (m1pos < 0 && m2pos > 0 || m1pos >= 0);
1910 if(!backward && region_match)
1911 {
1912 found = TRUE;
1913 break;
1914 }
1915 else if(backward && !region_match)
1916 {
1917 struct pavl_traverser iter = waveform->region_fixed_list_iter;
1918
1919 pavl_t_next(&waveform->region_fixed_list_iter);
1920 if(!waveform->region_fixed_list_iter.pavl_node)
1921 waveform->region_fixed_list_iter = iter;
1922
1923 found = TRUE;
1924 break;
1925 }
1926 }
1927
1928 if(!found)
1929 {
1930 struct pavl_traverser iter = waveform->region_fixed_list_iter;
1931 if(!backward)
1932 {
1933 pavl_t_next(&waveform->region_fixed_list_iter);
1934 }
1935 else
1936 {
1937 pavl_t_prev(&waveform->region_fixed_list_iter);
1938 }
1939
1940 if(pavl_t_cur(&waveform->region_fixed_list_iter) == NULL)
1941 {
1942 waveform->region_fixed_list_iter = iter;
1943 found = TRUE;
1944 }
1945 }
1946 }
1947 }
1948
kry_waveform_adjustment_value_changed(GtkAdjustment * adjustment,gpointer data)1949 static void kry_waveform_adjustment_value_changed (GtkAdjustment *adjustment, gpointer data)
1950 {
1951 KryWaveform *waveform;
1952
1953 g_return_if_fail (adjustment != NULL);
1954 g_return_if_fail (data != NULL);
1955
1956 waveform = KRY_WAVEFORM (data);
1957
1958 waveform->left = (long) adjustment->value;
1959
1960 kry_waveform_setup_rel_keyframe_list(waveform);
1961 if(waveform->left != waveform->left_previous)
1962 {
1963 int curx = kry_waveform_abs_pixel_from_rel(waveform, 0);
1964 GdkRectangle *rect = &waveform->last_draw_rect;
1965
1966 kry_waveform_find_first_region(waveform, curx < rect->x);
1967
1968 // scroll to the right (image scrolls left)
1969 if(curx > rect->x && curx < rect->x + rect->width)
1970 {
1971 #ifdef _WINDOWS
1972 RECT scroll, clip;
1973 scroll.left = curx - rect->x;
1974 scroll.right = rect->width;
1975 scroll.top = waveform->scrub_bar_height + waveform->time_bar_height;
1976 scroll.bottom = waveform->wave_height + scroll.top;
1977
1978 clip.left = 0;
1979 clip.right = rect->width;
1980 clip.top = scroll.top;
1981 clip.bottom = scroll.bottom;
1982
1983 if(!ScrollDC(waveform->backbuffer_final, rect->x - curx, 0, &scroll, &clip, NULL, NULL))
1984 g_warning("scroll failed");
1985 #else
1986 gdk_draw_drawable(waveform->backbuffer_final, waveform->gc, waveform->backbuffer_final,
1987 curx - rect->x, waveform->time_bar_height + waveform->scrub_bar_height, 0,
1988 waveform->time_bar_height + waveform->scrub_bar_height, rect->width - (curx - rect->x), waveform->wave_height);
1989 #endif
1990
1991 kry_waveform_redraw_partial(waveform, rect->width - (curx - rect->x), curx - rect->x, TRUE, FALSE);
1992 kry_waveform_update_front_buffer(waveform, 0, GTK_WIDGET(waveform)->allocation.width);
1993
1994 rect->x = curx;
1995 }
1996 // scroll left (image moves right)
1997 else if(curx < rect->x && curx + rect->width > rect->x)
1998 {
1999 #ifdef _WINDOWS
2000 RECT scroll, clip;
2001 scroll.left = 0;
2002 scroll.right = rect->width - (rect->x - curx);
2003 scroll.top = waveform->scrub_bar_height + waveform->time_bar_height;
2004 scroll.bottom = waveform->wave_height + scroll.top;
2005
2006 clip.left = 0;
2007 clip.right = rect->width;
2008 clip.top = scroll.top;
2009 clip.bottom = scroll.bottom;
2010
2011 if(!ScrollDC(waveform->backbuffer_final, rect->x - curx, 0, &scroll, &clip, NULL, NULL))
2012 g_warning("scroll failed");
2013 #else
2014 gdk_draw_drawable(waveform->backbuffer_final, waveform->gc, waveform->backbuffer_final,
2015 0, waveform->time_bar_height + waveform->scrub_bar_height, rect->x - curx,
2016 waveform->time_bar_height + waveform->scrub_bar_height, rect->width - (rect->x - curx), waveform->wave_height);
2017 #endif
2018
2019 kry_waveform_redraw_partial(waveform, 0, rect->x - curx, TRUE, FALSE);
2020 kry_waveform_update_front_buffer(waveform, 0, GTK_WIDGET(waveform)->allocation.width);
2021
2022 rect->x = curx;
2023 }
2024 else
2025 {
2026 kry_waveform_redraw(waveform);
2027 }
2028
2029 waveform->left_previous = waveform->left;
2030 }
2031 }
2032
kry_waveform_marker_set_active_start(KryWaveform * waveform,KryMarker * marker)2033 void kry_waveform_marker_set_active_start(KryWaveform *waveform, KryMarker *marker)
2034 {
2035 g_return_if_fail (waveform != NULL);
2036 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
2037
2038
2039 KryMarker *old_marker = waveform->marker_active_start;
2040 waveform->marker_active_start = marker;
2041
2042 if(!GTK_WIDGET_REALIZED(waveform))
2043 return;
2044
2045 if(old_marker)
2046 kry_waveform_marker_redraw_at_time(waveform, kry_marker_get_value(old_marker));
2047
2048 if(marker)
2049 kry_waveform_marker_redraw_at_time(waveform, kry_marker_get_value(marker));
2050 }
2051
kry_waveform_marker_set_active_end(KryWaveform * waveform,KryMarker * marker)2052 void kry_waveform_marker_set_active_end(KryWaveform *waveform, KryMarker *marker)
2053 {
2054 g_return_if_fail (waveform != NULL);
2055 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
2056
2057 KryMarker *old_marker = waveform->marker_active_end;
2058 waveform->marker_active_end = marker;
2059
2060 if(!GTK_WIDGET_REALIZED(waveform))
2061 return;
2062
2063 if(old_marker)
2064 kry_waveform_marker_redraw_at_time(waveform, kry_marker_get_value(old_marker));
2065
2066 if(marker)
2067 kry_waveform_marker_redraw_at_time(waveform, kry_marker_get_value(marker));
2068 }
2069
kry_waveform_get_color_table(KryWaveform * waveform)2070 kryColorTable *kry_waveform_get_color_table(KryWaveform *waveform)
2071 {
2072 g_return_val_if_fail (waveform != NULL, NULL);
2073 g_return_val_if_fail (KRY_IS_WAVEFORM (waveform), NULL);
2074
2075 return waveform->color_table;
2076 }
2077
kry_waveform_set_drag_selection(KryWaveform * waveform,gboolean drag)2078 void kry_waveform_set_drag_selection(KryWaveform *waveform, gboolean drag)
2079 {
2080 g_return_if_fail (waveform != NULL);
2081 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
2082
2083 waveform->drag_selection_enabled = drag;
2084 }
2085
kry_waveform_set_marker_dragging(KryWaveform * waveform,gboolean drag)2086 void kry_waveform_set_marker_dragging(KryWaveform *waveform, gboolean drag)
2087 {
2088 g_return_if_fail (waveform != NULL);
2089 g_return_if_fail (KRY_IS_WAVEFORM (waveform));
2090
2091 waveform->drag_markers_enabled = drag;
2092 }
2093