Coverage Report

Created: 2026-07-25 07:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vorbis/lib/psy.c
Line
Count
Source
1
/********************************************************************
2
 *                                                                  *
3
 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
4
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
5
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
7
 *                                                                  *
8
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
9
 * by the Xiph.Org Foundation https://xiph.org/                     *
10
 *                                                                  *
11
 ********************************************************************
12
13
 function: psychoacoustics not including preecho
14
15
 ********************************************************************/
16
17
#include <stdlib.h>
18
#include <math.h>
19
#include <string.h>
20
#include "vorbis/codec.h"
21
#include "codec_internal.h"
22
23
#include "masking.h"
24
#include "psy.h"
25
#include "os.h"
26
#include "lpc.h"
27
#include "smallft.h"
28
#include "scales.h"
29
#include "misc.h"
30
31
252M
#define NEGINF -9999.f
32
static const double stereo_threshholds[]={0.0, .5, 1.0, 1.5, 2.5, 4.5, 8.5, 16.5, 9e10};
33
static const double stereo_threshholds_limited[]={0.0, .5, 1.0, 1.5, 2.0, 2.5, 4.5, 8.5, 9e10};
34
35
2.21k
vorbis_look_psy_global *_vp_global_look(vorbis_info *vi){
36
2.21k
  codec_setup_info *ci=vi->codec_setup;
37
2.21k
  vorbis_info_psy_global *gi=&ci->psy_g_param;
38
2.21k
  vorbis_look_psy_global *look=_ogg_calloc(1,sizeof(*look));
39
40
2.21k
  look->channels=vi->channels;
41
42
2.21k
  look->ampmax=-9999.;
43
2.21k
  look->gi=gi;
44
2.21k
  return(look);
45
2.21k
}
46
47
2.21k
void _vp_global_free(vorbis_look_psy_global *look){
48
2.21k
  if(look){
49
2.21k
    memset(look,0,sizeof(*look));
50
2.21k
    _ogg_free(look);
51
2.21k
  }
52
2.21k
}
53
54
0
void _vi_gpsy_free(vorbis_info_psy_global *i){
55
0
  if(i){
56
0
    memset(i,0,sizeof(*i));
57
0
    _ogg_free(i);
58
0
  }
59
0
}
60
61
8.04k
void _vi_psy_free(vorbis_info_psy *i){
62
8.04k
  if(i){
63
8.04k
    memset(i,0,sizeof(*i));
64
8.04k
    _ogg_free(i);
65
8.04k
  }
66
8.04k
}
67
68
static void min_curve(float *c,
69
1.91M
                       float *c2){
70
1.91M
  int i;
71
109M
  for(i=0;i<EHMER_MAX;i++)if(c2[i]<c[i])c[i]=c2[i];
72
1.91M
}
73
static void max_curve(float *c,
74
1.09M
                       float *c2){
75
1.09M
  int i;
76
62.3M
  for(i=0;i<EHMER_MAX;i++)if(c2[i]>c[i])c[i]=c2[i];
77
1.09M
}
78
79
2.18M
static void attenuate_curve(float *c,float att){
80
2.18M
  int i;
81
124M
  for(i=0;i<EHMER_MAX;i++)
82
122M
    c[i]+=att;
83
2.18M
}
84
85
static float ***setup_tone_curves(float curveatt_dB[P_BANDS],float binHz,int n,
86
8.04k
                                  float center_boost, float center_decay_rate){
87
8.04k
  int i,j,k,m;
88
8.04k
  float ath[EHMER_MAX];
89
8.04k
  float workc[P_BANDS][P_LEVELS][EHMER_MAX];
90
8.04k
  float athc[P_LEVELS][EHMER_MAX];
91
8.04k
  float *brute_buffer=alloca(n*sizeof(*brute_buffer));
92
93
8.04k
  float ***ret=_ogg_malloc(sizeof(*ret)*P_BANDS);
94
95
8.04k
  memset(workc,0,sizeof(workc));
96
97
144k
  for(i=0;i<P_BANDS;i++){
98
    /* we add back in the ATH to avoid low level curves falling off to
99
       -infinity and unnecessarily cutting off high level curves in the
100
       curve limiting (last step). */
101
102
    /* A half-band's settings must be valid over the whole band, and
103
       it's better to mask too little than too much */
104
136k
    int ath_offset=i*4;
105
7.79M
    for(j=0;j<EHMER_MAX;j++){
106
7.65M
      float min=999.;
107
38.2M
      for(k=0;k<4;k++)
108
30.6M
        if(j+k+ath_offset<MAX_ATH){
109
25.5M
          if(min>ATH[j+k+ath_offset])min=ATH[j+k+ath_offset];
110
25.5M
        }else{
111
5.06M
          if(min>ATH[MAX_ATH-1])min=ATH[MAX_ATH-1];
112
5.06M
        }
113
7.65M
      ath[j]=min;
114
7.65M
    }
115
116
    /* copy curves into working space, replicate the 50dB curve to 30
117
       and 40, replicate the 100dB curve to 110 */
118
956k
    for(j=0;j<6;j++)
119
820k
      memcpy(workc[i][j+2],tonemasks[i][j],EHMER_MAX*sizeof(*tonemasks[i][j]));
120
136k
    memcpy(workc[i][0],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0]));
121
136k
    memcpy(workc[i][1],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0]));
122
123
    /* apply centered curve boost/decay */
124
1.23M
    for(j=0;j<P_LEVELS;j++){
125
62.3M
      for(k=0;k<EHMER_MAX;k++){
126
61.2M
        float adj=center_boost+abs(EHMER_OFFSET-k)*center_decay_rate;
127
61.2M
        if(adj<0. && center_boost>0)adj=0.;
128
61.2M
        if(adj>0. && center_boost<0)adj=0.;
129
61.2M
        workc[i][j][k]+=adj;
130
61.2M
      }
131
1.09M
    }
132
133
    /* normalize curves so the driving amplitude is 0dB */
134
    /* make temp curves with the ATH overlayed */
135
1.23M
    for(j=0;j<P_LEVELS;j++){
136
1.09M
      attenuate_curve(workc[i][j],curveatt_dB[i]+100.-(j<2?2:j)*10.-P_LEVEL_0);
137
1.09M
      memcpy(athc[j],ath,EHMER_MAX*sizeof(**athc));
138
1.09M
      attenuate_curve(athc[j],+100.-j*10.f-P_LEVEL_0);
139
1.09M
      max_curve(athc[j],workc[i][j]);
140
1.09M
    }
141
142
    /* Now limit the louder curves.
143
144
       the idea is this: We don't know what the playback attenuation
145
       will be; 0dB SL moves every time the user twiddles the volume
146
       knob. So that means we have to use a single 'most pessimal' curve
147
       for all masking amplitudes, right?  Wrong.  The *loudest* sound
148
       can be in (we assume) a range of ...+100dB] SL.  However, sounds
149
       20dB down will be in a range ...+80], 40dB down is from ...+60],
150
       etc... */
151
152
1.09M
    for(j=1;j<P_LEVELS;j++){
153
956k
      min_curve(athc[j],athc[j-1]);
154
956k
      min_curve(workc[i][j],athc[j]);
155
956k
    }
156
136k
  }
157
158
144k
  for(i=0;i<P_BANDS;i++){
159
136k
    int hi_curve,lo_curve,bin;
160
136k
    ret[i]=_ogg_malloc(sizeof(**ret)*P_LEVELS);
161
162
    /* low frequency curves are measured with greater resolution than
163
       the MDCT/FFT will actually give us; we want the curve applied
164
       to the tone data to be pessimistic and thus apply the minimum
165
       masking possible for a given bin.  That means that a single bin
166
       could span more than one octave and that the curve will be a
167
       composite of multiple octaves.  It also may mean that a single
168
       bin may span > an eighth of an octave and that the eighth
169
       octave values may also be composited. */
170
171
    /* which octave curves will we be compositing? */
172
136k
    bin=floor(fromOC(i*.5)/binHz);
173
136k
    lo_curve=  ceil(toOC(bin*binHz+1)*2);
174
136k
    hi_curve=  floor(toOC((bin+1)*binHz)*2);
175
136k
    if(lo_curve>i)lo_curve=i;
176
136k
    if(lo_curve<0)lo_curve=0;
177
136k
    if(hi_curve>=P_BANDS)hi_curve=P_BANDS-1;
178
179
1.23M
    for(m=0;m<P_LEVELS;m++){
180
1.09M
      ret[i][m]=_ogg_malloc(sizeof(***ret)*(EHMER_MAX+2));
181
182
574M
      for(j=0;j<n;j++)brute_buffer[j]=999.;
183
184
      /* render the curve into bins, then pull values back into curve.
185
         The point is that any inherent subsampling aliasing results in
186
         a safe minimum */
187
2.85M
      for(k=lo_curve;k<=hi_curve;k++){
188
1.76M
        int l=0;
189
190
100M
        for(j=0;j<EHMER_MAX;j++){
191
98.6M
          int lo_bin= fromOC(j*.125+k*.5-2.0625)/binHz;
192
98.6M
          int hi_bin= fromOC(j*.125+k*.5-1.9375)/binHz+1;
193
194
98.6M
          if(lo_bin<0)lo_bin=0;
195
98.6M
          if(lo_bin>n)lo_bin=n;
196
98.6M
          if(lo_bin<l)l=lo_bin;
197
98.6M
          if(hi_bin<0)hi_bin=0;
198
98.6M
          if(hi_bin>n)hi_bin=n;
199
200
587M
          for(;l<hi_bin && l<n;l++)
201
488M
            if(brute_buffer[l]>workc[k][m][j])
202
405M
              brute_buffer[l]=workc[k][m][j];
203
98.6M
        }
204
205
287M
        for(;l<n;l++)
206
285M
          if(brute_buffer[l]>workc[k][m][EHMER_MAX-1])
207
216M
            brute_buffer[l]=workc[k][m][EHMER_MAX-1];
208
209
1.76M
      }
210
211
      /* be equally paranoid about being valid up to next half ocatve */
212
1.09M
      if(i+1<P_BANDS){
213
1.02M
        int l=0;
214
1.02M
        k=i+1;
215
58.6M
        for(j=0;j<EHMER_MAX;j++){
216
57.6M
          int lo_bin= fromOC(j*.125+i*.5-2.0625)/binHz;
217
57.6M
          int hi_bin= fromOC(j*.125+i*.5-1.9375)/binHz+1;
218
219
57.6M
          if(lo_bin<0)lo_bin=0;
220
57.6M
          if(lo_bin>n)lo_bin=n;
221
57.6M
          if(lo_bin<l)l=lo_bin;
222
57.6M
          if(hi_bin<0)hi_bin=0;
223
57.6M
          if(hi_bin>n)hi_bin=n;
224
225
461M
          for(;l<hi_bin && l<n;l++)
226
403M
            if(brute_buffer[l]>workc[k][m][j])
227
67.5M
              brute_buffer[l]=workc[k][m][j];
228
57.6M
        }
229
230
183M
        for(;l<n;l++)
231
182M
          if(brute_buffer[l]>workc[k][m][EHMER_MAX-1])
232
21.7M
            brute_buffer[l]=workc[k][m][EHMER_MAX-1];
233
234
1.02M
      }
235
236
237
62.3M
      for(j=0;j<EHMER_MAX;j++){
238
61.2M
        int bin=fromOC(j*.125+i*.5-2.)/binHz;
239
61.2M
        if(bin<0){
240
0
          ret[i][m][j+2]=-999.;
241
61.2M
        }else{
242
61.2M
          if(bin>=n){
243
11.9M
            ret[i][m][j+2]=-999.;
244
49.2M
          }else{
245
49.2M
            ret[i][m][j+2]=brute_buffer[bin];
246
49.2M
          }
247
61.2M
        }
248
61.2M
      }
249
250
      /* add fenceposts */
251
12.2M
      for(j=0;j<EHMER_OFFSET;j++)
252
12.1M
        if(ret[i][m][j+2]>-200.f)break;
253
1.09M
      ret[i][m][0]=j;
254
255
31.2M
      for(j=EHMER_MAX-1;j>EHMER_OFFSET+1;j--)
256
31.0M
        if(ret[i][m][j+2]>-200.f)
257
952k
          break;
258
1.09M
      ret[i][m][1]=j;
259
260
1.09M
    }
261
136k
  }
262
263
8.04k
  return(ret);
264
8.04k
}
265
266
void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,
267
8.04k
                  vorbis_info_psy_global *gi,int n,long rate){
268
8.04k
  long i,j,lo=-99,hi=1;
269
8.04k
  long maxoc;
270
8.04k
  memset(p,0,sizeof(*p));
271
272
8.04k
  p->eighth_octave_lines=gi->eighth_octave_lines;
273
8.04k
  p->shiftoc=rint(log(gi->eighth_octave_lines*8.f)/log(2.f))-1;
274
275
8.04k
  p->firstoc=toOC(.25f*rate*.5/n)*(1<<(p->shiftoc+1))-gi->eighth_octave_lines;
276
8.04k
  maxoc=toOC((n+.25f)*rate*.5/n)*(1<<(p->shiftoc+1))+.5f;
277
8.04k
  p->total_octave_lines=maxoc-p->firstoc+1;
278
8.04k
  p->ath=_ogg_malloc(n*sizeof(*p->ath));
279
280
8.04k
  p->octave=_ogg_malloc(n*sizeof(*p->octave));
281
8.04k
  p->bark=_ogg_malloc(n*sizeof(*p->bark));
282
8.04k
  p->vi=vi;
283
8.04k
  p->n=n;
284
8.04k
  p->rate=rate;
285
286
  /* AoTuV HF weighting */
287
8.04k
  p->m_val = 1.;
288
8.04k
  if(rate < 26000) p->m_val = 0;
289
6.11k
  else if(rate < 38000) p->m_val = .94;   /* 32kHz */
290
4.36k
  else if(rate > 46000) p->m_val = 1.275; /* 48kHz */
291
292
  /* set up the lookups for a given blocksize and sample rate */
293
294
707k
  for(i=0,j=0;i<MAX_ATH-1;i++){
295
699k
    int endpos=rint(fromOC((i+1)*.125-2.)*2*n/rate);
296
699k
    float base=ATH[i];
297
699k
    if(j<endpos){
298
433k
      float delta=(ATH[i+1]-base)/(endpos-j);
299
3.80M
      for(;j<endpos && j<n;j++){
300
3.36M
        p->ath[j]=base+100.;
301
3.36M
        base+=delta;
302
3.36M
      }
303
433k
    }
304
699k
  }
305
306
853k
  for(;j<n;j++){
307
845k
    p->ath[j]=p->ath[j-1];
308
845k
  }
309
310
4.22M
  for(i=0;i<n;i++){
311
4.21M
    float bark=toBARK(rate/(2*n)*i);
312
313
8.79M
    for(;lo+vi->noisewindowlomin<i &&
314
7.93M
          toBARK(rate/(2*n)*lo)<(bark-vi->noisewindowlo);lo++);
315
316
8.43M
    for(;hi<=n && (hi<i+vi->noisewindowhimin ||
317
7.23M
          toBARK(rate/(2*n)*hi)<(bark+vi->noisewindowhi));hi++);
318
319
4.21M
    p->bark[i]=((lo-1)*(1<<16))+(hi-1);
320
321
4.21M
  }
322
323
4.22M
  for(i=0;i<n;i++)
324
4.21M
    p->octave[i]=toOC((i+.25f)*.5*rate/n)*(1<<(p->shiftoc+1))+.5f;
325
326
8.04k
  p->tonecurves=setup_tone_curves(vi->toneatt,rate*.5/n,n,
327
8.04k
                                  vi->tone_centerboost,vi->tone_decay);
328
329
  /* set up rolling noise median */
330
8.04k
  p->noiseoffset=_ogg_malloc(P_NOISECURVES*sizeof(*p->noiseoffset));
331
32.1k
  for(i=0;i<P_NOISECURVES;i++)
332
24.1k
    p->noiseoffset[i]=_ogg_malloc(n*sizeof(**p->noiseoffset));
333
334
4.22M
  for(i=0;i<n;i++){
335
4.21M
    float halfoc=toOC((i+.5)*rate/(2.*n))*2.;
336
4.21M
    int inthalfoc;
337
4.21M
    float del;
338
339
4.21M
    if(halfoc<0)halfoc=0;
340
4.21M
    if(halfoc>=P_BANDS-1)halfoc=P_BANDS-1;
341
4.21M
    inthalfoc=(int)halfoc;
342
    /*If we hit the P_BANDS-1 clamp above, inthalfoc+1 will be out of bounds,
343
       even though it will have an interpolation weight of 0.
344
      Shift the interval so we don't read past the end of the array.*/
345
4.21M
    if(inthalfoc>=P_BANDS-2)inthalfoc=P_BANDS-2;
346
4.21M
    del=halfoc-inthalfoc;
347
348
16.8M
    for(j=0;j<P_NOISECURVES;j++)
349
12.6M
      p->noiseoffset[j][i]=
350
12.6M
        p->vi->noiseoff[j][inthalfoc]*(1.-del) +
351
12.6M
        p->vi->noiseoff[j][inthalfoc+1]*del;
352
353
4.21M
  }
354
#if 0
355
  {
356
    static int ls=0;
357
    _analysis_output_always("noiseoff0",ls,p->noiseoffset[0],n,1,0,0);
358
    _analysis_output_always("noiseoff1",ls,p->noiseoffset[1],n,1,0,0);
359
    _analysis_output_always("noiseoff2",ls++,p->noiseoffset[2],n,1,0,0);
360
  }
361
#endif
362
8.04k
}
363
364
8.04k
void _vp_psy_clear(vorbis_look_psy *p){
365
8.04k
  int i,j;
366
8.04k
  if(p){
367
8.04k
    if(p->ath)_ogg_free(p->ath);
368
8.04k
    if(p->octave)_ogg_free(p->octave);
369
8.04k
    if(p->bark)_ogg_free(p->bark);
370
8.04k
    if(p->tonecurves){
371
144k
      for(i=0;i<P_BANDS;i++){
372
1.23M
        for(j=0;j<P_LEVELS;j++){
373
1.09M
          _ogg_free(p->tonecurves[i][j]);
374
1.09M
        }
375
136k
        _ogg_free(p->tonecurves[i]);
376
136k
      }
377
8.04k
      _ogg_free(p->tonecurves);
378
8.04k
    }
379
8.04k
    if(p->noiseoffset){
380
32.1k
      for(i=0;i<P_NOISECURVES;i++){
381
24.1k
        _ogg_free(p->noiseoffset[i]);
382
24.1k
      }
383
8.04k
      _ogg_free(p->noiseoffset);
384
8.04k
    }
385
8.04k
    memset(p,0,sizeof(*p));
386
8.04k
  }
387
8.04k
}
388
389
/* octave/(8*eighth_octave_lines) x scale and dB y scale */
390
static void seed_curve(float *seed,
391
                       const float **curves,
392
                       float amp,
393
                       int oc, int n,
394
10.7M
                       int linesper,float dBoffset){
395
10.7M
  int i,post1;
396
10.7M
  int seedptr;
397
10.7M
  const float *posts,*curve;
398
399
10.7M
  int choice=(int)((amp+dBoffset-P_LEVEL_0)*.1f);
400
10.7M
  choice=max(choice,0);
401
10.7M
  choice=min(choice,P_LEVELS-1);
402
10.7M
  posts=curves[choice];
403
10.7M
  curve=posts+2;
404
10.7M
  post1=(int)posts[1];
405
10.7M
  seedptr=oc+(posts[0]-EHMER_OFFSET)*linesper-(linesper>>1);
406
407
131M
  for(i=posts[0];i<post1;i++){
408
123M
    if(seedptr>0){
409
122M
      float lin=amp+curve[i];
410
122M
      if(seed[seedptr]<lin)seed[seedptr]=lin;
411
122M
    }
412
123M
    seedptr+=linesper;
413
123M
    if(seedptr>=n)break;
414
123M
  }
415
10.7M
}
416
417
static void seed_loop(vorbis_look_psy *p,
418
                      const float ***curves,
419
                      const float *f,
420
                      const float *flr,
421
                      float *seed,
422
105k
                      float specmax){
423
105k
  vorbis_info_psy *vi=p->vi;
424
105k
  long n=p->n,i;
425
105k
  float dBoffset=vi->max_curve_dB-specmax;
426
427
  /* prime the working vector with peak values */
428
429
15.6M
  for(i=0;i<n;i++){
430
15.5M
    float max=f[i];
431
15.5M
    long oc=p->octave[i];
432
21.4M
    while(i+1<n && p->octave[i+1]==oc){
433
5.89M
      i++;
434
5.89M
      if(f[i]>max)max=f[i];
435
5.89M
    }
436
437
15.5M
    if(max+6.f>flr[i]){
438
10.7M
      oc=oc>>p->shiftoc;
439
440
10.7M
      if(oc>=P_BANDS)oc=P_BANDS-1;
441
10.7M
      if(oc<0)oc=0;
442
443
10.7M
      seed_curve(seed,
444
10.7M
                 curves[oc],
445
10.7M
                 max,
446
10.7M
                 p->octave[i]-p->firstoc,
447
10.7M
                 p->total_octave_lines,
448
10.7M
                 p->eighth_octave_lines,
449
10.7M
                 dBoffset);
450
10.7M
    }
451
15.5M
  }
452
105k
}
453
454
105k
static void seed_chase(float *seeds, int linesper, long n){
455
105k
  long  *posstack=alloca(n*sizeof(*posstack));
456
105k
  float *ampstack=alloca(n*sizeof(*ampstack));
457
105k
  long   stack=0;
458
105k
  long   pos=0;
459
105k
  long   i;
460
461
64.5M
  for(i=0;i<n;i++){
462
64.4M
    if(stack<2){
463
211k
      posstack[stack]=i;
464
211k
      ampstack[stack++]=seeds[i];
465
64.2M
    }else{
466
112M
      while(1){
467
112M
        if(seeds[i]<ampstack[stack-1]){
468
44.9M
          posstack[stack]=i;
469
44.9M
          ampstack[stack++]=seeds[i];
470
44.9M
          break;
471
67.9M
        }else{
472
67.9M
          if(i<posstack[stack-1]+linesper){
473
67.9M
            if(stack>1 && ampstack[stack-1]<=ampstack[stack-2] &&
474
65.6M
               i<posstack[stack-2]+linesper){
475
              /* we completely overlap, making stack-1 irrelevant.  pop it */
476
48.6M
              stack--;
477
48.6M
              continue;
478
48.6M
            }
479
67.9M
          }
480
19.2M
          posstack[stack]=i;
481
19.2M
          ampstack[stack++]=seeds[i];
482
19.2M
          break;
483
484
67.9M
        }
485
112M
      }
486
64.2M
    }
487
64.4M
  }
488
489
  /* the stack now contains only the positions that are relevant. Scan
490
     'em straight through */
491
492
15.9M
  for(i=0;i<stack;i++){
493
15.8M
    long endpos;
494
15.8M
    if(i<stack-1 && ampstack[i+1]>ampstack[i]){
495
6.77M
      endpos=posstack[i+1];
496
9.05M
    }else{
497
9.05M
      endpos=posstack[i]+linesper+1; /* +1 is important, else bin 0 is
498
                                        discarded in short frames */
499
9.05M
    }
500
15.8M
    if(endpos>n)endpos=n;
501
80.3M
    for(;pos<endpos;pos++)
502
64.4M
      seeds[pos]=ampstack[i];
503
15.8M
  }
504
505
  /* there.  Linear time.  I now remember this was on a problem set I
506
     had in Grad Skool... I didn't solve it at the time ;-) */
507
508
105k
}
509
510
/* bleaugh, this is more complicated than it needs to be */
511
#include<stdio.h>
512
static void max_seeds(vorbis_look_psy *p,
513
                      float *seed,
514
105k
                      float *flr){
515
105k
  long   n=p->total_octave_lines;
516
105k
  int    linesper=p->eighth_octave_lines;
517
105k
  long   linpos=0;
518
105k
  long   pos;
519
520
105k
  seed_chase(seed,linesper,n); /* for masking */
521
522
105k
  pos=p->octave[0]-p->firstoc-(linesper>>1);
523
524
15.6M
  while(linpos+1<p->n){
525
15.5M
    float minV=seed[pos];
526
15.5M
    long end=((p->octave[linpos]+p->octave[linpos+1])>>1)-p->firstoc;
527
15.5M
    if(minV>p->vi->tone_abs_limit)minV=p->vi->tone_abs_limit;
528
79.3M
    while(pos+1<=end){
529
63.8M
      pos++;
530
63.8M
      if((seed[pos]>NEGINF && seed[pos]<minV) || minV==NEGINF)
531
13.0M
        minV=seed[pos];
532
63.8M
    }
533
534
15.5M
    end=pos+p->firstoc;
535
36.9M
    for(;linpos<p->n && p->octave[linpos]<=end;linpos++)
536
21.4M
      if(flr[linpos]<minV)flr[linpos]=minV;
537
15.5M
  }
538
539
105k
  {
540
105k
    float minV=seed[p->total_octave_lines-1];
541
168k
    for(;linpos<p->n;linpos++)
542
62.4k
      if(flr[linpos]<minV)flr[linpos]=minV;
543
105k
  }
544
545
105k
}
546
547
static void bark_noise_hybridmp(int n,const long *b,
548
                                const float *f,
549
                                float *noise,
550
                                const float offset,
551
211k
                                const int fixed){
552
553
211k
  float *N=alloca(n*sizeof(*N));
554
211k
  float *X=alloca(n*sizeof(*N));
555
211k
  float *XX=alloca(n*sizeof(*N));
556
211k
  float *Y=alloca(n*sizeof(*N));
557
211k
  float *XY=alloca(n*sizeof(*N));
558
559
211k
  float tN, tX, tXX, tY, tXY;
560
211k
  int i;
561
562
211k
  int lo, hi;
563
211k
  float R=0.f;
564
211k
  float A=0.f;
565
211k
  float B=0.f;
566
211k
  float D=1.f;
567
211k
  float w, x, y;
568
569
211k
  tN = tX = tXX = tY = tXY = 0.f;
570
571
211k
  y = f[0] + offset;
572
211k
  if (y < 1.f) y = 1.f;
573
574
211k
  w = y * y * .5;
575
576
211k
  tN += w;
577
211k
  tX += w;
578
211k
  tY += w * y;
579
580
211k
  N[0] = tN;
581
211k
  X[0] = tX;
582
211k
  XX[0] = tXX;
583
211k
  Y[0] = tY;
584
211k
  XY[0] = tXY;
585
586
42.9M
  for (i = 1, x = 1.f; i < n; i++, x += 1.f) {
587
588
42.7M
    y = f[i] + offset;
589
42.7M
    if (y < 1.f) y = 1.f;
590
591
42.7M
    w = y * y;
592
593
42.7M
    tN += w;
594
42.7M
    tX += w * x;
595
42.7M
    tXX += w * x * x;
596
42.7M
    tY += w * y;
597
42.7M
    tXY += w * x * y;
598
599
42.7M
    N[i] = tN;
600
42.7M
    X[i] = tX;
601
42.7M
    XX[i] = tXX;
602
42.7M
    Y[i] = tY;
603
42.7M
    XY[i] = tXY;
604
42.7M
  }
605
606
1.48M
  for (i = 0, x = 0.f; i < n; i++, x += 1.f) {
607
608
1.48M
    lo = b[i] >> 16;
609
1.48M
    hi = b[i] & 0xffff;
610
1.48M
    if( lo>=0 || -lo>=n ) break;
611
1.27M
    if( hi>=n ) break;
612
613
1.27M
    tN = N[hi] + N[-lo];
614
1.27M
    tX = X[hi] - X[-lo];
615
1.27M
    tXX = XX[hi] + XX[-lo];
616
1.27M
    tY = Y[hi] + Y[-lo];
617
1.27M
    tXY = XY[hi] - XY[-lo];
618
619
1.27M
    A = tY * tXX - tX * tXY;
620
1.27M
    B = tN * tXY - tX * tY;
621
1.27M
    D = tN * tXX - tX * tX;
622
1.27M
    R = (A + x * B) / D;
623
1.27M
    if (R < 0.f) R = 0.f;
624
625
1.27M
    noise[i] = R - offset;
626
1.27M
  }
627
628
37.7M
  for ( ; i < n; i++, x += 1.f) {
629
630
37.7M
    lo = b[i] >> 16;
631
37.7M
    hi = b[i] & 0xffff;
632
37.7M
    if( lo<0 || lo>=n ) break;
633
37.7M
    if( hi>=n ) break;
634
635
37.4M
    tN = N[hi] - N[lo];
636
37.4M
    tX = X[hi] - X[lo];
637
37.4M
    tXX = XX[hi] - XX[lo];
638
37.4M
    tY = Y[hi] - Y[lo];
639
37.4M
    tXY = XY[hi] - XY[lo];
640
641
37.4M
    A = tY * tXX - tX * tXY;
642
37.4M
    B = tN * tXY - tX * tY;
643
37.4M
    D = tN * tXX - tX * tX;
644
37.4M
    R = (A + x * B) / D;
645
37.4M
    if (R < 0.f) R = 0.f;
646
647
37.4M
    noise[i] = R - offset;
648
37.4M
  }
649
650
4.36M
  for ( ; i < n; i++, x += 1.f) {
651
652
4.15M
    R = (A + x * B) / D;
653
4.15M
    if (R < 0.f) R = 0.f;
654
655
4.15M
    noise[i] = R - offset;
656
4.15M
  }
657
658
211k
  if (fixed <= 0) return;
659
660
934k
  for (i = 0, x = 0.f; i < n; i++, x += 1.f) {
661
934k
    hi = i + fixed / 2;
662
934k
    lo = hi - fixed;
663
934k
    if ( hi>=n ) break;
664
934k
    if ( lo>=0 ) break;
665
666
852k
    tN = N[hi] + N[-lo];
667
852k
    tX = X[hi] - X[-lo];
668
852k
    tXX = XX[hi] + XX[-lo];
669
852k
    tY = Y[hi] + Y[-lo];
670
852k
    tXY = XY[hi] - XY[-lo];
671
672
673
852k
    A = tY * tXX - tX * tXY;
674
852k
    B = tN * tXY - tX * tY;
675
852k
    D = tN * tXX - tX * tX;
676
852k
    R = (A + x * B) / D;
677
678
852k
    if (R - offset < noise[i]) noise[i] = R - offset;
679
852k
  }
680
13.1M
  for ( ; i < n; i++, x += 1.f) {
681
682
13.1M
    hi = i + fixed / 2;
683
13.1M
    lo = hi - fixed;
684
13.1M
    if ( hi>=n ) break;
685
13.0M
    if ( lo<0 ) break;
686
687
13.0M
    tN = N[hi] - N[lo];
688
13.0M
    tX = X[hi] - X[lo];
689
13.0M
    tXX = XX[hi] - XX[lo];
690
13.0M
    tY = Y[hi] - Y[lo];
691
13.0M
    tXY = XY[hi] - XY[lo];
692
693
13.0M
    A = tY * tXX - tX * tXY;
694
13.0M
    B = tN * tXY - tX * tY;
695
13.0M
    D = tN * tXX - tX * tX;
696
13.0M
    R = (A + x * B) / D;
697
698
13.0M
    if (R - offset < noise[i]) noise[i] = R - offset;
699
13.0M
  }
700
856k
  for ( ; i < n; i++, x += 1.f) {
701
774k
    R = (A + x * B) / D;
702
774k
    if (R - offset < noise[i]) noise[i] = R - offset;
703
774k
  }
704
82.3k
}
705
706
void _vp_noisemask(vorbis_look_psy *p,
707
                   float *logmdct,
708
105k
                   float *logmask){
709
710
105k
  int i,n=p->n;
711
105k
  float *work=alloca(n*sizeof(*work));
712
713
105k
  bark_noise_hybridmp(n,p->bark,logmdct,logmask,
714
105k
                      140.,-1);
715
716
21.5M
  for(i=0;i<n;i++)work[i]=logmdct[i]-logmask[i];
717
718
105k
  bark_noise_hybridmp(n,p->bark,work,logmask,0.,
719
105k
                      p->vi->noisewindowfixed);
720
721
21.5M
  for(i=0;i<n;i++)work[i]=logmdct[i]-work[i];
722
723
#if 0
724
  {
725
    static int seq=0;
726
727
    float work2[n];
728
    for(i=0;i<n;i++){
729
      work2[i]=logmask[i]+work[i];
730
    }
731
732
    if(seq&1)
733
      _analysis_output("median2R",seq/2,work,n,1,0,0);
734
    else
735
      _analysis_output("median2L",seq/2,work,n,1,0,0);
736
737
    if(seq&1)
738
      _analysis_output("envelope2R",seq/2,work2,n,1,0,0);
739
    else
740
      _analysis_output("envelope2L",seq/2,work2,n,1,0,0);
741
    seq++;
742
  }
743
#endif
744
745
21.5M
  for(i=0;i<n;i++){
746
21.4M
    int dB=logmask[i]+.5;
747
21.4M
    if(dB>=NOISE_COMPAND_LEVELS)dB=NOISE_COMPAND_LEVELS-1;
748
21.4M
    if(dB<0)dB=0;
749
21.4M
    logmask[i]= work[i]+p->vi->noisecompand[dB];
750
21.4M
  }
751
752
105k
}
753
754
void _vp_tonemask(vorbis_look_psy *p,
755
                  float *logfft,
756
                  float *logmask,
757
                  float global_specmax,
758
105k
                  float local_specmax){
759
760
105k
  int i,n=p->n;
761
762
105k
  float *seed=alloca(sizeof(*seed)*p->total_octave_lines);
763
105k
  float att=local_specmax+p->vi->ath_adjatt;
764
64.5M
  for(i=0;i<p->total_octave_lines;i++)seed[i]=NEGINF;
765
766
  /* set the ATH (floating below localmax, not global max by a
767
     specified att) */
768
105k
  if(att<p->vi->ath_maxatt)att=p->vi->ath_maxatt;
769
770
21.5M
  for(i=0;i<n;i++)
771
21.4M
    logmask[i]=p->ath[i]+att;
772
773
  /* tone masking */
774
105k
  seed_loop(p,(const float ***)p->tonecurves,logfft,logmask,seed,global_specmax);
775
105k
  max_seeds(p,seed,logmask);
776
777
105k
}
778
779
void _vp_offset_and_mix(vorbis_look_psy *p,
780
                        float *noise,
781
                        float *tone,
782
                        int offset_select,
783
                        float *logmask,
784
                        float *mdct,
785
105k
                        float *logmdct){
786
105k
  int i,n=p->n;
787
105k
  float de, coeffi, cx;/* AoTuV */
788
105k
  float toneatt=p->vi->tone_masteratt[offset_select];
789
790
105k
  cx = p->m_val;
791
792
21.5M
  for(i=0;i<n;i++){
793
21.4M
    float val= noise[i]+p->noiseoffset[offset_select][i];
794
21.4M
    if(val>p->vi->noisemaxsupp)val=p->vi->noisemaxsupp;
795
21.4M
    logmask[i]=max(val,tone[i]+toneatt);
796
797
798
    /* AoTuV */
799
    /** @ M1 **
800
        The following codes improve a noise problem.
801
        A fundamental idea uses the value of masking and carries out
802
        the relative compensation of the MDCT.
803
        However, this code is not perfect and all noise problems cannot be solved.
804
        by Aoyumi @ 2004/04/18
805
    */
806
807
21.4M
    if(offset_select == 1) {
808
21.4M
      coeffi = -17.2;       /* coeffi is a -17.2dB threshold */
809
21.4M
      val = val - logmdct[i];  /* val == mdct line value relative to floor in dB */
810
811
21.4M
      if(val > coeffi){
812
        /* mdct value is > -17.2 dB below floor */
813
814
16.3M
        de = 1.0-((val-coeffi)*0.005*cx);
815
        /* pro-rated attenuation:
816
           -0.00 dB boost if mdct value is -17.2dB (relative to floor)
817
           -0.77 dB boost if mdct value is 0dB (relative to floor)
818
           -1.64 dB boost if mdct value is +17.2dB (relative to floor)
819
           etc... */
820
821
16.3M
        if(de < 0) de = 0.0001;
822
16.3M
      }else
823
        /* mdct value is <= -17.2 dB below floor */
824
825
5.10M
        de = 1.0-((val-coeffi)*0.0003*cx);
826
      /* pro-rated attenuation:
827
         +0.00 dB atten if mdct value is -17.2dB (relative to floor)
828
         +0.45 dB atten if mdct value is -34.4dB (relative to floor)
829
         etc... */
830
831
21.4M
      mdct[i] *= de;
832
833
21.4M
    }
834
21.4M
  }
835
105k
}
836
837
62.4k
float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd){
838
62.4k
  vorbis_info *vi=vd->vi;
839
62.4k
  codec_setup_info *ci=vi->codec_setup;
840
62.4k
  vorbis_info_psy_global *gi=&ci->psy_g_param;
841
842
62.4k
  int n=ci->blocksizes[vd->W]/2;
843
62.4k
  float secs=(float)n/vi->rate;
844
845
62.4k
  amp+=secs*gi->ampmax_att_per_sec;
846
62.4k
  if(amp<-9999)amp=-9999;
847
62.4k
  return(amp);
848
62.4k
}
849
850
static float FLOOR1_fromdB_LOOKUP[256]={
851
  1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
852
  1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
853
  1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
854
  2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
855
  2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
856
  3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
857
  4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
858
  6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
859
  7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
860
  1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
861
  1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
862
  1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
863
  2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
864
  2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
865
  3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
866
  4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
867
  5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
868
  7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
869
  9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
870
  1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
871
  1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
872
  2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
873
  2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
874
  3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
875
  4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
876
  5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
877
  7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
878
  9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
879
  0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
880
  0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
881
  0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
882
  0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
883
  0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
884
  0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
885
  0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
886
  0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
887
  0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
888
  0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
889
  0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
890
  0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
891
  0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
892
  0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
893
  0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
894
  0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
895
  0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
896
  0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
897
  0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
898
  0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
899
  0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
900
  0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
901
  0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
902
  0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
903
  0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
904
  0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
905
  0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
906
  0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
907
  0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
908
  0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
909
  0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
910
  0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
911
  0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
912
  0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
913
  0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
914
  0.82788260F, 0.88168307F, 0.9389798F, 1.F,
915
};
916
917
/* this is for per-channel noise normalization */
918
13.2M
static int apsort(const void *a, const void *b){
919
13.2M
  float f1=**(float**)a;
920
13.2M
  float f2=**(float**)b;
921
13.2M
  return (f1<f2)-(f1>f2);
922
13.2M
}
923
924
static void flag_lossless(int limit, float prepoint, float postpoint, float *mdct,
925
2.13M
                         float *floor, int *flag, int i, int jn){
926
2.13M
  int j;
927
22.5M
  for(j=0;j<jn;j++){
928
20.3M
    float point = j>=limit-i ? postpoint : prepoint;
929
20.3M
    float r = fabs(mdct[j])/floor[j];
930
20.3M
    if(r<point)
931
6.40M
      flag[j]=0;
932
13.9M
    else
933
13.9M
      flag[j]=1;
934
20.3M
  }
935
2.13M
}
936
937
/* Overload/Side effect: On input, the *q vector holds either the
938
   quantized energy (for elements with the flag set) or the absolute
939
   values of the *r vector (for elements with flag unset).  On output,
940
   *q holds the quantized energy for all elements */
941
2.23M
static float noise_normalize(vorbis_look_psy *p, int limit, float *r, float *q, float *f, int *flags, float acc, int i, int n, int *out){
942
943
2.23M
  vorbis_info_psy *vi=p->vi;
944
2.23M
  float **sort = alloca(n*sizeof(*sort));
945
2.23M
  int j,count=0;
946
2.23M
  int start = (vi->normal_p ? vi->normal_start-i : n);
947
2.23M
  if(start>n)start=n;
948
949
  /* force classic behavior where only energy in the current band is considered */
950
2.23M
  acc=0.f;
951
952
  /* still responsible for populating *out where noise norm not in
953
     effect.  There's no need to [re]populate *q in these areas */
954
15.1M
  for(j=0;j<start;j++){
955
12.9M
    if(!flags || !flags[j]){ /* lossless coupling already quantized.
956
                                Don't touch; requantizing based on
957
                                energy would be incorrect. */
958
12.4M
      float ve = q[j]/f[j];
959
12.4M
      if(r[j]<0)
960
6.16M
        out[j] = -rint(sqrt(ve));
961
6.26M
      else
962
6.26M
        out[j] = rint(sqrt(ve));
963
12.4M
    }
964
12.9M
  }
965
966
  /* sort magnitudes for noise norm portion of partition */
967
10.5M
  for(;j<n;j++){
968
8.35M
    if(!flags || !flags[j]){ /* can't noise norm elements that have
969
                                already been loslessly coupled; we can
970
                                only account for their energy error */
971
8.34M
      float ve = q[j]/f[j];
972
      /* Despite all the new, more capable coupling code, for now we
973
         implement noise norm as it has been up to this point. Only
974
         consider promotions to unit magnitude from 0.  In addition
975
         the only energy error counted is quantizations to zero. */
976
      /* also-- the original point code only applied noise norm at > pointlimit */
977
8.34M
      if(ve<.25f && (!flags || j>=limit-i)){
978
6.39M
        acc += ve;
979
6.39M
        sort[count++]=q+j; /* q is fabs(r) for unflagged element */
980
6.39M
      }else{
981
        /* For now: no acc adjustment for nonzero quantization.  populate *out and q as this value is final. */
982
1.95M
        if(r[j]<0)
983
982k
          out[j] = -rint(sqrt(ve));
984
969k
        else
985
969k
          out[j] = rint(sqrt(ve));
986
1.95M
        q[j] = out[j]*out[j]*f[j];
987
1.95M
      }
988
8.34M
    }/* else{
989
        again, no energy adjustment for error in nonzero quant-- for now
990
        }*/
991
8.35M
  }
992
993
2.23M
  if(count){
994
    /* noise norm to do */
995
856k
    qsort(sort,count,sizeof(*sort),apsort);
996
7.24M
    for(j=0;j<count;j++){
997
6.39M
      int k=sort[j]-q;
998
6.39M
      if(acc>=vi->normal_thresh){
999
176k
        out[k]=unitnorm(r[k]);
1000
176k
        acc-=1.f;
1001
176k
        q[k]=f[k];
1002
6.21M
      }else{
1003
6.21M
        out[k]=0;
1004
6.21M
        q[k]=0.f;
1005
6.21M
      }
1006
6.39M
    }
1007
856k
  }
1008
1009
2.23M
  return acc;
1010
2.23M
}
1011
1012
/* Noise normalization, quantization and coupling are not wholly
1013
   seperable processes in depth>1 coupling. */
1014
void _vp_couple_quantize_normalize(int blobno,
1015
                                   vorbis_info_psy_global *g,
1016
                                   vorbis_look_psy *p,
1017
                                   vorbis_info_mapping0 *vi,
1018
                                   float **mdct,
1019
                                   int   **iwork,
1020
                                   int    *nonzero,
1021
                                   int     sliding_lowpass,
1022
62.4k
                                   int     ch){
1023
1024
62.4k
  int i;
1025
62.4k
  int n = p->n;
1026
62.4k
  int partition=(p->vi->normal_p ? p->vi->normal_partition : 16);
1027
62.4k
  int limit = g->coupling_pointlimit[p->vi->blockflag][blobno];
1028
62.4k
  float prepoint=stereo_threshholds[g->coupling_prepointamp[blobno]];
1029
62.4k
  float postpoint=stereo_threshholds[g->coupling_postpointamp[blobno]];
1030
#if 0
1031
  float de=0.1*p->m_val; /* a blend of the AoTuV M2 and M3 code here and below */
1032
#endif
1033
1034
  /* mdct is our raw mdct output, floor not removed. */
1035
  /* inout passes in the ifloor, passes back quantized result */
1036
1037
  /* unquantized energy (negative indicates amplitude has negative sign) */
1038
62.4k
  float **raw = alloca(ch*sizeof(*raw));
1039
1040
  /* dual pupose; quantized energy (if flag set), othersize fabs(raw) */
1041
62.4k
  float **quant = alloca(ch*sizeof(*quant));
1042
1043
  /* floor energy */
1044
62.4k
  float **floor = alloca(ch*sizeof(*floor));
1045
1046
  /* flags indicating raw/quantized status of elements in raw vector */
1047
62.4k
  int   **flag  = alloca(ch*sizeof(*flag));
1048
1049
  /* non-zero flag working vector */
1050
62.4k
  int    *nz    = alloca(ch*sizeof(*nz));
1051
1052
  /* energy surplus/defecit tracking */
1053
62.4k
  float  *acc   = alloca((ch+vi->coupling_steps)*sizeof(*acc));
1054
1055
  /* The threshold of a stereo is changed with the size of n */
1056
62.4k
  if(n > 1000)
1057
1.91k
    postpoint=stereo_threshholds_limited[g->coupling_postpointamp[blobno]];
1058
1059
62.4k
  raw[0]   = alloca(ch*partition*sizeof(**raw));
1060
62.4k
  quant[0] = alloca(ch*partition*sizeof(**quant));
1061
62.4k
  floor[0] = alloca(ch*partition*sizeof(**floor));
1062
62.4k
  flag[0]  = alloca(ch*partition*sizeof(**flag));
1063
1064
105k
  for(i=1;i<ch;i++){
1065
43.4k
    raw[i]   = &raw[0][partition*i];
1066
43.4k
    quant[i] = &quant[0][partition*i];
1067
43.4k
    floor[i] = &floor[0][partition*i];
1068
43.4k
    flag[i]  = &flag[0][partition*i];
1069
43.4k
  }
1070
172k
  for(i=0;i<ch+vi->coupling_steps;i++)
1071
110k
    acc[i]=0.f;
1072
1073
1.43M
  for(i=0;i<n;i+=partition){
1074
1.37M
    int k,j,jn = partition > n-i ? n-i : partition;
1075
1.37M
    int step,track = 0;
1076
1077
1.37M
    memcpy(nz,nonzero,sizeof(*nz)*ch);
1078
1079
    /* prefill */
1080
1.37M
    memset(flag[0],0,ch*partition*sizeof(**flag));
1081
3.61M
    for(k=0;k<ch;k++){
1082
2.24M
      int *iout = &iwork[k][i];
1083
2.24M
      if(nz[k]){
1084
1085
22.5M
        for(j=0;j<jn;j++)
1086
20.3M
          floor[k][j] = FLOOR1_fromdB_LOOKUP[iout[j]];
1087
1088
2.13M
        flag_lossless(limit,prepoint,postpoint,&mdct[k][i],floor[k],flag[k],i,jn);
1089
1090
22.5M
        for(j=0;j<jn;j++){
1091
20.3M
          quant[k][j] = raw[k][j] = mdct[k][i+j]*mdct[k][i+j];
1092
20.3M
          if(mdct[k][i+j]<0.f) raw[k][j]*=-1.f;
1093
20.3M
          floor[k][j]*=floor[k][j];
1094
20.3M
        }
1095
1096
2.13M
        acc[track]=noise_normalize(p,limit,raw[k],quant[k],floor[k],NULL,acc[track],i,jn,iout);
1097
1098
2.13M
      }else{
1099
1.17M
        for(j=0;j<jn;j++){
1100
1.07M
          floor[k][j] = 1e-10f;
1101
1.07M
          raw[k][j] = 0.f;
1102
1.07M
          quant[k][j] = 0.f;
1103
1.07M
          flag[k][j] = 0;
1104
1.07M
          iout[j]=0;
1105
1.07M
        }
1106
102k
        acc[track]=0.f;
1107
102k
      }
1108
2.24M
      track++;
1109
2.24M
    }
1110
1111
    /* coupling */
1112
1.48M
    for(step=0;step<vi->coupling_steps;step++){
1113
114k
      int Mi = vi->coupling_mag[step];
1114
114k
      int Ai = vi->coupling_ang[step];
1115
114k
      int *iM = &iwork[Mi][i];
1116
114k
      int *iA = &iwork[Ai][i];
1117
114k
      float *reM = raw[Mi];
1118
114k
      float *reA = raw[Ai];
1119
114k
      float *qeM = quant[Mi];
1120
114k
      float *qeA = quant[Ai];
1121
114k
      float *floorM = floor[Mi];
1122
114k
      float *floorA = floor[Ai];
1123
114k
      int *fM = flag[Mi];
1124
114k
      int *fA = flag[Ai];
1125
1126
114k
      if(nz[Mi] || nz[Ai]){
1127
100k
        nz[Mi] = nz[Ai] = 1;
1128
1129
975k
        for(j=0;j<jn;j++){
1130
1131
874k
          if(j<sliding_lowpass-i){
1132
874k
            if(fM[j] || fA[j]){
1133
              /* lossless coupling */
1134
1135
495k
              reM[j] = fabs(reM[j])+fabs(reA[j]);
1136
495k
              qeM[j] = qeM[j]+qeA[j];
1137
495k
              fM[j]=fA[j]=1;
1138
1139
              /* couple iM/iA */
1140
495k
              {
1141
495k
                int A = iM[j];
1142
495k
                int B = iA[j];
1143
1144
495k
                if(abs(A)>abs(B)){
1145
190k
                  iA[j]=(A>0?A-B:B-A);
1146
305k
                }else{
1147
305k
                  iA[j]=(B>0?A-B:B-A);
1148
305k
                  iM[j]=B;
1149
305k
                }
1150
1151
                /* collapse two equivalent tuples to one */
1152
495k
                if(iA[j]>=abs(iM[j])*2){
1153
26.1k
                  iA[j]= -iA[j];
1154
26.1k
                  iM[j]= -iM[j];
1155
26.1k
                }
1156
1157
495k
              }
1158
1159
495k
            }else{
1160
              /* lossy (point) coupling */
1161
379k
              if(j<limit-i){
1162
                /* dipole */
1163
84.8k
                reM[j] += reA[j];
1164
84.8k
                qeM[j] = fabs(reM[j]);
1165
294k
              }else{
1166
#if 0
1167
                /* AoTuV */
1168
                /** @ M2 **
1169
                    The boost problem by the combination of noise normalization and point stereo is eased.
1170
                    However, this is a temporary patch.
1171
                    by Aoyumi @ 2004/04/18
1172
                */
1173
                float derate = (1.0 - de*((float)(j-limit+i) / (float)(n-limit)));
1174
                /* elliptical */
1175
                if(reM[j]+reA[j]<0){
1176
                  reM[j] = - (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate);
1177
                }else{
1178
                  reM[j] =   (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate);
1179
                }
1180
#else
1181
                /* elliptical */
1182
294k
                if(reM[j]+reA[j]<0){
1183
146k
                  reM[j] = - (qeM[j] = fabs(reM[j])+fabs(reA[j]));
1184
147k
                }else{
1185
147k
                  reM[j] =   (qeM[j] = fabs(reM[j])+fabs(reA[j]));
1186
147k
                }
1187
294k
#endif
1188
1189
294k
              }
1190
379k
              reA[j]=qeA[j]=0.f;
1191
379k
              fA[j]=1;
1192
379k
              iA[j]=0;
1193
379k
            }
1194
874k
          }
1195
874k
          floorM[j]=floorA[j]=floorM[j]+floorA[j];
1196
874k
        }
1197
        /* normalize the resulting mag vector */
1198
100k
        acc[track]=noise_normalize(p,limit,raw[Mi],quant[Mi],floor[Mi],flag[Mi],acc[track],i,jn,iM);
1199
100k
        track++;
1200
100k
      }
1201
114k
    }
1202
1.37M
  }
1203
1204
67.0k
  for(i=0;i<vi->coupling_steps;i++){
1205
    /* make sure coupling a zero and a nonzero channel results in two
1206
       nonzero channels. */
1207
4.65k
    if(nonzero[vi->coupling_mag[i]] ||
1208
4.15k
       nonzero[vi->coupling_ang[i]]){
1209
4.15k
      nonzero[vi->coupling_mag[i]]=1;
1210
4.15k
      nonzero[vi->coupling_ang[i]]=1;
1211
4.15k
    }
1212
4.65k
  }
1213
62.4k
}