From f0ccd2f19da56da9cb26f886898af7acf398d939 Mon Sep 17 00:00:00 2001 From: Monty Date: Sun, 24 Mar 2002 21:04:03 +0000 Subject: [PATCH] Continued preecho tuning/fixes. Gone to average dB with even/odd smoothing, and cranked the sensitivity back up to ala rc3. Result: when rc3 and current are working 'properly', current trips _slightly_ more impulse blocks but also catches many more audible cases. Current also seems more resistent to false positives. svn path=/trunk/vorbis/; revision=3181 --- examples/encoder_example.c | 4 +- lib/analysis.c | 5 +-- lib/block.c | 2 +- lib/envelope.c | 106 ++++++++++++++++++++++++++------------------- lib/envelope.h | 6 +-- lib/mapping0.c | 25 +++++++---- lib/modes/psych_44.h | 14 +++--- lib/psy.c | 3 +- lib/vorbisenc.c | 4 +- 9 files changed, 96 insertions(+), 73 deletions(-) diff --git a/examples/encoder_example.c b/examples/encoder_example.c index 998a3ed..8006170 100644 --- a/examples/encoder_example.c +++ b/examples/encoder_example.c @@ -11,7 +11,7 @@ ******************************************************************** function: simple example encoder - last mod: $Id: encoder_example.c,v 1.38 2002/03/23 03:17:33 xiphmont Exp $ + last mod: $Id: encoder_example.c,v 1.39 2002/03/24 21:03:59 xiphmont Exp $ ********************************************************************/ @@ -97,7 +97,7 @@ int main(){ /* (quality mode .4: 44kHz stereo coupled, roughly 128kbps VBR) */ vorbis_info_init(&vi); - vorbis_encode_init_vbr(&vi,2,44100,.3); /* max compression */ + vorbis_encode_init_vbr(&vi,2,44100,.0); /* max compression */ /* add a comment */ vorbis_comment_init(&vc); diff --git a/lib/analysis.c b/lib/analysis.c index 6fb0705..c75ef1b 100644 --- a/lib/analysis.c +++ b/lib/analysis.c @@ -11,7 +11,7 @@ ******************************************************************** function: single-block PCM analysis mode dispatch - last mod: $Id: analysis.c,v 1.49 2002/03/23 03:17:33 xiphmont Exp $ + last mod: $Id: analysis.c,v 1.50 2002/03/24 21:04:00 xiphmont Exp $ ********************************************************************/ @@ -58,9 +58,6 @@ int vorbis_analysis(vorbis_block *vb, ogg_packet *op){ if(vb->W){ oggpack_write(&vb->opb,vb->lW,1); oggpack_write(&vb->opb,vb->nW,1); - /*fprintf(stderr,"*"); - }else{ - fprintf(stderr,".");*/ } if((ret=_mapping_P[type]->forward(vb,b->mode[mode]))) diff --git a/lib/block.c b/lib/block.c index ab495db..5273cad 100644 --- a/lib/block.c +++ b/lib/block.c @@ -11,7 +11,7 @@ ******************************************************************** function: PCM data vector blocking, windowing and dis/reassembly - last mod: $Id: block.c,v 1.61 2002/03/23 03:17:33 xiphmont Exp $ + last mod: $Id: block.c,v 1.62 2002/03/24 21:04:00 xiphmont Exp $ Handle windowing, overlap-add, etc of the PCM vectors. This is made more amusing by Vorbis' current two allowed block sizes. diff --git a/lib/envelope.c b/lib/envelope.c index 9761616..52931cb 100644 --- a/lib/envelope.c +++ b/lib/envelope.c @@ -11,7 +11,7 @@ ******************************************************************** function: PCM data envelope analysis - last mod: $Id: envelope.c,v 1.43 2002/03/23 03:17:33 xiphmont Exp $ + last mod: $Id: envelope.c,v 1.44 2002/03/24 21:04:00 xiphmont Exp $ ********************************************************************/ @@ -37,7 +37,7 @@ void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){ int n=e->winlength=ci->blocksizes[0]; e->searchstep=ci->blocksizes[0]/VE_DIV; /* not random */ - e->minenergy=fromdB(gi->preecho_minenergy); + e->minenergy=gi->preecho_minenergy; e->ch=ch; e->storage=128; e->cursor=ci->blocksizes[1]/2; @@ -53,32 +53,41 @@ void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){ to Hell with that) */ /* 2(1.3-3) 4(2.6-6) 8(5.3-12) 16(10.6-18) */ - e->band[0].begin=rint(1300.f/22050.f*n/4.f)*2.f; - e->band[0].end=rint(3000.f/22050.f*n/4.f)*2.f-e->band[0].begin; - e->band[1].begin=rint(2600.f/22050.f*n/4.f)*2.f; - e->band[1].end=rint(6000.f/22050.f*n/4.f)*2.f-e->band[1].begin; - e->band[2].begin=rint(5300.f/22050.f*n/4.f)*2.f; - e->band[2].end=rint(12000.f/22050.f*n/4.f)*2.f-e->band[2].begin; - e->band[3].begin=rint(10600.f/22050.f*n/4.f)*2.f; - e->band[3].end=rint(18000.f/22050.f*n/4.f)*2.f-e->band[3].begin; - - e->band[0].window=_ogg_malloc((e->band[0].end)*sizeof(*e->band[0].window)); - e->band[1].window=_ogg_malloc((e->band[1].end)*sizeof(*e->band[1].window)); - e->band[2].window=_ogg_malloc((e->band[2].end)*sizeof(*e->band[2].window)); - e->band[3].window=_ogg_malloc((e->band[3].end)*sizeof(*e->band[3].window)); + e->band[0].begin=rint(3000.f/22050.f*n/4.f)*2.f; + e->band[0].end=rint(6000.f/22050.f*n/4.f)*2.f-e->band[0].begin; + e->band[1].begin=rint(5000.f/22050.f*n/4.f)*2.f; + e->band[1].end=rint(10000.f/22050.f*n/4.f)*2.f-e->band[1].begin; + e->band[2].begin=rint(8000.f/22050.f*n/4.f)*2.f; + e->band[2].end=rint(16000.f/22050.f*n/4.f)*2.f-e->band[2].begin; + e->band[3].begin=rint(12000.f/22050.f*n/4.f)*2.f; + e->band[3].end=rint(20000.f/22050.f*n/4.f)*2.f-e->band[3].begin; + + e->band[0].window=_ogg_malloc((e->band[0].end)/2*sizeof(*e->band[0].window)); + e->band[1].window=_ogg_malloc((e->band[1].end)/2*sizeof(*e->band[1].window)); + e->band[2].window=_ogg_malloc((e->band[2].end)/2*sizeof(*e->band[2].window)); + e->band[3].window=_ogg_malloc((e->band[3].end)/2*sizeof(*e->band[3].window)); - n=e->band[0].end; - for(i=0;iband[0].end/2; + for(i=0;iband[0].window[i]=sin((i+.5)/n*M_PI); - n=e->band[1].end; - for(i=0;iband[0].total+=e->band[0].window[i]; + } + n=e->band[1].end/2; + for(i=0;iband[1].window[i]=sin((i+.5)/n*M_PI); - n=e->band[2].end; - for(i=0;iband[1].total+=e->band[1].window[i]; + } + n=e->band[2].end/2; + for(i=0;iband[2].window[i]=sin((i+.5)/n*M_PI); - n=e->band[3].end; - for(i=0;iband[2].total+=e->band[2].window[i]; + } + n=e->band[3].end/2; + for(i=0;iband[3].window[i]=sin((i+.5)/n*M_PI); + e->band[3].total+=e->band[3].window[i]; + } + e->filter=_ogg_calloc(VE_BANDS*ch,sizeof(*e->filter)); e->mark=_ogg_calloc(e->storage,sizeof(*e->mark)); @@ -99,7 +108,6 @@ void _ve_envelope_clear(envelope_lookup *e){ /* fairly straight threshhold-by-band based until we find something that works better and isn't patented. */ -static int seq2=0; static int _ve_amp(envelope_lookup *ve, vorbis_info_psy_global *gi, float *data, @@ -125,14 +133,15 @@ static int _ve_amp(envelope_lookup *ve, /* accumulate amplitude by band */ for(j=0;j>1]; } - acc[j]/=i*.707f; - if(acc[j]gi->preecho_thresh[j] && buf[0]postecho_thresh[j] && buf[0]>buf[1] && acc[j]>buf[1])ret=1; + if(buf[1]>gi->preecho_thresh[j] && buf[0]postecho_thresh[j] && buf[0]>buf[1] && acc[j]>buf[1])ret|=2; buf[0]=buf[1];buf[1]=acc[j]; } return(ret); } -static int seq=0; -static ogg_int64_t totalshift=-1024; - long _ve_envelope_search(vorbis_dsp_state *v){ vorbis_info *vi=v->vi; codec_setup_info *ci=vi->codec_setup; @@ -192,11 +198,17 @@ long _ve_envelope_search(vorbis_dsp_state *v){ /* we assume a 'transient' occupies half a short block; this way, it's contained in two short blocks, else the first block is - short and the second long, causing smearing */ + short and the second long, causing smearing. + + preecho triggers follow the impulse marker; postecho triger preceed it */ + ve->mark[j+VE_DIV/2]=0; - if(ret) + if(ret&1) for(i=0;i<=VE_DIV/2;i++) - ve->mark[j+i]=ret; + ve->mark[j+i]=1; + if(ret&2) + for(i=-1;i>=-VE_DIV/2 && j+i>=0;i--) + ve->mark[j+i]=1; } ve->current=last*ve->searchstep; @@ -211,7 +223,12 @@ long _ve_envelope_search(vorbis_dsp_state *v){ j=ve->cursor; - while(jcurrent){ + while(jcurrent-(VE_DIV/2*ve->searchstep)){ /* modified to + stay clear of + possibly + unfinished + postecho + detection */ if(j>=testW)return(1); if(ve->mark[j/ve->searchstep]){ if(j>centerW){ @@ -221,12 +238,10 @@ long _ve_envelope_search(vorbis_dsp_state *v){ float *marker=alloca(v->pcm_current*sizeof(*marker)); int l; memset(marker,0,sizeof(*marker)*v->pcm_current); - fprintf(stderr,"mark! seq=%d, cursor:%fs time:%fs\n", seq, (totalshift+ve->cursor)/44100., (totalshift+j)/44100.); - _analysis_output_always("pcmL",seq,v->pcm[0],v->pcm_current,0,0,totalshift); _analysis_output_always("pcmR",seq,v->pcm[1],v->pcm_current,0,0,totalshift); @@ -250,11 +265,10 @@ long _ve_envelope_search(vorbis_dsp_state *v){ _analysis_output_always("delR2",seq,marker,v->pcm_current,0,0,totalshift); for(l=0;lsearchstep]=ve->filter[7].markers[l]*.01; _analysis_output_always("delR3",seq,marker,v->pcm_current,0,0,totalshift); - seq++; } -#endif +#endif ve->curmark=j; ve->cursor=j; @@ -307,16 +321,18 @@ void _ve_envelope_shift(envelope_lookup *e,long shift){ memmove(e->mark,e->mark+smallshift,(smallsize-smallshift)*sizeof(*e->mark)); +#if 0 for(i=0;ich;i++) memmove(e->filter[i].markers, e->filter[i].markers+smallshift, (1024-smallshift)*sizeof(*(*e->filter).markers)); + totalshift+=shift; +#endif e->current-=shift; if(e->curmark>=0) e->curmark-=shift; e->cursor-=shift; - totalshift+=shift; } diff --git a/lib/envelope.h b/lib/envelope.h index 20cf0ae..7087970 100644 --- a/lib/envelope.h +++ b/lib/envelope.h @@ -11,7 +11,7 @@ ******************************************************************** function: PCM data envelope analysis and manipulation - last mod: $Id: envelope.h,v 1.20 2002/03/23 03:17:34 xiphmont Exp $ + last mod: $Id: envelope.h,v 1.21 2002/03/24 21:04:00 xiphmont Exp $ ********************************************************************/ @@ -29,14 +29,14 @@ typedef struct { int ampptr; float delbuf[VE_CONV-1]; float convbuf[2]; - - float markers[1024]; + } envelope_filter_state; typedef struct { int begin; int end; float *window; + float total; } envelope_band; typedef struct { diff --git a/lib/mapping0.c b/lib/mapping0.c index 884caae..37356db 100644 --- a/lib/mapping0.c +++ b/lib/mapping0.c @@ -11,7 +11,7 @@ ******************************************************************** function: channel mapping 0 implementation - last mod: $Id: mapping0.c,v 1.46 2002/03/23 03:17:34 xiphmont Exp $ + last mod: $Id: mapping0.c,v 1.47 2002/03/24 21:04:00 xiphmont Exp $ ********************************************************************/ @@ -284,7 +284,6 @@ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb) /* no time mapping implementation for now */ static long seq=0; -ogg_int64_t total=0; static int mapping0_forward(vorbis_block *vb,vorbis_look_mapping *l){ vorbis_dsp_state *vd=vb->vd; @@ -333,13 +332,13 @@ static int mapping0_forward(vorbis_block *vb,vorbis_look_mapping *l){ float *logmask =work+n/2;*/ scale_dB=todB(&scale); - //_analysis_output_always("pcm",seq+i,pcm,n,0,0,total-n/2); + /*_analysis_output_always("pcm",seq+i,pcm,n,0,0,total-n/2);*/ /* window the PCM data */ _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW); memcpy(fft,pcm,sizeof(*fft)*n); - //_analysis_output_always("windowed",seq+i,pcm,n,0,0,total-n/2); + /*_analysis_output_always("windowed",seq+i,pcm,n,0,0,total-n/2);*/ /* transform the PCM data */ /* only MDCT right now.... */ @@ -359,7 +358,7 @@ static int mapping0_forward(vorbis_block *vb,vorbis_look_mapping *l){ if(local_ampmax[i]>0.f)local_ampmax[i]=0.f; if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i]; - //_analysis_output("fft",seq+i,logfft,n/2,1,0); + /*_analysis_output("fft",seq+i,logfft,n/2,1,0);*/ } for(i=0;ichannels;i++){ @@ -375,9 +374,17 @@ static int mapping0_forward(vorbis_block *vb,vorbis_look_mapping *l){ float *logmax =mdct+n/2; float *logmask =work+n/2; + /* + for(j=0;j>1]=FABS(mdct+j)+FABS(mdct+j+1); + logmdct[j>>1]=todB(logmdct+(j>>1)); + } + _analysis_output_always("mdct2",seq+i,logmdct,n/4,1,0,total-n/2);*/ + + for(j=0;javgnoise); - //_analysis_output("mask",seq+i,logmask,n/2,1,0); + /*_analysis_output("mask",seq+i,logmask,n/2,1,0);*/ /* perform floor encoding */ nonzero[i]=look->floor_func[submap]-> forward(vb,look->floor_look[submap], @@ -412,7 +419,7 @@ static int mapping0_forward(vorbis_block *vb,vorbis_look_mapping *l){ fprintf(stderr,"%ld ",seq+i); }*/ - //_analysis_output("codedflr",seq+i,codedflr,n/2,1,1); + /*_analysis_output("codedflr",seq+i,codedflr,n/2,1,1);*/ } @@ -562,7 +569,7 @@ static int mapping0_forward(vorbis_block *vb,vorbis_look_mapping *l){ seq+=vi->channels; } - total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4; + /*total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4;*/ look->lastframe=vb->sequence; return(0); } diff --git a/lib/modes/psych_44.h b/lib/modes/psych_44.h index 77ea530..d405c68 100644 --- a/lib/modes/psych_44.h +++ b/lib/modes/psych_44.h @@ -11,7 +11,7 @@ ******************************************************************** function: key psychoacoustic settings for 44.1/48kHz - last mod: $Id: psych_44.h,v 1.9 2002/03/23 03:17:35 xiphmont Exp $ + last mod: $Id: psych_44.h,v 1.10 2002/03/24 21:04:03 xiphmont Exp $ ********************************************************************/ @@ -23,20 +23,24 @@ static vorbis_info_psy_global _psy_global_44[4]={ {8, /* lines per eighth octave */ /*{990.f,990.f,990.f,990.f}, {-990.f,-990.f,-990.f,-990.f}, -90.f, {0.f,0.f,0.f,0.f}, {-0.f,-0.f,-0.f,-0.f}, -90.f,*/ - {46.f,40.f,36.f,36.f}, {-990.f,-990.f,-990.f,-990.f}, -100.f, + {16.f,14.f,12.f,12.f}, {-990.f,-990.f,-990.f,-990.f}, -80.f, -6.f, 0, }, {8, /* lines per eighth octave */ /*{990.f,990.f,990.f,990.f}, {-990.f,-990.f,-990.f,-990.f}, -90.f,*/ - {40.f,36.f,30.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -100.f, + {14.f,12.f,11.f,11.f}, {-990.f,-990.f,-990.f,-990.f}, -85.f, -6.f, 0, }, {8, /* lines per eighth octave */ - {40.f,36.f,30.f,30.f}, {-60.f,-40.f,-40.f,-40.f}, -100.f, + {14.f,12.f,10.f,10.f}, {-90.f,-90.f,-90.f,-90.f}, -85.f, -6.f, 0, }, {8, /* lines per eighth octave */ - {40.f,34.f,30.f,30.f}, {-40.f,-36.f,-32.f,-30.f}, -100.f, + {12.f,10.f,8.f,8.f}, {-40.f,-40.f,-40.f,-40.f}, -90.f, + -6.f, 0, + }, + {8, /* lines per eighth octave */ + {12.f,10.f,8.f,8.f}, {-14.f,-14.f,-12.f,-12.f}, -90.f, -6.f, 0, }, }; diff --git a/lib/psy.c b/lib/psy.c index 8a41dc9..6db811e 100644 --- a/lib/psy.c +++ b/lib/psy.c @@ -11,7 +11,7 @@ ******************************************************************** function: psychoacoustics not including preecho - last mod: $Id: psy.c,v 1.66 2002/03/18 03:30:23 segher Exp $ + last mod: $Id: psy.c,v 1.67 2002/03/24 21:04:01 xiphmont Exp $ ********************************************************************/ @@ -932,7 +932,6 @@ static void couple_point(float A, float B, float fA, float fB, } } - void _vp_quantize_couple(vorbis_look_psy *p, vorbis_info_mapping0 *vi, float **pcm, diff --git a/lib/vorbisenc.c b/lib/vorbisenc.c index f932eb6..e75f39e 100644 --- a/lib/vorbisenc.c +++ b/lib/vorbisenc.c @@ -11,7 +11,7 @@ ******************************************************************** function: simple programmatic interface for encoder mode setup - last mod: $Id: vorbisenc.c,v 1.38 2002/03/17 19:50:47 xiphmont Exp $ + last mod: $Id: vorbisenc.c,v 1.39 2002/03/24 21:04:01 xiphmont Exp $ ********************************************************************/ @@ -622,7 +622,7 @@ int vorbis_encode_setup_init(vorbis_info *vi){ 0,0,0,0,0,0,0,0,0,0,0); ret|=vorbis_encode_global_psych_setup(vi,hi->trigger_quality,_psy_global_44, - 0., 1., 1.5, 2., 2., 2.5, 3., 3., 3., 3., 3.); + 0., 1., 1.5, 2., 2., 2.5, 3., 3.5, 4., 4., 4.); ret|=vorbis_encode_psyset_setup(vi,0); ret|=vorbis_encode_psyset_setup(vi,1); -- 2.7.4