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 vector blocking, windowing and dis/reassembly
15 author: Monty <xiphmont@mit.edu>
16 modifications by: Monty
17 last modification date: Jun 26 1999
19 Handle windowing, overlap-add, etc of the original (and synthesized)
20 PCM vectors. This is made more amusing by Vorbis' current two allowed
21 block sizes (512 and 2048 elements/channel).
23 Vorbis manipulates the dynamic range of the incoming PCM data
24 envelope to minimise time-domain energy leakage from percussive and
25 plosive waveforms being quantized in the MDCT domain.
27 ********************************************************************/
29 static const char rcsid[] = "$Id";
33 /* pcm accumulator and multipliers
34 examples (not exhaustive):
36 <-------------- lW----------------->
37 <--------------- W ---------------->
38 : .....|..... _______________ |
39 : .''' | '''_--- | |\ |
40 :.....''' |_____--- '''......| | \_______|
41 :.................|__________________|_______|__|______|
42 |<------ Sl ------>| > Sr < |endW
43 |beginSl |endSl | |endSr
44 |beginW |endlW |beginSr
49 <--------------- W ---------------->
50 | | .. ______________ |
52 |___.'___/`. | ---_____|
53 |_______|__|_______|_________________|
54 | >|Sl|< |<------ Sr ----->|endW
55 | | |endSl |beginSr |endSr
57 mult[0] |beginSl mult[n]
59 <-------------- lW----------------->
61 : .............. __ | |
63 :.....''' |/`...\|...|
64 :.........................|__||__|___|
75 typedef struct vorbis_state{
76 int samples_per_envelope_step;
78 double *window[2][2][2]; /* windowsize, leadin, leadout */
88 int envelope_channels;
110 /* arbitrary settings and spec-mandated numbers get filled in here */
111 void vorbis_init_state(vorbis_state *v,int channels,int mode){
112 memset(v,0,sizeof(vorbis_state));
113 v->samples_per_envelope_step=64;
114 v->block_size[0]=512;
115 v->block_size[1]=2048;
117 v->window[0][0][0]=vorbis_window(v->block_size[0],
118 v->block_size[0]/2,v->block_size[0]/2);
119 v->window[1][0][0]=vorbis_window(v->block_size[1],
120 v->block_size[0]/2,v->block_size[0]/2);
121 v->window[1][0][1]=vorbis_window(v->block_size[1],
122 v->block_size[0]/2,v->block_size[1]/2);
123 v->window[1][1][0]=vorbis_window(v->block_size[1],
124 v->block_size[1]/2,v->block_size[0]/2);
125 v->window[1][1][1]=vorbis_window(v->block_size[1],
126 v->block_size[1]/2,v->block_size[1]/2);
128 /* initialize the storage vectors to a decent size greater than the
131 v->pcm_storage=8192; /* 8k samples. we'll assume later that we have
132 a minimum of twice the blocksize (2k) of
133 accumulated samples in analysis */
134 v->pcm_channels=channels;
135 v->pcm=malloc(channels*sizeof(double *));
138 for(i=0;i<channels;i++)
139 v->pcm[i]=calloc(v->pcm_storage,sizeof(double));
142 /* Initialize the envelope multiplier storage */
144 v->envelope_storage=v->pcmstorage/v->samples_per_envelope_step+1;
145 v->envelope_channels=channels;
146 v->deltas=calloc(v->envelope_channels,sizeof(double *));
147 v->multipliers=calloc(v->envelope_channels,sizeof(int *));
150 for(i=0;i<v->envelope_channels;i++){
151 v->deltas[i]=calloc(v->envelope_storage,sizeof(double));
152 v->multipliers[i]=calloc(v->envelope_storage,sizeof(int));
156 /* all 1 (large block) or 0 (small block) */
157 /*v->lW=0; previous window size */
158 /*v->W=0; determined during analysis */
159 /*v->Sl=0; previous Sr */
160 /*v->Sr=0; determined during analysis */
162 /* all vector indexes; multiples of samples_per_envelope_step */
163 /*v->beginW=0; determined during analysis */
164 /*v->endW=0; determined during analysis */
165 v->beginSl=v->block_size[1]/4-v->block_size[0]/4;
166 v->endSl=v->beginSl+v->block_size[0]/2;
167 /*v->beginSr=0; determined during analysis */
168 /*v->endSr=0; determined during analysis */
173 v->pcm_current=v->endSl;
174 v->last_multiplier=v->endSl/v->samples_per_envelope_step+1;
179 void vorbis_free_state(vorbis_state *v){
185 if(v->window[i][j][k])free(v->window[i][j][k]);
187 for(i=0;i<v->pcm_channels;i++)
188 if(v->pcm[i])free(v->pcm[i]);
192 for(i=0;i<v->envelope_channels;i++)
193 if(v->deltas[i])free(v->deltas[i]);
197 for(i=0;i<v->envelope_channels;i++)
198 if(v->multipliers[i])free(v->multipliers[i]);
199 free(v->multipliers);
205 int vorbis_analysis(vorbis_state *v, double **pcm, int vals){
208 /* vorbis encode state initialization */
210 vorbis_init_settings(v);
212 /* first we need to handle incoming data (if any) */
215 /* Do we have enough storage space for the incoming data? If not,
216 expand the PCM storage */
218 if(v->pcm_current+vals>=pcm_storage){
219 for(i=0;i<v->pcm_channels;i++)
220 v->pcm[i]=realloc(v->pcm[i],
221 (v->pcm_current+vals*2)*sizeof(double));
222 v->pcm_storage=v->pcm_current+vals*2;
225 /* If we're encoding the end of the stream and we're handing in
226 padding, vals will be set, but the passed in buffer will be
227 NULL; just add in zeroes */
229 for(i=0;i<v->pcm_channels;i++)
231 memset(v->pcm[i]+v->pcm_current,0,vals*sizeof(double));
233 memcpy(v->pcm[i]+v->pcm_current,pcm[i],vals*sizeof(double));
235 v->pcm_current+=vals;
238 /* Do we definately have enough for a frame? We assume we have more
239 than actually necessary to encode the current block to make some
242 if(v->pcm_current-v->endSl<v->blocksize[1]*2)
245 /* we have enough. begin analysis */
246 /* complete the envelope analysis vectors */
250 /* decide the blocksize of this frame */
253 /* algebra to set the rest of the window alignment vectors; many are
254 just derived, but they make the process clearer for the time
259 /* the real analysis begins; forward MDCT with window */
262 /* Noise floor, resolution floor */
264 /* encode the floor into LSP; get the actual floor back for quant */
266 /* use noise floor, res floor for culling, actual floor for quant */
270 /* advance storage vectors and clean up */
271 /* center the window leadout on blocksize[1]/4 */
273 int new_beginSr,new_endSr,movement,emove;
275 /* first do the pcm storage */
278 new_endSl=v->blocksize[1]/2;
280 new_beginSl=v->blocksize[1]/4-v->blocksize[0]/4;
281 new_endSl=new_beginSr+v->blocksize[0]/2;
283 movement=v->beginSr-new_beginSl;
285 for(i=0;i<v->pcm_channels;i++)
286 memmove(v->pcm[i],v->pcm[i]+movement,
287 (v->pcm_current-movement)*sizeof(double));
288 v->pcm_current-=movement;
291 v->beginSl=new_beginSl;
294 v->samples+=movement;
296 /* now advance the multipliers */
297 emove=movement/samples_per_envelope_step;
298 for(i=0;i<v->envelope_channels;i++){
299 memmove(v->deltas[i],v->deltas[i]+emove,
300 (v->envelope_current-emove)*sizeof(double));
301 memmove(v->multipliers[i],v->multipliers[i]+emove,
302 (v->envelope_current-emove)*sizeof(int));
304 v->envelope_current-=emove;