1 /*
2 * TwoLAME: an optimized MPEG Audio Layer Two encoder
3 *
4 * Copyright (C) 2001-2004 Michael Cheng
5 * Copyright (C) 2004-2018 The TwoLAME Project
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library 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 GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <math.h>
26 #include <string.h>
27
28 #include "twolame.h"
29 #include "common.h"
30 #include "mem.h"
31 #include "fft.h"
32 #include "ath.h"
33 #include "psycho_3.h"
34
35 /* This is a reimplementation of psy model 1 using the ISO11172 standard.
36 I found the original dist10 code (which is full of pointers) to be
37 a horrible thing to try and understand and debug.
38 This implementation is not built for speed, but is rather meant to
39 clearly outline the steps specified by the standard (still, it's only
40 a tiny fraction slower than the dist10 code, and nothing has been optimized)
41 MFC Feb 2003 */
42
psycho_3_add_db(psycho_3_mem * mem,FLOAT a,FLOAT b)43 static inline FLOAT psycho_3_add_db(psycho_3_mem * mem, FLOAT a, FLOAT b)
44 {
45 /* MFC - if the difference between a and b is large (>99), then just return the largest one.
46 (about 10% of the time) - For differences between 0 and 99, return the largest value, but
47 add in a pre-calculated difference value. - the value 99 was chosen arbitarily. - maximum
48 (a-b) i've seen is 572 */
49 FLOAT fdiff;
50 int idiff;
51 fdiff = (10.0 * (a - b));
52
53 if (fdiff > 990.0) {
54 return a;
55 }
56 if (fdiff < -990.0) {
57 return (b);
58 }
59
60 idiff = (int) fdiff;
61 if (idiff >= 0) {
62 return (a + mem->dbtable[idiff]);
63 }
64
65 return (b + mem->dbtable[-idiff]);
66 }
67
68
69
70 /* ISO11172 Sec D.1 Step 1 - Window with HANN and then perform the FFT */
psycho_3_fft(FLOAT sample[BLKSIZE],FLOAT energy[BLKSIZE])71 static void psycho_3_fft(FLOAT sample[BLKSIZE], FLOAT energy[BLKSIZE])
72 {
73 FLOAT x_real[BLKSIZE];
74 int i;
75 static int init = 0;
76 static FLOAT window[FFT_SIZE];
77
78 if (!init) { /* calculate window function for the Fourier transform */
79 FLOAT sqrt_8_over_3 = pow(8.0 / 3.0, 0.5);
80 for (i = 0; i < BLKSIZE; i++) {
81 window[i] = sqrt_8_over_3 * 0.5 * (1 - cos(2.0 * PI * i / (BLKSIZE))) / BLKSIZE;
82 }
83 init=1;
84 }
85
86 /* convolve the samples with the hann window */
87 for (i = 0; i < BLKSIZE; i++)
88 x_real[i] = (FLOAT) (sample[i] * window[i]);
89 /* do the FFT */
90 twolame_psycho_1_fft(x_real, energy, BLKSIZE);
91 }
92
93
94 /* Sect D.1 Step 1 - convert the energies into dB */
psycho_3_powerdensityspectrum(FLOAT energy[BLKSIZE],FLOAT power[HBLKSIZE])95 static void psycho_3_powerdensityspectrum(FLOAT energy[BLKSIZE], FLOAT power[HBLKSIZE])
96 {
97 int i;
98 for (i = 1; i < HBLKSIZE; i++) {
99 if (energy[i] < 1E-20)
100 power[i] = -200.0 + POWERNORM;
101 else
102 power[i] = 10 * log10(energy[i]) + POWERNORM;
103 }
104 }
105
106
107 /* Sect D.1 Step 2 - Determine the sound pressure level in each subband */
psycho_3_spl(FLOAT * Lsb,FLOAT * power,FLOAT * scale)108 static void psycho_3_spl(FLOAT * Lsb, FLOAT * power, FLOAT * scale)
109 {
110 int i;
111 FLOAT Xmax[SBLIMIT];
112
113 for (i = 0; i < SBLIMIT; i++) {
114 Xmax[i] = DBMIN;
115 }
116 /* Find the maximum SPL in the power spectrum */
117 for (i = 1; i < HBLKSIZE; i++) {
118 int index = (i - 1) >> 4;
119 if (Xmax[index] < power[i])
120 Xmax[index] = power[i];
121 }
122
123 /* Compare it to the sound pressure based upon the scale for this subband and pick the maximum
124 one */
125 for (i = 0; i < SBLIMIT; i++) {
126 FLOAT val = 20 * log10(scale[i] * 32768) - 10;
127 Lsb[i] = MAX(Xmax[i], val);
128 }
129 }
130
131
132 /* Sect D.1 Step4b
133 A tone within the range (start -> end), must be 7.0 dB greater than
134 all it's neighbours within +/- srange. Don't count its immediate neighbours. */
psycho_3_tonal_label_range(psycho_3_mem * mem,FLOAT * power,int * tonelabel,int * maxima,FLOAT * Xtm,int start,int end,int srange)135 static void psycho_3_tonal_label_range(psycho_3_mem * mem, FLOAT * power, int *tonelabel,
136 int *maxima, FLOAT * Xtm, int start, int end, int srange)
137 {
138 int j, k;
139
140 for (k = start; k < end; k++) /* Search for all the maxima in this range */
141 if (maxima[k] == 1) {
142 tonelabel[k] = TONE; /* assume it's a TONE and then prove otherwise */
143 for (j = -srange; j <= +srange; j++) /* Check the neighbours within +/- srange */
144 if (abs(j) > 1) /* Don't count the immediate neighbours, or itself */
145 if ((power[k] - power[k + j]) < 7.0)
146 tonelabel[k] = 0; /* Not greater by 7dB, therefore not a tone */
147 if (tonelabel[k] == TONE) {
148 /* Calculate the sound pressure level for this tone by summing the adjacent
149 spectral lines Xtm[k] = 10 * log10( pow(10.0, 0.1*power[k-1]) + pow(10.0,
150 0.1*power[k]) + pow(10.0, 0.1*power[k+1]) ); */
151 FLOAT temp = psycho_3_add_db(mem, power[k - 1], power[k]);
152 Xtm[k] = psycho_3_add_db(mem, temp, power[k + 1]);
153
154 /* *ALL* spectral lines within +/- srange are set to -inf dB So that when we do the
155 noise calculate, they are not counted */
156 for (j = -srange; j <= +srange; j++)
157 power[k + j] = DBMIN;
158 }
159 }
160 }
161
162
163 /* Sect D.1 Step 4 Label the Tonal Components */
psycho_3_tonal_label(psycho_3_mem * mem,FLOAT power[HBLKSIZE],int * tonelabel,FLOAT Xtm[HBLKSIZE])164 static void psycho_3_tonal_label(psycho_3_mem * mem, FLOAT power[HBLKSIZE], int *tonelabel,
165 FLOAT Xtm[HBLKSIZE])
166 {
167 int i;
168 int maxima[HBLKSIZE];
169
170 /* Find the maxima as per ISO11172 D.1.4.a */
171 maxima[0] = maxima[HBLKSIZE - 1] = 0;
172 tonelabel[0] = tonelabel[HBLKSIZE - 1] = 0;
173 Xtm[0] = Xtm[HBLKSIZE - 1] = DBMIN;
174 for (i = 1; i < HBLKSIZE - 1; i++) {
175 tonelabel[i] = 0;
176 Xtm[i] = DBMIN;
177 if (power[i] > power[i - 1] && power[i] > power[i + 1]) /* The first criteria for a maximum
178 */
179 maxima[i] = 1;
180 else
181 maxima[i] = 0;
182 }
183
184 {
185 /* Now find the tones as per ISO11172 D.1 Step4.b */
186 /* The standard is a bit vague (surprise surprise). So I'm going to assume that - a tone
187 must be 7dB greater than *all* the relevant neighbours - once a tone is found, the
188 neighbours are immediately set to -inf dB */
189
190 psycho_3_tonal_label_range(mem, power, tonelabel, maxima, Xtm, 2, 63, 2);
191 psycho_3_tonal_label_range(mem, power, tonelabel, maxima, Xtm, 63, 127, 3);
192 psycho_3_tonal_label_range(mem, power, tonelabel, maxima, Xtm, 127, 255, 6);
193 psycho_3_tonal_label_range(mem, power, tonelabel, maxima, Xtm, 255, 500, 12);
194
195 }
196 }
197
198
199
psycho_3_init_add_db(psycho_3_mem * mem)200 static void psycho_3_init_add_db(psycho_3_mem * mem)
201 {
202 int i;
203 FLOAT x;
204 for (i = 0; i < DBTAB; i++) {
205 x = (FLOAT) i / 10.0;
206 mem->dbtable[i] = 10 * log10(1 + pow(10.0, x / 10.0)) - x;
207 }
208 }
209
210
211 /* D.1 Step 4.c Labelling non-tonal (noise) components
212 Sum the energies in each critical band (the tone energies have been removed
213 during the tone labelling).
214 Find the "geometric mean" of these energies - i.e. find the best spot to put the
215 sum of energies within this critical band. */
psycho_3_noise_label(psycho_3_mem * mem,FLOAT power[HBLKSIZE],FLOAT energy[BLKSIZE],int * tonelabel,int * noiselabel,FLOAT Xnm[HBLKSIZE])216 static void psycho_3_noise_label(psycho_3_mem * mem, FLOAT power[HBLKSIZE], FLOAT energy[BLKSIZE],
217 int *tonelabel, int *noiselabel, FLOAT Xnm[HBLKSIZE])
218 {
219 int i, j;
220 int cbands = mem->cbands;
221 int *cbandindex = mem->cbandindex;
222
223 Xnm[0] = DBMIN;
224 for (i = 0; i < cbands; i++) {
225 /* for each critical band */
226 FLOAT sum = DBMIN;
227 FLOAT esum = 0;
228 FLOAT centreweight = 0;
229 int centre;
230 for (j = cbandindex[i]; j < cbandindex[i + 1]; j++) {
231 Xnm[j] = DBMIN;
232 /* go through all the spectral lines within the critical band, adding the energies. The
233 tone energies have already been removed */
234 if (power[j] != DBMIN) {
235 /* Found a noise energy, add it to the sum */
236 sum = psycho_3_add_db(mem, power[j], sum);
237
238 /* calculations for the geometric mean FIXME MFC Feb 2003: Would it just be easier
239 to do the *whole* of psycho_1 in the energy domain rather than in the dB domain?
240 FIXME: This is just a lazy arsed arithmetic mean. Don't know if it's really going
241 to make that much difference */
242 esum += energy[j]; /* Calculate the sum of energies */
243 centreweight += (j - cbandindex[i]) * energy[j]; /* And the energy moment */
244 }
245 }
246
247 /* MEANX, crash on AMD64 without this hack. See
248 https://sourceforge.net/tracker/?func=detail&atid=735435&aid=1453400&group_id=136040
249 Probably a better way to do this */
250 if (sum <= DBMIN || esum < 0.00001)
251 /* If the energy sum is really small, just pretend the noise occurs in the centre
252 frequency line */
253 centre = (cbandindex[i] + cbandindex[i + 1]) / 2;
254 else {
255 /* Otherwise, work out the mean position of the noise, and put it there. */
256 centre = cbandindex[i] + (int) (centreweight / esum);
257 }
258 // /MEANX
259 Xnm[centre] = sum;
260 noiselabel[centre] = NOISE;
261 }
262 }
263
264
265 /* ISO11172 D.1 Step 5
266 Get rid of noise/tones that aren't greater than the ATH
267 If two tones are within 0.5bark, then delete the tone with the lower energy */
psycho_3_decimation(FLOAT * ath,int * tonelabel,FLOAT * Xtm,int * noiselabel,FLOAT * Xnm,FLOAT * bark)268 static void psycho_3_decimation(FLOAT * ath, int *tonelabel, FLOAT * Xtm, int *noiselabel,
269 FLOAT * Xnm, FLOAT * bark)
270 {
271 int i;
272
273 /* Delete components which aren't above the ATH */
274 for (i = 1; i < HBLKSIZE; i++) {
275 if (noiselabel[i] == NOISE) {
276 if (Xnm[i] < ath[i]) {
277 /* this masker isn't above the ATH : delete it */
278 Xnm[i] = DBMIN;
279 noiselabel[i] = 0;
280 }
281 }
282 if (tonelabel[i] == TONE) {
283 if (Xtm[i] < ath[i]) {
284 Xtm[i] = DBMIN;
285 tonelabel[i] = 0;
286 }
287 }
288 }
289 /* Search for tones that are within 0.5 bark */
290 /* MFC FIXME Feb 2003: haven't done this yet */
291
292 }
293
294
295 /* ISO11172 Sect D.1 Step 6
296 Calculation of individual masking thresholds
297 Work out how each of the tones&noises maskes other frequencies
298 NOTE: Only a subset of other frequencies is checked. According to the
299 standard different subbands are subsampled to different amounts.
300 See psycho_3_init and freq_subset */
psycho_3_threshold(psycho_3_mem * mem,FLOAT * LTg,int * tonelabel,FLOAT * Xtm,int * noiselabel,FLOAT * Xnm,FLOAT * bark,FLOAT * ath,int bit_rate,int * freq_subset)301 static void psycho_3_threshold(psycho_3_mem * mem, FLOAT * LTg, int *tonelabel, FLOAT * Xtm,
302 int *noiselabel, FLOAT * Xnm, FLOAT * bark, FLOAT * ath,
303 int bit_rate, int *freq_subset)
304 {
305 int i, j, k;
306 FLOAT LTtm[SUBSIZE];
307 FLOAT LTnm[SUBSIZE];
308
309 for (i = 0; i < SUBSIZE; i++) {
310 LTtm[i] = DBMIN;
311 LTnm[i] = DBMIN;
312 }
313 /* Loop over the entire spectrum and find every noise and tone And then with each noise/tone
314 work out how it masks the spectral lines around it */
315 for (k = 1; k < HBLKSIZE; k++) {
316 /* Find every tone */
317 if (tonelabel[k] == TONE) {
318 for (j = 0; j < SUBSIZE; j++) {
319 /* figure out how it masks the levels around it */
320 FLOAT dz = bark[freq_subset[j]] - bark[k];
321 if (dz >= -3.0 && dz < 8.0) {
322 FLOAT vf;
323 FLOAT av = -1.525 - 0.275 * bark[k] - 4.5 + Xtm[k];
324 /* masking function for lower & upper slopes */
325 if (dz < -1)
326 vf = 17 * (dz + 1) - (0.4 * Xtm[k] + 6);
327 else if (dz < 0)
328 vf = (0.4 * Xtm[k] + 6) * dz;
329 else if (dz < 1)
330 vf = (-17 * dz);
331 else
332 vf = -(dz - 1) * (17 - 0.15 * Xtm[k]) - 17;
333 LTtm[j] = psycho_3_add_db(mem, LTtm[j], av + vf);
334 }
335 }
336 }
337
338 /* find every noise label */
339 if (noiselabel[k] == NOISE) {
340 for (j = 0; j < SUBSIZE; j++) {
341 /* figure out how it masks the levels around it */
342 FLOAT dz = bark[freq_subset[j]] - bark[k];
343 if (dz >= -3.0 && dz < 8.0) {
344 FLOAT vf;
345 FLOAT av = -1.525 - 0.175 * bark[k] - 0.5 + Xnm[k];
346 /* masking function for lower & upper slopes */
347 if (dz < -1)
348 vf = 17 * (dz + 1) - (0.4 * Xnm[k] + 6);
349 else if (dz < 0)
350 vf = (0.4 * Xnm[k] + 6) * dz;
351 else if (dz < 1)
352 vf = (-17 * dz);
353 else
354 vf = -(dz - 1) * (17 - 0.15 * Xnm[k]) - 17;
355 LTnm[j] = psycho_3_add_db(mem, LTnm[j], av + vf);
356 }
357 }
358 }
359 }
360
361 /* ISO11172 D.1 Step 7 Calculate the global masking threhold */
362 for (i = 0; i < SUBSIZE; i++) {
363 LTg[i] = psycho_3_add_db(mem, LTnm[i], LTtm[i]);
364 if (bit_rate < 96)
365 LTg[i] = psycho_3_add_db(mem, ath[freq_subset[i]], LTg[i]);
366 else
367 LTg[i] = psycho_3_add_db(mem, ath[freq_subset[i]] - 12.0, LTg[i]);
368 }
369 }
370
371
372 /* Find the minimum LTg for each subband. ISO11172 Sec D.1 Step 8 */
psycho_3_minimummasking(FLOAT * LTg,FLOAT * LTmin,int * freq_subset)373 static void psycho_3_minimummasking(FLOAT * LTg, FLOAT * LTmin, int *freq_subset)
374 {
375 int i;
376
377 for (i = 0; i < SBLIMIT; i++)
378 LTmin[i] = 999999.9;
379
380 for (i = 0; i < SUBSIZE; i++) {
381 int index = freq_subset[i] >> 4;
382 if (LTmin[index] > LTg[i]) {
383 LTmin[index] = LTg[i];
384 }
385 }
386 }
387
388
389 /* ISO11172 Sect D.1 Step 9
390 Calculate the signal-to-mask ratio
391 MFC FIXME Feb 2003 for better calling from
392 twolame, add a "float SMR[]" array and return it */
psycho_3_smr(FLOAT * LTmin,FLOAT * Lsb)393 static void psycho_3_smr(FLOAT * LTmin, FLOAT * Lsb)
394 {
395 int i;
396 for (i = 0; i < SBLIMIT; i++) {
397 LTmin[i] = Lsb[i] - LTmin[i];
398 }
399 }
400
401
twolame_psycho_3_init(twolame_options * glopts)402 static psycho_3_mem *twolame_psycho_3_init(twolame_options * glopts)
403 {
404 int i;
405 int cbase = 0; /* current base index for the bark range calculation */
406 FLOAT sfreq;
407 psycho_3_mem *mem;
408 int numlines[HBLKSIZE];
409 FLOAT cbval[HBLKSIZE];
410 int partition[HBLKSIZE];
411 int *freq_subset;
412 FLOAT *bark, *ath;
413 int cbands = 0;
414 int *cbandindex;
415
416 mem = (psycho_3_mem *) TWOLAME_MALLOC(sizeof(psycho_3_mem));
417 mem->off[0] = mem->off[1] = 256;
418 freq_subset = mem->freq_subset;
419 bark = mem->bark;
420 ath = mem->ath;
421 cbandindex = mem->cbandindex;
422
423 /* Initialise the tables for the adding dB */
424 psycho_3_init_add_db(mem);
425
426 /* For each spectral line calculate the bark and the ATH (in dB) */
427 sfreq = (FLOAT) glopts->samplerate_out;
428 for (i = 1; i < HBLKSIZE; i++) {
429 FLOAT freq = i * sfreq / BLKSIZE;
430 bark[i] = twolame_ath_freq2bark(freq);
431 ath[i] = twolame_ath_db(freq, glopts->athlevel);
432 }
433
434 { /* Work out the critical bands Starting from line 0, all lines
435 within 1 bark of the starting bark are added to the same
436 critical band. When a line is greater by 1.0 of a bark, start a
437 new critical band. */
438
439 cbandindex[0] = 1;
440 for (i = 1; i < HBLKSIZE; i++) {
441 if ((bark[i] - bark[cbase]) > 1.0) { /* 1 critical band? 1 bark? */
442 /* this frequency line is too different from the starting line, (in terms of the
443 bark distance) so make this spectral line the first member of the next critical
444 band */
445 cbase = i; /* Start the new critical band from this frequency line */
446 cbands++;
447 cbandindex[cbands] = cbase;
448 }
449 /* partition[i] tells us which critical band the i'th frequency line is in */
450 partition[i] = cbands;
451 /* keep a count of how many frequency lines are in each partition */
452 numlines[cbands]++;
453 }
454
455 cbands++;
456 cbandindex[cbands] = 513; /* Set the top of the last critical band */
457 mem->cbands = cbands; // make a not of the number of cbands
458
459 /* For each crtical band calculate the average bark value cbval [central bark value] */
460 for (i = 1; i < HBLKSIZE; i++)
461 cbval[partition[i]] += bark[i]; /* sum up all the bark values */
462 for (i = 1; i < CBANDS; i++) {
463 if (numlines[i] != 0)
464 cbval[i] /= numlines[i]; /* divide by the number of values */
465 else {
466 cbval[i] = 0; /* this isn't a partition */
467 }
468 }
469 }
470
471 {
472 /* For Step6 - For the calculation of individual masking thresholds the spectral lines are
473 subsampled i.e. no need to work out the masking for every single spectral line.
474 Depending upon which subband the calculation is for, you can skip a number of lines
475 There are 16 lines per subband -> 32 * 16 = 512 Subband 0-2 : Every line (3 * 16 = 48
476 lines) Subband 3-5 : Every Second line (3 * 16/2 = 24 lines) Subband 6-11 : Every 4th
477 line (6 * 16/4 = 24 lines) Subband 12-31 : Every 12th line (20 * 16/8 = 40 lines)
478
479 create this subset of frequencies (freq_subset) */
480 int freq_index = 0;
481 for (i = 1; i < (3 * 16) + 1; i++)
482 freq_subset[freq_index++] = i;
483 for (; i < (6 * 16) + 1; i += 2)
484 freq_subset[freq_index++] = i;
485 for (; i < (12 * 16) + 1; i += 4)
486 freq_subset[freq_index++] = i;
487 for (; i < (32 * 16) + 1; i += 8)
488 freq_subset[freq_index++] = i;
489 }
490
491 if (glopts->verbosity > 4) {
492 fprintf(stderr, "%i critical bands\n", cbands);
493 for (i = 0; i < cbands; i++)
494 fprintf(stderr, "cband %i spectral line index %i\n", i, cbandindex[i]);
495 fprintf(stderr, "%i Subsampled spectral lines\n", SUBSIZE);
496 for (i = 0; i < SUBSIZE; i++)
497 fprintf(stderr, "%i Spectral line %i Bark %.2f\n", i, freq_subset[i],
498 bark[freq_subset[i]]);
499 }
500
501 return (mem);
502 }
503
504
psycho_3_dump(int * tonelabel,FLOAT * Xtm,int * noiselabel,FLOAT * Xnm)505 static void psycho_3_dump(int *tonelabel, FLOAT * Xtm, int *noiselabel, FLOAT * Xnm)
506 {
507 int i;
508 fprintf(stderr, "3 Ton:");
509 for (i = 1; i < HAN_SIZE; i++) {
510 if (tonelabel[i] == TONE)
511 fprintf(stderr, "[%i] %3.0f ", i, Xtm[i]);
512 }
513 fprintf(stderr, "\n");
514
515 fprintf(stderr, "3 Nos:");
516 for (i = 1; i < HAN_SIZE; i++) {
517 if (noiselabel[i] == NOISE)
518 fprintf(stderr, "[%i] %3.0f ", i, Xnm[i]);
519 }
520 fprintf(stderr, "\n");
521 }
522
523
twolame_psycho_3(twolame_options * glopts,short int buffer[2][1152],FLOAT scale[2][32],FLOAT ltmin[2][32])524 void twolame_psycho_3(twolame_options * glopts, short int buffer[2][1152], FLOAT scale[2][32],
525 FLOAT ltmin[2][32])
526 {
527 psycho_3_mem *mem;
528 int nch = glopts->num_channels_out;
529 int k, i;
530 FLOAT sample[BLKSIZE];
531
532 FLOAT energy[BLKSIZE];
533 FLOAT power[HBLKSIZE] = {0};
534 FLOAT Xtm[HBLKSIZE], Xnm[HBLKSIZE];
535 int tonelabel[HBLKSIZE], noiselabel[HBLKSIZE] = {0};
536 FLOAT LTg[HBLKSIZE];
537 FLOAT Lsb[SBLIMIT];
538
539 if (!glopts->p3mem) {
540 glopts->p3mem = twolame_psycho_3_init(glopts);
541 }
542 mem = glopts->p3mem;
543
544 for (k = 0; k < nch; k++) {
545 int ok = mem->off[k] % 1408;
546 for (i = 0; i < 1152; i++) {
547 mem->fft_buf[k][ok++] = (FLOAT) buffer[k][i] / SCALE;
548 if (ok >= 1408)
549 ok = 0;
550 }
551 ok = (mem->off[k] + 1216) % 1408;
552 for (i = 0; i < BLKSIZE; i++) {
553 sample[i] = mem->fft_buf[k][ok++];
554 if (ok >= 1408)
555 ok = 0;
556 }
557
558 mem->off[k] += 1152;
559 mem->off[k] %= 1408;
560
561 psycho_3_fft(sample, energy);
562 psycho_3_powerdensityspectrum(energy, power);
563 psycho_3_spl(Lsb, power, &scale[k][0]);
564 psycho_3_tonal_label(mem, power, tonelabel, Xtm);
565 psycho_3_noise_label(mem, power, energy, tonelabel, noiselabel, Xnm);
566 if (glopts->verbosity > 8)
567 psycho_3_dump(tonelabel, Xtm, noiselabel, Xnm);
568 psycho_3_decimation(mem->ath, tonelabel, Xtm, noiselabel, Xnm, mem->bark);
569 psycho_3_threshold(mem, LTg, tonelabel, Xtm, noiselabel, Xnm, mem->bark, mem->ath,
570 glopts->bitrate / nch, mem->freq_subset);
571 psycho_3_minimummasking(LTg, <min[k][0], mem->freq_subset);
572 psycho_3_smr(<min[k][0], Lsb);
573 }
574 }
575
576
twolame_psycho_3_deinit(psycho_3_mem ** mem)577 void twolame_psycho_3_deinit(psycho_3_mem ** mem)
578 {
579
580 if (mem == NULL || *mem == NULL)
581 return;
582
583 TWOLAME_FREE(*mem);
584 }
585
586
587 // vim:ts=4:sw=4:nowrap:
588