@@ -150,18 +150,23 @@ static void band_energy(float *_out,float *_ps,const int *_bands,int _nbands,
150150 free (window );
151151}
152152
153- #define NBANDS (35 )
153+ #define NBANDS (28 )
154154#define NFREQS (240*2)
155155
156156/*Bands on which we compute the pseudo-NMR (Bark-derived
157157 CELT bands).*/
158158static const int BANDS [NBANDS + 1 ]= {
159- 0 ,2 ,4 ,6 ,8 ,10 ,12 ,14 ,16 ,20 ,24 ,28 ,32 ,40 ,48 ,56 ,68 ,80 ,96 ,120 ,156 ,200 , 220 , 240 ,260 , 280 ,300 , 320 ,340 , 360 ,380 , 400 ,420 , 440 , 460 ,480
159+ 0 ,2 ,4 ,6 ,8 ,10 ,12 ,14 ,16 ,20 ,24 ,28 ,32 ,40 ,48 ,56 ,68 ,80 ,96 ,120 ,156 ,200 , 240 ,280 ,320 ,360 ,400 ,440 ,480
160160};
161161
162162#define TEST_WIN_SIZE (480*2)
163163#define TEST_WIN_STEP (120*2)
164164
165+ void usage (const char * _argv0 ) {
166+ fprintf (stderr ,"Usage: %s [-s] [-48] [-r rate2] <file1.sw> <file2.sw>\n" ,
167+ _argv0 );
168+ }
169+
165170int main (int _argc ,const char * * _argv ){
166171 FILE * fin1 ;
167172 FILE * fin2 ;
@@ -181,42 +186,75 @@ int main(int _argc,const char **_argv){
181186 int bi ;
182187 int nchannels ;
183188 unsigned rate ;
189+ unsigned base_rate ;
184190 int downsample ;
191+ int nbands ;
185192 int ybands ;
193+ int nfreqs ;
186194 int yfreqs ;
195+ size_t test_win_size ;
196+ size_t test_win_step ;
187197 int max_compare ;
188- if ( _argc < 3 || _argc > 6 ){
189- fprintf ( stderr , "Usage: %s [-s] [-r rate2] <file1.sw> <file2.sw>\n" ,
190- _argv [ 0 ] );
198+ const char * argv0 = _argv [ 0 ];
199+ if ( _argc < 3 ){
200+ usage ( argv0 );
191201 return EXIT_FAILURE ;
192202 }
193203 nchannels = 1 ;
194- if (strcmp (_argv [1 ],"-s" )== 0 ){
195- nchannels = 2 ;
196- _argv ++ ;
197- }
198- rate = 96000 ;
199- ybands = NBANDS ;
200- yfreqs = NFREQS ;
204+ base_rate = 96000 ;
205+ rate = 0 ;
206+ nbands = NBANDS ;
207+ nfreqs = NFREQS ;
208+ test_win_size = TEST_WIN_SIZE ;
209+ test_win_step = TEST_WIN_STEP ;
201210 downsample = 1 ;
202- if (strcmp (_argv [1 ],"-r" )== 0 ){
203- rate = atoi (_argv [2 ]);
204- if (rate != 8000 && rate != 12000 && rate != 16000 && rate != 24000 && rate != 48000 && rate != 96000 ){
205- fprintf (stderr ,
206- "Sampling rate must be 8000, 12000, 16000, 24000, 48000, or 96000\n" );
211+ while (_argc > 3 ) {
212+ if (strcmp (_argv [1 ],"-s" )== 0 ){
213+ nchannels = 2 ;
214+ _argv ++ ;
215+ _argc -- ;
216+ } else if (strcmp (_argv [1 ],"-48" )== 0 ){
217+ base_rate = 48000 ;
218+ _argv ++ ;
219+ _argc -- ;
220+ } else if (strcmp (_argv [1 ],"-r" )== 0 ){
221+ rate = atoi (_argv [2 ]);
222+ if (rate != 8000 && rate != 12000 && rate != 16000 && rate != 24000 && rate != 48000 && rate != 96000 ){
223+ fprintf (stderr ,
224+ "Sampling rate must be 8000, 12000, 16000, 24000, 48000, or 96000\n" );
225+ return EXIT_FAILURE ;
226+ }
227+ _argv += 2 ;
228+ _argc -= 2 ;
229+ } else {
230+ usage (argv0 );
207231 return EXIT_FAILURE ;
208232 }
209- downsample = 96000 /rate ;
210- switch (rate ){
211- case 8000 :ybands = 13 ;break ;
212- case 12000 :ybands = 15 ;break ;
213- case 16000 :ybands = 17 ;break ;
214- case 24000 :ybands = 19 ;break ;
215- case 48000 :ybands = 21 ;break ;
216- }
217- yfreqs = NFREQS /downsample ;
218- _argv += 2 ;
219233 }
234+ if (_argc != 3 ){
235+ usage (argv0 );
236+ return EXIT_FAILURE ;
237+ }
238+ if (rate == 0 ) rate = base_rate ;
239+ if (base_rate == 48000 ) {
240+ test_win_size /=2 ;
241+ test_win_step /=2 ;
242+ nfreqs /=2 ;
243+ nbands = 22 ;
244+ }
245+ switch (rate ){
246+ case 8000 :ybands = 13 ;break ;
247+ case 12000 :ybands = 15 ;break ;
248+ case 16000 :ybands = 17 ;break ;
249+ case 24000 :ybands = 19 ;break ;
250+ case 48000 :ybands = 22 ;break ;
251+ case 96000 :ybands = NBANDS ;break ;
252+ default :
253+ usage (argv0 );
254+ return EXIT_FAILURE ;
255+ }
256+ downsample = base_rate /rate ;
257+ yfreqs = nfreqs /downsample ;
220258 fin1 = fopen (_argv [1 ],"rb" );
221259 if (fin1 == NULL ){
222260 fprintf (stderr ,"Error opening '%s'.\n" ,_argv [1 ]);
@@ -241,66 +279,66 @@ int main(int _argc,const char **_argv){
241279 (unsigned long )xlength ,(unsigned long )ylength * downsample );
242280 return EXIT_FAILURE ;
243281 }
244- if (xlength < TEST_WIN_SIZE ){
245- fprintf (stderr ,"Insufficient sample data (%lu<%i ).\n" ,
246- (unsigned long )xlength ,TEST_WIN_SIZE );
282+ if (xlength < test_win_size ){
283+ fprintf (stderr ,"Insufficient sample data (%lu<%lu ).\n" ,
284+ (unsigned long )xlength ,test_win_size );
247285 return EXIT_FAILURE ;
248286 }
249- nframes = (xlength - TEST_WIN_SIZE + TEST_WIN_STEP )/ TEST_WIN_STEP ;
250- xb = (float * )opus_malloc (nframes * NBANDS * nchannels * sizeof (* xb ));
251- X = (float * )opus_malloc (nframes * NFREQS * nchannels * sizeof (* X ));
287+ nframes = (xlength - test_win_size + test_win_step )/ test_win_step ;
288+ xb = (float * )opus_malloc (nframes * nbands * nchannels * sizeof (* xb ));
289+ X = (float * )opus_malloc (nframes * nfreqs * nchannels * sizeof (* X ));
252290 Y = (float * )opus_malloc (nframes * yfreqs * nchannels * sizeof (* Y ));
253291 /*Compute the per-band spectral energy of the original signal
254292 and the error.*/
255- band_energy (xb ,X ,BANDS ,NBANDS ,x ,nchannels ,nframes ,
256- TEST_WIN_SIZE , TEST_WIN_STEP ,1 );
293+ band_energy (xb ,X ,BANDS ,nbands ,x ,nchannels ,nframes ,
294+ test_win_size , test_win_step ,1 );
257295 free (x );
258296 band_energy (NULL ,Y ,BANDS ,ybands ,y ,nchannels ,nframes ,
259- TEST_WIN_SIZE /downsample ,TEST_WIN_STEP /downsample ,downsample );
297+ test_win_size /downsample ,test_win_step /downsample ,downsample );
260298 free (y );
261299 for (xi = 0 ;xi < nframes ;xi ++ ){
262300 /*Frequency masking (low to high): 10 dB/Bark slope.*/
263- for (bi = 1 ;bi < NBANDS ;bi ++ ){
301+ for (bi = 1 ;bi < nbands ;bi ++ ){
264302 for (ci = 0 ;ci < nchannels ;ci ++ ){
265- xb [(xi * NBANDS + bi )* nchannels + ci ]+=
266- 0.1F * xb [(xi * NBANDS + bi - 1 )* nchannels + ci ];
303+ xb [(xi * nbands + bi )* nchannels + ci ]+=
304+ 0.1F * xb [(xi * nbands + bi - 1 )* nchannels + ci ];
267305 }
268306 }
269307 /*Frequency masking (high to low): 15 dB/Bark slope.*/
270- for (bi = NBANDS - 1 ;bi -- > 0 ;){
308+ for (bi = nbands - 1 ;bi -- > 0 ;){
271309 for (ci = 0 ;ci < nchannels ;ci ++ ){
272- xb [(xi * NBANDS + bi )* nchannels + ci ]+=
273- 0.03F * xb [(xi * NBANDS + bi + 1 )* nchannels + ci ];
310+ xb [(xi * nbands + bi )* nchannels + ci ]+=
311+ 0.03F * xb [(xi * nbands + bi + 1 )* nchannels + ci ];
274312 }
275313 }
276314 if (xi > 0 ){
277315 /*Temporal masking: -3 dB/2.5ms slope.*/
278- for (bi = 0 ;bi < NBANDS ;bi ++ ){
316+ for (bi = 0 ;bi < nbands ;bi ++ ){
279317 for (ci = 0 ;ci < nchannels ;ci ++ ){
280- xb [(xi * NBANDS + bi )* nchannels + ci ]+=
281- 0.5F * xb [((xi - 1 )* NBANDS + bi )* nchannels + ci ];
318+ xb [(xi * nbands + bi )* nchannels + ci ]+=
319+ 0.5F * xb [((xi - 1 )* nbands + bi )* nchannels + ci ];
282320 }
283321 }
284322 }
285323 /* Allowing some cross-talk */
286324 if (nchannels == 2 ){
287- for (bi = 0 ;bi < NBANDS ;bi ++ ){
325+ for (bi = 0 ;bi < nbands ;bi ++ ){
288326 float l ,r ;
289- l = xb [(xi * NBANDS + bi )* nchannels + 0 ];
290- r = xb [(xi * NBANDS + bi )* nchannels + 1 ];
291- xb [(xi * NBANDS + bi )* nchannels + 0 ]+= 0.01F * r ;
292- xb [(xi * NBANDS + bi )* nchannels + 1 ]+= 0.01F * l ;
327+ l = xb [(xi * nbands + bi )* nchannels + 0 ];
328+ r = xb [(xi * nbands + bi )* nchannels + 1 ];
329+ xb [(xi * nbands + bi )* nchannels + 0 ]+= 0.01F * r ;
330+ xb [(xi * nbands + bi )* nchannels + 1 ]+= 0.01F * l ;
293331 }
294332 }
295333
296334 /* Apply masking */
297335 for (bi = 0 ;bi < ybands ;bi ++ ){
298336 for (xj = BANDS [bi ];xj < BANDS [bi + 1 ];xj ++ ){
299337 for (ci = 0 ;ci < nchannels ;ci ++ ){
300- X [(xi * NFREQS + xj )* nchannels + ci ]+=
301- 0.1F * xb [(xi * NBANDS + bi )* nchannels + ci ];
338+ X [(xi * nfreqs + xj )* nchannels + ci ]+=
339+ 0.1F * xb [(xi * nbands + bi )* nchannels + ci ];
302340 Y [(xi * yfreqs + xj )* nchannels + ci ]+=
303- 0.1F * xb [(xi * NBANDS + bi )* nchannels + ci ];
341+ 0.1F * xb [(xi * nbands + bi )* nchannels + ci ];
304342 }
305343 }
306344 }
@@ -317,9 +355,9 @@ int main(int _argc,const char **_argv){
317355 for (xi = 1 ;xi < nframes ;xi ++ ){
318356 float xtmp2 ;
319357 float ytmp2 ;
320- xtmp2 = X [(xi * NFREQS + xj )* nchannels + ci ];
358+ xtmp2 = X [(xi * nfreqs + xj )* nchannels + ci ];
321359 ytmp2 = Y [(xi * yfreqs + xj )* nchannels + ci ];
322- X [(xi * NFREQS + xj )* nchannels + ci ] += xtmp ;
360+ X [(xi * nfreqs + xj )* nchannels + ci ] += xtmp ;
323361 Y [(xi * yfreqs + xj )* nchannels + ci ] += ytmp ;
324362 xtmp = xtmp2 ;
325363 ytmp = ytmp2 ;
@@ -332,7 +370,7 @@ int main(int _argc,const char **_argv){
332370 300 Hz to allow for different transition bands.
333371 For 12 kHz, we don't skip anything, because the last band already skips
334372 400 Hz.*/
335- if (rate == 96000 )max_compare = BANDS [NBANDS ];
373+ if (rate == base_rate )max_compare = BANDS [nbands ];
336374 else if (rate == 12000 )max_compare = BANDS [ybands ];
337375 else max_compare = BANDS [ybands ]- 3 ;
338376 err = 0 ;
@@ -346,12 +384,8 @@ int main(int _argc,const char **_argv){
346384 for (ci = 0 ;ci < nchannels ;ci ++ ){
347385 float re ;
348386 float im ;
349- re = Y [(xi * yfreqs + xj )* nchannels + ci ]/X [(xi * NFREQS + xj )* nchannels + ci ];
387+ re = Y [(xi * yfreqs + xj )* nchannels + ci ]/X [(xi * nfreqs + xj )* nchannels + ci ];
350388 im = re - log (re )- 1 ;
351- /*Make comparison less sensitive around the SILK/CELT cross-over to
352- allow for mode freedom in the filters.*/
353- if (xj >=159 && xj <=161 )im *=0.1F ;
354- if (xj == 160 )im *=0.1F ;
355389 Eb += im ;
356390 }
357391 }
@@ -360,7 +394,7 @@ int main(int _argc,const char **_argv){
360394 }
361395 /*Using a fixed normalization value means we're willing to accept slightly
362396 lower quality for lower sampling rates.*/
363- Ef /=NBANDS ;
397+ Ef /=nbands ;
364398 Ef *=Ef ;
365399 err += Ef * Ef ;
366400 }
0 commit comments