• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-2007             *
9  * by the Xiph.Org Foundation http://www.xiph.org/                  *
10  *                                                                  *
11  ********************************************************************
12 
13  function: simple utility that runs audio through the psychoacoustics
14            without encoding
15  last mod: $Id: psytune.c 16037 2009-05-26 21:10:58Z xiphmont $
16 
17  ********************************************************************/
18 
19 /* NB: this is dead code, retained purely for doc and reference value
20        don't try to compile it */
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <math.h>
26 
27 #include "vorbis/codec.h"
28 #include "codec_internal.h"
29 #include "os.h"
30 #include "misc.h"
31 #include "psy.h"
32 #include "mdct.h"
33 #include "smallft.h"
34 #include "window.h"
35 #include "scales.h"
36 #include "lpc.h"
37 #include "lsp.h"
38 #include "masking.h"
39 #include "registry.h"
40 
41 static vorbis_info_psy_global _psy_set0G={
42   0,   /* decaydBpms */
43   8,   /* lines per eighth octave */
44 
45   /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
46   256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f,
47   -6.f,
48 
49   0,
50 
51   0.,
52   0.,
53 };
54 
55 static vp_part _vp_part0[]={
56   {    1,9e10f, 9e10f,       1.f,9999.f},
57   { 9999,  .75f, 9e10f,       .5f,9999.f},
58 /*{ 9999, 1.5f, 9e10f,       .5f,9999.f},*/
59   {   18,9e10f, 9e10f,       .5f,  30.f},
60   { 9999,9e10f, 9e10f,       .5f,  30.f}
61 };
62 
63 static vp_couple _vp_couple0[]={
64   {    1,  {9e10f,9e10f,0}, {   0.f,   0.f,0}, {   0.f, 0.f,0}, {0.f,0.f,0}},
65   {   18,  {9e10f,9e10f,0}, {   0.f,   0.f,0}, {   0.f, 0.f,0}, {0.f,0.f,0}},
66   { 9999,  {9e10f,9e10f,0}, {   0.f, 9e10f,0}, {   0.f,22.f,1}, {0.f,0.f,0}}
67 };
68 
69 static vorbis_info_psy _psy_set0={
70   ATH_Bark_dB_lineaggressive,
71 
72   -100.f,
73   -140.f,
74   6.f, /* floor master att */
75 
76   /*     0  1  2   3   4   5   6   7   8   9  10  11  12  13  14  15   16   */
77   /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
78   /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
79    1,  /* tonemaskp */
80   0.f, /* tone master att */
81   /*  0   10   20   30   40   50   60   70   80   90   100 */
82   {
83    {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*63*/
84    {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*88*/
85    {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*125*/
86 
87    {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*175*/
88    {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*250*/
89    {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*350*/
90    {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*500*/
91    {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*700*/
92    {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1000*/
93    {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1400*/
94    {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2000*/
95    {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2800*/
96    {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*4000*/
97 
98    {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*5600*/
99 
100    {-30.f,-30.f,-33.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*8000*/
101    {-30.f,-30.f,-33.f,-35.f,-40.f,-45.f,-50.f,-60.f,-70.f,-85.f,-100.f}, /*11500*/
102    {-24.f,-24.f,-26.f,-32.f,-32.f,-42.f,-50.f,-60.f,-70.f,-85.f,-100.f}, /*16000*/
103 
104   },
105 
106   1,/* peakattp */
107   {{-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*63*/
108    {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*88*/
109    {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*125*/
110    {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*175*/
111    {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*250*/
112    {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*350*/
113    {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*500*/
114    {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*700*/
115    {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*1000*/
116    {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*1400*/
117    {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*2000*/
118    {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*2800*/
119    {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*4000*/
120    {-10.f,-12.f,-14.f,-16.f,-16.f,-20.f,-24.f,-30.f,-32.f,-40.f,-40.f},/*5600*/
121    {-10.f,-12.f,-14.f,-16.f,-16.f,-20.f,-24.f,-30.f,-32.f,-40.f,-40.f},/*8000*/
122    {-10.f,-10.f,-10.f,-12.f,-14.f,-18.f,-22.f,-28.f,-32.f,-40.f,-40.f},/*11500*/
123    {-10.f,-10.f,-10.f,-12.f,-14.f,-18.f,-22.f,-28.f,-32.f,-40.f,-40.f},/*16000*/
124   },
125 
126   1,/*noisemaskp */
127   -10.f,  /* suppress any noise curve over maxspec+n */
128   .5f,   /* low window */
129   .5f,   /* high window */
130   10,
131   10,
132   25,
133   {.000f, 0.f, /*63*/
134    .000f, 0.f, /*88*/
135    .000f, 0.f, /*125*/
136    .000f, 0.f, /*175*/
137    .000f, 0.f, /*250*/
138    .000f, 0.f, /*350*/
139    .000f, 0.f, /*500*/
140    .000f, 0.f, /*700*/
141    .000f, 0.f, /*1000*/
142    .300f, 0.f, /*1400*/
143    .300f, 0.f, /*2000*/
144    .300f, 0.f, /*2800*/
145    .500f, 0.f, /*4000*/
146    .700f, 0.f, /*5600*/
147    .850f, 0.f, /*8000*/
148    .900f, 0.f, /*11500*/
149    .900f, 1.f, /*16000*/
150   },
151 
152   95.f,  /* even decade + 5 is important; saves an rint() later in a
153             tight loop) */
154   -44.,
155 
156   32,
157   _vp_part0,_vp_couple0
158 };
159 
160 static vorbis_info_floor1 _floor_set0={1,
161                                         {0},
162 
163                                         {32},
164                                         {0},
165                                         {0},
166                                         {{-1}},
167 
168                                         2,
169                                         {0,1024,
170 
171                                          88,31,243,
172 
173                                          14,54,143,460,
174 
175                                          6,3,10, 22,18,26, 41,36,47,
176                                          69,61,78, 112,99,126, 185,162,211,
177                                          329,282,387, 672,553,825
178                                          },
179 
180                                         60,30,400,
181                                         20,8,1,18.,
182                                         20,600,
183                                         960};
184 
185 
186 static vorbis_info_mapping0 mapping_info={1,{0,1},{0},{0},{0},0, 1, {0},{1}};
187 static codec_setup_info codec_setup0={ {0,0},
188                                        1,1,1,1,1,0,1,
189                                        {NULL},
190                                        {0},{&mapping_info},
191                                        {0},{NULL},
192                                        {1},{&_floor_set0},
193                                        {2},{NULL},
194                                        {NULL},
195                                        {&_psy_set0},
196                                        &_psy_set0G};
197 
198 static int noisy=0;
analysis(char * base,int i,float * v,int n,int bark,int dB)199 void analysis(char *base,int i,float *v,int n,int bark,int dB){
200   if(noisy){
201     int j;
202     FILE *of;
203     char buffer[80];
204     sprintf(buffer,"%s_%d.m",base,i);
205     of=fopen(buffer,"w");
206 
207     for(j=0;j<n;j++){
208       if(dB && v[j]==0)
209           fprintf(of,"\n\n");
210       else{
211         if(bark)
212           fprintf(of,"%g ",toBARK(22050.f*j/n));
213         else
214           fprintf(of,"%g ",(float)j);
215 
216         if(dB){
217           fprintf(of,"%g\n",todB(v+j));
218         }else{
219           fprintf(of,"%g\n",v[j]);
220         }
221       }
222     }
223     fclose(of);
224   }
225 }
226 
227 long frameno=0;
228 
229 /****************************************************************/
230 
main(int argc,char * argv[])231 int main(int argc,char *argv[]){
232   int eos=0;
233   float nonz=0.f;
234   float acc=0.f;
235   float tot=0.f;
236   float ampmax=-9999,newmax;
237   float local_ampmax[2];
238 
239   int framesize=2048;
240   float ampmax_att_per_sec=-6.;
241 
242   float *pcm[2],*out[2],*window,*flr[2],*mask[2],*work[2];
243   signed char *buffer,*buffer2;
244   mdct_lookup m_look;
245   drft_lookup f_look;
246   vorbis_look_psy p_look;
247   vorbis_look_psy_global *pg_look;
248   vorbis_look_floor *floor_look;
249   vorbis_info vi;
250   long i,j,k;
251 
252   int ath=0;
253   int decayp=0;
254 
255   argv++;
256   while(*argv){
257     if(*argv[0]=='-'){
258       /* option */
259       if(argv[0][1]=='v'){
260         noisy=0;
261       }
262     }else
263       if(*argv[0]=='+'){
264         /* option */
265         if(argv[0][1]=='v'){
266           noisy=1;
267         }
268       }else
269         framesize=atoi(argv[0]);
270     argv++;
271   }
272 
273   vi.channels=2;
274   vi.codec_setup=&codec_setup0;
275 
276   pcm[0]=_ogg_malloc(framesize*sizeof(float));
277   pcm[1]=_ogg_malloc(framesize*sizeof(float));
278   out[0]=_ogg_calloc(framesize/2,sizeof(float));
279   out[1]=_ogg_calloc(framesize/2,sizeof(float));
280   work[0]=_ogg_calloc(framesize,sizeof(float));
281   work[1]=_ogg_calloc(framesize,sizeof(float));
282   flr[0]=_ogg_calloc(framesize/2,sizeof(float));
283   flr[1]=_ogg_calloc(framesize/2,sizeof(float));
284   buffer=_ogg_malloc(framesize*4);
285   buffer2=buffer+framesize*2;
286   window=_vorbis_window_create(0,framesize,framesize/2,framesize/2);
287   mdct_init(&m_look,framesize);
288   drft_init(&f_look,framesize);
289   _vp_psy_init(&p_look,&_psy_set0,&_psy_set0G,framesize/2,44100);
290   pg_look=_vp_global_look(&vi);
291   floor_look=_floor_P[1]->look(NULL,NULL,&_floor_set0);
292 
293   /* we cheat on the WAV header; we just bypass 44 bytes and never
294      verify that it matches 16bit/stereo/44.1kHz. */
295 
296   fread(buffer,1,44,stdin);
297   fwrite(buffer,1,44,stdout);
298   memset(buffer,0,framesize*2);
299 
300   analysis("window",0,window,framesize,0,0);
301 
302   fprintf(stderr,"Processing for frame size %d...\n",framesize);
303 
304   while(!eos){
305     long bytes=fread(buffer2,1,framesize*2,stdin);
306     if(bytes<framesize*2)
307       memset(buffer2+bytes,0,framesize*2-bytes);
308 
309     if(bytes!=0){
310       int nonzero[2];
311 
312       /* uninterleave samples */
313       for(i=0;i<framesize;i++){
314         pcm[0][i]=((buffer[i*4+1]<<8)|
315                       (0x00ff&(int)buffer[i*4]))/32768.f;
316         pcm[1][i]=((buffer[i*4+3]<<8)|
317                    (0x00ff&(int)buffer[i*4+2]))/32768.f;
318       }
319 
320       {
321         float secs=framesize/44100.;
322 
323         ampmax+=secs*ampmax_att_per_sec;
324         if(ampmax<-9999)ampmax=-9999;
325       }
326 
327       for(i=0;i<2;i++){
328         float scale=4.f/framesize;
329         float *fft=work[i];
330         float *mdct=pcm[i];
331         float *logmdct=mdct+framesize/2;
332 
333         analysis("pre",frameno+i,pcm[i],framesize,0,0);
334 
335         /* fft and mdct transforms  */
336         for(j=0;j<framesize;j++)
337           fft[j]=pcm[i][j]*=window[j];
338 
339         drft_forward(&f_look,fft);
340 
341         local_ampmax[i]=-9999.f;
342         fft[0]*=scale;
343         fft[0]=todB(fft);
344         for(j=1;j<framesize-1;j+=2){
345           float temp=scale*FAST_HYPOT(fft[j],fft[j+1]);
346           temp=fft[(j+1)>>1]=todB(&temp);
347           if(temp>local_ampmax[i])local_ampmax[i]=temp;
348         }
349         if(local_ampmax[i]>ampmax)ampmax=local_ampmax[i];
350 
351         mdct_forward(&m_look,pcm[i],mdct);
352         for(j=0;j<framesize/2;j++)
353           logmdct[j]=todB(mdct+j);
354 
355         analysis("mdct",frameno+i,logmdct,framesize/2,1,0);
356         analysis("fft",frameno+i,fft,framesize/2,1,0);
357       }
358 
359       for(i=0;i<2;i++){
360         float amp;
361         float *fft=work[i];
362         float *logmax=fft;
363         float *mdct=pcm[i];
364         float *logmdct=mdct+framesize/2;
365         float *mask=fft+framesize/2;
366 
367         /* floor psychoacoustics */
368         _vp_compute_mask(&p_look,
369                          pg_look,
370                          i,
371                          fft,
372                          logmdct,
373                          mask,
374                          ampmax,
375                          local_ampmax[i],
376                          framesize/2);
377 
378         analysis("mask",frameno+i,mask,framesize/2,1,0);
379 
380         {
381           vorbis_block vb;
382           vorbis_dsp_state vd;
383           memset(&vd,0,sizeof(vd));
384           vd.vi=&vi;
385           vb.vd=&vd;
386           vb.pcmend=framesize;
387 
388           /* floor quantization/application */
389           nonzero[i]=_floor_P[1]->forward(&vb,floor_look,
390                                           mdct,
391                                           logmdct,
392                                           mask,
393                                           logmax,
394 
395                                           flr[i]);
396         }
397 
398         _vp_remove_floor(&p_look,
399                          pg_look,
400                          logmdct,
401                          mdct,
402                          flr[i],
403                          pcm[i],
404                          local_ampmax[i]);
405 
406         for(j=0;j<framesize/2;j++)
407           if(fabs(pcm[i][j])>1500)
408             fprintf(stderr,"%ld ",frameno+i);
409 
410         analysis("res",frameno+i,pcm[i],framesize/2,1,0);
411         analysis("codedflr",frameno+i,flr[i],framesize/2,1,1);
412       }
413 
414       /* residue prequantization */
415       _vp_partition_prequant(&p_look,
416                              &vi,
417                              pcm,
418                              nonzero);
419 
420       for(i=0;i<2;i++)
421         analysis("quant",frameno+i,pcm[i],framesize/2,1,0);
422 
423       /* channel coupling / stereo quantization */
424 
425       _vp_couple(&p_look,
426                  &mapping_info,
427                  pcm,
428                  nonzero);
429 
430       for(i=0;i<2;i++)
431         analysis("coupled",frameno+i,pcm[i],framesize/2,1,0);
432 
433       /* decoupling */
434       for(i=mapping_info.coupling_steps-1;i>=0;i--){
435         float *pcmM=pcm[mapping_info.coupling_mag[i]];
436         float *pcmA=pcm[mapping_info.coupling_ang[i]];
437 
438         for(j=0;j<framesize/2;j++){
439           float mag=pcmM[j];
440           float ang=pcmA[j];
441 
442           if(mag>0)
443             if(ang>0){
444               pcmM[j]=mag;
445               pcmA[j]=mag-ang;
446             }else{
447               pcmA[j]=mag;
448               pcmM[j]=mag+ang;
449             }
450           else
451             if(ang>0){
452               pcmM[j]=mag;
453               pcmA[j]=mag+ang;
454             }else{
455               pcmA[j]=mag;
456               pcmM[j]=mag-ang;
457             }
458         }
459       }
460 
461       for(i=0;i<2;i++)
462         analysis("decoupled",frameno+i,pcm[i],framesize/2,1,0);
463 
464       for(i=0;i<2;i++){
465         float amp;
466 
467         for(j=0;j<framesize/2;j++)
468           pcm[i][j]*=flr[i][j];
469 
470         analysis("final",frameno+i,pcm[i],framesize/2,1,1);
471 
472         /* take it back to time */
473         mdct_backward(&m_look,pcm[i],pcm[i]);
474 
475         for(j=0;j<framesize/2;j++)
476           out[i][j]+=pcm[i][j]*window[j];
477 
478         analysis("out",frameno+i,out[i],framesize/2,0,0);
479 
480 
481       }
482 
483       /* write data.  Use the part of buffer we're about to shift out */
484       for(i=0;i<2;i++){
485         char  *ptr=buffer+i*2;
486         float *mono=out[i];
487         int flag=0;
488         for(j=0;j<framesize/2;j++){
489           int val=mono[j]*32767.;
490           /* might as well guard against clipping */
491           if(val>32767){
492             if(!flag)fprintf(stderr,"clipping in frame %ld ",frameno+i);
493             flag=1;
494             val=32767;
495           }
496           if(val<-32768){
497             if(!flag)fprintf(stderr,"clipping in frame %ld ",frameno+i);
498             flag=1;
499             val=-32768;
500           }
501           ptr[0]=val&0xff;
502           ptr[1]=(val>>8)&0xff;
503           ptr+=4;
504         }
505       }
506 
507       fprintf(stderr,"*");
508       fwrite(buffer,1,framesize*2,stdout);
509       memmove(buffer,buffer2,framesize*2);
510 
511       for(i=0;i<2;i++){
512         for(j=0,k=framesize/2;j<framesize/2;j++,k++)
513           out[i][j]=pcm[i][k]*window[k];
514       }
515       frameno+=2;
516     }else
517       eos=1;
518   }
519   fprintf(stderr,"average raw bits of entropy: %.03g/sample\n",acc/tot);
520   fprintf(stderr,"average nonzero samples: %.03g/%d\n",nonz/tot*framesize/2,
521           framesize/2);
522   fprintf(stderr,"Done\n\n");
523   return 0;
524 }
525