1 /*
2  * Copyright (C) 2009, Magnus Hjorth
3  *
4  * This file is part of mhWaveEdit.
5  *
6  * mhWaveEdit 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  * mhWaveEdit 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 mhWaveEdit; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 
22 #include <config.h>
23 
24 #include "sandwichdialog.h"
25 #include "gettext.h"
26 #include "effectbrowser.h"
27 #include "um.h"
28 
sandwich_dialog_apply(EffectDialog * ed)29 static gboolean sandwich_dialog_apply(EffectDialog *ed)
30 {
31      SandwichDialog *sd = SANDWICH_DIALOG(ed);
32      Document *d1, *d2;
33      Chunk *c1, *c2, *t, *r;
34      off_t c1ap, c2ap, apo;
35      Dataformat fmt;
36      const gchar *c;
37 
38      d1 = EFFECT_BROWSER(ed->eb)->dl->selected;
39      d2 = sd->docsel->selected;
40 
41      c1 = d1->chunk;
42      c2 = d2->chunk;
43 
44      if (gtk_toggle_button_get_active(sd->align_begin)) {
45 	  c1ap = c2ap = 0;
46      } else if (gtk_toggle_button_get_active(sd->align_end)) {
47 	  c1ap = c1->length-1;
48 	  c2ap = c2->length-1;
49      } else if (gtk_toggle_button_get_active(sd->align_marker)) {
50 	  c = gtk_entry_get_text(sd->marker_entry);
51 	  c1ap = document_get_mark(d1,c);
52 	  c2ap = document_get_mark(d2,c);
53 	  if (c1ap == DOCUMENT_BAD_MARK || c2ap == DOCUMENT_BAD_MARK) {
54 	       user_error("Mark does not exist in both documents.");
55 	       return TRUE;
56 	  }
57      } else {
58 	  c1ap = c2ap = 0; /* Silence compiler */
59 	  g_assert_not_reached();
60      }
61 
62      t = NULL;
63      if (!dataformat_samples_equal(&(c1->format),&(c2->format)) ||
64 	 c1->format.samplerate != c2->format.samplerate) {
65 	  memcpy(&fmt,&(c1->format),sizeof(Dataformat));
66 	  fmt.channels = c2->format.channels;
67 	  t = chunk_convert(c2, &fmt, dither_editing, d1->bar);
68 	  if (t == NULL) return TRUE;
69 
70 	  if (t->format.samplerate != c2->format.samplerate) {
71 	       if (c2ap >= c2->length-1) c2ap = t->length-1;
72 	       else c2ap = (c2ap*t->format.samplerate)/(c2->format.samplerate);
73 	  }
74 
75 	  c2 = t;
76      }
77 
78      g_assert(dataformat_samples_equal(&(c1->format),&(c2->format)) &&
79 	      c1->format.samplerate == c2->format.samplerate);
80 
81      r = chunk_sandwich(c1,c2,c1ap,c2ap,&apo,dither_editing,d1->bar);
82 
83      if (t != NULL) gtk_object_sink(GTK_OBJECT(t));
84      if (r == NULL) return TRUE;
85 
86      document_update(d1, r, 0, apo-c1ap);
87      return FALSE;
88 }
89 
sandwich_dialog_class_init(SandwichDialogClass * klass)90 static void sandwich_dialog_class_init(SandwichDialogClass *klass)
91 {
92      EFFECT_DIALOG_CLASS(klass)->apply = sandwich_dialog_apply;
93 }
94 
marker_entry_changed(GtkEditable * editable,gpointer user_data)95 static void marker_entry_changed(GtkEditable *editable, gpointer user_data)
96 {
97      SandwichDialog *obj = SANDWICH_DIALOG(user_data);
98      gtk_toggle_button_set_active(obj->align_marker,TRUE);
99 }
100 
sandwich_dialog_init(SandwichDialog * obj)101 static void sandwich_dialog_init(SandwichDialog *obj)
102 {
103      GtkWidget *a,*b,*c,*d;
104 
105      a = document_list_new(NULL);
106      obj->docsel = DOCUMENT_LIST(a);
107      a = gtk_radio_button_new_with_label(NULL,_("Align beginning of files"));
108      obj->align_begin = GTK_TOGGLE_BUTTON(a);
109      a = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(a),
110 						     _("Align end of files"));
111      obj->align_end = GTK_TOGGLE_BUTTON(a);
112      a = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(a),
113 						     _("Align at marker: "));
114      obj->align_marker = GTK_TOGGLE_BUTTON(a);
115      gtk_toggle_button_set_active(obj->align_begin,TRUE);
116      a = gtk_entry_new();
117      obj->marker_entry = GTK_ENTRY(a);
118      gtk_entry_set_width_chars(obj->marker_entry, 7);
119      gtk_entry_set_text(obj->marker_entry, "0");
120      gtk_signal_connect(GTK_OBJECT(obj->marker_entry),"changed",
121 			GTK_SIGNAL_FUNC(marker_entry_changed),obj);
122 
123      a = gtk_vbox_new(FALSE,3);
124      b = gtk_hbox_new(FALSE,0);
125      gtk_container_add(GTK_CONTAINER(a),b);
126      c = gtk_label_new(_("Add channels from: "));
127      gtk_box_pack_start(GTK_BOX(b),c,FALSE,FALSE,0);
128      c = GTK_WIDGET(obj->docsel);
129      gtk_box_pack_start(GTK_BOX(b),c,TRUE,TRUE,0);
130      b = gtk_frame_new(_("Alignment"));
131      gtk_container_add(GTK_CONTAINER(a),b);
132      c = gtk_vbox_new(TRUE,0);
133      gtk_container_add(GTK_CONTAINER(b),c);
134      gtk_container_set_border_width(GTK_CONTAINER(c),3);
135      gtk_box_pack_start(GTK_BOX(c),GTK_WIDGET(obj->align_begin),FALSE,FALSE,0);
136      gtk_box_pack_start(GTK_BOX(c),GTK_WIDGET(obj->align_end),FALSE,FALSE,0);
137      d = gtk_hbox_new(FALSE,0);
138      gtk_box_pack_start(GTK_BOX(c),d,FALSE,FALSE,0);
139      gtk_box_pack_start(GTK_BOX(d),GTK_WIDGET(obj->align_marker),FALSE,FALSE,0);
140      gtk_box_pack_start(GTK_BOX(d),GTK_WIDGET(obj->marker_entry),FALSE,FALSE,0);
141 
142      gtk_box_pack_start(GTK_BOX(EFFECT_DIALOG(obj)->input_area),
143 			a,FALSE,FALSE,0);
144      gtk_widget_show_all(a);
145 }
146 
sandwich_dialog_get_type(void)147 GtkType sandwich_dialog_get_type(void)
148 {
149      static GtkType id = 0;
150      if (!id) {
151 	  GtkTypeInfo info = {
152 	       "SandwichDialog",
153 	       sizeof(SandwichDialog),
154 	       sizeof(SandwichDialogClass),
155 	       (GtkClassInitFunc) sandwich_dialog_class_init,
156 	       (GtkObjectInitFunc) sandwich_dialog_init
157 	  };
158 	  id = gtk_type_unique(effect_dialog_get_type(),&info);
159      }
160      return id;
161 }
162