00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include "ogg.h"
00022 #include "ivorbiscodec.h"
00023 #include "codec_internal.h"
00024
00025 #include "window.h"
00026 #include "registry.h"
00027 #include "misc.h"
00028
00029 static int ilog(unsigned int v){
00030 int ret=0;
00031 if(v)--v;
00032 while(v){
00033 ret++;
00034 v>>=1;
00035 }
00036 return(ret);
00037 }
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 #ifndef WORD_ALIGN
00080 #define WORD_ALIGN 8
00081 #endif
00082
00083 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
00084 memset(vb,0,sizeof(*vb));
00085 vb->vd=v;
00086 vb->localalloc=0;
00087 vb->localstore=NULL;
00088
00089 return(0);
00090 }
00091
00092 void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
00093 bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
00094 if(bytes+vb->localtop>vb->localalloc){
00095
00096 if(vb->localstore){
00097 struct alloc_chain *link=(struct alloc_chain *)_ogg_malloc(sizeof(*link));
00098 vb->totaluse+=vb->localtop;
00099 link->next=vb->reap;
00100 link->ptr=vb->localstore;
00101 vb->reap=link;
00102 }
00103
00104 vb->localalloc=bytes;
00105 vb->localstore=_ogg_malloc(vb->localalloc);
00106 vb->localtop=0;
00107 }
00108 {
00109 void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
00110 vb->localtop+=bytes;
00111 return ret;
00112 }
00113 }
00114
00115
00116 void _vorbis_block_ripcord(vorbis_block *vb){
00117
00118 struct alloc_chain *reap=vb->reap;
00119 while(reap){
00120 struct alloc_chain *next=reap->next;
00121 _ogg_free(reap->ptr);
00122 memset(reap,0,sizeof(*reap));
00123 _ogg_free(reap);
00124 reap=next;
00125 }
00126
00127 if(vb->totaluse){
00128 vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
00129 vb->localalloc+=vb->totaluse;
00130 vb->totaluse=0;
00131 }
00132
00133
00134 vb->localtop=0;
00135 vb->reap=NULL;
00136 }
00137
00138 int vorbis_block_clear(vorbis_block *vb){
00139 _vorbis_block_ripcord(vb);
00140 if(vb->localstore)_ogg_free(vb->localstore);
00141
00142 memset(vb,0,sizeof(*vb));
00143 return(0);
00144 }
00145
00146 static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){
00147 int i;
00148 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
00149 private_state *b=NULL;
00150
00151 memset(v,0,sizeof(*v));
00152 b=(private_state *)(v->backend_state=_ogg_calloc(1,sizeof(*b)));
00153
00154 v->vi=vi;
00155 b->modebits=ilog(ci->modes);
00156
00157
00158 b->window[0]=_vorbis_window(0,ci->blocksizes[0]/2);
00159 b->window[1]=_vorbis_window(0,ci->blocksizes[1]/2);
00160
00161
00162 if(!ci->fullbooks){
00163 ci->fullbooks=(codebook *)_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
00164 for(i=0;i<ci->books;i++){
00165 vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]);
00166
00167 vorbis_staticbook_destroy(ci->book_param[i]);
00168 ci->book_param[i]=NULL;
00169 }
00170 }
00171
00172 v->pcm_storage=ci->blocksizes[1];
00173 v->pcm=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcm));
00174 v->pcmret=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcmret));
00175 for(i=0;i<vi->channels;i++)
00176 v->pcm[i]=(ogg_int32_t *)_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
00177
00178
00179
00180 v->lW=0;
00181 v->W=0;
00182
00183
00184 b->mode=(vorbis_look_mapping **)_ogg_calloc(ci->modes,sizeof(*b->mode));
00185 for(i=0;i<ci->modes;i++){
00186 int mapnum=ci->mode_param[i]->mapping;
00187 int maptype=ci->map_type[mapnum];
00188 b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i],
00189 ci->map_param[mapnum]);
00190 }
00191 return(0);
00192 }
00193
00194 int vorbis_synthesis_restart(vorbis_dsp_state *v){
00195 vorbis_info *vi=v->vi;
00196 codec_setup_info *ci;
00197
00198 if(!v->backend_state)return -1;
00199 if(!vi)return -1;
00200 ci=(codec_setup_info*)vi->codec_setup;
00201 if(!ci)return -1;
00202
00203 v->centerW=ci->blocksizes[1]/2;
00204 v->pcm_current=v->centerW;
00205
00206 v->pcm_returned=-1;
00207 v->granulepos=-1;
00208 v->sequence=-1;
00209 ((private_state *)(v->backend_state))->sample_count=-1;
00210
00211 return(0);
00212 }
00213
00214 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
00215 _vds_init(v,vi);
00216 vorbis_synthesis_restart(v);
00217
00218 return(0);
00219 }
00220
00221 void vorbis_dsp_clear(vorbis_dsp_state *v){
00222 int i;
00223 if(v){
00224 vorbis_info *vi=v->vi;
00225 codec_setup_info *ci=(codec_setup_info *)(vi?vi->codec_setup:NULL);
00226 private_state *b=(private_state *)v->backend_state;
00227
00228 if(v->pcm){
00229 for(i=0;i<vi->channels;i++)
00230 if(v->pcm[i])_ogg_free(v->pcm[i]);
00231 _ogg_free(v->pcm);
00232 if(v->pcmret)_ogg_free(v->pcmret);
00233 }
00234
00235
00236 if(ci){
00237 for(i=0;i<ci->modes;i++){
00238 int mapnum=ci->mode_param[i]->mapping;
00239 int maptype=ci->map_type[mapnum];
00240 if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]);
00241 }
00242 }
00243
00244 if(b){
00245 if(b->mode)_ogg_free(b->mode);
00246 _ogg_free(b);
00247 }
00248
00249 memset(v,0,sizeof(*v));
00250 }
00251 }
00252
00253
00254
00255
00256
00257 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
00258 vorbis_info *vi=v->vi;
00259 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
00260 private_state *b=(private_state*)v->backend_state;
00261 int i,j;
00262
00263 if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
00264
00265 v->lW=v->W;
00266 v->W=vb->W;
00267 v->nW=-1;
00268
00269 if((v->sequence==-1)||
00270 (v->sequence+1 != vb->sequence)){
00271 v->granulepos=-1;
00272 b->sample_count=-1;
00273 }
00274
00275 v->sequence=vb->sequence;
00276
00277 if(vb->pcm){
00278
00279 int n=ci->blocksizes[v->W]/2;
00280 int n0=ci->blocksizes[0]/2;
00281 int n1=ci->blocksizes[1]/2;
00282
00283 int thisCenter;
00284 int prevCenter;
00285
00286 if(v->centerW){
00287 thisCenter=n1;
00288 prevCenter=0;
00289 }else{
00290 thisCenter=0;
00291 prevCenter=n1;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300 for(j=0;j<vi->channels;j++){
00301
00302 if(v->lW){
00303 if(v->W){
00304
00305 ogg_int32_t *pcm=v->pcm[j]+prevCenter;
00306 ogg_int32_t *p=vb->pcm[j];
00307 for(i=0;i<n1;i++)
00308 pcm[i]+=p[i];
00309 }else{
00310
00311 ogg_int32_t *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
00312 ogg_int32_t *p=vb->pcm[j];
00313 for(i=0;i<n0;i++)
00314 pcm[i]+=p[i];
00315 }
00316 }else{
00317 if(v->W){
00318
00319 ogg_int32_t *pcm=v->pcm[j]+prevCenter;
00320 ogg_int32_t *p=vb->pcm[j]+n1/2-n0/2;
00321 for(i=0;i<n0;i++)
00322 pcm[i]+=p[i];
00323 for(;i<n1/2+n0/2;i++)
00324 pcm[i]=p[i];
00325 }else{
00326
00327 ogg_int32_t *pcm=v->pcm[j]+prevCenter;
00328 ogg_int32_t *p=vb->pcm[j];
00329 for(i=0;i<n0;i++)
00330 pcm[i]+=p[i];
00331 }
00332 }
00333
00334
00335 {
00336 ogg_int32_t *pcm=v->pcm[j]+thisCenter;
00337 ogg_int32_t *p=vb->pcm[j]+n;
00338 for(i=0;i<n;i++)
00339 pcm[i]=p[i];
00340 }
00341 }
00342
00343 if(v->centerW)
00344 v->centerW=0;
00345 else
00346 v->centerW=n1;
00347
00348
00349
00350
00351
00352 if(v->pcm_returned==-1){
00353 v->pcm_returned=thisCenter;
00354 v->pcm_current=thisCenter;
00355 }else{
00356 v->pcm_returned=prevCenter;
00357 v->pcm_current=prevCenter+
00358 ci->blocksizes[v->lW]/4+
00359 ci->blocksizes[v->W]/4;
00360 }
00361
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375 if(b->sample_count==-1){
00376 b->sample_count=0;
00377 }else{
00378 b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
00379 }
00380
00381 if(v->granulepos==-1){
00382 if(vb->granulepos!=-1){
00383
00384 v->granulepos=vb->granulepos;
00385
00386
00387 if(b->sample_count>v->granulepos){
00388
00389
00390 if(vb->eofflag){
00391
00392
00393
00394
00395
00396
00397 v->pcm_current-=(b->sample_count-v->granulepos);
00398 }else{
00399
00400 v->pcm_returned+=(b->sample_count-v->granulepos);
00401 if(v->pcm_returned>v->pcm_current)
00402 v->pcm_returned=v->pcm_current;
00403 }
00404
00405 }
00406
00407 }
00408 }else{
00409 v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
00410 if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
00411
00412 if(v->granulepos>vb->granulepos){
00413 long extra=v->granulepos-vb->granulepos;
00414
00415 if(extra)
00416 if(vb->eofflag){
00417
00418 v->pcm_current-=extra;
00419 }
00420
00421 }
00422
00423 v->granulepos=vb->granulepos;
00424 }
00425 }
00426
00427
00428
00429 if(vb->eofflag)v->eofflag=1;
00430 return(0);
00431 }
00432
00433
00434 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,ogg_int32_t ***pcm){
00435 vorbis_info *vi=v->vi;
00436 if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
00437 if(pcm){
00438 int i;
00439 for(i=0;i<vi->channels;i++)
00440 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
00441 *pcm=v->pcmret;
00442 }
00443 return(v->pcm_current-v->pcm_returned);
00444 }
00445 return(0);
00446 }
00447
00448 int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){
00449 if(bytes && v->pcm_returned+bytes>v->pcm_current)return(OV_EINVAL);
00450 v->pcm_returned+=bytes;
00451 return(0);
00452 }
00453