diff options
Diffstat (limited to 'lib/envelope.c')
-rw-r--r-- | lib/envelope.c | 112 |
1 files changed, 81 insertions, 31 deletions
diff --git a/lib/envelope.c b/lib/envelope.c index a6545a4b..38b50741 100644 --- a/lib/envelope.c +++ b/lib/envelope.c @@ -11,7 +11,7 @@ ******************************************************************** function: PCM data envelope analysis and manipulation - last mod: $Id: envelope.c,v 1.38 2001/10/02 00:14:30 segher Exp $ + last mod: $Id: envelope.c,v 1.39 2001/12/12 09:45:24 xiphmont Exp $ Preecho calculation. @@ -82,11 +82,10 @@ static float cheb_bandpass1k_A[]={ void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){ codec_setup_info *ci=vi->codec_setup; - vorbis_info_psy_global *gi=ci->psy_g_param; + vorbis_info_psy_global *gi=&ci->psy_g_param; int ch=vi->channels; - int window=gi->envelopesa; + int window=e->winlength=ci->blocksizes[0]/2; /* not random */ int i; - e->winlength=window; e->minenergy=fromdB(gi->preecho_minenergy); e->iir=_ogg_calloc(ch*4,sizeof(*e->iir)); e->filtered=_ogg_calloc(ch*4,sizeof(*e->filtered)); @@ -148,10 +147,10 @@ static float _ve_deltai(envelope_lookup *ve,float *pre,float *post){ return(B-A); } -long _ve_envelope_search(vorbis_dsp_state *v,long searchpoint){ +long _ve_envelope_search(vorbis_dsp_state *v){ vorbis_info *vi=v->vi; codec_setup_info *ci=vi->codec_setup; - vorbis_info_psy_global *gi=ci->psy_g_param; + vorbis_info_psy_global *gi=&ci->psy_g_param; envelope_lookup *ve=((backend_lookup_state *)(v->backend_state))->ve; long i,j,k; @@ -192,45 +191,96 @@ long _ve_envelope_search(vorbis_dsp_state *v,long searchpoint){ ve->current=v->pcm_current; - /* Now search through our cached highpass data for breaking points */ - /* starting point */ - if(v->W) - j=v->centerW+ci->blocksizes[1]/4-ci->blocksizes[0]/4; - else - j=v->centerW; - - if(j<ve->lastmark)j=ve->lastmark; - - while(j+ve->winlength<=v->pcm_current){ - if(j>=searchpoint)return(1); - - ve->lastmark=j; - for(i=0;i<ve->ch;i++){ - for(k=0;k<4;k++){ - float *filtered=ve->filtered[i*4+k]+j; - float m=_ve_deltai(ve,filtered-ve->winlength,filtered); + { + int flag=-1; + long centerW=v->centerW; + long beginW=centerW-ci->blocksizes[v->W]/4; + //long endW=centerW+ci->blocksizes[v->W]/4+ci->blocksizes[0]/4; + long testW=centerW+ci->blocksizes[v->W]/4+ci->blocksizes[1]/2+ci->blocksizes[0]/4; + if(v->W) + beginW-=ci->blocksizes[v->lW]/4; + else + beginW-=ci->blocksizes[0]/4; + + if(ve->mark>=centerW && ve->mark<testW)return(0); + if(ve->mark>=testW)return(1); + + if(v->W) + j=ve->cursor; + else + j=centerW-ci->blocksizes[0]/4; + + while(j+ve->winlength*3/2<=v->pcm_current){ + if(j>=testW)return(1); + ve->cursor=j; + + for(i=0;i<ve->ch;i++){ + for(k=0;k<4;k++){ + float *filtered=ve->filtered[i*4+k]+j; + float *filtered2=ve->filtered[i*4+k]+j+ve->winlength/2; + float m=_ve_deltai(ve,filtered-ve->winlength,filtered); + float mm=_ve_deltai(ve,filtered2-ve->winlength,filtered2); + + if(m>gi->preecho_thresh[k] || m<gi->postecho_thresh[k]){ + if(j<=centerW){ + ve->prevmark=ve->mark=j; + }else{ + /* if a quarter-short-block advance is an even stronger + reading, set *that* as the impulse point. */ + if((m>0. && mm>m) || (m<0. && mm<m)) + flag=j+ve->winlength/2; + else + if(flag<0)flag=j; + } + } + } + } - if(m>gi->preecho_thresh[k])return(0); - if(m<gi->postecho_thresh[k])return(0); - + if(flag>=0){ + ve->prevmark=ve->mark; + ve->mark=flag; + if(flag>=testW)return(1); + return(0); } + + j+=ve->winlength/2; } - - j+=min(ci->blocksizes[0],ve->winlength)/2; - } - if(j>=searchpoint)return(1); return(-1); } +int _ve_envelope_mark(vorbis_dsp_state *v){ + envelope_lookup *ve=((backend_lookup_state *)(v->backend_state))->ve; + vorbis_info *vi=v->vi; + codec_setup_info *ci=vi->codec_setup; + long centerW=v->centerW; + long beginW=centerW-ci->blocksizes[v->W]/4; + long endW=centerW+ci->blocksizes[v->W]/4; + if(v->W){ + beginW-=ci->blocksizes[v->lW]/4; + endW+=ci->blocksizes[v->nW]/4; + }else{ + beginW-=ci->blocksizes[0]/4; + endW+=ci->blocksizes[0]/4; + } + + if(ve->prevmark>=beginW && ve->prevmark<endW)return(1); + if(ve->mark>=beginW && ve->mark<endW)return(1); + return(0); +} + void _ve_envelope_shift(envelope_lookup *e,long shift){ int i; for(i=0;i<e->ch*4;i++) memmove(e->filtered[i],e->filtered[i]+shift,(e->current-shift)* sizeof(*e->filtered[i])); e->current-=shift; - e->lastmark-=shift; + if(e->prevmark>=0) + e->prevmark-=shift; + if(e->mark>=0) + e->mark-=shift; + e->cursor-=shift; } |