rev |
line source |
nuclear@0
|
1 /********************************************************************
|
nuclear@0
|
2 * *
|
nuclear@0
|
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
|
nuclear@0
|
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
nuclear@0
|
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
nuclear@0
|
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
nuclear@0
|
7 * *
|
nuclear@0
|
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
nuclear@0
|
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
|
nuclear@0
|
10 * *
|
nuclear@0
|
11 ********************************************************************
|
nuclear@0
|
12
|
nuclear@0
|
13 function: PCM data vector blocking, windowing and dis/reassembly
|
nuclear@0
|
14 last mod: $Id: block.c 17561 2010-10-23 10:34:24Z xiphmont $
|
nuclear@0
|
15
|
nuclear@0
|
16 Handle windowing, overlap-add, etc of the PCM vectors. This is made
|
nuclear@0
|
17 more amusing by Vorbis' current two allowed block sizes.
|
nuclear@0
|
18
|
nuclear@0
|
19 ********************************************************************/
|
nuclear@0
|
20
|
nuclear@0
|
21 #include <stdio.h>
|
nuclear@0
|
22 #include <stdlib.h>
|
nuclear@0
|
23 #include <string.h>
|
nuclear@0
|
24 #include <ogg/ogg.h>
|
nuclear@0
|
25 #include "vorbis/codec.h"
|
nuclear@0
|
26 #include "codec_internal.h"
|
nuclear@0
|
27
|
nuclear@0
|
28 #include "window.h"
|
nuclear@0
|
29 #include "mdct.h"
|
nuclear@0
|
30 #include "lpc.h"
|
nuclear@0
|
31 #include "registry.h"
|
nuclear@0
|
32 #include "misc.h"
|
nuclear@0
|
33
|
nuclear@0
|
34 static int ilog2(unsigned int v){
|
nuclear@0
|
35 int ret=0;
|
nuclear@0
|
36 if(v)--v;
|
nuclear@0
|
37 while(v){
|
nuclear@0
|
38 ret++;
|
nuclear@0
|
39 v>>=1;
|
nuclear@0
|
40 }
|
nuclear@0
|
41 return(ret);
|
nuclear@0
|
42 }
|
nuclear@0
|
43
|
nuclear@0
|
44 /* pcm accumulator examples (not exhaustive):
|
nuclear@0
|
45
|
nuclear@0
|
46 <-------------- lW ---------------->
|
nuclear@0
|
47 <--------------- W ---------------->
|
nuclear@0
|
48 : .....|..... _______________ |
|
nuclear@0
|
49 : .''' | '''_--- | |\ |
|
nuclear@0
|
50 :.....''' |_____--- '''......| | \_______|
|
nuclear@0
|
51 :.................|__________________|_______|__|______|
|
nuclear@0
|
52 |<------ Sl ------>| > Sr < |endW
|
nuclear@0
|
53 |beginSl |endSl | |endSr
|
nuclear@0
|
54 |beginW |endlW |beginSr
|
nuclear@0
|
55
|
nuclear@0
|
56
|
nuclear@0
|
57 |< lW >|
|
nuclear@0
|
58 <--------------- W ---------------->
|
nuclear@0
|
59 | | .. ______________ |
|
nuclear@0
|
60 | | ' `/ | ---_ |
|
nuclear@0
|
61 |___.'___/`. | ---_____|
|
nuclear@0
|
62 |_______|__|_______|_________________|
|
nuclear@0
|
63 | >|Sl|< |<------ Sr ----->|endW
|
nuclear@0
|
64 | | |endSl |beginSr |endSr
|
nuclear@0
|
65 |beginW | |endlW
|
nuclear@0
|
66 mult[0] |beginSl mult[n]
|
nuclear@0
|
67
|
nuclear@0
|
68 <-------------- lW ----------------->
|
nuclear@0
|
69 |<--W-->|
|
nuclear@0
|
70 : .............. ___ | |
|
nuclear@0
|
71 : .''' |`/ \ | |
|
nuclear@0
|
72 :.....''' |/`....\|...|
|
nuclear@0
|
73 :.........................|___|___|___|
|
nuclear@0
|
74 |Sl |Sr |endW
|
nuclear@0
|
75 | | |endSr
|
nuclear@0
|
76 | |beginSr
|
nuclear@0
|
77 | |endSl
|
nuclear@0
|
78 |beginSl
|
nuclear@0
|
79 |beginW
|
nuclear@0
|
80 */
|
nuclear@0
|
81
|
nuclear@0
|
82 /* block abstraction setup *********************************************/
|
nuclear@0
|
83
|
nuclear@0
|
84 #ifndef WORD_ALIGN
|
nuclear@0
|
85 #define WORD_ALIGN 8
|
nuclear@0
|
86 #endif
|
nuclear@0
|
87
|
nuclear@0
|
88 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
|
nuclear@0
|
89 int i;
|
nuclear@0
|
90 memset(vb,0,sizeof(*vb));
|
nuclear@0
|
91 vb->vd=v;
|
nuclear@0
|
92 vb->localalloc=0;
|
nuclear@0
|
93 vb->localstore=NULL;
|
nuclear@0
|
94 if(v->analysisp){
|
nuclear@0
|
95 vorbis_block_internal *vbi=
|
nuclear@0
|
96 vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal));
|
nuclear@0
|
97 vbi->ampmax=-9999;
|
nuclear@0
|
98
|
nuclear@0
|
99 for(i=0;i<PACKETBLOBS;i++){
|
nuclear@0
|
100 if(i==PACKETBLOBS/2){
|
nuclear@0
|
101 vbi->packetblob[i]=&vb->opb;
|
nuclear@0
|
102 }else{
|
nuclear@0
|
103 vbi->packetblob[i]=
|
nuclear@0
|
104 _ogg_calloc(1,sizeof(oggpack_buffer));
|
nuclear@0
|
105 }
|
nuclear@0
|
106 oggpack_writeinit(vbi->packetblob[i]);
|
nuclear@0
|
107 }
|
nuclear@0
|
108 }
|
nuclear@0
|
109
|
nuclear@0
|
110 return(0);
|
nuclear@0
|
111 }
|
nuclear@0
|
112
|
nuclear@0
|
113 void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
|
nuclear@0
|
114 bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
|
nuclear@0
|
115 if(bytes+vb->localtop>vb->localalloc){
|
nuclear@0
|
116 /* can't just _ogg_realloc... there are outstanding pointers */
|
nuclear@0
|
117 if(vb->localstore){
|
nuclear@0
|
118 struct alloc_chain *link=_ogg_malloc(sizeof(*link));
|
nuclear@0
|
119 vb->totaluse+=vb->localtop;
|
nuclear@0
|
120 link->next=vb->reap;
|
nuclear@0
|
121 link->ptr=vb->localstore;
|
nuclear@0
|
122 vb->reap=link;
|
nuclear@0
|
123 }
|
nuclear@0
|
124 /* highly conservative */
|
nuclear@0
|
125 vb->localalloc=bytes;
|
nuclear@0
|
126 vb->localstore=_ogg_malloc(vb->localalloc);
|
nuclear@0
|
127 vb->localtop=0;
|
nuclear@0
|
128 }
|
nuclear@0
|
129 {
|
nuclear@0
|
130 void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
|
nuclear@0
|
131 vb->localtop+=bytes;
|
nuclear@0
|
132 return ret;
|
nuclear@0
|
133 }
|
nuclear@0
|
134 }
|
nuclear@0
|
135
|
nuclear@0
|
136 /* reap the chain, pull the ripcord */
|
nuclear@0
|
137 void _vorbis_block_ripcord(vorbis_block *vb){
|
nuclear@0
|
138 /* reap the chain */
|
nuclear@0
|
139 struct alloc_chain *reap=vb->reap;
|
nuclear@0
|
140 while(reap){
|
nuclear@0
|
141 struct alloc_chain *next=reap->next;
|
nuclear@0
|
142 _ogg_free(reap->ptr);
|
nuclear@0
|
143 memset(reap,0,sizeof(*reap));
|
nuclear@0
|
144 _ogg_free(reap);
|
nuclear@0
|
145 reap=next;
|
nuclear@0
|
146 }
|
nuclear@0
|
147 /* consolidate storage */
|
nuclear@0
|
148 if(vb->totaluse){
|
nuclear@0
|
149 vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
|
nuclear@0
|
150 vb->localalloc+=vb->totaluse;
|
nuclear@0
|
151 vb->totaluse=0;
|
nuclear@0
|
152 }
|
nuclear@0
|
153
|
nuclear@0
|
154 /* pull the ripcord */
|
nuclear@0
|
155 vb->localtop=0;
|
nuclear@0
|
156 vb->reap=NULL;
|
nuclear@0
|
157 }
|
nuclear@0
|
158
|
nuclear@0
|
159 int vorbis_block_clear(vorbis_block *vb){
|
nuclear@0
|
160 int i;
|
nuclear@0
|
161 vorbis_block_internal *vbi=vb->internal;
|
nuclear@0
|
162
|
nuclear@0
|
163 _vorbis_block_ripcord(vb);
|
nuclear@0
|
164 if(vb->localstore)_ogg_free(vb->localstore);
|
nuclear@0
|
165
|
nuclear@0
|
166 if(vbi){
|
nuclear@0
|
167 for(i=0;i<PACKETBLOBS;i++){
|
nuclear@0
|
168 oggpack_writeclear(vbi->packetblob[i]);
|
nuclear@0
|
169 if(i!=PACKETBLOBS/2)_ogg_free(vbi->packetblob[i]);
|
nuclear@0
|
170 }
|
nuclear@0
|
171 _ogg_free(vbi);
|
nuclear@0
|
172 }
|
nuclear@0
|
173 memset(vb,0,sizeof(*vb));
|
nuclear@0
|
174 return(0);
|
nuclear@0
|
175 }
|
nuclear@0
|
176
|
nuclear@0
|
177 /* Analysis side code, but directly related to blocking. Thus it's
|
nuclear@0
|
178 here and not in analysis.c (which is for analysis transforms only).
|
nuclear@0
|
179 The init is here because some of it is shared */
|
nuclear@0
|
180
|
nuclear@0
|
181 static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
|
nuclear@0
|
182 int i;
|
nuclear@0
|
183 codec_setup_info *ci=vi->codec_setup;
|
nuclear@0
|
184 private_state *b=NULL;
|
nuclear@0
|
185 int hs;
|
nuclear@0
|
186
|
nuclear@0
|
187 if(ci==NULL) return 1;
|
nuclear@0
|
188 hs=ci->halfrate_flag;
|
nuclear@0
|
189
|
nuclear@0
|
190 memset(v,0,sizeof(*v));
|
nuclear@0
|
191 b=v->backend_state=_ogg_calloc(1,sizeof(*b));
|
nuclear@0
|
192
|
nuclear@0
|
193 v->vi=vi;
|
nuclear@0
|
194 b->modebits=ilog2(ci->modes);
|
nuclear@0
|
195
|
nuclear@0
|
196 b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
|
nuclear@0
|
197 b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
|
nuclear@0
|
198
|
nuclear@0
|
199 /* MDCT is tranform 0 */
|
nuclear@0
|
200
|
nuclear@0
|
201 b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
|
nuclear@0
|
202 b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
|
nuclear@0
|
203 mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs);
|
nuclear@0
|
204 mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs);
|
nuclear@0
|
205
|
nuclear@0
|
206 /* Vorbis I uses only window type 0 */
|
nuclear@0
|
207 b->window[0]=ilog2(ci->blocksizes[0])-6;
|
nuclear@0
|
208 b->window[1]=ilog2(ci->blocksizes[1])-6;
|
nuclear@0
|
209
|
nuclear@0
|
210 if(encp){ /* encode/decode differ here */
|
nuclear@0
|
211
|
nuclear@0
|
212 /* analysis always needs an fft */
|
nuclear@0
|
213 drft_init(&b->fft_look[0],ci->blocksizes[0]);
|
nuclear@0
|
214 drft_init(&b->fft_look[1],ci->blocksizes[1]);
|
nuclear@0
|
215
|
nuclear@0
|
216 /* finish the codebooks */
|
nuclear@0
|
217 if(!ci->fullbooks){
|
nuclear@0
|
218 ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
|
nuclear@0
|
219 for(i=0;i<ci->books;i++)
|
nuclear@0
|
220 vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
|
nuclear@0
|
221 }
|
nuclear@0
|
222
|
nuclear@0
|
223 b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy));
|
nuclear@0
|
224 for(i=0;i<ci->psys;i++){
|
nuclear@0
|
225 _vp_psy_init(b->psy+i,
|
nuclear@0
|
226 ci->psy_param[i],
|
nuclear@0
|
227 &ci->psy_g_param,
|
nuclear@0
|
228 ci->blocksizes[ci->psy_param[i]->blockflag]/2,
|
nuclear@0
|
229 vi->rate);
|
nuclear@0
|
230 }
|
nuclear@0
|
231
|
nuclear@0
|
232 v->analysisp=1;
|
nuclear@0
|
233 }else{
|
nuclear@0
|
234 /* finish the codebooks */
|
nuclear@0
|
235 if(!ci->fullbooks){
|
nuclear@0
|
236 ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
|
nuclear@0
|
237 for(i=0;i<ci->books;i++){
|
nuclear@0
|
238 if(ci->book_param[i]==NULL)
|
nuclear@0
|
239 goto abort_books;
|
nuclear@0
|
240 if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]))
|
nuclear@0
|
241 goto abort_books;
|
nuclear@0
|
242 /* decode codebooks are now standalone after init */
|
nuclear@0
|
243 vorbis_staticbook_destroy(ci->book_param[i]);
|
nuclear@0
|
244 ci->book_param[i]=NULL;
|
nuclear@0
|
245 }
|
nuclear@0
|
246 }
|
nuclear@0
|
247 }
|
nuclear@0
|
248
|
nuclear@0
|
249 /* initialize the storage vectors. blocksize[1] is small for encode,
|
nuclear@0
|
250 but the correct size for decode */
|
nuclear@0
|
251 v->pcm_storage=ci->blocksizes[1];
|
nuclear@0
|
252 v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
|
nuclear@0
|
253 v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
|
nuclear@0
|
254 {
|
nuclear@0
|
255 int i;
|
nuclear@0
|
256 for(i=0;i<vi->channels;i++)
|
nuclear@0
|
257 v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
|
nuclear@0
|
258 }
|
nuclear@0
|
259
|
nuclear@0
|
260 /* all 1 (large block) or 0 (small block) */
|
nuclear@0
|
261 /* explicitly set for the sake of clarity */
|
nuclear@0
|
262 v->lW=0; /* previous window size */
|
nuclear@0
|
263 v->W=0; /* current window size */
|
nuclear@0
|
264
|
nuclear@0
|
265 /* all vector indexes */
|
nuclear@0
|
266 v->centerW=ci->blocksizes[1]/2;
|
nuclear@0
|
267
|
nuclear@0
|
268 v->pcm_current=v->centerW;
|
nuclear@0
|
269
|
nuclear@0
|
270 /* initialize all the backend lookups */
|
nuclear@0
|
271 b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
|
nuclear@0
|
272 b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
|
nuclear@0
|
273
|
nuclear@0
|
274 for(i=0;i<ci->floors;i++)
|
nuclear@0
|
275 b->flr[i]=_floor_P[ci->floor_type[i]]->
|
nuclear@0
|
276 look(v,ci->floor_param[i]);
|
nuclear@0
|
277
|
nuclear@0
|
278 for(i=0;i<ci->residues;i++)
|
nuclear@0
|
279 b->residue[i]=_residue_P[ci->residue_type[i]]->
|
nuclear@0
|
280 look(v,ci->residue_param[i]);
|
nuclear@0
|
281
|
nuclear@0
|
282 return 0;
|
nuclear@0
|
283 abort_books:
|
nuclear@0
|
284 for(i=0;i<ci->books;i++){
|
nuclear@0
|
285 if(ci->book_param[i]!=NULL){
|
nuclear@0
|
286 vorbis_staticbook_destroy(ci->book_param[i]);
|
nuclear@0
|
287 ci->book_param[i]=NULL;
|
nuclear@0
|
288 }
|
nuclear@0
|
289 }
|
nuclear@0
|
290 vorbis_dsp_clear(v);
|
nuclear@0
|
291 return -1;
|
nuclear@0
|
292 }
|
nuclear@0
|
293
|
nuclear@0
|
294 /* arbitrary settings and spec-mandated numbers get filled in here */
|
nuclear@0
|
295 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
|
nuclear@0
|
296 private_state *b=NULL;
|
nuclear@0
|
297
|
nuclear@0
|
298 if(_vds_shared_init(v,vi,1))return 1;
|
nuclear@0
|
299 b=v->backend_state;
|
nuclear@0
|
300 b->psy_g_look=_vp_global_look(vi);
|
nuclear@0
|
301
|
nuclear@0
|
302 /* Initialize the envelope state storage */
|
nuclear@0
|
303 b->ve=_ogg_calloc(1,sizeof(*b->ve));
|
nuclear@0
|
304 _ve_envelope_init(b->ve,vi);
|
nuclear@0
|
305
|
nuclear@0
|
306 vorbis_bitrate_init(vi,&b->bms);
|
nuclear@0
|
307
|
nuclear@0
|
308 /* compressed audio packets start after the headers
|
nuclear@0
|
309 with sequence number 3 */
|
nuclear@0
|
310 v->sequence=3;
|
nuclear@0
|
311
|
nuclear@0
|
312 return(0);
|
nuclear@0
|
313 }
|
nuclear@0
|
314
|
nuclear@0
|
315 void vorbis_dsp_clear(vorbis_dsp_state *v){
|
nuclear@0
|
316 int i;
|
nuclear@0
|
317 if(v){
|
nuclear@0
|
318 vorbis_info *vi=v->vi;
|
nuclear@0
|
319 codec_setup_info *ci=(vi?vi->codec_setup:NULL);
|
nuclear@0
|
320 private_state *b=v->backend_state;
|
nuclear@0
|
321
|
nuclear@0
|
322 if(b){
|
nuclear@0
|
323
|
nuclear@0
|
324 if(b->ve){
|
nuclear@0
|
325 _ve_envelope_clear(b->ve);
|
nuclear@0
|
326 _ogg_free(b->ve);
|
nuclear@0
|
327 }
|
nuclear@0
|
328
|
nuclear@0
|
329 if(b->transform[0]){
|
nuclear@0
|
330 mdct_clear(b->transform[0][0]);
|
nuclear@0
|
331 _ogg_free(b->transform[0][0]);
|
nuclear@0
|
332 _ogg_free(b->transform[0]);
|
nuclear@0
|
333 }
|
nuclear@0
|
334 if(b->transform[1]){
|
nuclear@0
|
335 mdct_clear(b->transform[1][0]);
|
nuclear@0
|
336 _ogg_free(b->transform[1][0]);
|
nuclear@0
|
337 _ogg_free(b->transform[1]);
|
nuclear@0
|
338 }
|
nuclear@0
|
339
|
nuclear@0
|
340 if(b->flr){
|
nuclear@0
|
341 if(ci)
|
nuclear@0
|
342 for(i=0;i<ci->floors;i++)
|
nuclear@0
|
343 _floor_P[ci->floor_type[i]]->
|
nuclear@0
|
344 free_look(b->flr[i]);
|
nuclear@0
|
345 _ogg_free(b->flr);
|
nuclear@0
|
346 }
|
nuclear@0
|
347 if(b->residue){
|
nuclear@0
|
348 if(ci)
|
nuclear@0
|
349 for(i=0;i<ci->residues;i++)
|
nuclear@0
|
350 _residue_P[ci->residue_type[i]]->
|
nuclear@0
|
351 free_look(b->residue[i]);
|
nuclear@0
|
352 _ogg_free(b->residue);
|
nuclear@0
|
353 }
|
nuclear@0
|
354 if(b->psy){
|
nuclear@0
|
355 if(ci)
|
nuclear@0
|
356 for(i=0;i<ci->psys;i++)
|
nuclear@0
|
357 _vp_psy_clear(b->psy+i);
|
nuclear@0
|
358 _ogg_free(b->psy);
|
nuclear@0
|
359 }
|
nuclear@0
|
360
|
nuclear@0
|
361 if(b->psy_g_look)_vp_global_free(b->psy_g_look);
|
nuclear@0
|
362 vorbis_bitrate_clear(&b->bms);
|
nuclear@0
|
363
|
nuclear@0
|
364 drft_clear(&b->fft_look[0]);
|
nuclear@0
|
365 drft_clear(&b->fft_look[1]);
|
nuclear@0
|
366
|
nuclear@0
|
367 }
|
nuclear@0
|
368
|
nuclear@0
|
369 if(v->pcm){
|
nuclear@0
|
370 if(vi)
|
nuclear@0
|
371 for(i=0;i<vi->channels;i++)
|
nuclear@0
|
372 if(v->pcm[i])_ogg_free(v->pcm[i]);
|
nuclear@0
|
373 _ogg_free(v->pcm);
|
nuclear@0
|
374 if(v->pcmret)_ogg_free(v->pcmret);
|
nuclear@0
|
375 }
|
nuclear@0
|
376
|
nuclear@0
|
377 if(b){
|
nuclear@0
|
378 /* free header, header1, header2 */
|
nuclear@0
|
379 if(b->header)_ogg_free(b->header);
|
nuclear@0
|
380 if(b->header1)_ogg_free(b->header1);
|
nuclear@0
|
381 if(b->header2)_ogg_free(b->header2);
|
nuclear@0
|
382 _ogg_free(b);
|
nuclear@0
|
383 }
|
nuclear@0
|
384
|
nuclear@0
|
385 memset(v,0,sizeof(*v));
|
nuclear@0
|
386 }
|
nuclear@0
|
387 }
|
nuclear@0
|
388
|
nuclear@0
|
389 float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
|
nuclear@0
|
390 int i;
|
nuclear@0
|
391 vorbis_info *vi=v->vi;
|
nuclear@0
|
392 private_state *b=v->backend_state;
|
nuclear@0
|
393
|
nuclear@0
|
394 /* free header, header1, header2 */
|
nuclear@0
|
395 if(b->header)_ogg_free(b->header);b->header=NULL;
|
nuclear@0
|
396 if(b->header1)_ogg_free(b->header1);b->header1=NULL;
|
nuclear@0
|
397 if(b->header2)_ogg_free(b->header2);b->header2=NULL;
|
nuclear@0
|
398
|
nuclear@0
|
399 /* Do we have enough storage space for the requested buffer? If not,
|
nuclear@0
|
400 expand the PCM (and envelope) storage */
|
nuclear@0
|
401
|
nuclear@0
|
402 if(v->pcm_current+vals>=v->pcm_storage){
|
nuclear@0
|
403 v->pcm_storage=v->pcm_current+vals*2;
|
nuclear@0
|
404
|
nuclear@0
|
405 for(i=0;i<vi->channels;i++){
|
nuclear@0
|
406 v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
|
nuclear@0
|
407 }
|
nuclear@0
|
408 }
|
nuclear@0
|
409
|
nuclear@0
|
410 for(i=0;i<vi->channels;i++)
|
nuclear@0
|
411 v->pcmret[i]=v->pcm[i]+v->pcm_current;
|
nuclear@0
|
412
|
nuclear@0
|
413 return(v->pcmret);
|
nuclear@0
|
414 }
|
nuclear@0
|
415
|
nuclear@0
|
416 static void _preextrapolate_helper(vorbis_dsp_state *v){
|
nuclear@0
|
417 int i;
|
nuclear@0
|
418 int order=16;
|
nuclear@0
|
419 float *lpc=alloca(order*sizeof(*lpc));
|
nuclear@0
|
420 float *work=alloca(v->pcm_current*sizeof(*work));
|
nuclear@0
|
421 long j;
|
nuclear@0
|
422 v->preextrapolate=1;
|
nuclear@0
|
423
|
nuclear@0
|
424 if(v->pcm_current-v->centerW>order*2){ /* safety */
|
nuclear@0
|
425 for(i=0;i<v->vi->channels;i++){
|
nuclear@0
|
426 /* need to run the extrapolation in reverse! */
|
nuclear@0
|
427 for(j=0;j<v->pcm_current;j++)
|
nuclear@0
|
428 work[j]=v->pcm[i][v->pcm_current-j-1];
|
nuclear@0
|
429
|
nuclear@0
|
430 /* prime as above */
|
nuclear@0
|
431 vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
|
nuclear@0
|
432
|
nuclear@0
|
433 #if 0
|
nuclear@0
|
434 if(v->vi->channels==2){
|
nuclear@0
|
435 if(i==0)
|
nuclear@0
|
436 _analysis_output("predataL",0,work,v->pcm_current-v->centerW,0,0,0);
|
nuclear@0
|
437 else
|
nuclear@0
|
438 _analysis_output("predataR",0,work,v->pcm_current-v->centerW,0,0,0);
|
nuclear@0
|
439 }else{
|
nuclear@0
|
440 _analysis_output("predata",0,work,v->pcm_current-v->centerW,0,0,0);
|
nuclear@0
|
441 }
|
nuclear@0
|
442 #endif
|
nuclear@0
|
443
|
nuclear@0
|
444 /* run the predictor filter */
|
nuclear@0
|
445 vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
|
nuclear@0
|
446 order,
|
nuclear@0
|
447 work+v->pcm_current-v->centerW,
|
nuclear@0
|
448 v->centerW);
|
nuclear@0
|
449
|
nuclear@0
|
450 for(j=0;j<v->pcm_current;j++)
|
nuclear@0
|
451 v->pcm[i][v->pcm_current-j-1]=work[j];
|
nuclear@0
|
452
|
nuclear@0
|
453 }
|
nuclear@0
|
454 }
|
nuclear@0
|
455 }
|
nuclear@0
|
456
|
nuclear@0
|
457
|
nuclear@0
|
458 /* call with val<=0 to set eof */
|
nuclear@0
|
459
|
nuclear@0
|
460 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
|
nuclear@0
|
461 vorbis_info *vi=v->vi;
|
nuclear@0
|
462 codec_setup_info *ci=vi->codec_setup;
|
nuclear@0
|
463
|
nuclear@0
|
464 if(vals<=0){
|
nuclear@0
|
465 int order=32;
|
nuclear@0
|
466 int i;
|
nuclear@0
|
467 float *lpc=alloca(order*sizeof(*lpc));
|
nuclear@0
|
468
|
nuclear@0
|
469 /* if it wasn't done earlier (very short sample) */
|
nuclear@0
|
470 if(!v->preextrapolate)
|
nuclear@0
|
471 _preextrapolate_helper(v);
|
nuclear@0
|
472
|
nuclear@0
|
473 /* We're encoding the end of the stream. Just make sure we have
|
nuclear@0
|
474 [at least] a few full blocks of zeroes at the end. */
|
nuclear@0
|
475 /* actually, we don't want zeroes; that could drop a large
|
nuclear@0
|
476 amplitude off a cliff, creating spread spectrum noise that will
|
nuclear@0
|
477 suck to encode. Extrapolate for the sake of cleanliness. */
|
nuclear@0
|
478
|
nuclear@0
|
479 vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
|
nuclear@0
|
480 v->eofflag=v->pcm_current;
|
nuclear@0
|
481 v->pcm_current+=ci->blocksizes[1]*3;
|
nuclear@0
|
482
|
nuclear@0
|
483 for(i=0;i<vi->channels;i++){
|
nuclear@0
|
484 if(v->eofflag>order*2){
|
nuclear@0
|
485 /* extrapolate with LPC to fill in */
|
nuclear@0
|
486 long n;
|
nuclear@0
|
487
|
nuclear@0
|
488 /* make a predictor filter */
|
nuclear@0
|
489 n=v->eofflag;
|
nuclear@0
|
490 if(n>ci->blocksizes[1])n=ci->blocksizes[1];
|
nuclear@0
|
491 vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
|
nuclear@0
|
492
|
nuclear@0
|
493 /* run the predictor filter */
|
nuclear@0
|
494 vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
|
nuclear@0
|
495 v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
|
nuclear@0
|
496 }else{
|
nuclear@0
|
497 /* not enough data to extrapolate (unlikely to happen due to
|
nuclear@0
|
498 guarding the overlap, but bulletproof in case that
|
nuclear@0
|
499 assumtion goes away). zeroes will do. */
|
nuclear@0
|
500 memset(v->pcm[i]+v->eofflag,0,
|
nuclear@0
|
501 (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
|
nuclear@0
|
502
|
nuclear@0
|
503 }
|
nuclear@0
|
504 }
|
nuclear@0
|
505 }else{
|
nuclear@0
|
506
|
nuclear@0
|
507 if(v->pcm_current+vals>v->pcm_storage)
|
nuclear@0
|
508 return(OV_EINVAL);
|
nuclear@0
|
509
|
nuclear@0
|
510 v->pcm_current+=vals;
|
nuclear@0
|
511
|
nuclear@0
|
512 /* we may want to reverse extrapolate the beginning of a stream
|
nuclear@0
|
513 too... in case we're beginning on a cliff! */
|
nuclear@0
|
514 /* clumsy, but simple. It only runs once, so simple is good. */
|
nuclear@0
|
515 if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
|
nuclear@0
|
516 _preextrapolate_helper(v);
|
nuclear@0
|
517
|
nuclear@0
|
518 }
|
nuclear@0
|
519 return(0);
|
nuclear@0
|
520 }
|
nuclear@0
|
521
|
nuclear@0
|
522 /* do the deltas, envelope shaping, pre-echo and determine the size of
|
nuclear@0
|
523 the next block on which to continue analysis */
|
nuclear@0
|
524 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
|
nuclear@0
|
525 int i;
|
nuclear@0
|
526 vorbis_info *vi=v->vi;
|
nuclear@0
|
527 codec_setup_info *ci=vi->codec_setup;
|
nuclear@0
|
528 private_state *b=v->backend_state;
|
nuclear@0
|
529 vorbis_look_psy_global *g=b->psy_g_look;
|
nuclear@0
|
530 long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
|
nuclear@0
|
531 vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
|
nuclear@0
|
532
|
nuclear@0
|
533 /* check to see if we're started... */
|
nuclear@0
|
534 if(!v->preextrapolate)return(0);
|
nuclear@0
|
535
|
nuclear@0
|
536 /* check to see if we're done... */
|
nuclear@0
|
537 if(v->eofflag==-1)return(0);
|
nuclear@0
|
538
|
nuclear@0
|
539 /* By our invariant, we have lW, W and centerW set. Search for
|
nuclear@0
|
540 the next boundary so we can determine nW (the next window size)
|
nuclear@0
|
541 which lets us compute the shape of the current block's window */
|
nuclear@0
|
542
|
nuclear@0
|
543 /* we do an envelope search even on a single blocksize; we may still
|
nuclear@0
|
544 be throwing more bits at impulses, and envelope search handles
|
nuclear@0
|
545 marking impulses too. */
|
nuclear@0
|
546 {
|
nuclear@0
|
547 long bp=_ve_envelope_search(v);
|
nuclear@0
|
548 if(bp==-1){
|
nuclear@0
|
549
|
nuclear@0
|
550 if(v->eofflag==0)return(0); /* not enough data currently to search for a
|
nuclear@0
|
551 full long block */
|
nuclear@0
|
552 v->nW=0;
|
nuclear@0
|
553 }else{
|
nuclear@0
|
554
|
nuclear@0
|
555 if(ci->blocksizes[0]==ci->blocksizes[1])
|
nuclear@0
|
556 v->nW=0;
|
nuclear@0
|
557 else
|
nuclear@0
|
558 v->nW=bp;
|
nuclear@0
|
559 }
|
nuclear@0
|
560 }
|
nuclear@0
|
561
|
nuclear@0
|
562 centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
|
nuclear@0
|
563
|
nuclear@0
|
564 {
|
nuclear@0
|
565 /* center of next block + next block maximum right side. */
|
nuclear@0
|
566
|
nuclear@0
|
567 long blockbound=centerNext+ci->blocksizes[v->nW]/2;
|
nuclear@0
|
568 if(v->pcm_current<blockbound)return(0); /* not enough data yet;
|
nuclear@0
|
569 although this check is
|
nuclear@0
|
570 less strict that the
|
nuclear@0
|
571 _ve_envelope_search,
|
nuclear@0
|
572 the search is not run
|
nuclear@0
|
573 if we only use one
|
nuclear@0
|
574 block size */
|
nuclear@0
|
575
|
nuclear@0
|
576
|
nuclear@0
|
577 }
|
nuclear@0
|
578
|
nuclear@0
|
579 /* fill in the block. Note that for a short window, lW and nW are *short*
|
nuclear@0
|
580 regardless of actual settings in the stream */
|
nuclear@0
|
581
|
nuclear@0
|
582 _vorbis_block_ripcord(vb);
|
nuclear@0
|
583 vb->lW=v->lW;
|
nuclear@0
|
584 vb->W=v->W;
|
nuclear@0
|
585 vb->nW=v->nW;
|
nuclear@0
|
586
|
nuclear@0
|
587 if(v->W){
|
nuclear@0
|
588 if(!v->lW || !v->nW){
|
nuclear@0
|
589 vbi->blocktype=BLOCKTYPE_TRANSITION;
|
nuclear@0
|
590 /*fprintf(stderr,"-");*/
|
nuclear@0
|
591 }else{
|
nuclear@0
|
592 vbi->blocktype=BLOCKTYPE_LONG;
|
nuclear@0
|
593 /*fprintf(stderr,"_");*/
|
nuclear@0
|
594 }
|
nuclear@0
|
595 }else{
|
nuclear@0
|
596 if(_ve_envelope_mark(v)){
|
nuclear@0
|
597 vbi->blocktype=BLOCKTYPE_IMPULSE;
|
nuclear@0
|
598 /*fprintf(stderr,"|");*/
|
nuclear@0
|
599
|
nuclear@0
|
600 }else{
|
nuclear@0
|
601 vbi->blocktype=BLOCKTYPE_PADDING;
|
nuclear@0
|
602 /*fprintf(stderr,".");*/
|
nuclear@0
|
603
|
nuclear@0
|
604 }
|
nuclear@0
|
605 }
|
nuclear@0
|
606
|
nuclear@0
|
607 vb->vd=v;
|
nuclear@0
|
608 vb->sequence=v->sequence++;
|
nuclear@0
|
609 vb->granulepos=v->granulepos;
|
nuclear@0
|
610 vb->pcmend=ci->blocksizes[v->W];
|
nuclear@0
|
611
|
nuclear@0
|
612 /* copy the vectors; this uses the local storage in vb */
|
nuclear@0
|
613
|
nuclear@0
|
614 /* this tracks 'strongest peak' for later psychoacoustics */
|
nuclear@0
|
615 /* moved to the global psy state; clean this mess up */
|
nuclear@0
|
616 if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
|
nuclear@0
|
617 g->ampmax=_vp_ampmax_decay(g->ampmax,v);
|
nuclear@0
|
618 vbi->ampmax=g->ampmax;
|
nuclear@0
|
619
|
nuclear@0
|
620 vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
|
nuclear@0
|
621 vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
|
nuclear@0
|
622 for(i=0;i<vi->channels;i++){
|
nuclear@0
|
623 vbi->pcmdelay[i]=
|
nuclear@0
|
624 _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
|
nuclear@0
|
625 memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
|
nuclear@0
|
626 vb->pcm[i]=vbi->pcmdelay[i]+beginW;
|
nuclear@0
|
627
|
nuclear@0
|
628 /* before we added the delay
|
nuclear@0
|
629 vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
|
nuclear@0
|
630 memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
|
nuclear@0
|
631 */
|
nuclear@0
|
632
|
nuclear@0
|
633 }
|
nuclear@0
|
634
|
nuclear@0
|
635 /* handle eof detection: eof==0 means that we've not yet received EOF
|
nuclear@0
|
636 eof>0 marks the last 'real' sample in pcm[]
|
nuclear@0
|
637 eof<0 'no more to do'; doesn't get here */
|
nuclear@0
|
638
|
nuclear@0
|
639 if(v->eofflag){
|
nuclear@0
|
640 if(v->centerW>=v->eofflag){
|
nuclear@0
|
641 v->eofflag=-1;
|
nuclear@0
|
642 vb->eofflag=1;
|
nuclear@0
|
643 return(1);
|
nuclear@0
|
644 }
|
nuclear@0
|
645 }
|
nuclear@0
|
646
|
nuclear@0
|
647 /* advance storage vectors and clean up */
|
nuclear@0
|
648 {
|
nuclear@0
|
649 int new_centerNext=ci->blocksizes[1]/2;
|
nuclear@0
|
650 int movementW=centerNext-new_centerNext;
|
nuclear@0
|
651
|
nuclear@0
|
652 if(movementW>0){
|
nuclear@0
|
653
|
nuclear@0
|
654 _ve_envelope_shift(b->ve,movementW);
|
nuclear@0
|
655 v->pcm_current-=movementW;
|
nuclear@0
|
656
|
nuclear@0
|
657 for(i=0;i<vi->channels;i++)
|
nuclear@0
|
658 memmove(v->pcm[i],v->pcm[i]+movementW,
|
nuclear@0
|
659 v->pcm_current*sizeof(*v->pcm[i]));
|
nuclear@0
|
660
|
nuclear@0
|
661
|
nuclear@0
|
662 v->lW=v->W;
|
nuclear@0
|
663 v->W=v->nW;
|
nuclear@0
|
664 v->centerW=new_centerNext;
|
nuclear@0
|
665
|
nuclear@0
|
666 if(v->eofflag){
|
nuclear@0
|
667 v->eofflag-=movementW;
|
nuclear@0
|
668 if(v->eofflag<=0)v->eofflag=-1;
|
nuclear@0
|
669 /* do not add padding to end of stream! */
|
nuclear@0
|
670 if(v->centerW>=v->eofflag){
|
nuclear@0
|
671 v->granulepos+=movementW-(v->centerW-v->eofflag);
|
nuclear@0
|
672 }else{
|
nuclear@0
|
673 v->granulepos+=movementW;
|
nuclear@0
|
674 }
|
nuclear@0
|
675 }else{
|
nuclear@0
|
676 v->granulepos+=movementW;
|
nuclear@0
|
677 }
|
nuclear@0
|
678 }
|
nuclear@0
|
679 }
|
nuclear@0
|
680
|
nuclear@0
|
681 /* done */
|
nuclear@0
|
682 return(1);
|
nuclear@0
|
683 }
|
nuclear@0
|
684
|
nuclear@0
|
685 int vorbis_synthesis_restart(vorbis_dsp_state *v){
|
nuclear@0
|
686 vorbis_info *vi=v->vi;
|
nuclear@0
|
687 codec_setup_info *ci;
|
nuclear@0
|
688 int hs;
|
nuclear@0
|
689
|
nuclear@0
|
690 if(!v->backend_state)return -1;
|
nuclear@0
|
691 if(!vi)return -1;
|
nuclear@0
|
692 ci=vi->codec_setup;
|
nuclear@0
|
693 if(!ci)return -1;
|
nuclear@0
|
694 hs=ci->halfrate_flag;
|
nuclear@0
|
695
|
nuclear@0
|
696 v->centerW=ci->blocksizes[1]>>(hs+1);
|
nuclear@0
|
697 v->pcm_current=v->centerW>>hs;
|
nuclear@0
|
698
|
nuclear@0
|
699 v->pcm_returned=-1;
|
nuclear@0
|
700 v->granulepos=-1;
|
nuclear@0
|
701 v->sequence=-1;
|
nuclear@0
|
702 v->eofflag=0;
|
nuclear@0
|
703 ((private_state *)(v->backend_state))->sample_count=-1;
|
nuclear@0
|
704
|
nuclear@0
|
705 return(0);
|
nuclear@0
|
706 }
|
nuclear@0
|
707
|
nuclear@0
|
708 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
|
nuclear@0
|
709 if(_vds_shared_init(v,vi,0)){
|
nuclear@0
|
710 vorbis_dsp_clear(v);
|
nuclear@0
|
711 return 1;
|
nuclear@0
|
712 }
|
nuclear@0
|
713 vorbis_synthesis_restart(v);
|
nuclear@0
|
714 return 0;
|
nuclear@0
|
715 }
|
nuclear@0
|
716
|
nuclear@0
|
717 /* Unlike in analysis, the window is only partially applied for each
|
nuclear@0
|
718 block. The time domain envelope is not yet handled at the point of
|
nuclear@0
|
719 calling (as it relies on the previous block). */
|
nuclear@0
|
720
|
nuclear@0
|
721 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
|
nuclear@0
|
722 vorbis_info *vi=v->vi;
|
nuclear@0
|
723 codec_setup_info *ci=vi->codec_setup;
|
nuclear@0
|
724 private_state *b=v->backend_state;
|
nuclear@0
|
725 int hs=ci->halfrate_flag;
|
nuclear@0
|
726 int i,j;
|
nuclear@0
|
727
|
nuclear@0
|
728 if(!vb)return(OV_EINVAL);
|
nuclear@0
|
729 if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
|
nuclear@0
|
730
|
nuclear@0
|
731 v->lW=v->W;
|
nuclear@0
|
732 v->W=vb->W;
|
nuclear@0
|
733 v->nW=-1;
|
nuclear@0
|
734
|
nuclear@0
|
735 if((v->sequence==-1)||
|
nuclear@0
|
736 (v->sequence+1 != vb->sequence)){
|
nuclear@0
|
737 v->granulepos=-1; /* out of sequence; lose count */
|
nuclear@0
|
738 b->sample_count=-1;
|
nuclear@0
|
739 }
|
nuclear@0
|
740
|
nuclear@0
|
741 v->sequence=vb->sequence;
|
nuclear@0
|
742
|
nuclear@0
|
743 if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
|
nuclear@0
|
744 was called on block */
|
nuclear@0
|
745 int n=ci->blocksizes[v->W]>>(hs+1);
|
nuclear@0
|
746 int n0=ci->blocksizes[0]>>(hs+1);
|
nuclear@0
|
747 int n1=ci->blocksizes[1]>>(hs+1);
|
nuclear@0
|
748
|
nuclear@0
|
749 int thisCenter;
|
nuclear@0
|
750 int prevCenter;
|
nuclear@0
|
751
|
nuclear@0
|
752 v->glue_bits+=vb->glue_bits;
|
nuclear@0
|
753 v->time_bits+=vb->time_bits;
|
nuclear@0
|
754 v->floor_bits+=vb->floor_bits;
|
nuclear@0
|
755 v->res_bits+=vb->res_bits;
|
nuclear@0
|
756
|
nuclear@0
|
757 if(v->centerW){
|
nuclear@0
|
758 thisCenter=n1;
|
nuclear@0
|
759 prevCenter=0;
|
nuclear@0
|
760 }else{
|
nuclear@0
|
761 thisCenter=0;
|
nuclear@0
|
762 prevCenter=n1;
|
nuclear@0
|
763 }
|
nuclear@0
|
764
|
nuclear@0
|
765 /* v->pcm is now used like a two-stage double buffer. We don't want
|
nuclear@0
|
766 to have to constantly shift *or* adjust memory usage. Don't
|
nuclear@0
|
767 accept a new block until the old is shifted out */
|
nuclear@0
|
768
|
nuclear@0
|
769 for(j=0;j<vi->channels;j++){
|
nuclear@0
|
770 /* the overlap/add section */
|
nuclear@0
|
771 if(v->lW){
|
nuclear@0
|
772 if(v->W){
|
nuclear@0
|
773 /* large/large */
|
nuclear@0
|
774 float *w=_vorbis_window_get(b->window[1]-hs);
|
nuclear@0
|
775 float *pcm=v->pcm[j]+prevCenter;
|
nuclear@0
|
776 float *p=vb->pcm[j];
|
nuclear@0
|
777 for(i=0;i<n1;i++)
|
nuclear@0
|
778 pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
|
nuclear@0
|
779 }else{
|
nuclear@0
|
780 /* large/small */
|
nuclear@0
|
781 float *w=_vorbis_window_get(b->window[0]-hs);
|
nuclear@0
|
782 float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
|
nuclear@0
|
783 float *p=vb->pcm[j];
|
nuclear@0
|
784 for(i=0;i<n0;i++)
|
nuclear@0
|
785 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
|
nuclear@0
|
786 }
|
nuclear@0
|
787 }else{
|
nuclear@0
|
788 if(v->W){
|
nuclear@0
|
789 /* small/large */
|
nuclear@0
|
790 float *w=_vorbis_window_get(b->window[0]-hs);
|
nuclear@0
|
791 float *pcm=v->pcm[j]+prevCenter;
|
nuclear@0
|
792 float *p=vb->pcm[j]+n1/2-n0/2;
|
nuclear@0
|
793 for(i=0;i<n0;i++)
|
nuclear@0
|
794 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
|
nuclear@0
|
795 for(;i<n1/2+n0/2;i++)
|
nuclear@0
|
796 pcm[i]=p[i];
|
nuclear@0
|
797 }else{
|
nuclear@0
|
798 /* small/small */
|
nuclear@0
|
799 float *w=_vorbis_window_get(b->window[0]-hs);
|
nuclear@0
|
800 float *pcm=v->pcm[j]+prevCenter;
|
nuclear@0
|
801 float *p=vb->pcm[j];
|
nuclear@0
|
802 for(i=0;i<n0;i++)
|
nuclear@0
|
803 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
|
nuclear@0
|
804 }
|
nuclear@0
|
805 }
|
nuclear@0
|
806
|
nuclear@0
|
807 /* the copy section */
|
nuclear@0
|
808 {
|
nuclear@0
|
809 float *pcm=v->pcm[j]+thisCenter;
|
nuclear@0
|
810 float *p=vb->pcm[j]+n;
|
nuclear@0
|
811 for(i=0;i<n;i++)
|
nuclear@0
|
812 pcm[i]=p[i];
|
nuclear@0
|
813 }
|
nuclear@0
|
814 }
|
nuclear@0
|
815
|
nuclear@0
|
816 if(v->centerW)
|
nuclear@0
|
817 v->centerW=0;
|
nuclear@0
|
818 else
|
nuclear@0
|
819 v->centerW=n1;
|
nuclear@0
|
820
|
nuclear@0
|
821 /* deal with initial packet state; we do this using the explicit
|
nuclear@0
|
822 pcm_returned==-1 flag otherwise we're sensitive to first block
|
nuclear@0
|
823 being short or long */
|
nuclear@0
|
824
|
nuclear@0
|
825 if(v->pcm_returned==-1){
|
nuclear@0
|
826 v->pcm_returned=thisCenter;
|
nuclear@0
|
827 v->pcm_current=thisCenter;
|
nuclear@0
|
828 }else{
|
nuclear@0
|
829 v->pcm_returned=prevCenter;
|
nuclear@0
|
830 v->pcm_current=prevCenter+
|
nuclear@0
|
831 ((ci->blocksizes[v->lW]/4+
|
nuclear@0
|
832 ci->blocksizes[v->W]/4)>>hs);
|
nuclear@0
|
833 }
|
nuclear@0
|
834
|
nuclear@0
|
835 }
|
nuclear@0
|
836
|
nuclear@0
|
837 /* track the frame number... This is for convenience, but also
|
nuclear@0
|
838 making sure our last packet doesn't end with added padding. If
|
nuclear@0
|
839 the last packet is partial, the number of samples we'll have to
|
nuclear@0
|
840 return will be past the vb->granulepos.
|
nuclear@0
|
841
|
nuclear@0
|
842 This is not foolproof! It will be confused if we begin
|
nuclear@0
|
843 decoding at the last page after a seek or hole. In that case,
|
nuclear@0
|
844 we don't have a starting point to judge where the last frame
|
nuclear@0
|
845 is. For this reason, vorbisfile will always try to make sure
|
nuclear@0
|
846 it reads the last two marked pages in proper sequence */
|
nuclear@0
|
847
|
nuclear@0
|
848 if(b->sample_count==-1){
|
nuclear@0
|
849 b->sample_count=0;
|
nuclear@0
|
850 }else{
|
nuclear@0
|
851 b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
|
nuclear@0
|
852 }
|
nuclear@0
|
853
|
nuclear@0
|
854 if(v->granulepos==-1){
|
nuclear@0
|
855 if(vb->granulepos!=-1){ /* only set if we have a position to set to */
|
nuclear@0
|
856
|
nuclear@0
|
857 v->granulepos=vb->granulepos;
|
nuclear@0
|
858
|
nuclear@0
|
859 /* is this a short page? */
|
nuclear@0
|
860 if(b->sample_count>v->granulepos){
|
nuclear@0
|
861 /* corner case; if this is both the first and last audio page,
|
nuclear@0
|
862 then spec says the end is cut, not beginning */
|
nuclear@0
|
863 long extra=b->sample_count-vb->granulepos;
|
nuclear@0
|
864
|
nuclear@0
|
865 /* we use ogg_int64_t for granule positions because a
|
nuclear@0
|
866 uint64 isn't universally available. Unfortunately,
|
nuclear@0
|
867 that means granposes can be 'negative' and result in
|
nuclear@0
|
868 extra being negative */
|
nuclear@0
|
869 if(extra<0)
|
nuclear@0
|
870 extra=0;
|
nuclear@0
|
871
|
nuclear@0
|
872 if(vb->eofflag){
|
nuclear@0
|
873 /* trim the end */
|
nuclear@0
|
874 /* no preceding granulepos; assume we started at zero (we'd
|
nuclear@0
|
875 have to in a short single-page stream) */
|
nuclear@0
|
876 /* granulepos could be -1 due to a seek, but that would result
|
nuclear@0
|
877 in a long count, not short count */
|
nuclear@0
|
878
|
nuclear@0
|
879 /* Guard against corrupt/malicious frames that set EOP and
|
nuclear@0
|
880 a backdated granpos; don't rewind more samples than we
|
nuclear@0
|
881 actually have */
|
nuclear@0
|
882 if(extra > (v->pcm_current - v->pcm_returned)<<hs)
|
nuclear@0
|
883 extra = (v->pcm_current - v->pcm_returned)<<hs;
|
nuclear@0
|
884
|
nuclear@0
|
885 v->pcm_current-=extra>>hs;
|
nuclear@0
|
886 }else{
|
nuclear@0
|
887 /* trim the beginning */
|
nuclear@0
|
888 v->pcm_returned+=extra>>hs;
|
nuclear@0
|
889 if(v->pcm_returned>v->pcm_current)
|
nuclear@0
|
890 v->pcm_returned=v->pcm_current;
|
nuclear@0
|
891 }
|
nuclear@0
|
892
|
nuclear@0
|
893 }
|
nuclear@0
|
894
|
nuclear@0
|
895 }
|
nuclear@0
|
896 }else{
|
nuclear@0
|
897 v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
|
nuclear@0
|
898 if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
|
nuclear@0
|
899
|
nuclear@0
|
900 if(v->granulepos>vb->granulepos){
|
nuclear@0
|
901 long extra=v->granulepos-vb->granulepos;
|
nuclear@0
|
902
|
nuclear@0
|
903 if(extra)
|
nuclear@0
|
904 if(vb->eofflag){
|
nuclear@0
|
905 /* partial last frame. Strip the extra samples off */
|
nuclear@0
|
906
|
nuclear@0
|
907 /* Guard against corrupt/malicious frames that set EOP and
|
nuclear@0
|
908 a backdated granpos; don't rewind more samples than we
|
nuclear@0
|
909 actually have */
|
nuclear@0
|
910 if(extra > (v->pcm_current - v->pcm_returned)<<hs)
|
nuclear@0
|
911 extra = (v->pcm_current - v->pcm_returned)<<hs;
|
nuclear@0
|
912
|
nuclear@0
|
913 /* we use ogg_int64_t for granule positions because a
|
nuclear@0
|
914 uint64 isn't universally available. Unfortunately,
|
nuclear@0
|
915 that means granposes can be 'negative' and result in
|
nuclear@0
|
916 extra being negative */
|
nuclear@0
|
917 if(extra<0)
|
nuclear@0
|
918 extra=0;
|
nuclear@0
|
919
|
nuclear@0
|
920 v->pcm_current-=extra>>hs;
|
nuclear@0
|
921 } /* else {Shouldn't happen *unless* the bitstream is out of
|
nuclear@0
|
922 spec. Either way, believe the bitstream } */
|
nuclear@0
|
923 } /* else {Shouldn't happen *unless* the bitstream is out of
|
nuclear@0
|
924 spec. Either way, believe the bitstream } */
|
nuclear@0
|
925 v->granulepos=vb->granulepos;
|
nuclear@0
|
926 }
|
nuclear@0
|
927 }
|
nuclear@0
|
928
|
nuclear@0
|
929 /* Update, cleanup */
|
nuclear@0
|
930
|
nuclear@0
|
931 if(vb->eofflag)v->eofflag=1;
|
nuclear@0
|
932 return(0);
|
nuclear@0
|
933
|
nuclear@0
|
934 }
|
nuclear@0
|
935
|
nuclear@0
|
936 /* pcm==NULL indicates we just want the pending samples, no more */
|
nuclear@0
|
937 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
|
nuclear@0
|
938 vorbis_info *vi=v->vi;
|
nuclear@0
|
939
|
nuclear@0
|
940 if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
|
nuclear@0
|
941 if(pcm){
|
nuclear@0
|
942 int i;
|
nuclear@0
|
943 for(i=0;i<vi->channels;i++)
|
nuclear@0
|
944 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
|
nuclear@0
|
945 *pcm=v->pcmret;
|
nuclear@0
|
946 }
|
nuclear@0
|
947 return(v->pcm_current-v->pcm_returned);
|
nuclear@0
|
948 }
|
nuclear@0
|
949 return(0);
|
nuclear@0
|
950 }
|
nuclear@0
|
951
|
nuclear@0
|
952 int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
|
nuclear@0
|
953 if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
|
nuclear@0
|
954 v->pcm_returned+=n;
|
nuclear@0
|
955 return(0);
|
nuclear@0
|
956 }
|
nuclear@0
|
957
|
nuclear@0
|
958 /* intended for use with a specific vorbisfile feature; we want access
|
nuclear@0
|
959 to the [usually synthetic/postextrapolated] buffer and lapping at
|
nuclear@0
|
960 the end of a decode cycle, specifically, a half-short-block worth.
|
nuclear@0
|
961 This funtion works like pcmout above, except it will also expose
|
nuclear@0
|
962 this implicit buffer data not normally decoded. */
|
nuclear@0
|
963 int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
|
nuclear@0
|
964 vorbis_info *vi=v->vi;
|
nuclear@0
|
965 codec_setup_info *ci=vi->codec_setup;
|
nuclear@0
|
966 int hs=ci->halfrate_flag;
|
nuclear@0
|
967
|
nuclear@0
|
968 int n=ci->blocksizes[v->W]>>(hs+1);
|
nuclear@0
|
969 int n0=ci->blocksizes[0]>>(hs+1);
|
nuclear@0
|
970 int n1=ci->blocksizes[1]>>(hs+1);
|
nuclear@0
|
971 int i,j;
|
nuclear@0
|
972
|
nuclear@0
|
973 if(v->pcm_returned<0)return 0;
|
nuclear@0
|
974
|
nuclear@0
|
975 /* our returned data ends at pcm_returned; because the synthesis pcm
|
nuclear@0
|
976 buffer is a two-fragment ring, that means our data block may be
|
nuclear@0
|
977 fragmented by buffering, wrapping or a short block not filling
|
nuclear@0
|
978 out a buffer. To simplify things, we unfragment if it's at all
|
nuclear@0
|
979 possibly needed. Otherwise, we'd need to call lapout more than
|
nuclear@0
|
980 once as well as hold additional dsp state. Opt for
|
nuclear@0
|
981 simplicity. */
|
nuclear@0
|
982
|
nuclear@0
|
983 /* centerW was advanced by blockin; it would be the center of the
|
nuclear@0
|
984 *next* block */
|
nuclear@0
|
985 if(v->centerW==n1){
|
nuclear@0
|
986 /* the data buffer wraps; swap the halves */
|
nuclear@0
|
987 /* slow, sure, small */
|
nuclear@0
|
988 for(j=0;j<vi->channels;j++){
|
nuclear@0
|
989 float *p=v->pcm[j];
|
nuclear@0
|
990 for(i=0;i<n1;i++){
|
nuclear@0
|
991 float temp=p[i];
|
nuclear@0
|
992 p[i]=p[i+n1];
|
nuclear@0
|
993 p[i+n1]=temp;
|
nuclear@0
|
994 }
|
nuclear@0
|
995 }
|
nuclear@0
|
996
|
nuclear@0
|
997 v->pcm_current-=n1;
|
nuclear@0
|
998 v->pcm_returned-=n1;
|
nuclear@0
|
999 v->centerW=0;
|
nuclear@0
|
1000 }
|
nuclear@0
|
1001
|
nuclear@0
|
1002 /* solidify buffer into contiguous space */
|
nuclear@0
|
1003 if((v->lW^v->W)==1){
|
nuclear@0
|
1004 /* long/short or short/long */
|
nuclear@0
|
1005 for(j=0;j<vi->channels;j++){
|
nuclear@0
|
1006 float *s=v->pcm[j];
|
nuclear@0
|
1007 float *d=v->pcm[j]+(n1-n0)/2;
|
nuclear@0
|
1008 for(i=(n1+n0)/2-1;i>=0;--i)
|
nuclear@0
|
1009 d[i]=s[i];
|
nuclear@0
|
1010 }
|
nuclear@0
|
1011 v->pcm_returned+=(n1-n0)/2;
|
nuclear@0
|
1012 v->pcm_current+=(n1-n0)/2;
|
nuclear@0
|
1013 }else{
|
nuclear@0
|
1014 if(v->lW==0){
|
nuclear@0
|
1015 /* short/short */
|
nuclear@0
|
1016 for(j=0;j<vi->channels;j++){
|
nuclear@0
|
1017 float *s=v->pcm[j];
|
nuclear@0
|
1018 float *d=v->pcm[j]+n1-n0;
|
nuclear@0
|
1019 for(i=n0-1;i>=0;--i)
|
nuclear@0
|
1020 d[i]=s[i];
|
nuclear@0
|
1021 }
|
nuclear@0
|
1022 v->pcm_returned+=n1-n0;
|
nuclear@0
|
1023 v->pcm_current+=n1-n0;
|
nuclear@0
|
1024 }
|
nuclear@0
|
1025 }
|
nuclear@0
|
1026
|
nuclear@0
|
1027 if(pcm){
|
nuclear@0
|
1028 int i;
|
nuclear@0
|
1029 for(i=0;i<vi->channels;i++)
|
nuclear@0
|
1030 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
|
nuclear@0
|
1031 *pcm=v->pcmret;
|
nuclear@0
|
1032 }
|
nuclear@0
|
1033
|
nuclear@0
|
1034 return(n1+n-v->pcm_returned);
|
nuclear@0
|
1035
|
nuclear@0
|
1036 }
|
nuclear@0
|
1037
|
nuclear@0
|
1038 float *vorbis_window(vorbis_dsp_state *v,int W){
|
nuclear@0
|
1039 vorbis_info *vi=v->vi;
|
nuclear@0
|
1040 codec_setup_info *ci=vi->codec_setup;
|
nuclear@0
|
1041 int hs=ci->halfrate_flag;
|
nuclear@0
|
1042 private_state *b=v->backend_state;
|
nuclear@0
|
1043
|
nuclear@0
|
1044 if(b->window[W]-1<0)return NULL;
|
nuclear@0
|
1045 return _vorbis_window_get(b->window[W]-hs);
|
nuclear@0
|
1046 }
|