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