1 /*
2 * Copyright (C) 2002 2003 2004 2005, 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 "mainwindow.h"
25 #include "combinechannelsdialog.h"
26 #include "effectbrowser.h"
27 #include "main.h"
28
29 static GtkObjectClass *parent_class;
30 static sample_t *combination_matrix;
31 static sample_t *samples = NULL;
32
combine_channels_dialog_apply_proc(void * in,guint sample_size,chunk_writeout_func out_func,WriteoutID id,Dataformat * format)33 static gboolean combine_channels_dialog_apply_proc(void *in, guint sample_size,
34 chunk_writeout_func out_func,
35 WriteoutID id,
36 Dataformat *format)
37 {
38 sample_t *s = (sample_t *)in, d;
39 guint i,j,chn=format->channels;
40 if (!samples)
41 samples = g_malloc(sample_size);
42 for (i=0; i<chn; i++) {
43 d = 0.0;
44 for (j=0; j<chn; j++)
45 d += s[j] * combination_matrix[i*chn+j];
46 samples[i] = d;
47 }
48 return out_func(id,samples,sample_size);
49 }
50
combine_channels_dialog_apply(EffectDialog * ed)51 static gboolean combine_channels_dialog_apply(EffectDialog *ed)
52 {
53 guint i;
54 gboolean b;
55 Document *d = EFFECT_BROWSER(ed->eb)->dl->selected;
56 CombineChannelsDialog *ccd = COMBINE_CHANNELS_DIALOG(ed);
57 g_assert(ccd->channels == d->chunk->format.channels);
58 for (i=0; i<ccd->channels*ccd->channels; i++)
59 if (floatbox_check(ccd->combination_matrix[i])) return TRUE;
60 combination_matrix =g_malloc(ccd->channels*ccd->channels*sizeof(sample_t));
61 for (i=0; i<ccd->channels*ccd->channels; i++)
62 combination_matrix[i] = ccd->combination_matrix[i]->val / 100.0;
63 b = document_apply(d,combine_channels_dialog_apply_proc,NULL,
64 CHUNK_FILTER_FULL,TRUE,NULL);
65 g_free(samples);
66 samples = NULL;
67 g_free(combination_matrix);
68 return b;
69 }
70
combine_channels_dialog_target_changed(EffectDialog * ed)71 static void combine_channels_dialog_target_changed(EffectDialog *ed)
72 {
73 CombineChannelsDialog *ccd = COMBINE_CHANNELS_DIALOG(ed);
74 if (ccd->channels != EFFECT_BROWSER(ed->eb)->dl->format.channels)
75 effect_browser_invalidate_effect(EFFECT_BROWSER(ed->eb),"combine",
76 'B');
77 }
78
combine_channels_setup(EffectDialog * ed)79 static void combine_channels_setup(EffectDialog *ed)
80 {
81 int i,j;
82 GtkWidget *a,*b,*c;
83 guint channels = EFFECT_BROWSER(ed->eb)->dl->format.channels;
84 CombineChannelsDialog *ccd = COMBINE_CHANNELS_DIALOG(ed);
85 ccd->channels = channels;
86 ccd->combination_matrix = g_malloc(channels*channels*sizeof(Floatbox *));
87 for (i=0; i<channels*channels; i++)
88 ccd->combination_matrix[i] =
89 FLOATBOX(floatbox_new( (i%(channels+1)==0) ? 100.0 : 0.0 ));
90 for (i=0; i<ccd->channels; i++) {
91 a=gtk_frame_new(channel_name(i,channels));
92 gtk_container_set_border_width(GTK_CONTAINER(a),3);
93 gtk_box_pack_start(GTK_BOX(ed->input_area),a,FALSE,FALSE,0);
94 gtk_widget_show(a);
95 b = gtk_table_new(channels,3,FALSE);
96 gtk_container_add(GTK_CONTAINER(a),b);
97 gtk_widget_show(b);
98 for (j=0; j<channels; j++) {
99 c=gtk_label_new(channel_name(j,channels));
100 gtk_table_attach(GTK_TABLE(b),c,0,1,j,j+1,GTK_FILL,0,3,3);
101 gtk_widget_show(c);
102 c = GTK_WIDGET(ccd->combination_matrix[i*channels+j]);
103 gtk_table_attach(GTK_TABLE(b),c,1,2,j,j+1,GTK_FILL,0,3,3);
104 gtk_widget_show(c);
105 c = gtk_label_new("%");
106 gtk_table_attach(GTK_TABLE(b),c,2,3,j,j+1,GTK_FILL,0,0,3);
107 gtk_widget_show(c);
108 }
109 }
110 }
111
combine_channels_destroy(GtkObject * obj)112 static void combine_channels_destroy(GtkObject *obj)
113 {
114 CombineChannelsDialog *ccd = COMBINE_CHANNELS_DIALOG(obj);
115 g_free(ccd->combination_matrix);
116 ccd->combination_matrix = NULL;
117 parent_class->destroy(obj);
118 }
119
combine_channels_dialog_class_init(EffectDialogClass * klass)120 static void combine_channels_dialog_class_init(EffectDialogClass *klass)
121 {
122 parent_class = gtk_type_class(effect_dialog_get_type());
123 klass->apply = combine_channels_dialog_apply;
124 klass->setup = combine_channels_setup;
125 klass->target_changed = combine_channels_dialog_target_changed;
126 GTK_OBJECT_CLASS(klass)->destroy = combine_channels_destroy;
127 }
128
combine_channels_dialog_init(CombineChannelsDialog * obj)129 static void combine_channels_dialog_init(CombineChannelsDialog *obj)
130 {
131 }
132
combine_channels_dialog_get_type(void)133 GtkType combine_channels_dialog_get_type(void)
134 {
135 static GtkType id = 0;
136 if (!id) {
137 GtkTypeInfo info = {
138 "CombineChannelsDialog",
139 sizeof(CombineChannelsDialog),
140 sizeof(CombineChannelsDialogClass),
141 (GtkClassInitFunc)combine_channels_dialog_class_init,
142 (GtkObjectInitFunc)combine_channels_dialog_init
143 };
144 id = gtk_type_unique(effect_dialog_get_type(),&info);
145 }
146 return id;
147 }
148