Merge of the current Monty branch; this brings in new psychoacoustic
[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-2000             *
9  * by 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  last mod: $Id: envelope.c,v 1.18 2000/06/14 01:38:31 xiphmont Exp $
16
17  Preecho calculation.
18
19  ********************************************************************/
20
21 #include <stdlib.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <math.h>
25 #include "vorbis/codec.h"
26
27 #include "os.h"
28 #include "mdct.h"
29 #include "envelope.h"
30 #include "bitwise.h"
31 #include "window.h"
32 #include "misc.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^2(x) window for this */
42   for(i=0;i<e->winlen;i++){
43     e->window[i]=sin((i+.5)/e->winlen*M_PI);
44     e->window[i]*=e->window[i];
45   }
46 }
47
48 void _ve_envelope_clear(envelope_lookup *e){
49   if(e->window)free(e->window);
50   mdct_clear(&e->mdct);
51   memset(e,0,sizeof(envelope_lookup));
52 }
53
54 /* use MDCT for spectral power estimation */
55
56 static void _ve_deltas(double *deltas,double *pcm,int n,double *window,
57                        int winsize,mdct_lookup *m){
58   int i,j;
59   double *out=alloca(sizeof(double)*winsize);
60   
61   for(j=0;j<n;j++){
62     double acc=0.;
63  
64     memcpy(out,pcm+j*winsize,winsize*sizeof(double));
65     for(i=0;i<winsize;i++)
66       out[i]*=window[i];
67
68     mdct_forward(m,out,out);
69
70     for(i=winsize/10;i<winsize/2;i++)
71       acc+=fabs(out[i]);
72     if(deltas[j]<acc)deltas[j]=acc;
73   }
74 }
75
76 void _ve_envelope_deltas(vorbis_dsp_state *v){
77   vorbis_info *vi=v->vi;
78   int step=vi->envelopesa;
79   
80   int dtotal=v->pcm_current/vi->envelopesa;
81   int dcurr=v->envelope_current;
82   int pch;
83   
84   if(dtotal>dcurr){
85     double *mult=v->multipliers+dcurr;
86     memset(mult,0,sizeof(double)*(dtotal-dcurr));
87       
88     for(pch=0;pch<vi->channels;pch++){
89       double *pcm=v->pcm[pch]+dcurr*step;
90       _ve_deltas(mult,pcm,dtotal-dcurr,v->ve.window,v->ve.winlen,&v->ve.mdct);
91     }
92     v->envelope_current=dtotal;
93
94   }
95 }
96
97
98
99
100
101