1 /*
2 * Copyright (C) 2002 2003 2004, 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 <math.h>
25 #include <gtk/gtk.h>
26 #include "mainwindow.h"
27 #include "effectdialog.h"
28 #include "effectbrowser.h"
29 #include "volumedialog.h"
30 #include "float_box.h"
31 #include "gettext.h"
32
33
volume_dialog_apply_proc(Chunk * chunk,StatusBar * bar,gpointer user_data)34 static Chunk *volume_dialog_apply_proc(Chunk *chunk, StatusBar *bar,
35 gpointer user_data)
36 {
37 VolumeDialog *v = VOLUME_DIALOG(user_data);
38 return chunk_volume_ramp(chunk,v->start_percent->val / 100.0,
39 v->end_percent->val / 100.0,dither_editing,bar);
40 }
41
volume_dialog_apply(EffectDialog * ed)42 static gboolean volume_dialog_apply(EffectDialog *ed)
43 {
44 sample_t sv,ev;
45 VolumeDialog *v = VOLUME_DIALOG(ed);
46 if (floatbox_check(v->start_percent) || floatbox_check(v->end_percent))
47 return TRUE;
48 sv = v->start_percent->val / 100.0;
49 ev = v->end_percent->val / 100.0;
50 if (sv == ev && sv == 1.0) return FALSE;
51 return document_apply_cb(EFFECT_BROWSER(ed->eb)->dl->selected,
52 volume_dialog_apply_proc,TRUE,v);
53 }
54
55 static sample_t peak;
56
findtop_proc(void * sample,gint sample_size,Chunk * chunk)57 static gboolean findtop_proc(void *sample, gint sample_size, Chunk *chunk)
58 {
59 sample_t d;
60 d = fabs(* ((sample_t *)sample));
61 if (d>peak) peak = d;
62 return (d>=1.0);
63 }
64
findtop(VolumeDialog * v)65 static void findtop(VolumeDialog *v)
66 {
67 gfloat f;
68 Document *d = EFFECT_BROWSER(EFFECT_DIALOG(v)->eb)->dl->selected;
69 peak = 0.0;
70 if (d == NULL) return;
71 document_parse(d,findtop_proc,FALSE,TRUE,_("Calculating peak volume..."));
72 gdk_window_raise(GTK_WIDGET(EFFECT_DIALOG(v)->eb)->window);
73 f = 100.0 * maximum_float_value(&(d->chunk->format)) / peak;
74 if (f < 100.0) f = 100.0;
75 floatbox_set(v->start_percent,f);
76 floatbox_set(v->end_percent,f);
77 }
78
volume_dialog_init(VolumeDialog * v)79 static void volume_dialog_init(VolumeDialog *v)
80 {
81 GtkWidget *a,*b,*c;
82
83 a = gtk_hbox_new(FALSE,3);
84 gtk_box_pack_start(GTK_BOX(EFFECT_DIALOG(v)->input_area),a,FALSE,FALSE,0);
85 b = gtk_table_new(2,3,FALSE);
86 gtk_box_pack_start(GTK_BOX(a),b,FALSE,FALSE,0);
87 c = gtk_label_new (_("Start:"));
88 gtk_label_set_justify(GTK_LABEL(c),GTK_JUSTIFY_RIGHT);
89 gtk_table_attach(GTK_TABLE(b),c,0,1,0,1,0,0,0,0);
90 c = gtk_label_new (_("End:"));
91 gtk_label_set_justify(GTK_LABEL(c),GTK_JUSTIFY_RIGHT);
92 gtk_table_attach(GTK_TABLE(b),c,0,1,1,2,0,0,0,0);
93 c = floatbox_new(100.0);
94 v->start_percent = FLOATBOX(c);
95 gtk_table_attach(GTK_TABLE(b),c,1,2,0,1,
96 GTK_EXPAND|GTK_SHRINK|GTK_FILL,0,3,0);
97 gtk_widget_show(c);
98 c = floatbox_new(100.0);
99 v->end_percent = FLOATBOX(c);
100 gtk_table_attach(GTK_TABLE(b), c, 1, 2, 1, 2,
101 GTK_EXPAND|GTK_SHRINK|GTK_FILL,0,3,0);
102 gtk_widget_show(c);
103 c = gtk_label_new("%");
104 gtk_table_attach(GTK_TABLE(b),c,2,3,0,1,0,0,0,0);
105 c = gtk_label_new("%");
106 gtk_table_attach(GTK_TABLE(b),c,2,3,1,2,0,0,0,0);
107 b = gtk_alignment_new(0,1,0,0);
108 gtk_box_pack_start(GTK_BOX(a),b,FALSE,FALSE,0);
109 c = gtk_button_new_with_label(_("Find top volume"));
110 gtk_signal_connect_object(GTK_OBJECT(c),"clicked",
111 GTK_SIGNAL_FUNC(findtop),GTK_OBJECT(v));
112 gtk_container_add(GTK_CONTAINER(b),c);
113 gtk_widget_show_all(a);
114 }
115
volume_dialog_class_init(EffectDialogClass * klass)116 static void volume_dialog_class_init(EffectDialogClass *klass)
117 {
118 klass->apply = volume_dialog_apply;
119 }
120
volume_dialog_get_type(void)121 GtkType volume_dialog_get_type(void)
122 {
123 static GtkType id = 0;
124 if (!id) {
125 GtkTypeInfo info = {
126 "VolumeDialog",
127 sizeof(VolumeDialog),
128 sizeof(VolumeDialogClass),
129 (GtkClassInitFunc) volume_dialog_class_init,
130 (GtkObjectInitFunc) volume_dialog_init
131 };
132 id = gtk_type_unique(effect_dialog_get_type(),&info);
133 }
134 return id;
135 }
136