3
* $Id: normalize.c,v 1.9.2.1 2002/01/23 20:23:54 richi Exp $
5
* Copyright (C) 2001 Alexander Ehlert
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
#include <sys/types.h>
37
#include "util/glame_gui_utils.h"
38
#include "network_utils.h"
42
typedef struct task_entry task_entry_t;
45
struct glame_list_head list;
51
GtkWidget *dialog, *appbar, *text, *spin_db, *spin_abs, *spin_freq;
52
GtkWidget *analyze_button, /* *simulate_button,*/ *ok_button;
55
long total_size, start, length;
57
float ampl_abs, ampl_db, maxrms;
65
static void cleanup_task_list(struct normalize_s *ns) {
66
task_entry_t *task, *last, *next;
71
last = task = ns->head;
73
next = glame_list_getnext(&task->list, task, task_entry_t, list);
76
} while ( (task!=last) && (task!=NULL));
80
static gint normmode_cb(GtkMenu *menu, struct normalize_s* ns)
82
int oldmode = ns->mode;
83
ns->mode = glame_menu_get_active_index(menu);
84
DPRINTF("Selected normalize mode %d\n", ns->mode);
87
gtk_widget_set_sensitive(ns->spin_abs, FALSE);
88
gtk_widget_set_sensitive(ns->spin_db, FALSE);
89
gtk_widget_set_sensitive(ns->spin_freq, FALSE);
96
gtk_widget_set_sensitive(ns->spin_abs, TRUE);
97
gtk_widget_set_sensitive(ns->spin_db, TRUE);
98
gtk_widget_set_sensitive(ns->spin_freq, FALSE);
101
gtk_widget_set_sensitive(ns->spin_abs, TRUE);
102
gtk_widget_set_sensitive(ns->spin_db, TRUE);
103
gtk_widget_set_sensitive(ns->spin_freq, TRUE);
112
static gint ampl_abs_cb(GtkSpinButton *button, struct normalize_s* ns) {
113
ns->ampl_abs = gtk_spin_button_get_value_as_float(button);
114
ns->ampl_db = GAIN2DB(ns->ampl_abs);
115
gtk_spin_button_set_value(GTK_SPIN_BUTTON(ns->spin_db), ns->ampl_db);
119
static gint ampl_db_cb(GtkSpinButton *button, struct normalize_s* ns) {
120
ns->ampl_db = gtk_spin_button_get_value_as_float(button);
121
ns->ampl_abs = DB2GAIN(ns->ampl_db);
122
gtk_spin_button_set_value(GTK_SPIN_BUTTON(ns->spin_abs), ns->ampl_abs);
126
static gint norm_freq_cb(GtkSpinButton *button, struct normalize_s* ns) {
127
ns->freq = gtk_spin_button_get_value_as_int(button);
132
static gint cancel_cb(GtkWidget *button, struct normalize_s* ns) {
135
gtk_widget_destroy(ns->dialog);
139
static gint paranoia_cb(GtkWidget *bla, struct normalize_s* ns) {
145
/* static void simulate_cb(GtkWidget *, struct normalize_s*); */
146
static void analyze_cb(GtkWidget *, struct normalize_s*);
147
static void normalize_cb(GtkWidget *, struct normalize_s*);
149
void normalize_dialog(struct normalize_s* norms)
152
GtkWidget *dialog_vbox1;
154
GtkWidget *vbox1, *hbox1;
161
GtkObject *spinbutton1_adj;
162
GtkWidget *spinbutton1;
163
GtkObject *spinbutton2_adj;
164
GtkWidget *spinbutton2;
165
GtkWidget *optionmenu1;
166
GtkWidget *optionmenu1_menu;
167
GtkWidget *glade_menuitem;
169
GtkObject *spinbutton3_adj;
170
GtkWidget *spinbutton3;
172
GtkWidget *scrolledwindow1;
174
GtkWidget /* *button4,*/ *button5;
176
GtkWidget *dialog_action_area1;
180
norms->dialog = dialog1 = gnome_dialog_new (NULL, NULL);
181
gtk_object_set_data (GTK_OBJECT (dialog1), "dialog1", dialog1);
182
gtk_window_set_policy (GTK_WINDOW (dialog1), FALSE, FALSE, FALSE);
184
dialog_vbox1 = GNOME_DIALOG (dialog1)->vbox;
185
gtk_object_set_data (GTK_OBJECT (dialog1), "dialog_vbox1", dialog_vbox1);
186
gtk_widget_show (dialog_vbox1);
188
frame1 = gtk_frame_new (_("Normalize"));
189
gtk_widget_ref (frame1);
190
gtk_object_set_data_full (GTK_OBJECT (dialog1), "frame1", frame1,
191
(GtkDestroyNotify) gtk_widget_unref);
192
gtk_widget_show (frame1);
193
gtk_box_pack_start (GTK_BOX (dialog_vbox1), frame1, TRUE, TRUE, 0);
194
gtk_container_set_border_width (GTK_CONTAINER (frame1), 3);
196
vbox1 = gtk_vbox_new (FALSE, 6);
197
gtk_widget_ref (vbox1);
198
gtk_object_set_data_full (GTK_OBJECT (dialog1), "vbox1", vbox1,
199
(GtkDestroyNotify) gtk_widget_unref);
200
gtk_widget_show (vbox1);
201
gtk_container_add (GTK_CONTAINER (frame1), vbox1);
202
gtk_container_set_border_width (GTK_CONTAINER (vbox1), 3);
204
table1 = gtk_table_new (3, 2, FALSE);
205
gtk_widget_ref (table1);
206
gtk_object_set_data_full (GTK_OBJECT (dialog1), "table1", table1,
207
(GtkDestroyNotify) gtk_widget_unref);
208
gtk_widget_show (table1);
209
gtk_box_pack_start (GTK_BOX (vbox1), table1, TRUE, TRUE, 0);
210
gtk_container_set_border_width (GTK_CONTAINER (table1), 4);
211
gtk_table_set_row_spacings (GTK_TABLE (table1), 8);
213
label3 = gtk_label_new (_("Volume:"));
214
gtk_widget_ref (label3);
215
gtk_object_set_data_full (GTK_OBJECT (dialog1), "label3", label3,
216
(GtkDestroyNotify) gtk_widget_unref);
217
gtk_widget_show (label3);
218
gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 1, 2,
219
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
220
(GtkAttachOptions) (0), 0, 0);
221
gtk_misc_set_alignment (GTK_MISC (label3), 0, 0.5);
223
label2 = gtk_label_new (_("Mode:"));
224
gtk_widget_ref (label2);
225
gtk_object_set_data_full (GTK_OBJECT (dialog1), "label2", label2,
226
(GtkDestroyNotify) gtk_widget_unref);
227
gtk_widget_show (label2);
228
gtk_table_attach (GTK_TABLE (table1), label2, 0, 1, 0, 1,
229
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
230
(GtkAttachOptions) (0), 0, 0);
231
gtk_misc_set_alignment (GTK_MISC (label2), 0, 0.5);
233
table2 = gtk_table_new (2, 2, FALSE);
234
gtk_widget_ref (table2);
235
gtk_object_set_data_full (GTK_OBJECT (dialog1), "table2", table2,
236
(GtkDestroyNotify) gtk_widget_unref);
237
gtk_widget_show (table2);
238
gtk_table_attach (GTK_TABLE (table1), table2, 1, 2, 1, 2,
239
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
240
(GtkAttachOptions) (GTK_FILL), 0, 0);
242
label5 = gtk_label_new (_("Abs"));
243
gtk_widget_ref (label5);
244
gtk_object_set_data_full (GTK_OBJECT (dialog1), "label5", label5,
245
(GtkDestroyNotify) gtk_widget_unref);
246
gtk_widget_show (label5);
247
gtk_table_attach (GTK_TABLE (table2), label5, 0, 1, 0, 1,
248
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
249
(GtkAttachOptions) (0), 0, 0);
250
gtk_misc_set_alignment (GTK_MISC (label5), 0, 0.5);
252
label6 = gtk_label_new (_("dB"));
253
gtk_widget_ref (label6);
254
gtk_object_set_data_full (GTK_OBJECT (dialog1), "label6", label6,
255
(GtkDestroyNotify) gtk_widget_unref);
256
gtk_widget_show (label6);
257
gtk_table_attach (GTK_TABLE (table2), label6, 0, 1, 1, 2,
258
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
259
(GtkAttachOptions) (0), 0, 0);
260
gtk_misc_set_alignment (GTK_MISC (label6), 0, 0.5);
262
spinbutton1_adj = gtk_adjustment_new (1.0, 0.0, 1.0, 0.01, 0.1, 0.0);
263
norms->spin_abs = spinbutton1 = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton1_adj), 1, 2);
264
gtk_widget_ref (spinbutton1);
265
gtk_object_set_data_full (GTK_OBJECT (dialog1), "spinbutton1", spinbutton1,
266
(GtkDestroyNotify) gtk_widget_unref);
267
gtk_widget_show (spinbutton1);
268
gtk_table_attach (GTK_TABLE (table2), spinbutton1, 1, 2, 0, 1,
269
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
270
(GtkAttachOptions) (0), 0, 0);
272
gtk_widget_set_sensitive(spinbutton1, FALSE);
274
gtk_signal_connect(GTK_OBJECT(spinbutton1),
276
(GtkSignalFunc)ampl_abs_cb, norms);
278
spinbutton2_adj = gtk_adjustment_new (0.0, -100.0, 0.0, 0.1, 0.5, 0.0);
279
norms->spin_db = spinbutton2 = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton2_adj), 1, 2);
280
gtk_widget_ref (spinbutton2);
281
gtk_object_set_data_full (GTK_OBJECT (dialog1), "spinbutton2", spinbutton2,
282
(GtkDestroyNotify) gtk_widget_unref);
283
gtk_widget_show (spinbutton2);
284
gtk_table_attach (GTK_TABLE (table2), spinbutton2, 1, 2, 1, 2,
285
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
286
(GtkAttachOptions) (0), 0, 0);
287
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton2), TRUE);
289
gtk_widget_set_sensitive(spinbutton2, FALSE);
290
gtk_signal_connect(GTK_OBJECT(spinbutton2),
292
(GtkSignalFunc)ampl_db_cb, norms);
294
optionmenu1 = gtk_option_menu_new ();
295
gtk_widget_ref (optionmenu1);
296
gtk_object_set_data_full (GTK_OBJECT (dialog1), "optionmenu1", optionmenu1,
297
(GtkDestroyNotify) gtk_widget_unref);
298
gtk_widget_show (optionmenu1);
299
gtk_table_attach (GTK_TABLE (table1), optionmenu1, 1, 2, 0, 1,
300
(GtkAttachOptions) (GTK_FILL),
301
(GtkAttachOptions) (0), 0, 0);
302
optionmenu1_menu = gtk_menu_new ();
303
glade_menuitem = gtk_menu_item_new_with_label (_("Peak"));
304
gtk_widget_show (glade_menuitem);
305
gtk_menu_append (GTK_MENU (optionmenu1_menu), glade_menuitem);
306
glade_menuitem = gtk_menu_item_new_with_label (_("Volume"));
307
gtk_widget_show (glade_menuitem);
308
gtk_menu_append (GTK_MENU (optionmenu1_menu), glade_menuitem);
309
glade_menuitem = gtk_menu_item_new_with_label (_("Volume/Frequency"));
310
gtk_widget_show (glade_menuitem);
311
gtk_menu_append (GTK_MENU (optionmenu1_menu), glade_menuitem);
312
gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu1), optionmenu1_menu);
314
gtk_signal_connect(GTK_OBJECT(optionmenu1_menu),
316
(GtkSignalFunc)normmode_cb, norms);
320
label7 = gtk_label_new (_("Frequency:"));
321
gtk_widget_ref (label7);
322
gtk_object_set_data_full (GTK_OBJECT (dialog1), "label7", label7,
323
(GtkDestroyNotify) gtk_widget_unref);
324
gtk_widget_show (label7);
325
gtk_table_attach (GTK_TABLE (table1), label7, 0, 1, 2, 3,
326
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
327
(GtkAttachOptions) (0), 0, 0);
328
gtk_label_set_justify (GTK_LABEL (label7), GTK_JUSTIFY_LEFT);
329
gtk_misc_set_alignment (GTK_MISC (label7), 0, 0.5);
331
spinbutton3_adj = gtk_adjustment_new (1000, 1, 96000, 1, 100, 10);
332
norms->spin_freq = spinbutton3 = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton3_adj), 1, 2);
333
gtk_widget_ref (spinbutton3);
334
gtk_object_set_data_full (GTK_OBJECT (dialog1), "spinbutton3", spinbutton3,
335
(GtkDestroyNotify) gtk_widget_unref);
336
gtk_widget_show (spinbutton3);
337
gtk_table_attach (GTK_TABLE (table1), spinbutton3, 1, 2, 2, 3,
338
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
339
(GtkAttachOptions) (0), 0, 0);
340
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton3), TRUE);
341
gtk_widget_set_sensitive(norms->spin_freq, FALSE);
343
gtk_signal_connect(GTK_OBJECT(spinbutton3),
345
(GtkSignalFunc)norm_freq_cb, norms);
349
frame2 = gtk_frame_new (_("Operation Stats"));
350
gtk_widget_ref (frame2);
351
gtk_object_set_data_full (GTK_OBJECT (dialog1), "frame2", frame2,
352
(GtkDestroyNotify) gtk_widget_unref);
353
gtk_widget_show (frame2);
354
gtk_box_pack_start (GTK_BOX (vbox1), frame2, TRUE, TRUE, 0);
356
scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
357
gtk_widget_ref (scrolledwindow1);
358
gtk_object_set_data_full (GTK_OBJECT (dialog1), "scrolledwindow1", scrolledwindow1,
359
(GtkDestroyNotify) gtk_widget_unref);
360
gtk_widget_show (scrolledwindow1);
361
gtk_container_add (GTK_CONTAINER (frame2), scrolledwindow1);
362
gtk_widget_set_usize (scrolledwindow1, 400, 150);
363
gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow1), 3);
364
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
366
norms->text = text1 = gtk_text_new (NULL, NULL);
367
gtk_widget_ref (text1);
368
gtk_object_set_data_full (GTK_OBJECT (dialog1), "text1", text1,
369
(GtkDestroyNotify) gtk_widget_unref);
370
gtk_widget_show (text1);
371
gtk_container_add (GTK_CONTAINER (scrolledwindow1), text1);
373
hbox1 = gtk_hbox_new(TRUE, 2);
374
gtk_widget_show(hbox1);
375
gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, FALSE, 0);
377
norms->analyze_button = button5 = gtk_button_new_with_label (_("Analyze"));
378
gtk_widget_ref (button5);
379
gtk_object_set_data_full (GTK_OBJECT (dialog1), "button5", button5,
380
(GtkDestroyNotify) gtk_widget_unref);
381
gtk_widget_show (button5);
382
gtk_box_pack_start (GTK_BOX (hbox1), button5, TRUE, TRUE, 0);
384
gtk_signal_connect(GTK_OBJECT(button5), "clicked",
385
(GtkSignalFunc)analyze_cb, norms);
388
norms->simulate_button = button4 = gtk_button_new_with_label (_("Simulate"));
389
gtk_widget_ref (button4);
390
gtk_object_set_data_full (GTK_OBJECT (dialog1), "button4", button4,
391
(GtkDestroyNotify) gtk_widget_unref);
392
gtk_widget_show (button4);
393
gtk_box_pack_start (GTK_BOX (hbox1), button4, TRUE, TRUE, 0);
395
gtk_signal_connect(GTK_OBJECT(button4), "clicked",
396
(GtkSignalFunc)simulate_cb, norms);
398
norms->appbar = appbar1 = gnome_appbar_new (TRUE, TRUE, GNOME_PREFERENCES_NEVER);
399
gtk_widget_ref (appbar1);
400
gtk_object_set_data_full (GTK_OBJECT (dialog1), "appbar1", appbar1,
401
(GtkDestroyNotify) gtk_widget_unref);
402
gtk_widget_show (appbar1);
403
gtk_box_pack_start (GTK_BOX (vbox1), appbar1, TRUE, TRUE, 0);
405
dialog_action_area1 = GNOME_DIALOG (dialog1)->action_area;
406
gtk_object_set_data (GTK_OBJECT (dialog1), "dialog_action_area1", dialog_action_area1);
407
gtk_widget_show (dialog_action_area1);
408
gtk_button_box_set_spacing (GTK_BUTTON_BOX (dialog_action_area1), 8);
409
gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_EDGE);
411
gnome_dialog_append_button (GNOME_DIALOG (dialog1), GNOME_STOCK_BUTTON_OK);
412
norms->ok_button = button1 = GTK_WIDGET (g_list_last (GNOME_DIALOG (dialog1)->buttons)->data);
413
gtk_widget_ref (button1);
414
gtk_object_set_data_full (GTK_OBJECT (dialog1), "button1", button1,
415
(GtkDestroyNotify) gtk_widget_unref);
416
gtk_widget_show (button1);
417
GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
419
gtk_signal_connect(GTK_OBJECT(button1), "clicked",
420
(GtkSignalFunc)normalize_cb, norms);
422
gnome_dialog_append_button (GNOME_DIALOG (dialog1), GNOME_STOCK_BUTTON_CANCEL);
423
button3 = GTK_WIDGET (g_list_last (GNOME_DIALOG (dialog1)->buttons)->data);
424
gtk_widget_ref (button3);
425
gtk_object_set_data_full (GTK_OBJECT (dialog1), "button3", button3,
426
(GtkDestroyNotify) gtk_widget_unref);
427
gtk_widget_show (button3);
428
GTK_WIDGET_SET_FLAGS (button3, GTK_CAN_DEFAULT);
429
gtk_signal_connect(GTK_OBJECT(button3), "clicked",
430
(GtkSignalFunc)cancel_cb, norms);
432
gnome_dialog_append_button(GNOME_DIALOG(dialog1), GNOME_STOCK_BUTTON_HELP);
433
gnome_dialog_button_connect(GNOME_DIALOG(dialog1), 2,
434
glame_help_cb, "Normalize");
438
gtk_signal_connect(GTK_OBJECT(norms->dialog),
440
GTK_SIGNAL_FUNC(paranoia_cb), norms);
443
norms->ampl_abs = 1.0;
444
norms->ampl_db = 0.0;
448
static float get_max_rms(task_entry_t* head, gpsm_item_t** item) {
449
task_entry_t* task, *last;
455
if (task->rms > maxrms) {
459
task = glame_list_getnext(&task->list, task, task_entry_t, list);
460
} while ( (task!=last) && (task!=NULL));
465
static void analyze_rms(struct normalize_s *ns) {
466
task_entry_t *te, *ote, *task, *last;
467
filter_t *net, *ssp, *maxrms, *swap;
468
filter_param_t *param;
469
float percentage, mrms;
472
char label[128], string[2048];
480
gpsm_grp_foreach_item(ns->grp, item) {
482
snprintf(label, 127, "Analyzing Track %s", gpsm_item_label(item));
483
gnome_appbar_set_status(GNOME_APPBAR(ns->appbar), label);
485
te = ALLOC(task_entry_t);
486
GLAME_INIT_LIST_HEAD(&te->list);
491
glame_list_add(&te->list, &ote->list);
498
bsize = MAX(gpsm_swfile_samplerate(item)/ns->freq, 1);
501
net = filter_creat(NULL);
502
ssp = net_add_plugin_by_name(net, "ssp_streamer");
503
maxrms = net_add_plugin_by_name(net, "maxrms");
504
swap = net_add_gpsm_input(net, (gpsm_swfile_t *)item,
505
ns->start, MIN(ns->length, gpsm_item_hsize(item)), 0);
506
DPRINTF("Processing %ld samples\n", MIN(ns->length, (gpsm_item_hsize(item))));
507
net_apply_node(net, ssp);
508
net_apply_node(net, maxrms);
510
param = filterparamdb_get_param(filter_paramdb(ssp), "bsize");
511
filterparam_set(param, &bsize);
513
if (filter_launch(net, GLAME_BULK_BUFSIZE) == -1
514
|| filter_start(net) == -1)
517
param = filterparamdb_get_param(filter_paramdb(swap),
518
FILTERPARAM_LABEL_POS);
521
while(!filter_is_ready(net)) {
522
while (gtk_events_pending())
523
gtk_main_iteration();
526
percentage = (float)(done+filterparam_val_pos(param))/
527
(float)ns->total_size;
532
gnome_appbar_set_progress(GNOME_APPBAR(ns->appbar),
537
done+=filterparam_val_pos(param);
538
DPRINTF("posparam=%ld\n", filterparam_val_pos(param));
540
param = filterparamdb_get_param(filter_paramdb(maxrms), "maxrms");
541
te->rms = filterparam_val_float(param);
542
DPRINTF("found rms = %f\n", te->rms);
550
strcat(string, "Results:\n");
552
snprintf(label, 127, "%s (max rms = %.3f = %.3f dB)\n", gpsm_item_label(task->item), task->rms, GAIN2DB(task->rms));
553
strcat(string, label);
554
task = glame_list_getnext(&task->list, task, task_entry_t, list);
555
} while ( (task!=last) && (task!=NULL));
556
ns->maxrms = mrms = get_max_rms(te, &item);
557
snprintf(label, 127, "Found maximum rms = %.3f(%.3f dB) in track %s.\n\n", mrms, GAIN2DB(mrms), gpsm_item_label(item));
558
strcat(string, label);
559
gtk_text_insert(GTK_TEXT(ns->text), NULL, NULL, NULL, string, strlen(string));
565
filter_terminate(net);
567
gpsm_item_destroy(ns->grp);
568
cleanup_task_list(ns);
578
static void normalize_do_task(struct normalize_s *ns) {
580
filter_t *net, *vadjust, *swapi, *swapo;
581
filter_param_t *param;
583
float gain, percentage;
588
This is probably ok for peak normalizing, but otherwise ?
594
gain = ns->ampl_abs/ns->maxrms;
596
gpsm_op_prepare(ns->grp);
598
gpsm_grp_foreach_item(ns->grp, item) {
600
snprintf(label, 128, "Normalizing Track %s", gpsm_item_label(item));
601
gnome_appbar_set_status(GNOME_APPBAR(ns->appbar), label);
602
net = filter_creat(NULL);
603
vadjust = net_add_plugin_by_name(net, "volume_adjust");
604
swapi = net_add_gpsm_input(net, (gpsm_swfile_t *)item,
605
ns->start, MIN(ns->length, gpsm_item_hsize(item)) , 0);
607
net_apply_node(net, vadjust);
608
swapo = net_add_gpsm_output(net, (gpsm_swfile_t *)item,
609
ns->start, MIN(ns->length, gpsm_item_hsize(item)) , 0);
610
net_apply_node(net, swapo);
612
param = filterparamdb_get_param(filter_paramdb(vadjust), "factor");
613
filterparam_set(param, &gain);
616
if (filter_launch(net, GLAME_BULK_BUFSIZE) == -1
617
|| filter_start(net) == -1)
620
param = filterparamdb_get_param(filter_paramdb(swapi),
621
FILTERPARAM_LABEL_POS);
624
while(!filter_is_ready(net)) {
625
while (gtk_events_pending())
626
gtk_main_iteration();
629
percentage = (float)(done+filterparam_val_pos(param))/
630
(float)ns->total_size;
635
gnome_appbar_set_progress(GNOME_APPBAR(ns->appbar),
640
done+=filterparam_val_pos(param);
641
DPRINTF("posparam=%ld\n", filterparam_val_pos(param));
646
gpsm_grp_foreach_item(ns->grp, item) {
647
gpsm_notify_swapfile_change(gpsm_swfile_filename(item),
648
ns->start, MIN(ns->length, (gpsm_item_hsize(item)-ns->start+1)));
651
gtk_widget_destroy(ns->dialog);
652
gpsm_item_destroy(ns->grp);
653
cleanup_task_list(ns);
658
filter_terminate(net);
660
cleanup_task_list(ns);
661
gpsm_op_undo_and_forget(ns->grp);
662
gpsm_item_destroy(ns->grp);
667
DPRINTF("Error starting normalizing network!\n");
671
static long get_total_size(struct normalize_s *ns) {
676
gpsm_grp_foreach_item(ns->grp, item) {
678
size+=MIN(gpsm_item_hsize(item), ns->length);
679
DPRINTF("hsize=%ld\n vsize = %ld processed length=%ld\n",
680
gpsm_item_hsize(item),
681
gpsm_item_vsize(item),
682
MIN(gpsm_item_hsize(item), ns->length));
686
DPRINTF("%d tracks with total size %ld\n", num, size);
687
return (size == 0 ? 1 : size);
691
static void simulate_cb(GtkWidget *button, struct normalize_s* ns) {
692
DPRINTF("working hard ;)\n");
696
static void normalize_cb(GtkWidget *button, struct normalize_s* ns) {
697
DPRINTF("working like a dog every night and day ;)\n");
698
gtk_widget_set_sensitive(ns->ok_button, FALSE);
699
gtk_widget_set_sensitive(ns->analyze_button, FALSE);
700
/* gtk_widget_set_sensitive(ns->simulate_button, FALSE); */
701
normalize_do_task(ns);
704
static void analyze_cb(GtkWidget *button, struct normalize_s* ns) {
705
gtk_widget_set_sensitive(ns->analyze_button, FALSE);
706
gtk_widget_set_sensitive(ns->ok_button, FALSE);
707
/* gtk_widget_set_sensitive(ns->simulate_button, FALSE); */
709
gtk_widget_set_sensitive(ns->analyze_button, TRUE);
710
gtk_widget_set_sensitive(ns->ok_button, TRUE);
711
/* gtk_widget_set_sensitive(ns->simulate_button, TRUE); */
715
static int normalize_gpsm(gpsm_item_t *grp, long start, long length)
717
struct normalize_s *ns;
719
ns = ALLOCN(1, struct normalize_s);
721
ns->grp = (gpsm_item_t*)gpsm_collect_swfiles(grp);
725
normalize_dialog(ns);
726
gtk_widget_show(ns->dialog);
730
ns->total_size = get_total_size(ns);
733
DPRINTF("Size of all selected tracks: %ld\n", ns->total_size);
738
int normalize_register(plugin_t *p)
740
plugin_set(p, PLUGIN_GPSMOP, normalize_gpsm);
741
plugin_set(p, PLUGIN_DESCRIPTION, "normalizes a gpsm subtree");
742
plugin_set(p, PLUGIN_CATEGORY, "Volume");
746
/* Generalization strikes 240 lines for a simple function :) */