mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-19 09:01:15 +02:00
Update libvorbis to 1.3.3.
This commit is contained in:
@@ -5,17 +5,17 @@
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: PCM data vector blocking, windowing and dis/reassembly
|
||||
last mod: $Id: block.c,v 1.8 2008-02-02 15:53:51 richardash1981 Exp $
|
||||
last mod: $Id: block.c 17561 2010-10-23 10:34:24Z xiphmont $
|
||||
|
||||
Handle windowing, overlap-add, etc of the PCM vectors. This is made
|
||||
more amusing by Vorbis' current two allowed block sizes.
|
||||
|
||||
|
||||
********************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -50,33 +50,33 @@ static int ilog2(unsigned int v){
|
||||
:.....''' |_____--- '''......| | \_______|
|
||||
:.................|__________________|_______|__|______|
|
||||
|<------ Sl ------>| > Sr < |endW
|
||||
|beginSl |endSl | |endSr
|
||||
|beginSl |endSl | |endSr
|
||||
|beginW |endlW |beginSr
|
||||
|
||||
|
||||
|< lW >|
|
||||
|< lW >|
|
||||
<--------------- W ---------------->
|
||||
| | .. ______________ |
|
||||
| | ' `/ | ---_ |
|
||||
|___.'___/`. | ---_____|
|
||||
|___.'___/`. | ---_____|
|
||||
|_______|__|_______|_________________|
|
||||
| >|Sl|< |<------ Sr ----->|endW
|
||||
| | |endSl |beginSr |endSr
|
||||
|beginW | |endlW
|
||||
|beginW | |endlW
|
||||
mult[0] |beginSl mult[n]
|
||||
|
||||
<-------------- lW ----------------->
|
||||
|<--W-->|
|
||||
: .............. ___ | |
|
||||
: .''' |`/ \ | |
|
||||
:.....''' |/`....\|...|
|
||||
:.........................|___|___|___|
|
||||
|Sl |Sr |endW
|
||||
|<--W-->|
|
||||
: .............. ___ | |
|
||||
: .''' |`/ \ | |
|
||||
:.....''' |/`....\|...|
|
||||
:.........................|___|___|___|
|
||||
|Sl |Sr |endW
|
||||
| | |endSr
|
||||
| |beginSr
|
||||
| |endSl
|
||||
|beginSl
|
||||
|beginW
|
||||
|beginSl
|
||||
|beginW
|
||||
*/
|
||||
|
||||
/* block abstraction setup *********************************************/
|
||||
@@ -98,13 +98,13 @@ int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
|
||||
|
||||
for(i=0;i<PACKETBLOBS;i++){
|
||||
if(i==PACKETBLOBS/2){
|
||||
vbi->packetblob[i]=&vb->opb;
|
||||
vbi->packetblob[i]=&vb->opb;
|
||||
}else{
|
||||
vbi->packetblob[i]=
|
||||
_ogg_calloc(1,sizeof(oggpack_buffer));
|
||||
vbi->packetblob[i]=
|
||||
_ogg_calloc(1,sizeof(oggpack_buffer));
|
||||
}
|
||||
oggpack_writeinit(vbi->packetblob[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
@@ -185,7 +185,7 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
|
||||
int hs;
|
||||
|
||||
if(ci==NULL) return 1;
|
||||
hs=ci->halfrate_flag;
|
||||
hs=ci->halfrate_flag;
|
||||
|
||||
memset(v,0,sizeof(*v));
|
||||
b=v->backend_state=_ogg_calloc(1,sizeof(*b));
|
||||
@@ -217,16 +217,16 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
|
||||
if(!ci->fullbooks){
|
||||
ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
|
||||
for(i=0;i<ci->books;i++)
|
||||
vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
|
||||
vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
|
||||
}
|
||||
|
||||
b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy));
|
||||
for(i=0;i<ci->psys;i++){
|
||||
_vp_psy_init(b->psy+i,
|
||||
ci->psy_param[i],
|
||||
&ci->psy_g_param,
|
||||
ci->blocksizes[ci->psy_param[i]->blockflag]/2,
|
||||
vi->rate);
|
||||
ci->psy_param[i],
|
||||
&ci->psy_g_param,
|
||||
ci->blocksizes[ci->psy_param[i]->blockflag]/2,
|
||||
vi->rate);
|
||||
}
|
||||
|
||||
v->analysisp=1;
|
||||
@@ -235,10 +235,13 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
|
||||
if(!ci->fullbooks){
|
||||
ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
|
||||
for(i=0;i<ci->books;i++){
|
||||
vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]);
|
||||
/* decode codebooks are now standalone after init */
|
||||
vorbis_staticbook_destroy(ci->book_param[i]);
|
||||
ci->book_param[i]=NULL;
|
||||
if(ci->book_param[i]==NULL)
|
||||
goto abort_books;
|
||||
if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]))
|
||||
goto abort_books;
|
||||
/* decode codebooks are now standalone after init */
|
||||
vorbis_staticbook_destroy(ci->book_param[i]);
|
||||
ci->book_param[i]=NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -274,9 +277,18 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
|
||||
|
||||
for(i=0;i<ci->residues;i++)
|
||||
b->residue[i]=_residue_P[ci->residue_type[i]]->
|
||||
look(v,ci->residue_param[i]);
|
||||
look(v,ci->residue_param[i]);
|
||||
|
||||
return 0;
|
||||
abort_books:
|
||||
for(i=0;i<ci->books;i++){
|
||||
if(ci->book_param[i]!=NULL){
|
||||
vorbis_staticbook_destroy(ci->book_param[i]);
|
||||
ci->book_param[i]=NULL;
|
||||
}
|
||||
}
|
||||
vorbis_dsp_clear(v);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* arbitrary settings and spec-mandated numbers get filled in here */
|
||||
@@ -308,42 +320,42 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){
|
||||
private_state *b=v->backend_state;
|
||||
|
||||
if(b){
|
||||
|
||||
|
||||
if(b->ve){
|
||||
_ve_envelope_clear(b->ve);
|
||||
_ogg_free(b->ve);
|
||||
_ve_envelope_clear(b->ve);
|
||||
_ogg_free(b->ve);
|
||||
}
|
||||
|
||||
if(b->transform[0]){
|
||||
mdct_clear(b->transform[0][0]);
|
||||
_ogg_free(b->transform[0][0]);
|
||||
_ogg_free(b->transform[0]);
|
||||
mdct_clear(b->transform[0][0]);
|
||||
_ogg_free(b->transform[0][0]);
|
||||
_ogg_free(b->transform[0]);
|
||||
}
|
||||
if(b->transform[1]){
|
||||
mdct_clear(b->transform[1][0]);
|
||||
_ogg_free(b->transform[1][0]);
|
||||
_ogg_free(b->transform[1]);
|
||||
mdct_clear(b->transform[1][0]);
|
||||
_ogg_free(b->transform[1][0]);
|
||||
_ogg_free(b->transform[1]);
|
||||
}
|
||||
|
||||
if(b->flr){
|
||||
if(ci)
|
||||
for(i=0;i<ci->floors;i++)
|
||||
_floor_P[ci->floor_type[i]]->
|
||||
free_look(b->flr[i]);
|
||||
_ogg_free(b->flr);
|
||||
if(ci)
|
||||
for(i=0;i<ci->floors;i++)
|
||||
_floor_P[ci->floor_type[i]]->
|
||||
free_look(b->flr[i]);
|
||||
_ogg_free(b->flr);
|
||||
}
|
||||
if(b->residue){
|
||||
if(ci)
|
||||
for(i=0;i<ci->residues;i++)
|
||||
_residue_P[ci->residue_type[i]]->
|
||||
free_look(b->residue[i]);
|
||||
_ogg_free(b->residue);
|
||||
if(ci)
|
||||
for(i=0;i<ci->residues;i++)
|
||||
_residue_P[ci->residue_type[i]]->
|
||||
free_look(b->residue[i]);
|
||||
_ogg_free(b->residue);
|
||||
}
|
||||
if(b->psy){
|
||||
if(ci)
|
||||
for(i=0;i<ci->psys;i++)
|
||||
_vp_psy_clear(b->psy+i);
|
||||
_ogg_free(b->psy);
|
||||
if(ci)
|
||||
for(i=0;i<ci->psys;i++)
|
||||
_vp_psy_clear(b->psy+i);
|
||||
_ogg_free(b->psy);
|
||||
}
|
||||
|
||||
if(b->psy_g_look)_vp_global_free(b->psy_g_look);
|
||||
@@ -353,11 +365,11 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){
|
||||
drft_clear(&b->fft_look[1]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(v->pcm){
|
||||
if(vi)
|
||||
for(i=0;i<vi->channels;i++)
|
||||
if(v->pcm[i])_ogg_free(v->pcm[i]);
|
||||
for(i=0;i<vi->channels;i++)
|
||||
if(v->pcm[i])_ogg_free(v->pcm[i]);
|
||||
_ogg_free(v->pcm);
|
||||
if(v->pcmret)_ogg_free(v->pcmret);
|
||||
}
|
||||
@@ -369,7 +381,7 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){
|
||||
if(b->header2)_ogg_free(b->header2);
|
||||
_ogg_free(b);
|
||||
}
|
||||
|
||||
|
||||
memset(v,0,sizeof(*v));
|
||||
}
|
||||
}
|
||||
@@ -386,10 +398,10 @@ float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
|
||||
|
||||
/* Do we have enough storage space for the requested buffer? If not,
|
||||
expand the PCM (and envelope) storage */
|
||||
|
||||
|
||||
if(v->pcm_current+vals>=v->pcm_storage){
|
||||
v->pcm_storage=v->pcm_current+vals*2;
|
||||
|
||||
|
||||
for(i=0;i<vi->channels;i++){
|
||||
v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
|
||||
}
|
||||
@@ -397,13 +409,13 @@ float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
|
||||
|
||||
for(i=0;i<vi->channels;i++)
|
||||
v->pcmret[i]=v->pcm[i]+v->pcm_current;
|
||||
|
||||
|
||||
return(v->pcmret);
|
||||
}
|
||||
|
||||
static void _preextrapolate_helper(vorbis_dsp_state *v){
|
||||
int i;
|
||||
int order=32;
|
||||
int order=16;
|
||||
float *lpc=alloca(order*sizeof(*lpc));
|
||||
float *work=alloca(v->pcm_current*sizeof(*work));
|
||||
long j;
|
||||
@@ -413,19 +425,30 @@ static void _preextrapolate_helper(vorbis_dsp_state *v){
|
||||
for(i=0;i<v->vi->channels;i++){
|
||||
/* need to run the extrapolation in reverse! */
|
||||
for(j=0;j<v->pcm_current;j++)
|
||||
work[j]=v->pcm[i][v->pcm_current-j-1];
|
||||
|
||||
work[j]=v->pcm[i][v->pcm_current-j-1];
|
||||
|
||||
/* prime as above */
|
||||
vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
|
||||
|
||||
|
||||
#if 0
|
||||
if(v->vi->channels==2){
|
||||
if(i==0)
|
||||
_analysis_output("predataL",0,work,v->pcm_current-v->centerW,0,0,0);
|
||||
else
|
||||
_analysis_output("predataR",0,work,v->pcm_current-v->centerW,0,0,0);
|
||||
}else{
|
||||
_analysis_output("predata",0,work,v->pcm_current-v->centerW,0,0,0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* run the predictor filter */
|
||||
vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
|
||||
order,
|
||||
work+v->pcm_current-v->centerW,
|
||||
v->centerW);
|
||||
order,
|
||||
work+v->pcm_current-v->centerW,
|
||||
v->centerW);
|
||||
|
||||
for(j=0;j<v->pcm_current;j++)
|
||||
v->pcm[i][v->pcm_current-j-1]=work[j];
|
||||
v->pcm[i][v->pcm_current-j-1]=work[j];
|
||||
|
||||
}
|
||||
}
|
||||
@@ -453,29 +476,29 @@ int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
|
||||
amplitude off a cliff, creating spread spectrum noise that will
|
||||
suck to encode. Extrapolate for the sake of cleanliness. */
|
||||
|
||||
vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
|
||||
vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
|
||||
v->eofflag=v->pcm_current;
|
||||
v->pcm_current+=ci->blocksizes[1]*3;
|
||||
|
||||
for(i=0;i<vi->channels;i++){
|
||||
if(v->eofflag>order*2){
|
||||
/* extrapolate with LPC to fill in */
|
||||
long n;
|
||||
/* extrapolate with LPC to fill in */
|
||||
long n;
|
||||
|
||||
/* make a predictor filter */
|
||||
n=v->eofflag;
|
||||
if(n>ci->blocksizes[1])n=ci->blocksizes[1];
|
||||
vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
|
||||
/* make a predictor filter */
|
||||
n=v->eofflag;
|
||||
if(n>ci->blocksizes[1])n=ci->blocksizes[1];
|
||||
vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
|
||||
|
||||
/* run the predictor filter */
|
||||
vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
|
||||
v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
|
||||
/* run the predictor filter */
|
||||
vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
|
||||
v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
|
||||
}else{
|
||||
/* not enough data to extrapolate (unlikely to happen due to
|
||||
/* not enough data to extrapolate (unlikely to happen due to
|
||||
guarding the overlap, but bulletproof in case that
|
||||
assumtion goes away). zeroes will do. */
|
||||
memset(v->pcm[i]+v->eofflag,0,
|
||||
(v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
|
||||
memset(v->pcm[i]+v->eofflag,0,
|
||||
(v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -520,19 +543,19 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
|
||||
/* we do an envelope search even on a single blocksize; we may still
|
||||
be throwing more bits at impulses, and envelope search handles
|
||||
marking impulses too. */
|
||||
{
|
||||
{
|
||||
long bp=_ve_envelope_search(v);
|
||||
if(bp==-1){
|
||||
|
||||
if(v->eofflag==0)return(0); /* not enough data currently to search for a
|
||||
full long block */
|
||||
full long block */
|
||||
v->nW=0;
|
||||
}else{
|
||||
|
||||
if(ci->blocksizes[0]==ci->blocksizes[1])
|
||||
v->nW=0;
|
||||
v->nW=0;
|
||||
else
|
||||
v->nW=bp;
|
||||
v->nW=bp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,7 +575,7 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* fill in the block. Note that for a short window, lW and nW are *short*
|
||||
regardless of actual settings in the stream */
|
||||
|
||||
@@ -580,12 +603,12 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vb->vd=v;
|
||||
vb->sequence=v->sequence++;
|
||||
vb->granulepos=v->granulepos;
|
||||
vb->pcmend=ci->blocksizes[v->W];
|
||||
|
||||
|
||||
/* copy the vectors; this uses the local storage in vb */
|
||||
|
||||
/* this tracks 'strongest peak' for later psychoacoustics */
|
||||
@@ -593,7 +616,7 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
|
||||
if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
|
||||
g->ampmax=_vp_ampmax_decay(g->ampmax,v);
|
||||
vbi->ampmax=g->ampmax;
|
||||
|
||||
|
||||
vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
|
||||
vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
|
||||
for(i=0;i<vi->channels;i++){
|
||||
@@ -601,14 +624,14 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
|
||||
_vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
|
||||
memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
|
||||
vb->pcm[i]=vbi->pcmdelay[i]+beginW;
|
||||
|
||||
/* before we added the delay
|
||||
|
||||
/* before we added the delay
|
||||
vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
|
||||
memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* handle eof detection: eof==0 means that we've not yet received EOF
|
||||
eof>0 marks the last 'real' sample in pcm[]
|
||||
eof<0 'no more to do'; doesn't get here */
|
||||
@@ -630,27 +653,27 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
|
||||
|
||||
_ve_envelope_shift(b->ve,movementW);
|
||||
v->pcm_current-=movementW;
|
||||
|
||||
|
||||
for(i=0;i<vi->channels;i++)
|
||||
memmove(v->pcm[i],v->pcm[i]+movementW,
|
||||
v->pcm_current*sizeof(*v->pcm[i]));
|
||||
|
||||
|
||||
memmove(v->pcm[i],v->pcm[i]+movementW,
|
||||
v->pcm_current*sizeof(*v->pcm[i]));
|
||||
|
||||
|
||||
v->lW=v->W;
|
||||
v->W=v->nW;
|
||||
v->centerW=new_centerNext;
|
||||
|
||||
|
||||
if(v->eofflag){
|
||||
v->eofflag-=movementW;
|
||||
if(v->eofflag<=0)v->eofflag=-1;
|
||||
/* do not add padding to end of stream! */
|
||||
if(v->centerW>=v->eofflag){
|
||||
v->granulepos+=movementW-(v->centerW-v->eofflag);
|
||||
}else{
|
||||
v->granulepos+=movementW;
|
||||
}
|
||||
v->eofflag-=movementW;
|
||||
if(v->eofflag<=0)v->eofflag=-1;
|
||||
/* do not add padding to end of stream! */
|
||||
if(v->centerW>=v->eofflag){
|
||||
v->granulepos+=movementW-(v->centerW-v->eofflag);
|
||||
}else{
|
||||
v->granulepos+=movementW;
|
||||
}
|
||||
}else{
|
||||
v->granulepos+=movementW;
|
||||
v->granulepos+=movementW;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -668,11 +691,11 @@ int vorbis_synthesis_restart(vorbis_dsp_state *v){
|
||||
if(!vi)return -1;
|
||||
ci=vi->codec_setup;
|
||||
if(!ci)return -1;
|
||||
hs=ci->halfrate_flag;
|
||||
hs=ci->halfrate_flag;
|
||||
|
||||
v->centerW=ci->blocksizes[1]>>(hs+1);
|
||||
v->pcm_current=v->centerW>>hs;
|
||||
|
||||
|
||||
v->pcm_returned=-1;
|
||||
v->granulepos=-1;
|
||||
v->sequence=-1;
|
||||
@@ -683,9 +706,11 @@ int vorbis_synthesis_restart(vorbis_dsp_state *v){
|
||||
}
|
||||
|
||||
int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
|
||||
if(_vds_shared_init(v,vi,0)) return 1;
|
||||
if(_vds_shared_init(v,vi,0)){
|
||||
vorbis_dsp_clear(v);
|
||||
return 1;
|
||||
}
|
||||
vorbis_synthesis_restart(v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -697,16 +722,16 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
|
||||
vorbis_info *vi=v->vi;
|
||||
codec_setup_info *ci=vi->codec_setup;
|
||||
private_state *b=v->backend_state;
|
||||
int hs=ci->halfrate_flag;
|
||||
int hs=ci->halfrate_flag;
|
||||
int i,j;
|
||||
|
||||
if(!vb)return(OV_EINVAL);
|
||||
if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
|
||||
|
||||
|
||||
v->lW=v->W;
|
||||
v->W=vb->W;
|
||||
v->nW=-1;
|
||||
|
||||
|
||||
if((v->sequence==-1)||
|
||||
(v->sequence+1 != vb->sequence)){
|
||||
v->granulepos=-1; /* out of sequence; lose count */
|
||||
@@ -714,21 +739,21 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
|
||||
}
|
||||
|
||||
v->sequence=vb->sequence;
|
||||
|
||||
if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
|
||||
was called on block */
|
||||
|
||||
if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
|
||||
was called on block */
|
||||
int n=ci->blocksizes[v->W]>>(hs+1);
|
||||
int n0=ci->blocksizes[0]>>(hs+1);
|
||||
int n1=ci->blocksizes[1]>>(hs+1);
|
||||
|
||||
int thisCenter;
|
||||
int prevCenter;
|
||||
|
||||
|
||||
v->glue_bits+=vb->glue_bits;
|
||||
v->time_bits+=vb->time_bits;
|
||||
v->floor_bits+=vb->floor_bits;
|
||||
v->res_bits+=vb->res_bits;
|
||||
|
||||
|
||||
if(v->centerW){
|
||||
thisCenter=n1;
|
||||
prevCenter=0;
|
||||
@@ -736,84 +761,84 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
|
||||
thisCenter=0;
|
||||
prevCenter=n1;
|
||||
}
|
||||
|
||||
|
||||
/* v->pcm is now used like a two-stage double buffer. We don't want
|
||||
to have to constantly shift *or* adjust memory usage. Don't
|
||||
accept a new block until the old is shifted out */
|
||||
|
||||
|
||||
for(j=0;j<vi->channels;j++){
|
||||
/* the overlap/add section */
|
||||
if(v->lW){
|
||||
if(v->W){
|
||||
/* large/large */
|
||||
float *w=_vorbis_window_get(b->window[1]-hs);
|
||||
float *pcm=v->pcm[j]+prevCenter;
|
||||
float *p=vb->pcm[j];
|
||||
for(i=0;i<n1;i++)
|
||||
pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
|
||||
}else{
|
||||
/* large/small */
|
||||
float *w=_vorbis_window_get(b->window[0]-hs);
|
||||
float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
|
||||
float *p=vb->pcm[j];
|
||||
for(i=0;i<n0;i++)
|
||||
pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
|
||||
}
|
||||
if(v->W){
|
||||
/* large/large */
|
||||
float *w=_vorbis_window_get(b->window[1]-hs);
|
||||
float *pcm=v->pcm[j]+prevCenter;
|
||||
float *p=vb->pcm[j];
|
||||
for(i=0;i<n1;i++)
|
||||
pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
|
||||
}else{
|
||||
/* large/small */
|
||||
float *w=_vorbis_window_get(b->window[0]-hs);
|
||||
float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
|
||||
float *p=vb->pcm[j];
|
||||
for(i=0;i<n0;i++)
|
||||
pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
|
||||
}
|
||||
}else{
|
||||
if(v->W){
|
||||
/* small/large */
|
||||
float *w=_vorbis_window_get(b->window[0]-hs);
|
||||
float *pcm=v->pcm[j]+prevCenter;
|
||||
float *p=vb->pcm[j]+n1/2-n0/2;
|
||||
for(i=0;i<n0;i++)
|
||||
pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
|
||||
for(;i<n1/2+n0/2;i++)
|
||||
pcm[i]=p[i];
|
||||
}else{
|
||||
/* small/small */
|
||||
float *w=_vorbis_window_get(b->window[0]-hs);
|
||||
float *pcm=v->pcm[j]+prevCenter;
|
||||
float *p=vb->pcm[j];
|
||||
for(i=0;i<n0;i++)
|
||||
pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
|
||||
}
|
||||
if(v->W){
|
||||
/* small/large */
|
||||
float *w=_vorbis_window_get(b->window[0]-hs);
|
||||
float *pcm=v->pcm[j]+prevCenter;
|
||||
float *p=vb->pcm[j]+n1/2-n0/2;
|
||||
for(i=0;i<n0;i++)
|
||||
pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
|
||||
for(;i<n1/2+n0/2;i++)
|
||||
pcm[i]=p[i];
|
||||
}else{
|
||||
/* small/small */
|
||||
float *w=_vorbis_window_get(b->window[0]-hs);
|
||||
float *pcm=v->pcm[j]+prevCenter;
|
||||
float *p=vb->pcm[j];
|
||||
for(i=0;i<n0;i++)
|
||||
pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* the copy section */
|
||||
{
|
||||
float *pcm=v->pcm[j]+thisCenter;
|
||||
float *p=vb->pcm[j]+n;
|
||||
for(i=0;i<n;i++)
|
||||
pcm[i]=p[i];
|
||||
float *pcm=v->pcm[j]+thisCenter;
|
||||
float *p=vb->pcm[j]+n;
|
||||
for(i=0;i<n;i++)
|
||||
pcm[i]=p[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(v->centerW)
|
||||
v->centerW=0;
|
||||
else
|
||||
v->centerW=n1;
|
||||
|
||||
|
||||
/* deal with initial packet state; we do this using the explicit
|
||||
pcm_returned==-1 flag otherwise we're sensitive to first block
|
||||
being short or long */
|
||||
|
||||
|
||||
if(v->pcm_returned==-1){
|
||||
v->pcm_returned=thisCenter;
|
||||
v->pcm_current=thisCenter;
|
||||
}else{
|
||||
v->pcm_returned=prevCenter;
|
||||
v->pcm_current=prevCenter+
|
||||
((ci->blocksizes[v->lW]/4+
|
||||
ci->blocksizes[v->W]/4)>>hs);
|
||||
((ci->blocksizes[v->lW]/4+
|
||||
ci->blocksizes[v->W]/4)>>hs);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* track the frame number... This is for convenience, but also
|
||||
making sure our last packet doesn't end with added padding. If
|
||||
the last packet is partial, the number of samples we'll have to
|
||||
return will be past the vb->granulepos.
|
||||
|
||||
|
||||
This is not foolproof! It will be confused if we begin
|
||||
decoding at the last page after a seek or hole. In that case,
|
||||
we don't have a starting point to judge where the last frame
|
||||
@@ -825,7 +850,7 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
|
||||
}else{
|
||||
b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
|
||||
}
|
||||
|
||||
|
||||
if(v->granulepos==-1){
|
||||
if(vb->granulepos!=-1){ /* only set if we have a position to set to */
|
||||
|
||||
@@ -833,22 +858,37 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
|
||||
|
||||
/* is this a short page? */
|
||||
if(b->sample_count>v->granulepos){
|
||||
/* corner case; if this is both the first and last audio page,
|
||||
then spec says the end is cut, not beginning */
|
||||
if(vb->eofflag){
|
||||
/* trim the end */
|
||||
/* no preceeding granulepos; assume we started at zero (we'd
|
||||
have to in a short single-page stream) */
|
||||
/* granulepos could be -1 due to a seek, but that would result
|
||||
in a long count, not short count */
|
||||
|
||||
v->pcm_current-=(b->sample_count-v->granulepos)>>hs;
|
||||
}else{
|
||||
/* trim the beginning */
|
||||
v->pcm_returned+=(b->sample_count-v->granulepos)>>hs;
|
||||
if(v->pcm_returned>v->pcm_current)
|
||||
v->pcm_returned=v->pcm_current;
|
||||
}
|
||||
/* corner case; if this is both the first and last audio page,
|
||||
then spec says the end is cut, not beginning */
|
||||
long extra=b->sample_count-vb->granulepos;
|
||||
|
||||
/* we use ogg_int64_t for granule positions because a
|
||||
uint64 isn't universally available. Unfortunately,
|
||||
that means granposes can be 'negative' and result in
|
||||
extra being negative */
|
||||
if(extra<0)
|
||||
extra=0;
|
||||
|
||||
if(vb->eofflag){
|
||||
/* trim the end */
|
||||
/* no preceding granulepos; assume we started at zero (we'd
|
||||
have to in a short single-page stream) */
|
||||
/* granulepos could be -1 due to a seek, but that would result
|
||||
in a long count, not short count */
|
||||
|
||||
/* Guard against corrupt/malicious frames that set EOP and
|
||||
a backdated granpos; don't rewind more samples than we
|
||||
actually have */
|
||||
if(extra > (v->pcm_current - v->pcm_returned)<<hs)
|
||||
extra = (v->pcm_current - v->pcm_returned)<<hs;
|
||||
|
||||
v->pcm_current-=extra>>hs;
|
||||
}else{
|
||||
/* trim the beginning */
|
||||
v->pcm_returned+=extra>>hs;
|
||||
if(v->pcm_returned>v->pcm_current)
|
||||
v->pcm_returned=v->pcm_current;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -856,27 +896,41 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
|
||||
}else{
|
||||
v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
|
||||
if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
|
||||
|
||||
if(v->granulepos>vb->granulepos){
|
||||
long extra=v->granulepos-vb->granulepos;
|
||||
|
||||
if(extra)
|
||||
if(vb->eofflag){
|
||||
/* partial last frame. Strip the extra samples off */
|
||||
v->pcm_current-=extra>>hs;
|
||||
} /* else {Shouldn't happen *unless* the bitstream is out of
|
||||
spec. Either way, believe the bitstream } */
|
||||
if(v->granulepos>vb->granulepos){
|
||||
long extra=v->granulepos-vb->granulepos;
|
||||
|
||||
if(extra)
|
||||
if(vb->eofflag){
|
||||
/* partial last frame. Strip the extra samples off */
|
||||
|
||||
/* Guard against corrupt/malicious frames that set EOP and
|
||||
a backdated granpos; don't rewind more samples than we
|
||||
actually have */
|
||||
if(extra > (v->pcm_current - v->pcm_returned)<<hs)
|
||||
extra = (v->pcm_current - v->pcm_returned)<<hs;
|
||||
|
||||
/* we use ogg_int64_t for granule positions because a
|
||||
uint64 isn't universally available. Unfortunately,
|
||||
that means granposes can be 'negative' and result in
|
||||
extra being negative */
|
||||
if(extra<0)
|
||||
extra=0;
|
||||
|
||||
v->pcm_current-=extra>>hs;
|
||||
} /* else {Shouldn't happen *unless* the bitstream is out of
|
||||
spec. Either way, believe the bitstream } */
|
||||
} /* else {Shouldn't happen *unless* the bitstream is out of
|
||||
spec. Either way, believe the bitstream } */
|
||||
spec. Either way, believe the bitstream } */
|
||||
v->granulepos=vb->granulepos;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Update, cleanup */
|
||||
|
||||
|
||||
if(vb->eofflag)v->eofflag=1;
|
||||
return(0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* pcm==NULL indicates we just want the pending samples, no more */
|
||||
@@ -887,7 +941,7 @@ int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
|
||||
if(pcm){
|
||||
int i;
|
||||
for(i=0;i<vi->channels;i++)
|
||||
v->pcmret[i]=v->pcm[i]+v->pcm_returned;
|
||||
v->pcmret[i]=v->pcm[i]+v->pcm_returned;
|
||||
*pcm=v->pcmret;
|
||||
}
|
||||
return(v->pcm_current-v->pcm_returned);
|
||||
@@ -909,8 +963,8 @@ int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
|
||||
int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
|
||||
vorbis_info *vi=v->vi;
|
||||
codec_setup_info *ci=vi->codec_setup;
|
||||
int hs=ci->halfrate_flag;
|
||||
|
||||
int hs=ci->halfrate_flag;
|
||||
|
||||
int n=ci->blocksizes[v->W]>>(hs+1);
|
||||
int n0=ci->blocksizes[0]>>(hs+1);
|
||||
int n1=ci->blocksizes[1]>>(hs+1);
|
||||
@@ -934,9 +988,9 @@ int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
|
||||
for(j=0;j<vi->channels;j++){
|
||||
float *p=v->pcm[j];
|
||||
for(i=0;i<n1;i++){
|
||||
float temp=p[i];
|
||||
p[i]=p[i+n1];
|
||||
p[i+n1]=temp;
|
||||
float temp=p[i];
|
||||
p[i]=p[i+n1];
|
||||
p[i+n1]=temp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -944,7 +998,7 @@ int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
|
||||
v->pcm_returned-=n1;
|
||||
v->centerW=0;
|
||||
}
|
||||
|
||||
|
||||
/* solidify buffer into contiguous space */
|
||||
if((v->lW^v->W)==1){
|
||||
/* long/short or short/long */
|
||||
@@ -952,7 +1006,7 @@ int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
|
||||
float *s=v->pcm[j];
|
||||
float *d=v->pcm[j]+(n1-n0)/2;
|
||||
for(i=(n1+n0)/2-1;i>=0;--i)
|
||||
d[i]=s[i];
|
||||
d[i]=s[i];
|
||||
}
|
||||
v->pcm_returned+=(n1-n0)/2;
|
||||
v->pcm_current+=(n1-n0)/2;
|
||||
@@ -960,16 +1014,16 @@ int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
|
||||
if(v->lW==0){
|
||||
/* short/short */
|
||||
for(j=0;j<vi->channels;j++){
|
||||
float *s=v->pcm[j];
|
||||
float *d=v->pcm[j]+n1-n0;
|
||||
for(i=n0-1;i>=0;--i)
|
||||
d[i]=s[i];
|
||||
float *s=v->pcm[j];
|
||||
float *d=v->pcm[j]+n1-n0;
|
||||
for(i=n0-1;i>=0;--i)
|
||||
d[i]=s[i];
|
||||
}
|
||||
v->pcm_returned+=n1-n0;
|
||||
v->pcm_current+=n1-n0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(pcm){
|
||||
int i;
|
||||
for(i=0;i<vi->channels;i++)
|
||||
@@ -984,10 +1038,9 @@ int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
|
||||
float *vorbis_window(vorbis_dsp_state *v,int W){
|
||||
vorbis_info *vi=v->vi;
|
||||
codec_setup_info *ci=vi->codec_setup;
|
||||
int hs=ci->halfrate_flag;
|
||||
int hs=ci->halfrate_flag;
|
||||
private_state *b=v->backend_state;
|
||||
|
||||
if(b->window[W]-1<0)return NULL;
|
||||
return _vorbis_window_get(b->window[W]-hs);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user