1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 *
9 * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: random psychoacoustics (not including preecho)
15 author: Monty <xiphmont@mit.edu>
16 modifications by: Monty
17 last modification date: Aug 26 1999
19 ********************************************************************/
41 /* Find the mean log energy of a given 'band'; used to evaluate tones
42 against background noise */
44 /* This is faster than a real convolution, gives us roughly the log f
45 scale we seek, and gives OK results. So, that means it's a good
48 /* To add: f scale noise attenuation curve */
50 void _vp_noise_floor(double *f, double *m,int n){
56 long newlo=i*LNOISE-NOISEBIAS;
57 long newhi=i*HNOISE+NOISEBIAS;
63 for(j=hi;j<newhi;j++){
67 for(j=lo;j<newlo;j++){
75 temp=fromdB(acc/div+NOISEdB); /* The NOISEdB constant should be an
77 if(m[i]<temp)m[i]=temp;
81 /* figure the masking curve. linear rolloff on a dB scale, adjusted
83 void _vp_mask_floor(double *f, double *m,int n){
84 double ocSCALE=1./log(2);
85 double curmask=-9.e40;
86 double curoc=log(MASKBIAS)*ocSCALE;
89 /* run mask forward then backward */
91 double newmask=todB(f[i])-MASKdB;
92 double newoc=log(i+MASKBIAS)*ocSCALE;
93 double roll=curmask-(newoc-curoc)*HROLL;
100 if(m[i]<lroll)m[i]=lroll;
104 curoc=log(n+MASKBIAS)*ocSCALE;
106 double newmask=todB(f[i])-MASKdB;
107 double newoc=log(i+MASKBIAS)*ocSCALE;
108 double roll=curmask-(curoc-newoc)*LROLL;
111 roll=curmask=newmask;
115 if(m[i]<lroll)m[i]=lroll;
119 /* s must be padded at the end with m-1 zeroes */
120 static void time_convolve(double *s,double *r,int n,int m){
128 acc+=s[i+j]*r[m-j-1];
134 /*************************************************************************/
135 /* Continuous balance analysis/synthesis *********************************/
138 /* Compute the average continual spectral balance of the given vectors
139 (in radians); encode into LPC coefficients */
141 double _vp_balance_compute(double *A, double *B, double *lpc,lpc_lookup *vb){
142 /* correlate in time (the response function is small). Log
143 frequency scale, small mapping */
148 /* 256/15 are arbitrary but unimportant to decoding */
152 /* This is encode side. Don't think too hard about it */
154 double workA[mapped+resp];
155 double workB[mapped+resp];
159 memset(workA,0,sizeof(workA));
160 memset(workB,0,sizeof(workB));
161 memset(workC,0,sizeof(workC));
164 int j=vb->bscale[i]+(resp>>1);
165 double mag_sq=A[i]*A[i]+B[i]*B[i];
172 if((A[i]<0 && B[i]>0)||
174 /* rotate II and IV into the first quadrant. III is already there */
179 workA[j]+=mag_sq*sin(phi);
180 workB[j]+=mag_sq*cos(phi);
183 /* prepare convolution vector. Play with a few different shapes */
186 workC[i]=sin(M_PI*(i+1)/(float)(resp+1));
190 time_convolve(workA,workC,mapped,resp);
191 time_convolve(workB,workC,mapped,resp);
196 for(i=0;i<mapped;i++){
197 p[i]=atan2(workA[i],workB[i]);
200 amp1=sqrt(vorbis_gen_lpc(p,lpc,vb));
207 void _vp_balance_apply(double *A, double *B, double *lpc, double amp,
208 lpc_lookup *vb,int divp){
210 for(i=0;i<vb->n;i++){
211 double mag=sqrt(A[i]*A[i]+B[i]*B[i]);
212 double del=vorbis_lpc_magnitude(vb->dscale[i],lpc,vb->m)*amp;
213 double phi=atan2(A[i],B[i]);