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 void _vp_psy_quantize(double *f, double *m,int n){
122 int val=rint(f[i]/m[i]);
125 if(val==0 || val==2){
136 void _vp_psy_unquantize(double *f, double *m,int n){
142 void _vp_psy_sparsify(double *f, double *m,int n){
145 if(fabs(f[i])<m[i]*.5)f[i]=0;
148 /* s must be padded at the end with m-1 zeroes */
149 static void time_convolve(double *s,double *r,int n,int m){
157 acc+=s[i+j]*r[m-j-1];
163 /*************************************************************************/
164 /* Continuous balance analysis/synthesis *********************************/
167 /* Compute the average continual spectral balance of the given vectors
168 (in radians); encode into LPC coefficients */
170 double _vp_balance_compute(double *A, double *B, double *lpc,lpc_lookup *vb){
171 /* correlate in time (the response function is small). Log
172 frequency scale, small mapping */
177 /* 256/15 are arbitrary but unimportant to decoding */
181 /* This is encode side. Don't think too hard about it */
183 double workA[mapped+resp];
184 double workB[mapped+resp];
188 memset(workA,0,sizeof(workA));
189 memset(workB,0,sizeof(workB));
190 memset(workC,0,sizeof(workC));
193 int j=vb->bscale[i]+(resp>>1);
194 double mag_sq=A[i]*A[i]+B[i]*B[i];
201 if((A[i]<0 && B[i]>0)||
203 /* rotate II and IV into the first quadrant. III is already there */
208 workA[j]+=mag_sq*sin(phi);
209 workB[j]+=mag_sq*cos(phi);
212 /* prepare convolution vector. Play with a few different shapes */
215 workC[i]=sin(M_PI*(i+1)/(float)(resp+1));
219 time_convolve(workA,workC,mapped,resp);
220 time_convolve(workB,workC,mapped,resp);
225 for(i=0;i<mapped;i++){
226 p[i]=atan2(workA[i],workB[i]);
229 amp1=sqrt(vorbis_gen_lpc(p,lpc,vb));
236 void _vp_balance_apply(double *A, double *B, double *lpc, double amp,
237 lpc_lookup *vb,int divp){
239 for(i=0;i<vb->n;i++){
240 double mag=sqrt(A[i]*A[i]+B[i]*B[i]);
241 double del=vorbis_lpc_magnitude(vb->dscale[i],lpc,vb->m)*amp;
242 double phi=atan2(A[i],B[i]);