Commit for general psychoacoustics debugging/improvement.
[platform/upstream/libvorbis.git] / lib / envelope.c
1 /********************************************************************
2  *                                                                  *
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.                            *
7  *                                                                  *
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/                                             *
11  *                                                                  *
12  ********************************************************************
13
14  function: PCM data envelope analysis and manipulation
15  author: Monty <xiphmont@mit.edu>
16  modifications by: Monty
17  last modification date: Oct 22 1999
18
19  Preecho calculation.
20
21  ********************************************************************/
22
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdio.h>
26 #include <math.h>
27
28 #include "codec.h"
29 #include "mdct.h"
30 #include "envelope.h"
31 #include "bitwise.h"
32 #include "window.h"
33
34 void _ve_envelope_init(envelope_lookup *e,int samples_per){
35   int i;
36
37   e->winlen=samples_per;
38   e->window=malloc(e->winlen*sizeof(double));
39   mdct_init(&e->mdct,e->winlen);
40
41   /* We just use a straight sin(x) window for this */
42   for(i=0;i<e->winlen;i++)
43     e->window[i]=sin((i+.5)/e->winlen*M_PI);
44
45 }
46
47 void _ve_envelope_clear(envelope_lookup *e){
48   if(e->window)free(e->window);
49   mdct_clear(&e->mdct);
50   memset(e,0,sizeof(envelope_lookup));
51 }
52
53 /* use MDCT for spectral power estimation */
54
55 static void _ve_deltas(double *deltas,double *pcm,int n,double *window,
56                        int winsize,mdct_lookup *m){
57   int i,j;
58   double out[winsize/2];
59   
60   for(j=0;j<n;j++){
61     double acc=0.;
62
63     mdct_forward(m,pcm+j*winsize,out,window);
64     for(i=winsize/10;i<winsize/2;i++)
65       acc+=fabs(out[i]);
66     if(deltas[j]<acc)deltas[j]=acc;
67   }
68 }
69
70 void _ve_envelope_deltas(vorbis_dsp_state *v){
71   vorbis_info *vi=v->vi;
72   int step=vi->envelopesa;
73
74   int dtotal=v->pcm_current/vi->envelopesa;
75   int dcurr=v->envelope_current;
76   int pch;
77   
78   if(dtotal>dcurr){
79     double *mult=v->multipliers+dcurr;
80     memset(mult,0,sizeof(double)*(dtotal-dcurr));
81       
82     for(pch=0;pch<vi->channels;pch++){
83       double *pcm=v->pcm[pch]+dcurr*step;
84       _ve_deltas(mult,pcm,dtotal-dcurr,v->ve.window,v->ve.winlen,&v->ve.mdct);
85     }
86     v->envelope_current=dtotal;
87
88 #ifdef ANALYSIS
89     {
90       static int frameno=0;
91       FILE *out;
92       char buffer[80];
93       int j,k;
94       
95       sprintf(buffer,"delt%d.m",frameno);
96       out=fopen(buffer,"w+");
97       for(j=0;j<v->envelope_current;j++)
98         fprintf(out,"%d %g\n",j*vi->envelopesa+vi->envelopesa/2,v->multipliers[j]);
99       fclose(out);
100
101       sprintf(buffer,"deltpcm%d.m",frameno++);
102       out=fopen(buffer,"w+");
103       for(k=0;k<vi->channels;k++){
104         for(j=0;j<v->pcm_current;j++)
105           fprintf(out,"%d %g\n",j,v->pcm[k][j]);
106         fprintf(out,"\n");
107       }
108       fclose(out);
109     }
110 #endif
111
112   }
113 }
114
115
116
117
118
119