1 /*
2 * Sweep, a sound wave editor.
3 *
4 * Copyright (C) 2000 Conrad Parker
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28
29 #include <glib.h>
30 #include <gdk/gdkkeysyms.h>
31 #include <gtk/gtk.h>
32
33 #include <sweep/sweep_i18n.h>
34 #include <sweep/sweep_sample.h>
35 #include <sweep/sweep_typeconvert.h>
36 #include <sweep/sweep_sounddata.h>
37 #include <sweep/sweep_selection.h>
38 #include <sweep/sweep_undo.h>
39
40 #include "sample.h" /* app internal functions for samples */
41
42 #include "format.h"
43 #include "print.h"
44 #include "view.h"
45 #include "sample-display.h"
46 #include "play.h"
47 #include "undo_dialog.h"
48 #include "head.h"
49 #include "interface.h"
50 #include "preferences.h"
51 #include "record.h"
52 #include "question_dialogs.h"
53 #include "sw_chooser.h"
54
55 #include "../pixmaps/new.xpm"
56
57 /* Defaults for new files */
58 #define DEFAULT_DURATION "00:01:00.000"
59 #define DEFAULT_SAMPLERATE 44100
60 #define DEFAULT_CHANNELS 2
61
62 /* Preferences keys for "new file" remembered values */
63 #define SAMPLERATE_KEY "NewFile_Samplerate"
64 #define CHANNELS_KEY "NewFile_Channels"
65
66 /*#define DEBUG*/
67
68 extern sw_view * last_tmp_view;
69
70 static GList * sample_bank = NULL;
71
72 static int untitled_count = 0;
73
74 static void
75 sample_info_update (sw_sample * sample);
76
77 /* Sample functions */
78
79 void
sample_add_view(sw_sample * s,sw_view * v)80 sample_add_view (sw_sample * s, sw_view * v)
81 {
82 s->views = g_list_append(s->views, v);
83 }
84
85 void
sample_remove_view(sw_sample * s,sw_view * v)86 sample_remove_view (sw_sample * s, sw_view * v)
87 {
88 s->views = g_list_remove(s->views, v);
89
90 if(!s->views) {
91 sample_bank_remove(s);
92 }
93 }
94
95 /*
96 * filename_color_hash
97 *
98 * Choose colour for this file based on the filename, such that
99 * a file is loaded with the same colour each time it is edited.
100 *
101 * Idea due to Erik de Castro Lopo
102 */
103 static int
filename_color_hash(char * filename)104 filename_color_hash (char * filename)
105 {
106 char *p;
107 int i = 0;
108
109 if (filename == NULL) return 0;
110
111 for (p = filename; *p; p++) i += (int)*p;
112
113 return (i % VIEW_COLOR_DEFAULT_MAX);
114 }
115
116 static gchar *
filename_generate(void)117 filename_generate (void)
118 {
119 return g_strdup_printf ("%s-%d.aiff", _("Untitled"), ++untitled_count);
120 }
121
122 sw_sample *
sample_new_empty(gchar * pathname,gint nr_channels,gint sample_rate,sw_framecount_t sample_length)123 sample_new_empty(gchar * pathname,
124 gint nr_channels, gint sample_rate,
125 sw_framecount_t sample_length)
126 {
127 sw_sample *s;
128
129 s = g_malloc0 (sizeof(sw_sample));
130 if (!s)
131 return NULL;
132
133 s->sounddata = sounddata_new_empty (nr_channels, sample_rate, sample_length);
134
135 s->views = NULL;
136
137 if (pathname != NULL)
138 s->pathname = strdup (pathname);
139 else
140 s->pathname = filename_generate ();
141
142 s->ops_thread = (pthread_t) -1;
143
144 s->ops_mutex = g_mutex_new ();
145 s->registered_ops = NULL;
146 s->current_undo = NULL;
147 s->current_redo = NULL;
148 s->active_op = NULL;
149 s->op_progress_tag = -1;
150
151 s->tmp_sel = NULL;
152
153 s->playmarker_tag = 0;
154
155 s->edit_mutex = g_mutex_new ();
156 s->edit_mode = SWEEP_EDIT_MODE_READY;
157 s->edit_state = SWEEP_EDIT_STATE_IDLE;
158 s->modified = FALSE;
159
160 s->pending_cond = g_cond_new ();
161 s->pending_ops = NULL;
162
163 s->play_mutex = g_mutex_new ();
164 #if 0
165 s->play_mode = SWEEP_TRANSPORT_STOP;
166 s->stop_offset = 0;
167 s->play_offset = 0;
168 s->play_looping = FALSE;
169 s->play_scrubbing = FALSE;
170 s->previewing = FALSE;
171 s->play_reverse = FALSE;
172 s->play_mute = FALSE;
173 #endif
174 s->user_offset = 0;
175 s->by_user = 0;
176
177 s->play_head = head_new (s, SWEEP_HEAD_PLAY);
178
179 s->rate = 1.0;
180
181 #if 0
182 s->color = ((int)random()) % VIEW_COLOR_MAX;
183 #else
184 s->color = filename_color_hash ((gchar *)g_basename (s->pathname));
185 #endif
186
187 s->info_clist = NULL;
188
189 /* s->recording = FALSE;*/
190 /* s->rec_offset = 0;*/
191 s->rec_head = NULL;
192
193 s->tmp_message_active = FALSE;
194 s->last_tmp_message = NULL;
195 s->tmp_message_tag = -1;
196
197 return s;
198 }
199
200 sw_sample *
sample_new_copy(sw_sample * s)201 sample_new_copy(sw_sample * s)
202 {
203 sw_sample * sn;
204
205 sn = sample_new_empty(NULL,
206 s->sounddata->format->channels,
207 s->sounddata->format->rate,
208 s->sounddata->nr_frames);
209
210 if(!sn) {
211 fprintf(stderr, "Unable to allocate new sample.\n");
212 return NULL;
213 }
214
215 memcpy(sn->sounddata->data, s->sounddata->data,
216 frames_to_bytes(s->sounddata->format, s->sounddata->nr_frames));
217
218 sounddata_copyin_selection (s->sounddata, sn->sounddata);
219
220 /* sn->last_mtime = s->last_mtime;*/
221
222 return sn;
223 }
224
225 static void
sample_new_dialog_ok_cb(GtkWidget * widget,gpointer data)226 sample_new_dialog_ok_cb (GtkWidget * widget, gpointer data)
227 {
228 GtkWidget * dialog;
229 GtkWidget * entry;
230 GtkWidget * checkbutton;
231 gchar * filename, * text;
232 gdouble seconds;
233 sw_framecount_t nr_frames;
234 gint nr_channels;
235 gint sample_rate;
236 gboolean rem_format;
237
238 sw_sample * s;
239 sw_view * v;
240
241 dialog = gtk_widget_get_toplevel (widget);
242
243 entry = g_object_get_data (G_OBJECT(dialog), "name_entry");
244 filename = (gchar *) gtk_entry_get_text (GTK_ENTRY(entry));
245
246 entry = g_object_get_data (G_OBJECT(dialog), "duration_entry");
247 text = (gchar *) gtk_entry_get_text (GTK_ENTRY(entry));
248 seconds = strtime_to_seconds (text);
249 if (seconds == -1) goto out; /* XXX: invalid time spec */
250
251 entry = g_object_get_data (G_OBJECT(dialog), "rate_chooser");
252 sample_rate = samplerate_chooser_get_rate (entry);
253
254 entry = g_object_get_data (G_OBJECT(dialog), "channelcount_chooser");
255 nr_channels = channelcount_chooser_get_count (entry);
256
257 nr_frames = (sw_framecount_t) (sample_rate * seconds);
258
259 checkbutton =
260 GTK_WIDGET(g_object_get_data (G_OBJECT(dialog), "rem_format_chb"));
261 rem_format =
262 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbutton));
263
264 if (rem_format) {
265 prefs_set_int (SAMPLERATE_KEY, sample_rate);
266 prefs_set_int (CHANNELS_KEY, nr_channels);
267 }
268
269 s = sample_new_empty ((gchar *)filename, nr_channels, sample_rate, nr_frames);
270 v = view_new_all (s, 1.0);
271 sample_add_view (s, v);
272 sample_bank_add (s);
273
274 out:
275 gtk_widget_destroy (dialog);
276 }
277
278 static void
sample_new_dialog_cancel_cb(GtkWidget * widget,gpointer data)279 sample_new_dialog_cancel_cb (GtkWidget * widget, gpointer data)
280 {
281 GtkWidget * dialog;
282
283 dialog = gtk_widget_get_toplevel (widget);
284 gtk_widget_destroy (dialog);
285
286 if (sample_bank == NULL) {
287 sweep_quit ();
288 }
289 }
290
291
292 static void
sample_new_dialog_update(GtkWidget * widget)293 sample_new_dialog_update (GtkWidget * widget)
294 {
295 GtkWidget * dialog;
296 GtkWidget * entry;
297 GtkWidget * memsize_label;
298 GtkWidget * ok_button;
299 gchar * text;
300 gdouble seconds;
301 gint sample_rate, nr_channels;
302 glong bytes;
303
304 #undef BUF_LEN
305 #define BUF_LEN 16
306 char buf[BUF_LEN];
307
308 dialog = gtk_widget_get_toplevel (widget);
309
310 entry = g_object_get_data (G_OBJECT(dialog), "duration_entry");
311 text = (gchar *)gtk_entry_get_text (GTK_ENTRY(entry));
312 seconds = strtime_to_seconds (text);
313
314 entry = g_object_get_data (G_OBJECT(dialog), "rate_chooser");
315 sample_rate = samplerate_chooser_get_rate (entry);
316
317 entry = g_object_get_data (G_OBJECT(dialog), "channelcount_chooser");
318 nr_channels = channelcount_chooser_get_count (entry);
319
320 memsize_label = g_object_get_data (G_OBJECT(dialog), "memsize_label");
321
322 bytes = (glong) (seconds * sample_rate * nr_channels * sizeof(sw_audio_t));
323 if (bytes < 0) {
324 gtk_label_set_text (GTK_LABEL(memsize_label), _("Overflow"));
325 } else {
326 snprint_bytes (buf, BUF_LEN, bytes);
327 gtk_label_set_text (GTK_LABEL(memsize_label), buf);
328 }
329
330 ok_button = g_object_get_data (G_OBJECT(dialog), "ok_button");
331
332 if (seconds <= 0.0 || sample_rate <= 0 || nr_channels <= 0 || bytes < 0) {
333 gtk_widget_set_sensitive (ok_button, FALSE);
334 } else {
335 gtk_widget_set_sensitive (ok_button, TRUE);
336 }
337 }
338
339 static void
sample_new_dialog_reset_cb(GtkWidget * widget,gpointer data)340 sample_new_dialog_reset_cb (GtkWidget * widget, gpointer data)
341 {
342 GtkWidget * dialog;
343 GtkWidget * entry;
344
345 int * i, sample_rate, nr_channels;
346
347 i = prefs_get_int (SAMPLERATE_KEY);
348 sample_rate = i ? *i : DEFAULT_SAMPLERATE;
349
350 i = prefs_get_int (CHANNELS_KEY);
351 nr_channels = i ? *i : DEFAULT_CHANNELS;
352
353 dialog = gtk_widget_get_toplevel (widget);
354
355 entry = g_object_get_data (G_OBJECT(dialog), "rate_chooser");
356 samplerate_chooser_set_rate (entry, sample_rate);
357
358 entry = g_object_get_data (G_OBJECT(dialog), "channelcount_chooser");
359 channelcount_chooser_set_count (entry, nr_channels);
360
361 sample_new_dialog_update (dialog);
362 }
363
364 static void
sample_new_dialog_defaults_cb(GtkWidget * widget,gpointer data)365 sample_new_dialog_defaults_cb (GtkWidget * widget, gpointer data)
366 {
367 GtkWidget * dialog;
368 GtkWidget * entry;
369
370 dialog = gtk_widget_get_toplevel (widget);
371
372 entry = g_object_get_data (G_OBJECT(dialog), "duration_entry");
373 gtk_entry_set_text (GTK_ENTRY (entry), DEFAULT_DURATION);
374
375 entry = g_object_get_data (G_OBJECT(dialog), "rate_chooser");
376 samplerate_chooser_set_rate (entry, DEFAULT_SAMPLERATE);
377
378 entry = g_object_get_data (G_OBJECT(dialog), "channelcount_chooser");
379 channelcount_chooser_set_count (entry, DEFAULT_CHANNELS);
380
381 sample_new_dialog_update (dialog);
382 }
383
384 static void
create_sample_new_dialog(gchar * pathname,gint nr_channels,gint sample_rate,sw_time_t duration,gboolean do_reset)385 create_sample_new_dialog ( gchar * pathname, gint nr_channels, gint sample_rate,
386 sw_time_t duration, gboolean do_reset)
387 {
388 GtkWidget * dialog;
389 GtkWidget * main_vbox, * vbox;
390 GtkWidget * main_hbox, * hbox, * hbox2;
391 GtkWidget * pixmap;
392 GtkWidget * frame;
393 GtkWidget * ebox;
394 GtkWidget * label;
395 GtkWidget * entry;
396 GtkWidget * button;
397 GtkWidget * checkbutton;
398 GtkWidget * ok_button;
399 GtkTooltips * tooltips;
400
401 #define BUF_LEN 16
402 gchar buf[BUF_LEN];
403
404 dialog = gtk_dialog_new ();
405 sweep_set_window_icon (GTK_WINDOW(dialog));
406 gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
407 gtk_window_set_title (GTK_WINDOW(dialog), _("Sweep: New file"));
408 /*gtk_container_border_width (GTK_CONTAINER(dialog), 8);*/
409
410 g_signal_connect (G_OBJECT(dialog), "destroy",
411 G_CALLBACK(sample_new_dialog_cancel_cb), dialog);
412
413 attach_window_close_accel(GTK_WINDOW(dialog));
414
415 main_vbox = GTK_DIALOG(dialog)->vbox;
416
417 main_hbox = gtk_hbox_new (FALSE, 0);
418 gtk_box_pack_start (GTK_BOX(main_vbox), main_hbox, FALSE, FALSE, 0);
419 gtk_widget_show (main_hbox);
420
421 /* Left side */
422
423 vbox = gtk_vbox_new (FALSE, 0);
424 gtk_box_pack_start (GTK_BOX(main_hbox), vbox, FALSE, FALSE, 0);
425 gtk_container_set_border_width (GTK_CONTAINER(vbox), 4);
426 gtk_widget_show (vbox);
427
428 /* Name */
429
430 hbox = gtk_hbox_new (FALSE, 0);
431 gtk_container_set_border_width (GTK_CONTAINER(hbox), 8);
432 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 4);
433 gtk_widget_show (hbox);
434
435 label = gtk_label_new (_("Name:"));
436 gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 4);
437 gtk_widget_show (label);
438
439 entry = gtk_entry_new ();
440 gtk_box_pack_start (GTK_BOX(hbox), entry, TRUE, TRUE, 4);
441 gtk_widget_show (entry);
442
443 gtk_entry_set_text (GTK_ENTRY (entry),
444 pathname ? pathname : filename_generate ());
445
446 g_object_set_data (G_OBJECT (dialog), "name_entry", entry);
447
448 /* Duration */
449
450 hbox = gtk_hbox_new (FALSE, 0);
451 gtk_container_set_border_width (GTK_CONTAINER(hbox), 8);
452 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 4);
453 gtk_widget_show (hbox);
454
455 label = gtk_label_new (_("Duration:"));
456 gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 4);
457 gtk_widget_show (label);
458
459 entry = gtk_entry_new ();
460 gtk_box_pack_start (GTK_BOX(hbox), entry, TRUE, TRUE, 4);
461 gtk_widget_show (entry);
462
463 snprint_time (buf, BUF_LEN, duration);
464 gtk_entry_set_text (GTK_ENTRY (entry), buf);
465
466 g_signal_connect (G_OBJECT(entry), "changed",
467 G_CALLBACK(sample_new_dialog_update), NULL);
468
469 g_object_set_data (G_OBJECT (dialog), "duration_entry", entry);
470
471 label = gtk_label_new (_("hh:mm:ss.xxx"));
472 gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 4);
473 gtk_widget_show (label);
474
475 /* Right side */
476
477 vbox = gtk_vbox_new (FALSE, 0);
478 gtk_box_pack_start (GTK_BOX(main_hbox), vbox, FALSE, FALSE, 0);
479 gtk_container_set_border_width (GTK_CONTAINER(vbox), 4);
480 gtk_widget_show (vbox);
481
482 /* Sampling rate */
483
484 entry = samplerate_chooser_new (NULL);
485 samplerate_chooser_set_rate (entry, sample_rate);
486 gtk_box_pack_start (GTK_BOX(vbox), entry, FALSE, FALSE, 4);
487 gtk_widget_show (entry);
488
489 g_signal_connect (G_OBJECT(entry), "number-changed",
490 G_CALLBACK(sample_new_dialog_update), NULL);
491
492 g_object_set_data (G_OBJECT (dialog), "rate_chooser", entry);
493
494 /* Channels */
495
496 entry = channelcount_chooser_new (NULL);
497 channelcount_chooser_set_count (entry, nr_channels);
498 gtk_box_pack_start (GTK_BOX(vbox), entry, FALSE, FALSE, 4);
499 gtk_widget_show (entry);
500
501 g_signal_connect (G_OBJECT(entry), "number-changed",
502 G_CALLBACK(sample_new_dialog_update), NULL);
503
504 g_object_set_data (G_OBJECT (dialog), "channelcount_chooser", entry);
505
506 /* Defaults */
507
508 hbox = gtk_hbox_new (FALSE, 4);
509 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 4);
510 gtk_container_set_border_width (GTK_CONTAINER(hbox), 12);
511 gtk_widget_show (hbox);
512
513 checkbutton =
514 gtk_check_button_new_with_label (_("Remember this format"));
515 gtk_box_pack_start (GTK_BOX (hbox), checkbutton, TRUE, TRUE, 0);
516 gtk_widget_show (checkbutton);
517
518 tooltips = gtk_tooltips_new ();
519 gtk_tooltips_set_tip (tooltips, checkbutton,
520 _("Remember this sampling rate and channel "
521 "configuration for creating new files."),
522 NULL);
523
524 g_object_set_data (G_OBJECT (dialog), "rem_format_chb", checkbutton);
525
526 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(checkbutton), do_reset);
527
528 hbox2 = gtk_hbox_new (TRUE, 4);
529 gtk_box_pack_start (GTK_BOX (hbox), hbox2, FALSE, TRUE, 0);
530 gtk_widget_show (hbox2);
531
532 button = gtk_button_new_with_label (_("Reset"));
533 gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, TRUE, 4);
534 g_signal_connect (G_OBJECT(button), "clicked",
535 G_CALLBACK(sample_new_dialog_reset_cb), NULL);
536 gtk_widget_show (button);
537
538 tooltips = gtk_tooltips_new ();
539 gtk_tooltips_set_tip (tooltips, button,
540 _("Reset to the last remembered format for new files."),
541 NULL);
542
543 button = gtk_button_new_with_label (_("Defaults"));
544 gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, TRUE, 4);
545 g_signal_connect (G_OBJECT(button), "clicked",
546 G_CALLBACK(sample_new_dialog_defaults_cb), NULL);
547 gtk_widget_show (button);
548
549 tooltips = gtk_tooltips_new ();
550 gtk_tooltips_set_tip (tooltips, button,
551 _("Set to the default format for new files."),
552 NULL);
553
554 /* Data memory */
555
556 frame = gtk_frame_new (NULL);
557 gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 4);
558 gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
559 gtk_widget_show (frame);
560
561 ebox = gtk_event_box_new ();
562 gtk_container_add (GTK_CONTAINER(frame), ebox);
563 gtk_widget_show (ebox);
564
565 tooltips = gtk_tooltips_new ();
566 gtk_tooltips_set_tip (tooltips, ebox,
567 _("Indicates the amount of data memory which "
568 "will be allocated for the selected duration and "
569 "format. All audio data is processed "
570 "internally in 32 bit floating point format."),
571 NULL);
572
573 hbox = gtk_hbox_new (FALSE, 0);
574 gtk_container_add (GTK_CONTAINER(ebox), hbox);
575 gtk_container_set_border_width (GTK_CONTAINER(hbox), 2);
576 gtk_widget_show (hbox);
577
578 pixmap = create_widget_from_xpm (dialog, new_xpm);
579 gtk_box_pack_start (GTK_BOX(hbox), pixmap, FALSE, FALSE, 4);
580 gtk_widget_show (pixmap);
581
582 label = gtk_label_new (_("Data memory:"));
583 gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 4);
584 gtk_widget_show (label);
585
586 label = gtk_label_new (NULL);
587 gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 4);
588 gtk_widget_show (label);
589
590 g_object_set_data (G_OBJECT (dialog), "memsize_label", label);
591
592 /* OK */
593
594 ok_button = gtk_button_new_with_label (_("Create"));
595 GTK_WIDGET_SET_FLAGS (GTK_WIDGET(ok_button), GTK_CAN_DEFAULT);
596 gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->action_area), ok_button,
597 TRUE, TRUE, 0);
598 gtk_widget_show (ok_button);
599 g_signal_connect (G_OBJECT(ok_button), "clicked",
600 G_CALLBACK (sample_new_dialog_ok_cb), NULL);
601
602 g_object_set_data (G_OBJECT (dialog), "ok_button", ok_button);
603
604 /* Cancel */
605
606 button = gtk_button_new_with_label (_("Don't create"));
607 GTK_WIDGET_SET_FLAGS (GTK_WIDGET(button), GTK_CAN_DEFAULT);
608 gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->action_area), button,
609 TRUE, TRUE, 0);
610 gtk_widget_show (button);
611 g_signal_connect (G_OBJECT(button), "clicked",
612 G_CALLBACK (sample_new_dialog_cancel_cb), NULL);
613
614 gtk_widget_grab_default (ok_button);
615
616 if (do_reset) {
617 /* Call the reset callback now to set remembered options */
618 sample_new_dialog_reset_cb (dialog, NULL);
619 } else {
620 sample_new_dialog_update (dialog);
621 }
622
623 gtk_widget_show (dialog);
624
625 #undef BUF_LEN
626 }
627
628 void
create_sample_new_dialog_defaults(gchar * pathname)629 create_sample_new_dialog_defaults ( gchar * pathname)
630 {
631 create_sample_new_dialog (pathname, DEFAULT_CHANNELS, DEFAULT_SAMPLERATE,
632 60, TRUE);
633 }
634
635 void
create_sample_new_dialog_like(sw_sample * s)636 create_sample_new_dialog_like (sw_sample * s)
637 {
638 sw_format * f = s->sounddata->format;
639
640 create_sample_new_dialog (NULL, f->channels, f->rate,
641 frames_to_time (f, s->sounddata->nr_frames),
642 FALSE);
643 }
644
645 void
sample_destroy(sw_sample * s)646 sample_destroy (sw_sample * s)
647 {
648 stop_playback (s);
649
650 sounddata_destroy (s->sounddata);
651
652 /* XXX: Should do this: */
653 /* trim_registered_ops (s, 0); */
654
655 g_free (s);
656 }
657
658 sw_sounddata *
sample_get_sounddata(sw_sample * s)659 sample_get_sounddata (sw_sample * s)
660 {
661 return s->sounddata;
662 }
663
664 void
sample_set_pathname(sw_sample * s,gchar * pathname)665 sample_set_pathname (sw_sample * s, gchar * pathname)
666 {
667 sw_view * v;
668 GList * gl;
669
670 if (pathname == s->pathname) return;
671
672 if (pathname) {
673 s->pathname = strdup (pathname);
674 } else {
675 if (s->pathname) g_free (s->pathname);
676 s->pathname = NULL;
677 }
678
679 for(gl = s->views; gl; gl = gl->next) {
680 v = (sw_view *)gl->data;
681 view_refresh_title (v);
682 }
683 }
684
685 GList *
sample_bank_list_names(void)686 sample_bank_list_names (void)
687 {
688 GList * ret = NULL;
689 GList * gl = NULL;
690 sw_sample * s;
691
692 for (gl = sample_bank; gl; gl = gl->next) {
693 s = (sw_sample *)gl->data;
694
695 ret = g_list_append (ret, (gpointer *)g_basename (s->pathname));
696 }
697
698 return ret;
699 }
700
701 sw_sample *
sample_bank_find_byname(const gchar * name)702 sample_bank_find_byname (const gchar * name)
703 {
704 GList * gl;
705 sw_sample * sample;
706
707 if (name == NULL) return NULL;
708
709 for (gl = sample_bank; gl; gl = gl->next) {
710 sample = (sw_sample *)gl->data;
711
712 if ((sample->pathname != NULL) &&
713 (!strcmp (name, g_basename (sample->pathname))))
714 return sample;
715 }
716
717 return NULL;
718 }
719
720 gboolean
sample_bank_contains(sw_sample * s)721 sample_bank_contains (sw_sample *s)
722 {
723 return (g_list_find (sample_bank, s) != 0);
724 }
725
726 void
sample_bank_add(sw_sample * s)727 sample_bank_add (sw_sample * s)
728 {
729 /* Check that sample is not already in sample_bank */
730 if (g_list_find (sample_bank, s)) return;
731
732 sample_bank = g_list_append (sample_bank, s);
733
734 undo_dialog_refresh_sample_list ();
735 rec_dialog_refresh_sample_list ();
736 }
737
738 /*
739 * sample_bank_remove (s)
740 *
741 * Takes a sample out of the sample list.
742 */
743 void
sample_bank_remove(sw_sample * s)744 sample_bank_remove (sw_sample * s)
745 {
746 if (s) {
747 sample_destroy(s);
748 sample_bank = g_list_remove(sample_bank, s);
749
750 undo_dialog_refresh_sample_list ();
751 rec_dialog_refresh_sample_list ();
752 }
753
754 if (sample_bank == NULL) {
755 sweep_quit ();
756 }
757 }
758
759 void
sweep_quit_ok_cb(GtkWidget * widget,gpointer data)760 sweep_quit_ok_cb (GtkWidget * widget, gpointer data)
761 {
762 stop_all_playback ();
763 gtk_main_quit ();
764 }
765
766 void
sweep_quit_cancel_cb(GtkWidget * widget,gpointer data)767 sweep_quit_cancel_cb (GtkWidget * widget, gpointer data)
768 {
769 GList * gl;
770 sw_sample * s;
771
772 for (gl = sample_bank; gl; gl = gl->next) {
773 s = (sw_sample *)gl->data;
774 sample_set_tmp_message (s, _("Excellent!!!"));
775 sample_set_progress_ready (s);
776 }
777
778 }
779
780 void
sweep_quit(void)781 sweep_quit (void)
782 {
783 GList * gl;
784 sw_sample * s;
785 gboolean any_modified = FALSE;
786
787 for (gl = sample_bank; gl; gl = gl->next) {
788 s = (sw_sample *)gl->data;
789 if (s->modified) {
790 any_modified = TRUE;
791 break;
792 }
793 }
794
795 if (any_modified) {
796 question_dialog_new (NULL, _("Files unsaved"),
797 _("Some files are unsaved. If you quit, all "
798 "changes will be lost.\n\n"
799 "Are you sure you want to quit?"),
800 _("Quit"), _("Don't quit"),
801 G_CALLBACK (sweep_quit_ok_cb), NULL, G_CALLBACK (sweep_quit_cancel_cb), NULL,
802 SWEEP_EDIT_MODE_READY);
803 } else if (any_playing()) {
804 question_dialog_new (NULL, _("Files playing"),
805 _("No files are unsaved, but some files are "
806 "currently playing.\n\n"
807 "Are you sure you want to quit?"),
808 _("Quit"), _("Don't quit"),
809 G_CALLBACK (sweep_quit_ok_cb), NULL, G_CALLBACK (sweep_quit_cancel_cb), NULL,
810 SWEEP_EDIT_MODE_READY);
811 } else {
812 sweep_quit_ok_cb (NULL, NULL);
813 }
814 }
815
816 /* info dialog */
817
818
819 void
sample_refresh_views(sw_sample * s)820 sample_refresh_views (sw_sample * s)
821 {
822 sw_view * v;
823 GList * gl;
824
825 g_mutex_lock (s->ops_mutex);
826
827 sample_info_update (s);
828
829 for(gl = s->views; gl; gl = gl->next) {
830 v = (sw_view *)gl->data;
831 view_refresh (v);
832 }
833
834 g_mutex_unlock (s->ops_mutex);
835 }
836
837 void
sample_start_marching_ants(sw_sample * s)838 sample_start_marching_ants (sw_sample * s)
839 {
840 sw_view * v;
841 GList * gl;
842
843 for(gl = s->views; gl; gl = gl->next) {
844 v = (sw_view *)gl->data;
845 sample_display_start_marching_ants (SAMPLE_DISPLAY(v->display));
846 }
847 }
848
849 void
sample_stop_marching_ants(sw_sample * s)850 sample_stop_marching_ants (sw_sample * s)
851 {
852 sw_view * v;
853 GList * gl;
854
855 for(gl = s->views; gl; gl = gl->next) {
856 v = (sw_view *)gl->data;
857 sample_display_stop_marching_ants (SAMPLE_DISPLAY(v->display));
858 }
859 }
860
861 /* Edit state */
862
863
864 static void
_sample_set_edit_mode(sw_sample * s,sw_edit_mode edit_mode)865 _sample_set_edit_mode (sw_sample * s, sw_edit_mode edit_mode)
866 {
867 GList * gl;
868 sw_view * v;
869
870 s->edit_mode = edit_mode;
871
872 for(gl = s->views; gl; gl = gl->next) {
873 v = (sw_view *)gl->data;
874 view_refresh_edit_mode (v);
875 }
876
877 undo_dialog_refresh_edit_mode (s);
878 }
879
880 void
sample_set_edit_mode(sw_sample * s,sw_edit_mode edit_mode)881 sample_set_edit_mode (sw_sample * s, sw_edit_mode edit_mode)
882 {
883 g_mutex_lock (s->edit_mutex);
884
885 _sample_set_edit_mode (s, edit_mode);
886
887 #ifdef DEBUG
888 g_print ("set_edit_mode %d\n", edit_mode);
889 #endif
890
891 g_mutex_unlock (s->edit_mutex);
892 }
893
894 void
sample_set_edit_state(sw_sample * s,sw_edit_state edit_state)895 sample_set_edit_state (sw_sample * s, sw_edit_state edit_state)
896 {
897 g_mutex_lock (s->edit_mutex);
898
899 s->edit_state = edit_state;
900
901 #ifdef DEBUG
902 g_print ("set_edit_state %d\n", edit_state);
903 #endif
904
905 if (edit_state == SWEEP_EDIT_STATE_IDLE) {
906 _sample_set_edit_mode (s, SWEEP_EDIT_MODE_READY);
907 }
908
909 g_mutex_unlock (s->edit_mutex);
910
911 if (edit_state == SWEEP_EDIT_STATE_PENDING) {
912 g_cond_signal (s->pending_cond);
913 }
914 }
915
916 /* Playback state */
917
918 void
sample_refresh_playmode(sw_sample * s)919 sample_refresh_playmode (sw_sample * s)
920 {
921 GList * gl;
922 sw_view * v;
923 sw_head * head = s->play_head;
924
925 if (!head->going) {
926 if (s->playmarker_tag > 0) {
927 g_source_remove (s->playmarker_tag);
928 }
929 }
930
931 for(gl = s->views; gl; gl = gl->next) {
932 v = (sw_view *)gl->data;
933 view_refresh_playmode (v);
934 }
935 }
936
937 void
sample_set_stop_offset(sw_sample * s)938 sample_set_stop_offset (sw_sample * s)
939 {
940 sw_framecount_t offset;
941
942 g_mutex_lock (s->play_mutex);
943
944 offset = s->user_offset;
945 if (offset == s->sounddata->nr_frames)
946 offset = 0;
947
948 head_set_stop_offset (s->play_head, offset);
949 /* s->play_head->stop_offset = offset;*/
950
951 g_mutex_unlock (s->play_mutex);
952 }
953
954 void
sample_set_playmarker(sw_sample * s,sw_framecount_t offset,gboolean by_user)955 sample_set_playmarker (sw_sample * s, sw_framecount_t offset,
956 gboolean by_user)
957 {
958 GList * gl;
959 sw_view * v;
960 sw_head * head = s->play_head;
961
962 #ifdef DEBUG
963 g_print ("sample_set_playmarker (%p, %d, %s)\n", s, offset,
964 by_user ? "TRUE" : "FALSE");
965 #endif
966
967 g_mutex_lock (s->play_mutex);
968
969 if (offset < 0) offset = 0;
970 if (offset > s->sounddata->nr_frames) offset = s->sounddata->nr_frames;
971
972 if (by_user) {
973 s->by_user = by_user;
974 s->user_offset = offset;
975 if (!head->going || head->scrubbing == FALSE) {
976 head_set_stop_offset (head, offset);
977 head_set_offset (head, offset);
978 }
979 } else {
980 /*
981 if (head->scrubbing == FALSE)
982 head_set_offset (head, offset);
983 */
984 }
985
986 g_mutex_unlock (s->play_mutex);
987
988 for(gl = s->views; gl; gl = gl->next) {
989 v = (sw_view *)gl->data;
990 view_refresh_offset_indicators (v);
991 }
992 }
993
994 void
sample_set_offset_next_bound_left(sw_sample * s)995 sample_set_offset_next_bound_left (sw_sample * s)
996 {
997 GList * gl;
998 sw_sel * sel;
999
1000 for (gl = g_list_last (s->sounddata->sels); gl; gl = gl->prev) {
1001 sel = (sw_sel *)gl->data;
1002 if (sel->sel_end < s->user_offset) {
1003 sample_set_playmarker (s, sel->sel_end, TRUE);
1004 return;
1005 }
1006 if (sel->sel_start < s->user_offset) {
1007 sample_set_playmarker (s, sel->sel_start, TRUE);
1008 return;
1009 }
1010 }
1011 }
1012
1013 void
sample_set_offset_next_bound_right(sw_sample * s)1014 sample_set_offset_next_bound_right (sw_sample * s)
1015 {
1016 GList * gl;
1017 sw_sel * sel;
1018
1019 for (gl = s->sounddata->sels; gl; gl = gl->next) {
1020 sel = (sw_sel *)gl->data;
1021 if (sel->sel_start > s->user_offset) {
1022 sample_set_playmarker (s, sel->sel_start, TRUE);
1023 return;
1024 }
1025 if (sel->sel_end > s->user_offset) {
1026 sample_set_playmarker (s, sel->sel_end, TRUE);
1027 return;
1028 }
1029 }
1030 }
1031
1032 void
sample_set_rec_marker(sw_sample * s,sw_framecount_t offset)1033 sample_set_rec_marker (sw_sample * s, sw_framecount_t offset)
1034 {
1035 GList * gl;
1036 sw_view * v;
1037
1038 g_assert (s->rec_head != NULL);
1039
1040 head_set_offset (s->rec_head, (gdouble)offset);
1041
1042 for(gl = s->views; gl; gl = gl->next) {
1043 v = (sw_view *)gl->data;
1044 view_refresh_rec_offset_indicators (v);
1045 }
1046
1047 }
1048
1049 void
sample_refresh_rec_marker(sw_sample * s)1050 sample_refresh_rec_marker (sw_sample * s)
1051 {
1052 GList * gl;
1053 sw_view * v;
1054
1055 g_assert (s->rec_head != NULL);
1056
1057 for(gl = s->views; gl; gl = gl->next) {
1058 v = (sw_view *)gl->data;
1059 view_refresh_rec_offset_indicators (v);
1060 }
1061 }
1062
1063 void
sample_set_scrubbing(sw_sample * s,gboolean scrubbing)1064 sample_set_scrubbing (sw_sample * s, gboolean scrubbing)
1065 {
1066 sw_head * head = s->play_head;
1067
1068 head_set_scrubbing (head, scrubbing);
1069
1070 #if 0
1071 g_mutex_lock (s->play_mutex);
1072
1073 s->play_scrubbing = scrubbing;
1074
1075 g_mutex_unlock (s->play_mutex);
1076 #endif
1077
1078 sample_set_progress_ready (s);
1079 }
1080
1081 void
sample_set_looping(sw_sample * s,gboolean looping)1082 sample_set_looping (sw_sample * s, gboolean looping)
1083 {
1084 GList * gl;
1085 sw_view * v;
1086 sw_head * head = s->play_head;
1087
1088 head_set_looping (head, looping);
1089
1090 #if 0
1091 g_mutex_lock (s->play_mutex);
1092
1093 s->play_looping = looping;
1094 #endif
1095
1096 for(gl = s->views; gl; gl = gl->next) {
1097 v = (sw_view *)gl->data;
1098 view_refresh_looping (v);
1099 }
1100
1101 #if 0
1102 g_mutex_unlock (s->play_mutex);
1103 #endif
1104 }
1105
1106 void
sample_set_playrev(sw_sample * s,gboolean reverse)1107 sample_set_playrev (sw_sample * s, gboolean reverse)
1108 {
1109 GList * gl;
1110 sw_view * v;
1111 sw_head * head = s->play_head;
1112
1113 head_set_reverse (head, reverse);
1114
1115 #if 0
1116 g_mutex_lock (s->play_mutex);
1117
1118 s->play_reverse = reverse;
1119 #endif
1120
1121 for(gl = s->views; gl; gl = gl->next) {
1122 v = (sw_view *)gl->data;
1123 view_refresh_playrev (v);
1124 }
1125
1126 #if 0
1127 g_mutex_unlock (s->play_mutex);
1128 #endif
1129 }
1130
1131 void
sample_set_mute(sw_sample * s,gboolean mute)1132 sample_set_mute (sw_sample * s, gboolean mute)
1133 {
1134 GList * gl;
1135 sw_view * v;
1136 sw_head * head = s->play_head;
1137
1138 head_set_mute (head, mute);
1139
1140 #if 0
1141 g_mutex_lock (s->play_mutex);
1142
1143 s->play_mute = mute;
1144 #endif
1145
1146 for(gl = s->views; gl; gl = gl->next) {
1147 v = (sw_view *)gl->data;
1148 view_refresh_mute (v);
1149 }
1150
1151 #if 0
1152 g_mutex_unlock (s->play_mutex);
1153 #endif
1154 }
1155
1156 void
sample_set_monitor(sw_sample * s,gboolean monitor)1157 sample_set_monitor (sw_sample * s, gboolean monitor)
1158 {
1159 GList * gl;
1160 sw_view * v;
1161 sw_head * head = s->play_head;
1162
1163 head_set_monitor (head, monitor);
1164
1165 for(gl = s->views; gl; gl = gl->next) {
1166 v = (sw_view *)gl->data;
1167 view_refresh_monitor (v);
1168 }
1169 }
1170
1171 void
sample_set_previewing(sw_sample * s,gboolean previewing)1172 sample_set_previewing (sw_sample * s, gboolean previewing)
1173 {
1174 head_set_previewing (s->play_head, previewing);
1175 #if 0
1176 g_mutex_lock (s->play_mutex);
1177
1178 s->previewing = previewing;
1179
1180 g_mutex_unlock (s->play_mutex);
1181 #endif
1182 }
1183
1184 void
sample_set_color(sw_sample * s,gint color)1185 sample_set_color (sw_sample * s, gint color)
1186 {
1187 GList * gl;
1188 sw_view * v;
1189
1190 if (color < 0 || color > VIEW_COLOR_MAX) return;
1191
1192 s->color = color;
1193
1194 for(gl = s->views; gl; gl = gl->next) {
1195 v = (sw_view *)gl->data;
1196 view_refresh_display (v);
1197 }
1198 }
1199
1200 void
sample_set_progress_text(sw_sample * s,gchar * text)1201 sample_set_progress_text (sw_sample * s, gchar * text)
1202 {
1203 GList * gl;
1204 sw_view * v;
1205
1206 s->tmp_message_active = FALSE;
1207
1208 for(gl = s->views; gl; gl = gl->next) {
1209 v = (sw_view *)gl->data;
1210 view_set_progress_text (v, text);
1211 }
1212 }
1213
1214 void
sample_set_progress_percent(sw_sample * s,gint percent)1215 sample_set_progress_percent (sw_sample * s, gint percent)
1216 {
1217 s->progress_percent = CLAMP (percent, 0, 100);
1218 }
1219
1220 void
sample_refresh_progress_percent(sw_sample * s)1221 sample_refresh_progress_percent (sw_sample * s)
1222 {
1223 GList * gl;
1224 sw_view * v;
1225
1226 if (s->edit_state == SWEEP_EDIT_STATE_IDLE) return;
1227
1228 for(gl = s->views; gl; gl = gl->next) {
1229 v = (sw_view *)gl->data;
1230 view_set_progress_percent (v, s->progress_percent);
1231 }
1232 }
1233
1234 int
sample_set_progress_ready(sw_sample * s)1235 sample_set_progress_ready (sw_sample * s)
1236 {
1237 GList * gl;
1238 sw_view * v;
1239
1240 if (s->edit_state != SWEEP_EDIT_STATE_IDLE) return FALSE;
1241
1242 if (s->tmp_message_active) {
1243 for(gl = s->views; gl; gl = gl->next) {
1244 v = (sw_view *)gl->data;
1245 view_set_tmp_message (v, s->last_tmp_message);
1246 }
1247 } else {
1248 for(gl = s->views; gl; gl = gl->next) {
1249 v = (sw_view *)gl->data;
1250 view_set_progress_ready (v);
1251 }
1252 }
1253
1254 return FALSE; /* for use as a one-shot timeout function */
1255 }
1256
1257 gint
sample_clear_tmp_message(gpointer data)1258 sample_clear_tmp_message (gpointer data)
1259 {
1260 sw_sample * sample = (sw_sample *)data;
1261
1262 sample->tmp_message_active = FALSE;
1263
1264 if (sample->edit_state == SWEEP_EDIT_STATE_IDLE)
1265 sample_set_progress_ready (sample);
1266
1267 g_free (sample->last_tmp_message);
1268 sample->last_tmp_message = NULL;
1269
1270 sample->tmp_message_tag = -1;
1271
1272 return FALSE;
1273 }
1274
1275 void
sample_set_tmp_message(sw_sample * s,const char * fmt,...)1276 sample_set_tmp_message (sw_sample * s, const char * fmt, ...)
1277 {
1278 va_list ap;
1279 #undef BUF_LEN
1280 #define BUF_LEN 512
1281 char buf[BUF_LEN];
1282
1283 va_start (ap, fmt);
1284 vsnprintf (buf, BUF_LEN, fmt, ap);
1285 va_end (ap);
1286
1287 s->tmp_message_active = TRUE;
1288 s->last_tmp_message = g_strdup (buf);
1289
1290 if (s->tmp_message_tag != -1) {
1291 sweep_timeout_remove (s->tmp_message_tag);
1292 }
1293
1294 s->tmp_message_tag =
1295 sweep_timeout_add ((guint32)5000,
1296 (GtkFunction)sample_clear_tmp_message, s);
1297
1298 sweep_timeout_add ((guint32)0, (GtkFunction)sample_set_progress_ready, s);
1299 }
1300
1301 /*
1302 * sample_replace_throughout (os, s)
1303 *
1304 * Replaces os with s throughout the program, ie:
1305 * - in the sample bank
1306 * - in all os's views
1307 *
1308 * Destroys os.
1309 *
1310 * This function is not needed in general filters because sw_sample
1311 * pointers are persistent across sounddata modifications.
1312 * However, this function is still required where the entire sample
1313 * changes but the view must stay the same, eg. for File->Revert.
1314 */
1315 void
sample_replace_throughout(sw_sample * os,sw_sample * s)1316 sample_replace_throughout (sw_sample * os, sw_sample * s)
1317 {
1318 sw_view * v;
1319 GList * gl;
1320
1321 if (os == s) return;
1322
1323 if ((!os) || (!s)) return;
1324
1325 s->views = os->views;
1326
1327 for(gl = s->views; gl; gl = gl->next) {
1328 v = (sw_view *)gl->data;
1329 v->sample = s;
1330 /* view_refresh (v); */
1331 }
1332
1333 sample_bank_remove (os);
1334 sample_bank_add (s);
1335 }
1336
1337 gboolean
sample_offset_in_sel(sw_sample * s,sw_framecount_t offset)1338 sample_offset_in_sel (sw_sample * s, sw_framecount_t offset)
1339 {
1340 GList * gl;
1341 sw_sel * sel;
1342
1343 for (gl = s->sounddata->sels; gl; gl = gl->next) {
1344 sel = (sw_sel *)gl->data;
1345
1346 if (sel->sel_start <= offset && sel->sel_end >= offset)
1347 return TRUE;
1348 }
1349
1350 return FALSE;
1351 }
1352
1353 guint
sample_sel_nr_regions(sw_sample * s)1354 sample_sel_nr_regions (sw_sample * s)
1355 {
1356 return g_list_length (s->sounddata->sels);
1357 }
1358
1359 void
sample_clear_selection(sw_sample * s)1360 sample_clear_selection (sw_sample * s)
1361 {
1362 sounddata_clear_selection (s->sounddata);
1363
1364 sample_stop_marching_ants (s);
1365 }
1366
1367 static void
sample_normalise_selection(sw_sample * s)1368 sample_normalise_selection (sw_sample * s)
1369 {
1370 sounddata_normalise_selection (s->sounddata);
1371 }
1372
1373 void
sample_add_selection(sw_sample * s,sw_sel * sel)1374 sample_add_selection (sw_sample * s, sw_sel * sel)
1375 {
1376 if (!s->sounddata->sels)
1377 sample_start_marching_ants (s);
1378
1379 sounddata_add_selection (s->sounddata, sel);
1380 }
1381
1382 sw_sel *
sample_add_selection_1(sw_sample * s,sw_framecount_t start,sw_framecount_t end)1383 sample_add_selection_1 (sw_sample * s, sw_framecount_t start, sw_framecount_t end)
1384 {
1385 return sounddata_add_selection_1 (s->sounddata, start, end);
1386 }
1387
1388 void
sample_set_selection(sw_sample * s,GList * gl)1389 sample_set_selection (sw_sample * s, GList * gl)
1390 {
1391 sample_clear_selection(s);
1392
1393 s->sounddata->sels = sels_copy (gl);
1394 }
1395
1396 sw_sel *
sample_set_selection_1(sw_sample * s,sw_framecount_t start,sw_framecount_t end)1397 sample_set_selection_1 (sw_sample * s, sw_framecount_t start, sw_framecount_t end)
1398 {
1399 return sounddata_set_selection_1 (s->sounddata, start, end);
1400 }
1401
1402 void
sample_selection_modify(sw_sample * s,sw_sel * sel,sw_framecount_t new_start,sw_framecount_t new_end)1403 sample_selection_modify (sw_sample * s, sw_sel * sel,
1404 sw_framecount_t new_start, sw_framecount_t new_end)
1405 {
1406 sel->sel_start = new_start;
1407 sel->sel_end = new_end;
1408
1409 sample_normalise_selection (s);
1410 }
1411
1412 static sw_sample *
ss_invert(sw_sample * s,sw_param_set unused,gpointer unused2)1413 ss_invert (sw_sample * s, sw_param_set unused, gpointer unused2)
1414 {
1415 sw_sounddata * sounddata = s->sounddata;
1416 GList * gl;
1417 GList * osels;
1418 sw_sel * osel, * sel;
1419
1420 g_mutex_lock (sounddata->sels_mutex);
1421
1422 #if 0
1423 sounddata->sels = sels_invert (sounddata->sels, sounddata->nr_frames);
1424
1425 #else
1426
1427 if (!sounddata->sels) {
1428 sounddata_set_selection_1 (sounddata, 0, sounddata->nr_frames);
1429 goto out;
1430 }
1431
1432 gl = osels = sounddata->sels;
1433 sounddata->sels = NULL;
1434
1435 sel = osel = (sw_sel *)gl->data;
1436 if (osel->sel_start > 0) {
1437 sounddata_add_selection_1 (sounddata, 0, osel->sel_start - 1);
1438 }
1439
1440 gl = gl->next;
1441
1442 for (; gl; gl = gl->next) {
1443 sel = (sw_sel *)gl->data;
1444 sounddata_add_selection_1 (sounddata, osel->sel_end, sel->sel_start - 1);
1445 osel = sel;
1446 }
1447
1448 if (sel->sel_end != sounddata->nr_frames) {
1449 sounddata_add_selection_1 (sounddata, sel->sel_end, sounddata->nr_frames);
1450 }
1451
1452 g_list_free (osels);
1453
1454 out:
1455 #endif
1456
1457 g_mutex_unlock (sounddata->sels_mutex);
1458
1459 return s;
1460 }
1461
1462 void
sample_selection_invert(sw_sample * s)1463 sample_selection_invert (sw_sample * s)
1464 {
1465 perform_selection_op (s, _("Invert selection"), ss_invert, NULL, NULL);
1466 }
1467
1468 static sw_sample *
ss_select_all(sw_sample * s,sw_param_set unused,gpointer unused2)1469 ss_select_all (sw_sample * s, sw_param_set unused, gpointer unused2)
1470 {
1471 sw_sounddata * sounddata = s->sounddata;
1472
1473 g_mutex_lock (sounddata->sels_mutex);
1474
1475 sounddata_set_selection_1 (sounddata, 0, sounddata->nr_frames);
1476
1477 g_mutex_unlock (sounddata->sels_mutex);
1478
1479 return s;
1480 }
1481
1482 void
sample_selection_select_all(sw_sample * s)1483 sample_selection_select_all (sw_sample * s)
1484 {
1485 perform_selection_op (s, _("Select all"), ss_select_all, NULL, NULL);
1486 }
1487
1488 static sw_sample *
ss_select_none(sw_sample * s,sw_param_set unused,gpointer unused2)1489 ss_select_none (sw_sample * s, sw_param_set unused, gpointer unused2)
1490 {
1491 sw_sounddata * sounddata = s->sounddata;
1492
1493 g_mutex_lock (sounddata->sels_mutex);
1494
1495 sounddata_clear_selection (sounddata);
1496
1497 g_mutex_unlock (sounddata->sels_mutex);
1498
1499 return s;
1500 }
1501
1502 void
sample_selection_select_none(sw_sample * s)1503 sample_selection_select_none (sw_sample * s)
1504 {
1505 perform_selection_op (s, _("Select none"), ss_select_none, NULL, NULL);
1506 }
1507
1508 static sw_sample *
ss_halve(sw_sample * s,sw_param_set unused,gpointer unused2)1509 ss_halve (sw_sample * s, sw_param_set unused, gpointer unused2)
1510 {
1511 sw_sounddata * sounddata = s->sounddata;
1512
1513 g_mutex_lock (sounddata->sels_mutex);
1514
1515 sounddata_selection_scale (sounddata, 0.5);
1516
1517 g_mutex_unlock (sounddata->sels_mutex);
1518
1519 return s;
1520 }
1521
1522 void
sample_selection_halve(sw_sample * s)1523 sample_selection_halve (sw_sample * s)
1524 {
1525 perform_selection_op (s, _("Halve selection"), ss_halve, NULL, NULL);
1526 }
1527
1528 static sw_sample *
ss_double(sw_sample * s,sw_param_set unused,gpointer unused2)1529 ss_double (sw_sample * s, sw_param_set unused, gpointer unused2)
1530 {
1531 sw_sounddata * sounddata = s->sounddata;
1532
1533 g_mutex_lock (sounddata->sels_mutex);
1534
1535 sounddata_selection_scale (sounddata, 2.0);
1536
1537 g_mutex_unlock (sounddata->sels_mutex);
1538
1539 return s;
1540 }
1541
1542 void
sample_selection_double(sw_sample * s)1543 sample_selection_double (sw_sample * s)
1544 {
1545 perform_selection_op (s, _("Double selection"), ss_double, NULL, NULL);
1546 }
1547
1548 static sw_sample *
ss_shift_left(sw_sample * s,sw_param_set unused,gpointer unused2)1549 ss_shift_left (sw_sample * s, sw_param_set unused, gpointer unused2)
1550 {
1551 sw_sounddata * sounddata = s->sounddata;
1552
1553 sw_framecount_t delta;
1554
1555 g_mutex_lock (sounddata->sels_mutex);
1556
1557 delta = - (sounddata_selection_width (sounddata));
1558 sounddata_selection_translate (sounddata, delta);
1559
1560 g_mutex_unlock (sounddata->sels_mutex);
1561
1562 return s;
1563 }
1564
1565 void
sample_selection_shift_left(sw_sample * s)1566 sample_selection_shift_left (sw_sample * s)
1567 {
1568 perform_selection_op (s, _("Selection left"), ss_shift_left, NULL, NULL);
1569 }
1570
1571 static sw_sample *
ss_shift_right(sw_sample * s,sw_param_set unused,gpointer unused2)1572 ss_shift_right (sw_sample * s, sw_param_set unused, gpointer unused2)
1573 {
1574 sw_sounddata * sounddata = s->sounddata;
1575 sw_framecount_t delta;
1576
1577 g_mutex_lock (sounddata->sels_mutex);
1578
1579 delta = (sounddata_selection_width (sounddata));
1580 sounddata_selection_translate (sounddata, delta);
1581
1582 g_mutex_unlock (sounddata->sels_mutex);
1583
1584 return s;
1585 }
1586
1587 void
sample_selection_shift_right(sw_sample * s)1588 sample_selection_shift_right (sw_sample * s)
1589 {
1590 perform_selection_op (s, _("Selection right"), ss_shift_right, NULL, NULL);
1591 }
1592
1593 /*
1594 * Functions to handle the temporary selection
1595 */
1596
1597 void
sample_clear_tmp_sel(sw_sample * s)1598 sample_clear_tmp_sel (sw_sample * s)
1599 {
1600 if (s->tmp_sel) g_free (s->tmp_sel);
1601 s->tmp_sel = NULL;
1602 last_tmp_view = NULL;
1603 }
1604
1605
1606 /*
1607 * sample_set_tmp_sel (s, tsel)
1608 *
1609 * sets the tmp_sel of sample s to a list containing only tsel.
1610 * If tsel was part of the actual selection of s, it is first
1611 * removed from the selection.
1612 */
1613 void
sample_set_tmp_sel(sw_sample * s,sw_view * tview,sw_sel * tsel)1614 sample_set_tmp_sel (sw_sample * s, sw_view * tview, sw_sel * tsel)
1615 {
1616 GList * gl;
1617 sw_sel * sel;
1618
1619 /* XXX: Dump old tmp_sel */
1620 sample_clear_tmp_sel (s);
1621
1622 s->tmp_sel =
1623 sel_copy (tsel); /* XXX: try to do this without copying? */
1624 last_tmp_view = tview;
1625
1626 g_mutex_lock (s->sounddata->sels_mutex);
1627
1628 for(gl = s->sounddata->sels; gl; gl = gl->next) {
1629 sel = (sw_sel *)gl->data;
1630
1631 if(sel == tsel) {
1632 s->sounddata->sels = g_list_remove(s->sounddata->sels, sel);
1633 }
1634 }
1635
1636 g_mutex_unlock (s->sounddata->sels_mutex);
1637 }
1638
1639 void
sample_set_tmp_sel_1(sw_sample * s,sw_view * tview,sw_framecount_t start,sw_framecount_t end)1640 sample_set_tmp_sel_1 (sw_sample * s, sw_view * tview, sw_framecount_t start, sw_framecount_t end)
1641 {
1642 sw_sel * tsel;
1643
1644 tsel = sel_new (start, end);
1645
1646 sample_set_tmp_sel (s, tview, tsel);
1647 }
1648
1649 /* For convenience, as the tmp_sel handling is internal to the application,
1650 * we pass the actual sw_sample pointer to the tmp_sel handling ops.
1651 */
1652
1653 static sw_sample *
ssits(sw_sample * s,sw_param_set unused,gpointer data)1654 ssits (sw_sample * s, sw_param_set unused, gpointer data)
1655 {
1656 sw_sel * sel = (sw_sel *)data;
1657
1658 g_mutex_lock (s->sounddata->sels_mutex);
1659
1660 sample_add_selection (s, sel);
1661 sample_normalise_selection (s);
1662
1663 g_mutex_unlock (s->sounddata->sels_mutex);
1664
1665 return s;
1666 }
1667
1668 void
sample_selection_insert_tmp_sel(sw_sample * s)1669 sample_selection_insert_tmp_sel (sw_sample * s)
1670 {
1671 int n;
1672 #undef BUF_LEN
1673 #define BUF_LEN 64
1674 gchar buf[BUF_LEN];
1675 sw_format * format = s->sounddata->format;
1676 sw_sel * sel;
1677
1678 n = snprintf (buf, BUF_LEN, _("Insert selection ["));
1679 n += snprint_time (buf+n, BUF_LEN-n,
1680 frames_to_time (format, s->tmp_sel->sel_start));
1681 n += snprintf (buf+n, BUF_LEN-n, " - ");
1682 n += snprint_time (buf+n, BUF_LEN-n,
1683 frames_to_time (format, s->tmp_sel->sel_end));
1684 n += snprintf (buf+n, BUF_LEN-n, "]");
1685
1686 g_mutex_lock (s->sounddata->sels_mutex);
1687
1688 sel = sel_copy (s->tmp_sel);
1689
1690 s->tmp_sel = NULL;
1691 last_tmp_view = NULL;
1692
1693 g_mutex_unlock (s->sounddata->sels_mutex);
1694
1695 perform_selection_op (s, buf, ssits, NULL, sel);
1696 #undef BUF_LEN
1697 }
1698
1699 static sw_sample *
sssts(sw_sample * s,sw_param_set unused,gpointer data)1700 sssts (sw_sample * s, sw_param_set unused, gpointer data)
1701 {
1702 GList * sels;
1703 sw_sel * sel = (sw_sel *)data;
1704
1705 g_mutex_lock (s->sounddata->sels_mutex);
1706
1707 sels = s->sounddata->sels;
1708
1709 sels = sels_invert (sels, s->sounddata->nr_frames);
1710 s->sounddata->sels = sels_add_selection (sels, sel);
1711
1712 sample_normalise_selection (s);
1713 sels = s->sounddata->sels;
1714
1715 s->sounddata->sels = sels_invert (sels, s->sounddata->nr_frames);
1716
1717 g_mutex_unlock (s->sounddata->sels_mutex);
1718
1719 return s;
1720 }
1721
1722 void
sample_selection_subtract_tmp_sel(sw_sample * s)1723 sample_selection_subtract_tmp_sel (sw_sample * s)
1724 {
1725 int n;
1726 #define BUF_LEN 64
1727 gchar buf[BUF_LEN];
1728 sw_format * format = s->sounddata->format;
1729 sw_sel * sel;
1730
1731 n = snprintf (buf, BUF_LEN, _("Subtract selection ["));
1732 n += snprint_time (buf+n, BUF_LEN-n,
1733 frames_to_time (format, s->tmp_sel->sel_start));
1734 n += snprintf (buf+n, BUF_LEN-n, " - ");
1735 n += snprint_time (buf+n, BUF_LEN-n,
1736 frames_to_time (format, s->tmp_sel->sel_end));
1737 n += snprintf (buf+n, BUF_LEN-n, "]");
1738
1739 g_mutex_lock (s->sounddata->sels_mutex);
1740
1741 sel = sel_copy (s->tmp_sel);
1742
1743 s->tmp_sel = NULL;
1744 last_tmp_view = NULL;
1745
1746 g_mutex_unlock (s->sounddata->sels_mutex);
1747
1748 perform_selection_op (s, buf, sssts, NULL, sel);
1749 }
1750
1751 static sw_sample *
ssrwts(sw_sample * s,sw_param_set unused,gpointer data)1752 ssrwts (sw_sample * s, sw_param_set unused, gpointer data)
1753 {
1754 sw_sel * sel = (sw_sel *)data;
1755
1756 g_mutex_lock (s->sounddata->sels_mutex);
1757
1758 sample_clear_selection (s);
1759
1760 sample_add_selection (s, sel);
1761
1762 g_mutex_unlock (s->sounddata->sels_mutex);
1763
1764 return s;
1765 }
1766
1767 void
sample_selection_replace_with_tmp_sel(sw_sample * s)1768 sample_selection_replace_with_tmp_sel (sw_sample * s)
1769 {
1770 int n;
1771 #define BUF_LEN 64
1772 gchar buf[BUF_LEN];
1773 sw_format * format = s->sounddata->format;
1774 sw_sel * sel;
1775
1776 n = snprintf (buf, BUF_LEN, _("Set selection ["));
1777 n += snprint_time (buf+n, BUF_LEN-n,
1778 frames_to_time (format, s->tmp_sel->sel_start));
1779 n += snprintf (buf+n, BUF_LEN-n, " - ");
1780 n += snprint_time (buf+n, BUF_LEN-n,
1781 frames_to_time (format, s->tmp_sel->sel_end));
1782 n += snprintf (buf+n, BUF_LEN-n, "]");
1783
1784 g_mutex_lock (s->sounddata->sels_mutex);
1785
1786 sel = sel_copy (s->tmp_sel);
1787
1788 s->tmp_sel = NULL;
1789 last_tmp_view = NULL;
1790
1791 g_mutex_unlock (s->sounddata->sels_mutex);
1792
1793 perform_selection_op (s, buf, ssrwts, NULL, sel);
1794 }
1795
1796
1797 /* Sample info dialog */
1798
1799 static void
sample_info_update(sw_sample * sample)1800 sample_info_update (sw_sample * sample)
1801 {
1802 sw_sounddata * sounddata = sample->sounddata;
1803 GtkWidget * clist = sample->info_clist;
1804
1805 #define RATE_BUF_LEN 16
1806 char rate_buf[RATE_BUF_LEN];
1807
1808 #define CHAN_BUF_LEN 16
1809 char chan_buf[CHAN_BUF_LEN];
1810
1811 #define BYTE_BUF_LEN 16
1812 char byte_buf[BYTE_BUF_LEN];
1813
1814 #define TIME_BUF_LEN 16
1815 char time_buf[TIME_BUF_LEN];
1816
1817 if (clist == NULL) return;
1818
1819 snprintf (rate_buf, RATE_BUF_LEN, "%d Hz", sounddata->format->rate);
1820
1821 snprintf (chan_buf, CHAN_BUF_LEN, "%d", sounddata->format->channels);
1822
1823 snprint_bytes (byte_buf, BYTE_BUF_LEN,
1824 frames_to_bytes (sounddata->format, sounddata->nr_frames));
1825
1826 snprint_time (time_buf, TIME_BUF_LEN,
1827 frames_to_time (sounddata->format, sounddata->nr_frames));
1828
1829
1830 gtk_clist_set_text (GTK_CLIST(clist), 0, 1, g_basename(sample->pathname));
1831 gtk_clist_set_text (GTK_CLIST(clist), 1, 1, rate_buf);
1832 gtk_clist_set_text (GTK_CLIST(clist), 2, 1, chan_buf);
1833 gtk_clist_set_text (GTK_CLIST(clist), 3, 1, byte_buf);
1834 gtk_clist_set_text (GTK_CLIST(clist), 4, 1, time_buf);
1835
1836 }
1837
1838 static void
sample_info_dialog_destroy_cb(GtkWidget * widget,gpointer data)1839 sample_info_dialog_destroy_cb (GtkWidget * widget, gpointer data)
1840 {
1841 sw_sample * sample = (sw_sample *)data;
1842
1843 sample->info_clist = NULL;
1844 }
1845
1846 static void
sample_info_dialog_ok_cb(GtkWidget * widget,gpointer data)1847 sample_info_dialog_ok_cb (GtkWidget * widget, gpointer data)
1848 {
1849 GtkWidget * dialog;
1850
1851 dialog = gtk_widget_get_toplevel (widget);
1852 gtk_widget_hide (dialog);
1853 }
1854
1855 /*
1856 static gchar * filename_info[] = { N_("Filename:"), "" };
1857 static gchar * rate_info[] = { N_("Sampling rate:"), "" };
1858 static gchar * channels_info[] = { N_("Channels:"), "" };
1859 static gchar * size_info[] = { N_("Data memory:"), "" };
1860 static gchar * duration_info[] = { N_("Duration:"), "" };
1861 */
1862
1863 void
sample_show_info_dialog(sw_sample * sample)1864 sample_show_info_dialog (sw_sample * sample)
1865 {
1866 GtkWidget * dialog;
1867 GtkWidget * clist;
1868 GtkWidget * ok_button;
1869 gchar * list_item[] = { "" };
1870 gint i=0;
1871
1872 if (sample->info_clist == NULL) {
1873 dialog = gtk_dialog_new ();
1874 gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
1875 gtk_window_set_title (GTK_WINDOW(dialog), _("Sweep: File properties"));
1876 gtk_container_set_border_width (GTK_CONTAINER(dialog), 8);
1877
1878 g_signal_connect (G_OBJECT(dialog), "destroy",
1879 G_CALLBACK(sample_info_dialog_destroy_cb),
1880 sample);
1881
1882 clist = gtk_clist_new (2);
1883 gtk_clist_set_selection_mode (GTK_CLIST(clist), GTK_SELECTION_BROWSE);
1884 gtk_clist_set_column_justification (GTK_CLIST(clist), 0,
1885 GTK_JUSTIFY_RIGHT);
1886 gtk_clist_set_column_justification (GTK_CLIST(clist), 1,
1887 GTK_JUSTIFY_LEFT);
1888 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), clist,
1889 FALSE, FALSE, 0);
1890 /*
1891 gtk_clist_append (GTK_CLIST(clist), filename_info);
1892 gtk_clist_append (GTK_CLIST(clist), rate_info);
1893 gtk_clist_append (GTK_CLIST(clist), channels_info);
1894 gtk_clist_append (GTK_CLIST(clist), size_info);
1895 gtk_clist_append (GTK_CLIST(clist), duration_info);
1896 */
1897
1898 gtk_clist_append (GTK_CLIST(clist), list_item);
1899 gtk_clist_set_text (GTK_CLIST(clist), i++, 0, _("Filename: "));
1900 gtk_clist_append (GTK_CLIST(clist), list_item);
1901 gtk_clist_set_text (GTK_CLIST(clist), i++, 0, _("Sampling rate: "));
1902 gtk_clist_append (GTK_CLIST(clist), list_item);
1903 gtk_clist_set_text (GTK_CLIST(clist), i++, 0, _("Channels: "));
1904 gtk_clist_append (GTK_CLIST(clist), list_item);
1905 gtk_clist_set_text (GTK_CLIST(clist), i++, 0, _("Data memory: "));
1906 gtk_clist_append (GTK_CLIST(clist), list_item);
1907 gtk_clist_set_text (GTK_CLIST(clist), i++, 0, _("Duration: "));
1908
1909 gtk_clist_set_column_min_width (GTK_CLIST(clist), 0, 120);
1910 gtk_clist_set_column_min_width (GTK_CLIST(clist), 1, 160);
1911
1912 gtk_widget_show (clist);
1913
1914 sample->info_clist = clist;
1915
1916 /* OK */
1917
1918 ok_button = gtk_button_new_with_label (_("OK"));
1919 GTK_WIDGET_SET_FLAGS (GTK_WIDGET (ok_button), GTK_CAN_DEFAULT);
1920 gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->action_area), ok_button,
1921 TRUE, TRUE, 0);
1922 gtk_widget_show (ok_button);
1923 g_signal_connect (G_OBJECT(ok_button), "clicked",
1924 G_CALLBACK (sample_info_dialog_ok_cb), sample);
1925
1926 gtk_widget_grab_default (ok_button);
1927
1928 } else {
1929 dialog = gtk_widget_get_toplevel (sample->info_clist);
1930 }
1931
1932 sample_info_update (sample);
1933
1934 if (!GTK_WIDGET_VISIBLE(dialog)) {
1935 gtk_widget_show (dialog);
1936 } else {
1937 gdk_window_raise (dialog->window);
1938 }
1939 }
1940