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: Jun 17 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 ********************************************************************/
29 static typedef struct {
34 static double oPI = 3.14159265358979323846;
36 envelope_lookup *init_envelope(int length,int divleng){
37 envelope_lookup *ret=malloc(sizeof(envelope_lookup));
41 ret->window=malloc(divleng*sizeof(double)*2);
43 /* We just use a straight sin^2(x) window for this */
44 for(i=0;i<divleng*2;i++){
45 double temp=sin((i+.5)/divleng*oPI);
46 ret->window[i]=temp*temp;
50 /* right now, we do things simple and dirty. Should this prove
51 inadequate, then we'll think of something different. The details
52 of the encoding format do not depend on the exact behavior, only
53 the format of the bits that come out.
55 Using residual from an LPC whitening filter to judge envelope
56 energy would probably yield cleaner results, but that's slow.
57 Let's see if simple delta analysis gives us acceptible results. */
59 int analyze_envelope0(double *vector, envelope_lookup *init, int n,
62 int divisor=init->length;
64 double *win=init->window;
67 double max,spanlo,spanhi;
69 /* initial and final blocks are special cases. Eg:
72 |_______|______\|_______|_______|
76 |_______|/______|______\|_______|
80 |_______|_______|/______|_______|
82 as we go block by block, we watch the collective metrics span. If we
83 span the threshhold (assuming the threshhold is active), we use an
88 for(i=1;i<divisor;i++){
89 double temp=abs(vector[i-1]-vector[i]);
92 for(;i<divisor*2;i++){
93 double temp=abs(win[i-1]*vector[i-1]-win[i]*vector[i]);
96 spanlo=spanhi=deltas[count++]=max;
99 for(j=divisor;j<n-divisor*2;j+=divisor){
101 for(i=1;i<divisor*2;i++){
102 double temp=abs(win[i-1]*vector[j+i-1]-win[i]*vector[j+i]);
103 if(max<temp)max=temp;
106 if(max<spanlo)spanlo=max;
107 if(max>spanhi)spanhi=max;
108 if(threshhold>1 && spanlo*threshhold<spanhi)
110 if(abbrevflag && j>n0-divisor/2)break;
116 for(i=1;i<divisor;i++){
117 double temp=abs(win[i-1]*vector[j+i-1]-win[i]*vector[j+i]);
118 if(max<temp)max=temp;
120 for(;i<divisor*2;i++){
121 double temp=abs(vector[j+i-1]-vector[j+i]);
122 if(max<temp)max=temp;
125 if(max<spanlo)spanlo=max;
126 if(max>spanhi)spanhi=max;
127 if(threshhold>1 && spanlo*threshhold<spanhi)
131 if(abbrevflag)return(n0);
135 /* also decide if we're going with a full sized or abbreviated
136 vector. Some encoding tactics might want to use envelope massaging
137 fully and discard abbreviated vectors entriely. We make that
140 int analyze_envelope1(envelope_lookup *init,int n,
141 double triggerthresh,double spanthresh,
144 /* Look at the delta values; decide if we need to do any envelope
145 manipulation at all on this vector; if so, choose the
146 multipliers and placeholders.
148 '0' is a placeholder. Other values specify a
149 multiplier/divisor. Multipliers are used by the decoder, divisors
150 in the encoder. The mapped m/d value for each segment is
151 2^(n-1). Placeholders (zeros) take on the value of the last
152 non-zero multiplier/divisor. When the placeholder is not
153 preceeded by a non-placeholder value in the current vector, it
154 assumes the value of the *next* non-zero value. In this way, the
155 vector manipulation is local to the current vector and does not
156 rely on preceeding vectors.
160 /* scan forward with sliding windows; we start manipulating envelopes
161 when the collective deltas span over a threshhold. If in fact we
162 begin manipulating, we can manage on a finer scale than the
163 original threshhold. first look for the larger threshhold and if
164 we span it, manipulate the vector to hold within the smaller span
167 /* scan for the trigger */
169 int divisor=init->length;
170 int divs=n/divisor-1;
172 double spanlo,spanhi;
174 spanlo=spanhi=deltas[0];
177 double max=deltas[i];
178 if(max<spanlo)spanlo=max;
179 if(max>spanhi)spanhi=max;
180 if(spanlo*triggerthresh<spanhi){
187 /* choose divisors/multipliers to fit the vector into the
188 specified span. In the decoder, these values are *multipliers*, so */