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: Aug 05 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 /* initial and final blocks are special cases. Eg:
49 |_______|_`-.___|_______|_______|
53 |___.-'_|_______|_`-.___|_______|
57 |_______|___.-'_|_______|_`-.___|
61 |_______|_______|____.-'|_______|
63 as we go block by block, we watch the collective metrics span. If we
64 span the threshhold (assuming the threshhold is active), we use an
67 static void _ve_envelope_generate(double *mult,double *env,double *look,
73 /* first multiplier special case */
75 for(i=0;i<step/2;i++)env[i]=m;
77 for(i=step;i<step*2;i++,p++)env[p]=m*look[i];
79 /* mid multipliers normal case */
80 for(j=1;p<n-step/2;j++){
83 for(i=0;i<step;i++,p++)env[p]+=m*look[i];
84 for(;i<step*2;i++,p++)env[p]=m*look[i];
87 /* last multiplier special case */
90 for(i=0;i<step;i++,p++)env[p]+=m*look[i];
91 for(;p<n;p++)env[p]=m;
99 sprintf(path,"env%d",frameno);
102 fprintf(out,"%g\n",env[i]);
109 /* right now, we do things simple and dirty (read: our current preecho
110 is a joke). Should this prove inadequate, then we'll think of
111 something different. The details of the encoding format do not
112 depend on the exact behavior, only the format of the bits that come
115 Mark Taylor probably has much witter ways of doing this... Let's
116 see if simple delta analysis gives us acceptible results for now. */
118 static void _ve_deltas(double *deltas,double *pcm,int n,double *win,
123 for(i=0;i<winsize-1;i++,p++){
124 double temp=fabs(win[i]*pcm[p]-win[i+1]*pcm[p+1]);
125 if(deltas[j]<temp)deltas[j]=temp;
131 void _ve_envelope_multipliers(vorbis_dsp_state *v){
132 int step=v->samples_per_envelope_step;
135 /* we need a 1-1/4 envelope window overlap begin and 1/4 end */
136 int dtotal=(v->pcm_current-step/2)/v->samples_per_envelope_step;
137 int dcurr=v->envelope_current;
138 double *window=v->ve.window;
139 int winlen=v->ve.winlen;
141 vorbis_info *vi=&v->vi;
144 for(ech=0;ech<vi->envelopech;ech++){
145 double *mult=v->multipliers[ech]+dcurr;
146 memset(mult,0,sizeof(double)*(dtotal-dcurr));
148 for(pch=0;pch<vi->channels;pch++){
150 /* does this channel contribute to the envelope analysis */
151 if(vi->envelopemap[pch]==ech){
153 /* we need a 1/4 envelope window overlap front and back */
154 double *pcm=v->pcm[pch]+dcurr*step-step/2;
155 _ve_deltas(mult,pcm,dtotal-dcurr,window,winlen);
160 v->envelope_current=dtotal;
165 /* This readies the multiplier vector for use/coding. Clamp/adjust
166 the multipliers to the allowed range and eliminate unneeded
169 void _ve_envelope_sparsify(vorbis_block *vb){
171 for(ch=0;ch<vb->vd->vi.envelopech;ch++){
173 double *mult=vb->mult[ch];
175 double first=mult[0];
180 /* are we going to multiply anything? */
183 if(mult[i]>=last*vb->vd->vi.preecho_thresh){
187 if(i<n-1 && mult[i+1]>=last*vb->vd->vi.preecho_thresh){
195 /* we need to adjust, so we might as well go nuts */
200 for(i=0;i<begin;i++)mult[i]=0;
204 if(mult[i]/last>clamp*vb->vd->vi.preecho_thresh){
205 last=mult[i]/vb->vd->vi.preecho_clamp;
207 mult[i]=floor(log(mult[i]/clamp/vb->vd->vi.preecho_clamp)/log(2))-1;
208 if(mult[i]>15)mult[i]=15;
214 memset(mult,0,sizeof(double)*n);
218 void _ve_envelope_apply(vorbis_block *vb,int multp){
219 vorbis_info *vi=&vb->vd->vi;
220 double env[vb->multend*vi->envelopesa];
221 envelope_lookup *look=&vb->vd->ve;
224 for(i=0;i<vi->envelopech;i++){
225 double *mult=vb->mult[i];
228 /* fill in the multiplier placeholders */
230 for(j=0;j<vb->multend;j++){
237 /* compute the envelope curve */
238 _ve_envelope_generate(mult,env,look->window,vb->multend,vi->envelopesa);
240 /* apply the envelope curve */
241 for(j=0;j<vi->channels;j++){
243 /* check to see if the generated envelope applies to this channel */
244 if(vi->envelopemap[j]==i){
247 for(k=0;k<vb->multend*vi->envelopesa;k++)
248 vb->pcm[j][k]*=env[k];
250 for(k=0;k<vb->multend*vi->envelopesa;k++)
251 vb->pcm[j][k]/=env[k];