1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
5 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
6 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
7 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
9 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
10 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
12 ********************************************************************
14 function: PCM data vector blocking, windowing and dis/reassembly
16 ********************************************************************/
22 #include "ivorbiscodec.h"
23 #include "codec_internal.h"
30 static int ilog(unsigned int v
){
40 /* pcm accumulator examples (not exhaustive):
42 <-------------- lW ---------------->
43 <--------------- W ---------------->
44 : .....|..... _______________ |
45 : .''' | '''_--- | |\ |
46 :.....''' |_____--- '''......| | \_______|
47 :.................|__________________|_______|__|______|
48 |<------ Sl ------>| > Sr < |endW
49 |beginSl |endSl | |endSr
50 |beginW |endlW |beginSr
54 <--------------- W ---------------->
55 | | .. ______________ |
57 |___.'___/`. | ---_____|
58 |_______|__|_______|_________________|
59 | >|Sl|< |<------ Sr ----->|endW
60 | | |endSl |beginSr |endSr
62 mult[0] |beginSl mult[n]
64 <-------------- lW ----------------->
66 : .............. ___ | |
68 :.....''' |/`....\|...|
69 :.........................|___|___|___|
78 /* block abstraction setup *********************************************/
84 int vorbis_block_init(vorbis_dsp_state
*v
, vorbis_block
*vb
){
85 memset(vb
,0,sizeof(*vb
));
93 void *_vorbis_block_alloc(vorbis_block
*vb
,long bytes
){
94 bytes
=(bytes
+(WORD_ALIGN
-1)) & ~(WORD_ALIGN
-1);
95 if(bytes
+vb
->localtop
>vb
->localalloc
){
96 /* can't just _ogg_realloc... there are outstanding pointers */
98 struct alloc_chain
*link
=(struct alloc_chain
*)_ogg_malloc(sizeof(*link
));
99 vb
->totaluse
+=vb
->localtop
;
101 link
->ptr
=vb
->localstore
;
104 /* highly conservative */
105 vb
->localalloc
=bytes
;
106 vb
->localstore
=_ogg_malloc(vb
->localalloc
);
110 void *ret
=(void *)(((char *)vb
->localstore
)+vb
->localtop
);
116 /* reap the chain, pull the ripcord */
117 void _vorbis_block_ripcord(vorbis_block
*vb
){
119 struct alloc_chain
*reap
=vb
->reap
;
121 struct alloc_chain
*next
=reap
->next
;
122 _ogg_free(reap
->ptr
);
123 memset(reap
,0,sizeof(*reap
));
127 /* consolidate storage */
129 vb
->localstore
=_ogg_realloc(vb
->localstore
,vb
->totaluse
+vb
->localalloc
);
130 vb
->localalloc
+=vb
->totaluse
;
134 /* pull the ripcord */
139 int vorbis_block_clear(vorbis_block
*vb
){
140 _vorbis_block_ripcord(vb
);
141 if(vb
->localstore
)_ogg_free(vb
->localstore
);
143 memset(vb
,0,sizeof(*vb
));
147 int vorbis_synthesis_init(vorbis_dsp_state
*v
,vorbis_info
*vi
){
149 codec_setup_info
*ci
=(codec_setup_info
*)vi
->codec_setup
;
150 backend_lookup_state
*b
=NULL
;
152 memset(v
,0,sizeof(*v
));
153 b
=(backend_lookup_state
*)(v
->backend_state
=_ogg_calloc(1,sizeof(*b
)));
156 b
->modebits
=ilog(ci
->modes
);
158 /* Vorbis I uses only window type 0 */
159 b
->window
[0]=_vorbis_window(0,ci
->blocksizes
[0]/2);
160 b
->window
[1]=_vorbis_window(0,ci
->blocksizes
[1]/2);
162 /* finish the codebooks */
164 ci
->fullbooks
=(codebook
*)_ogg_calloc(ci
->books
,sizeof(*ci
->fullbooks
));
165 for(i
=0;i
<ci
->books
;i
++){
166 vorbis_book_init_decode(ci
->fullbooks
+i
,ci
->book_param
[i
]);
167 /* decode codebooks are now standalone after init */
168 vorbis_staticbook_destroy(ci
->book_param
[i
]);
169 ci
->book_param
[i
]=NULL
;
173 v
->pcm_storage
=ci
->blocksizes
[1];
174 v
->pcm
=(ogg_int32_t
**)_ogg_malloc(vi
->channels
*sizeof(*v
->pcm
));
175 v
->pcmret
=(ogg_int32_t
**)_ogg_malloc(vi
->channels
*sizeof(*v
->pcmret
));
176 for(i
=0;i
<vi
->channels
;i
++)
177 v
->pcm
[i
]=(ogg_int32_t
*)_ogg_calloc(v
->pcm_storage
,sizeof(*v
->pcm
[i
]));
179 /* all 1 (large block) or 0 (small block) */
180 /* explicitly set for the sake of clarity */
181 v
->lW
=0; /* previous window size */
182 v
->W
=0; /* current window size */
184 /* all vector indexes */
185 v
->centerW
=ci
->blocksizes
[1]/2;
187 v
->pcm_current
=v
->centerW
;
189 /* initialize all the mapping/backend lookups */
190 b
->mode
=(vorbis_look_mapping
**)_ogg_calloc(ci
->modes
,sizeof(*b
->mode
));
191 for(i
=0;i
<ci
->modes
;i
++){
192 int mapnum
=ci
->mode_param
[i
]->mapping
;
193 int maptype
=ci
->map_type
[mapnum
];
194 b
->mode
[i
]=_mapping_P
[maptype
]->look(v
,ci
->mode_param
[i
],
195 ci
->map_param
[mapnum
]);
205 void vorbis_dsp_clear(vorbis_dsp_state
*v
){
208 vorbis_info
*vi
=v
->vi
;
209 codec_setup_info
*ci
=(codec_setup_info
*)(vi
?vi
->codec_setup
:NULL
);
210 backend_lookup_state
*b
=(backend_lookup_state
*)v
->backend_state
;
213 for(i
=0;i
<vi
->channels
;i
++)
214 if(v
->pcm
[i
])_ogg_free(v
->pcm
[i
]);
216 if(v
->pcmret
)_ogg_free(v
->pcmret
);
219 /* free mode lookups; these are actually vorbis_look_mapping structs */
221 for(i
=0;i
<ci
->modes
;i
++){
222 int mapnum
=ci
->mode_param
[i
]->mapping
;
223 int maptype
=ci
->map_type
[mapnum
];
224 if(b
&& b
->mode
)_mapping_P
[maptype
]->free_look(b
->mode
[i
]);
229 if(b
->mode
)_ogg_free(b
->mode
);
233 memset(v
,0,sizeof(*v
));
237 /* Unlike in analysis, the window is only partially applied for each
238 block. The time domain envelope is not yet handled at the point of
239 calling (as it relies on the previous block). */
241 int vorbis_synthesis_blockin(vorbis_dsp_state
*v
,vorbis_block
*vb
){
242 vorbis_info
*vi
=v
->vi
;
243 codec_setup_info
*ci
=(codec_setup_info
*)vi
->codec_setup
;
246 if(v
->pcm_current
>v
->pcm_returned
&& v
->pcm_returned
!=-1)return(OV_EINVAL
);
252 if(v
->sequence
+1 != vb
->sequence
)v
->granulepos
=-1; /* out of sequence;
255 v
->sequence
=vb
->sequence
;
258 int n
=ci
->blocksizes
[v
->W
]/2;
259 int n0
=ci
->blocksizes
[0]/2;
260 int n1
=ci
->blocksizes
[1]/2;
273 /* v->pcm is now used like a two-stage double buffer. We don't want
274 to have to constantly shift *or* adjust memory usage. Don't
275 accept a new block until the old is shifted out */
277 /* overlap/add PCM */
279 for(j
=0;j
<vi
->channels
;j
++){
280 /* the overlap/add section */
284 ogg_int32_t
*pcm
=v
->pcm
[j
]+prevCenter
;
285 ogg_int32_t
*p
=vb
->pcm
[j
];
290 ogg_int32_t
*pcm
=v
->pcm
[j
]+prevCenter
+n1
/2-n0
/2;
291 ogg_int32_t
*p
=vb
->pcm
[j
];
298 ogg_int32_t
*pcm
=v
->pcm
[j
]+prevCenter
;
299 ogg_int32_t
*p
=vb
->pcm
[j
]+n1
/2-n0
/2;
302 for(;i
<n1
/2+n0
/2;i
++)
306 ogg_int32_t
*pcm
=v
->pcm
[j
]+prevCenter
;
307 ogg_int32_t
*p
=vb
->pcm
[j
];
313 /* the copy section */
315 ogg_int32_t
*pcm
=v
->pcm
[j
]+thisCenter
;
316 ogg_int32_t
*p
=vb
->pcm
[j
]+n
;
327 /* deal with initial packet state; we do this using the explicit
328 pcm_returned==-1 flag otherwise we're sensitive to first block
329 being short or long */
331 if(v
->pcm_returned
==-1){
332 v
->pcm_returned
=thisCenter
;
333 v
->pcm_current
=thisCenter
;
335 v
->pcm_returned
=prevCenter
;
336 v
->pcm_current
=prevCenter
+
337 ci
->blocksizes
[v
->lW
]/4+
338 ci
->blocksizes
[v
->W
]/4;
341 /* track the frame number... This is for convenience, but also
342 making sure our last packet doesn't end with added padding. If
343 the last packet is partial, the number of samples we'll have to
344 return will be past the vb->granulepos.
346 This is not foolproof! It will be confused if we begin
347 decoding at the last page after a seek or hole. In that case,
348 we don't have a starting point to judge where the last frame
349 is. For this reason, vorbisfile will always try to make sure
350 it reads the last two marked pages in proper sequence */
352 if(v
->granulepos
==-1)
353 if(vb
->granulepos
==-1){
356 v
->granulepos
=vb
->granulepos
;
359 v
->granulepos
+=ci
->blocksizes
[v
->lW
]/4+ci
->blocksizes
[v
->W
]/4;
360 if(vb
->granulepos
!=-1 && v
->granulepos
!=vb
->granulepos
){
362 if(v
->granulepos
>vb
->granulepos
){
363 long extra
=v
->granulepos
-vb
->granulepos
;
366 /* partial last frame. Strip the extra samples off */
367 v
->pcm_current
-=extra
;
368 }else if(vb
->sequence
== 1){
369 /* ^^^ argh, this can be 1 from seeking! */
372 /* partial first frame. Discard extra leading samples */
373 v
->pcm_returned
+=extra
;
374 if(v
->pcm_returned
>v
->pcm_current
)
375 v
->pcm_returned
=v
->pcm_current
;
379 }/* else{ Shouldn't happen *unless* the bitstream is out of
380 spec. Either way, believe the bitstream } */
381 v
->granulepos
=vb
->granulepos
;
385 /* Update, cleanup */
387 if(vb
->eofflag
)v
->eofflag
=1;
393 /* pcm==NULL indicates we just want the pending samples, no more */
394 int vorbis_synthesis_pcmout(vorbis_dsp_state
*v
,ogg_int32_t
***pcm
){
395 vorbis_info
*vi
=v
->vi
;
396 if(v
->pcm_returned
>-1 && v
->pcm_returned
<v
->pcm_current
){
399 for(i
=0;i
<vi
->channels
;i
++)
400 v
->pcmret
[i
]=v
->pcm
[i
]+v
->pcm_returned
;
403 return(v
->pcm_current
-v
->pcm_returned
);
408 int vorbis_synthesis_read(vorbis_dsp_state
*v
,int bytes
){
409 if(bytes
&& v
->pcm_returned
+bytes
>v
->pcm_current
)return(OV_EINVAL
);
410 v
->pcm_returned
+=bytes
;