1 /*
2 MPEG Maaate: An Australian MPEG audio analysis toolkit
3 Copyright (C) 2000 Commonwealth Scientific and Industrial Research Organisation
4 (CSIRO), Australia.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "module.H"
22
23 #include <math.h>
24
25 #define ROUND(number) floor((number)+0.5)
26
27 static void
init_SBmean(Module * m)28 init_SBmean(Module * m) {
29
30 // set up member values
31 m->set_name (string("SBmean"));
32 m->set_desc (string("subband mean over each subband"));
33 m->set_author (string("CSIRO-MIS AAS Thomas VINCENT"));
34 m->set_copyright (string("(c) 2002 CSIRO"));
35 m->set_url (string("http://www.cmis.csiro.au/Maaate/docs/modules.html"));
36
37 // set up input parameter list
38 m->inputSpecs()->clear();
39
40 // first parameter: sound file
41 m->inputSpecs()->push_back
42 (ModuleParamSpec(string("soundfile"),
43 string("the SOUND file for which the subband "
44 "mean gets calculated"),
45 MAAATE_TYPE_SOUNDFILE,
46 new ModuleParam((SOUNDfile*)NULL)) // default
47 );
48
49 // second parameter: start time
50 MaaateConstraint * constraint = new MaaateConstraint();
51 constraint->addConstraintGreaterThan(0.0);
52 m->inputSpecs()->push_back
53 (ModuleParamSpec(string("starttime"),
54 string("time instant from which to start the "
55 "subband mean calculation"),
56 MAAATE_TYPE_REAL,
57 new ModuleParam((double)0.0), // default
58 constraint));
59
60 // third parameter: end time
61 constraint = new MaaateConstraint();
62 constraint->clear();
63 constraint->addConstraintGreaterThan(0.0);
64 m->inputSpecs()->push_back
65 (ModuleParamSpec(string("endtime"),
66 string("time instant until which to calculate "
67 "the subband mean"),
68 MAAATE_TYPE_REAL,
69 new ModuleParam((double)DBL_MAX), // default
70 constraint));
71
72 // fourth parameter: start subband
73 constraint = new MaaateConstraint();
74 constraint->clear();
75 constraint->addConstraintGreaterThan(0);
76 m->inputSpecs()->push_back
77 (ModuleParamSpec(string("start-subband"),
78 string("subband from which to start the subband "
79 "mean calculation"),
80 MAAATE_TYPE_INT,
81 new ModuleParam(0), // default
82 constraint));
83
84 // fifth parameter: end subband
85 constraint = new MaaateConstraint();
86 constraint->clear();
87 constraint->addConstraintGreaterThan(0);
88 m->inputSpecs()->push_back
89 (ModuleParamSpec(string("end-subband"),
90 string("subband at which to end the subband"
91 "mean calculation"),
92 MAAATE_TYPE_INT,
93 new ModuleParam(0), // default
94 constraint));
95
96 // set up output parameter list
97 m->outputSpecs()->clear();
98
99 // first parameter: subband mean curves
100 m->outputSpecs()->push_back
101 (ModuleParamSpec(string("subband mean curves"),
102 string("an approximation of subband mean for the "
103 "requested time interval for each subband"),
104 MAAATE_TYPE_SEGMENTDATA,
105 new ModuleParam((SegmentData*)NULL)) // default
106 );
107
108 };
109
110
111 // function to suggest parameter values given that some of the input
112 // parameters have already been set; also changes constraints accordingly
113 static void
suggest_SBmean(Module * m,list<ModuleParam> * paramsIn)114 suggest_SBmean (Module * m, list<ModuleParam> * paramsIn) {
115 list<ModuleParam>::iterator iter;
116
117 // get module's input parameter specifications
118 list<ModuleParamSpec> * inSpecs = m->inputSpecs();
119 list<ModuleParamSpec>::iterator iterSpecs;
120
121 iter = paramsIn->begin(); // SOUND file
122 iterSpecs = inSpecs->begin();
123 if (iter == paramsIn->end()) return;
124 SOUNDfile * mf = (*iter).get_sf();
125 if (mf == NULL) return;
126
127 ++iter; // start time
128 ++iterSpecs;
129 (*iterSpecs).constraint()->clear();
130 (*iterSpecs).constraint()->addConstraintRange(0.0, mf->file_duration());
131 double startTime = (*iter).get_r();
132
133 ++iter; // end time
134 ++iterSpecs;
135 (*iterSpecs).constraint()->clear();
136 (*iterSpecs).constraint()->addConstraintRange(0.0, mf->file_duration());
137 double endTime = (*iter).get_r();
138
139 //check time
140 if (endTime < startTime) {
141 endTime = startTime;
142 (*iter).set(startTime);
143 }
144
145 ++iter; // start subband
146 ++iterSpecs;
147 (*iterSpecs).constraint()->clear();
148 (*iterSpecs).constraint()->addConstraintRange(0, (mf->nb_subbands(HIGH) - 1) );
149 int startSubband = (*iter).get_i();
150
151 ++iter; // end subband
152 ++iterSpecs;
153 (*iterSpecs).constraint()->clear();
154 (*iterSpecs).constraint()->addConstraintRange(0, (mf->nb_subbands(HIGH) - 1) );
155
156 // check nr of subbands
157 int endSubband = (*iter).get_i();
158 if (endSubband < startSubband) {
159 endSubband = startSubband;
160 (*iter).set(startSubband);
161 }
162
163 }
164
165 // function to work on input parameters and return output parameters
166 static list<ModuleParam> *
apply_SBmean(Module * m,list<ModuleParam> * paramsIn)167 apply_SBmean (Module * m, list<ModuleParam> * paramsIn) {
168
169 // the output parameter list
170 list<ModuleParam> * mpl = new list<ModuleParam>();
171
172 // iterator in input parmeter list
173 list<ModuleParam>::iterator iter;
174
175 //Getting input parameters and last checking
176 //SOUND file
177 iter = paramsIn->begin();
178 if (iter == paramsIn->end()) return mpl;
179 SOUNDfile * mf = (*iter).get_sf();
180 if (mf == NULL) return mpl;
181
182 //start time
183 ++iter;
184 double startTime = (*iter).get_r();
185
186 //end time
187 ++iter;
188 double endTime = (*iter).get_r();
189
190 //check time
191 if (endTime < startTime) {
192 endTime = startTime;
193 }
194
195 // start subband
196 ++iter;
197 int startSubband = (*iter).get_i();
198
199 //end subband
200 ++iter;
201 int endSubband = (*iter).get_i();
202
203 //check subband
204 if (endSubband < startSubband) {
205 endSubband = startSubband;
206 }
207 //End getting and checking
208
209
210 //convert time into window number
211 long start = mf->time2window( (float)startTime);
212
213 long end = mf->time2window( (float)endTime);
214
215 // go to start window within soundfile
216 if (!mf->seek_window(start)) {
217 cerr << "MaaateM: Error when positioning" << endl;
218 cerr << " startposition = 0.0" << endl;
219 mf->seek_window(0);
220 start = 0;
221 }
222
223
224 // analyse first window
225 if (!mf->next_window(HIGH)) {
226 cerr << "MaaateM: Warning: could not analyse first window." << endl;
227 return mpl;
228 }
229
230 //colunms number
231 long columns = end - start;
232 columns = (columns > mf->file_window_number()) ? mf->file_window_number() : columns;
233
234 //rows number
235 int nbsubband = endSubband - startSubband + 1;
236
237 SegmentData *result = new SegmentData(startTime,
238 endTime,
239 columns,
240 nbsubband);
241
242 //extract subband means
243 while (mf->at_window() <= end) {
244
245 for (int sb = startSubband; sb <= endSubband; sb++) { //from one subband to another
246 result->data[result->colFilled][sb-startSubband] = mf->subband_mean (sb,HIGH);
247 }
248
249 result->colFilled++;
250
251 // analyse next window
252 if (!mf->next_window(HIGH)) {
253 break;
254 }
255
256 }
257
258 #ifdef DEBUG
259 cout << "Columns filled:" << result->colFilled << endl;
260 cout << "Sum:" << result->sum() << endl;
261 cout << "Average:" << result->avg() << endl;
262 cout << *result;
263 #endif
264
265 mpl->push_back(ModuleParam(result));
266
267 return mpl;
268
269 };
270
271
272 Module
loadSBmeanModule(void)273 loadSBmeanModule (void)
274 {
275 return Module(init_SBmean,
276 NULL,
277 suggest_SBmean,
278 apply_SBmean ,
279 NULL,
280 NULL);
281 }
282