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: PCM data envelope analysis and manipulation
15 author: Monty <xiphmont@mit.edu>
16 modifications by: Monty
17 last modification date: Oct 02 1999
19 Vorbis manipulates the dynamic range of the incoming PCM data
20 envelope to minimise time-domain energy leakage from percussive and
21 plosive waveforms being quantized in the MDCT domain.
23 ********************************************************************/
33 void _ve_envelope_init(envelope_lookup *e,int samples_per){
36 e->winlen=samples_per*2;
37 e->window=malloc(e->winlen*sizeof(double));
39 /* We just use a straight sin^2(x) window for this */
40 for(i=0;i<e->winlen;i++){
41 double temp=sin((i+.5)/e->winlen*M_PI);
42 e->window[i]=temp*temp;
46 void _ve_envelope_clear(envelope_lookup *e){
47 if(e->window)free(e->window);
48 memset(e,0,sizeof(envelope_lookup));
51 /* initial and final blocks are special cases. Eg:
54 |_______|_`-.___|_______|_______|
58 |___.-'_|_______|_`-.___|_______|
62 |_______|___.-'_|_______|_`-.___|
66 |_______|_______|____.-'|_______|
68 as we go block by block, we watch the collective metrics span. If we
69 span the threshhold (assuming the threshhold is active), we use an
72 static int _ve_envelope_generate(double *mult,double *env,double *look,
77 for(j=0;j<n;j++)if(mult[j]!=1)break;
81 /* first multiplier special case */
83 for(p=0;p<step/2;p++)env[p]=m;
85 /* mid multipliers normal case */
86 for(j=1;p<n-step/2;j++){
90 for(i=0;i<step;i++,p++)env[p]=m;
92 for(i=0;i<step;i++,p++)env[p]=m*look[i]+mo*look[i+step];
95 /* last multiplier special case */
96 for(;p<n;p++)env[p]=m;
100 /* right now, we do things simple and dirty (read: our current preecho
101 is a joke). Should this prove inadequate, then we'll think of
102 something different. The details of the encoding format do not
103 depend on the exact behavior, only the format of the bits that come
106 Mark Taylor probably has much witter ways of doing this... Let's
107 see if simple delta analysis gives us acceptible results for now. */
109 static void _ve_deltas(double *deltas,double *pcm,int n,double *win,
114 for(i=0;i<winsize-1;i++,p++){
115 double temp=fabs(win[i]*pcm[p]-win[i+1]*pcm[p+1]);
116 if(deltas[j]<temp)deltas[j]=temp;
122 void _ve_envelope_multipliers(vorbis_dsp_state *v){
123 int step=v->samples_per_envelope_step;
126 /* we need a 1-1/4 envelope window overlap begin and 1/4 end */
127 int dtotal=(v->pcm_current-step/2)/v->samples_per_envelope_step;
128 int dcurr=v->envelope_current;
129 double *window=v->ve.window;
130 int winlen=v->ve.winlen;
132 vorbis_info *vi=&v->vi;
135 for(ech=0;ech<vi->envelopech;ech++){
136 double *mult=v->multipliers[ech]+dcurr;
137 memset(mult,0,sizeof(double)*(dtotal-dcurr));
139 for(pch=0;pch<vi->channels;pch++){
141 /* does this channel contribute to the envelope analysis */
142 /*if(vi->envelopemap[pch]==ech){ not mapping yet */
145 /* we need a 1/4 envelope window overlap front and back */
146 double *pcm=v->pcm[pch]+dcurr*step-step/2;
147 _ve_deltas(mult,pcm,dtotal-dcurr,window,winlen);
152 v->envelope_current=dtotal;
157 /* This readies the multiplier vector for use/coding. Clamp/adjust
158 the multipliers to the allowed range and eliminate unneeded
161 void _ve_envelope_sparsify(vorbis_block *vb){
163 for(ch=0;ch<vb->vd->vi.envelopech;ch++){
165 double *mult=vb->mult[ch];
167 double first=mult[0];
172 /* are we going to multiply anything? */
175 if(mult[i]>=last*vb->vd->vi.preecho_thresh){
179 if(i<n-1 && mult[i+1]>=last*vb->vd->vi.preecho_thresh){
187 /* we need to adjust, so we might as well go nuts */
192 for(i=0;i<begin;i++)mult[i]=0;
196 if(mult[i]/last>clamp*vb->vd->vi.preecho_thresh){
197 last=mult[i]/vb->vd->vi.preecho_clamp;
199 mult[i]=floor(log(mult[i]/clamp/vb->vd->vi.preecho_clamp)/log(2))-1;
200 if(mult[i]>15)mult[i]=15;
206 memset(mult,0,sizeof(double)*n);
210 void _ve_envelope_apply(vorbis_block *vb,int multp){
211 vorbis_info *vi=&vb->vd->vi;
212 double env[vb->multend*vi->envelopesa];
213 envelope_lookup *look=&vb->vd->ve;
216 for(i=0;i<vi->envelopech;i++){
217 double *mult=vb->mult[i];
220 /* fill in the multiplier placeholders */
222 for(j=0;j<vb->multend;j++){
229 /* compute the envelope curve */
230 if(_ve_envelope_generate(mult,env,look->window,vb->multend,
233 /* apply the envelope curve */
234 for(j=0;j<vi->channels;j++){
236 /* check to see if the generated envelope applies to this channel */
237 /*if(vi->envelopemap[j]==i){ not mapping yet */
241 for(k=0;k<vb->multend*vi->envelopesa;k++)
242 vb->pcm[j][k]*=env[k];
244 for(k=0;k<vb->multend*vi->envelopesa;k++)
245 vb->pcm[j][k]/=env[k];