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 #include <stdio.h>
22 #include <string.h>
23 
24 #include <gdk/gdkkeysyms.h>
25 
26 #include <sweep/sweep.h>
27 
28 #include <../src/sweep_app.h> /* XXX */
29 
30 static sw_sample *
normalise(sw_sample * sample,sw_param_set pset,gpointer custom_data)31 normalise (sw_sample * sample, sw_param_set pset, gpointer custom_data)
32 {
33   sw_sounddata * sounddata;
34   sw_format * f;
35   GList * gl;
36   sw_sel * sel;
37   sw_audio_t * d;
38   sw_audio_t max = 0;
39   gfloat factor = 1.0;
40   sw_framecount_t op_total, run_total;
41   glong i;
42   sw_framecount_t offset, remaining, n;
43 
44   gboolean active = TRUE;
45 
46   sounddata = sample_get_sounddata (sample);
47   f = sounddata->format;
48 
49   op_total = sounddata_selection_nr_frames (sounddata) * 2 / 100;/* 2 passes */
50   if (op_total == 0) op_total = 1;
51   run_total = 0;
52 
53   /* Find max */
54   for (gl = sounddata->sels; active && gl; gl = gl->next) {
55     sel = (sw_sel *)gl->data;
56 
57     offset = 0;
58     remaining = sel->sel_end - sel->sel_start;
59 
60     while (active && remaining > 0) {
61       g_mutex_lock (sample->ops_mutex);
62 
63       if (sample->edit_state == SWEEP_EDIT_STATE_CANCEL) {
64 	active = FALSE;
65       } else {
66 
67 	d = sounddata->data + frames_to_bytes (f, sel->sel_start + offset);
68 
69 	n = MIN(remaining, 1024);
70 
71 	for (i=0; i < n * f->channels; i++) {
72 	  if(d[i]>=0) max = MAX(max, d[i]);
73 	  else max = MAX(max, -d[i]);
74 	}
75 
76 	remaining -= n;
77 	offset += n;
78 
79 	run_total += n;
80 	sample_set_progress_percent (sample, run_total / op_total);
81       }
82 
83       g_mutex_unlock (sample->ops_mutex);
84     }
85   }
86 
87   if (max != 0) factor = SW_AUDIO_T_MAX / (gfloat)max;
88 
89   /* Scale */
90   for (gl = sounddata->sels; active && gl; gl = gl->next) {
91     sel = (sw_sel *)gl->data;
92 
93     offset = 0;
94     remaining = sel->sel_end - sel->sel_start;
95 
96     while (active && remaining > 0) {
97       g_mutex_lock (sample->ops_mutex);
98 
99       if (sample->edit_state == SWEEP_EDIT_STATE_CANCEL) {
100 	active = FALSE;
101       } else {
102 	d = sounddata->data + frames_to_bytes (f, sel->sel_start + offset);
103 
104 	n = MIN(remaining, 1024);
105 
106 	for (i=0; i < n * f->channels; i++) {
107 	  d[i] = (sw_audio_t)((gfloat)d[i] * factor);
108 	}
109 
110 	remaining -= n;
111 	offset += n;
112 
113 	run_total += n;
114 	sample_set_progress_percent (sample, run_total * 100 / op_total);
115       }
116 
117       g_mutex_unlock (sample->ops_mutex);
118     }
119   }
120 
121   return sample;
122 }
123 
124 static sw_op_instance *
apply_normalise(sw_sample * sample,sw_param_set pset,gpointer custom_data)125 apply_normalise(sw_sample * sample, sw_param_set pset, gpointer custom_data)
126 {
127   return
128     perform_filter_op (sample, _("Normalise"), (SweepFilter)normalise,
129 		       pset, NULL);
130 }
131 
132 static sw_procedure proc_normalise = {
133   N_("Normalise"),
134   N_("Alter the sample's amplitude to lie between 1.0 and -1.0"),
135   "Conrad Parker",
136   "Copyright (C) 2000",
137   "http://sweep.sourceforge.net/plugins/normalise",
138   "Filters/Normalise", /* identifier */
139   GDK_n, /* accel_key */
140   GDK_SHIFT_MASK, /* accel_mods */
141   0, /* nr_params */
142   NULL, /* param_specs */
143   NULL, /* suggests() */
144   apply_normalise,
145   NULL, /* custom_data */
146 };
147 
148 static GList *
normalise_init(void)149 normalise_init (void)
150 {
151   return g_list_append ((GList *)NULL, &proc_normalise);
152 }
153 
154 
155 sw_plugin plugin = {
156   normalise_init, /* plugin_init */
157   NULL, /* plugin_cleanup */
158 };
159