********************************************************************
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 $
********************************************************************/
/* (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);
********************************************************************
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 $
********************************************************************/
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])))
********************************************************************
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.
********************************************************************
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 $
********************************************************************/
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;
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;i<n;i++)
+ n=e->band[0].end/2;
+ for(i=0;i<n;i++){
e->band[0].window[i]=sin((i+.5)/n*M_PI);
- n=e->band[1].end;
- for(i=0;i<n;i++)
+ e->band[0].total+=e->band[0].window[i];
+ }
+ n=e->band[1].end/2;
+ for(i=0;i<n;i++){
e->band[1].window[i]=sin((i+.5)/n*M_PI);
- n=e->band[2].end;
- for(i=0;i<n;i++)
+ e->band[1].total+=e->band[1].window[i];
+ }
+ n=e->band[2].end/2;
+ for(i=0;i<n;i++){
e->band[2].window[i]=sin((i+.5)/n*M_PI);
- n=e->band[3].end;
- for(i=0;i<n;i++)
+ e->band[2].total+=e->band[2].window[i];
+ }
+ n=e->band[3].end/2;
+ for(i=0;i<n;i++){
e->band[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));
/* 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,
/* accumulate amplitude by band */
for(j=0;j<VE_BANDS;j++){
- for(i=0;i<bands[j].end;i++){
- float val=vec[i+bands[j].begin];
- acc[j]+=val*val*bands[j].window[i];
+ for(i=0;i<bands[j].end;i+=2){
+ float val=FABS(vec+i+bands[j].begin)+FABS(vec+i+bands[j].begin+1);
+ acc[j]+=todB(&val)*bands[j].window[i>>1];
}
- acc[j]/=i*.707f;
- if(acc[j]<minV*minV)acc[j]=minV*minV;
- acc[j]=todB(acc+j);
+ acc[j]/=bands[j].total;
+ if(acc[j]<minV)acc[j]=minV;
+ //fprintf(stderr,"%d %gdB :: ",j,acc[j]);
}
+ //fprintf(stderr,"\n");
/* convert amplitude to delta */
for(j=0;j<VE_BANDS;j++){
float val=.14*buf[0]+.14*buf[1]+.72*acc[j];
buf[0]=buf[1];buf[1]=acc[j];
acc[j]=val;
- filters[j].markers[pos+1]=val;
+ /*filters[j].markers[pos+1]=val;*/
}
/* look at local min/max */
for(j=0;j<VE_BANDS;j++){
float *buf=filters[j].convbuf;
- if(buf[1]>gi->preecho_thresh[j] && buf[0]<buf[1] && acc[j]<buf[1])ret=1;
- if(buf[1]<gi->postecho_thresh[j] && buf[0]>buf[1] && acc[j]>buf[1])ret=1;
+ if(buf[1]>gi->preecho_thresh[j] && buf[0]<buf[1] && acc[j]<buf[1])ret|=1;
+ if(buf[1]<gi->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;
/* 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;
j=ve->cursor;
- while(j<ve->current){
+ while(j<ve->current-(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){
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);
_analysis_output_always("delR2",seq,marker,v->pcm_current,0,0,totalshift);
for(l=0;l<last;l++)marker[l*ve->searchstep]=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;
memmove(e->mark,e->mark+smallshift,(smallsize-smallshift)*sizeof(*e->mark));
+#if 0
for(i=0;i<VE_BANDS*e->ch;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;
}
********************************************************************
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 $
********************************************************************/
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 {
********************************************************************
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 $
********************************************************************/
/* 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;
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.... */
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;i<vi->channels;i++){
float *logmax =mdct+n/2;
float *logmask =work+n/2;
+ /*
+ for(j=0;j<n/2;j+=2){
+ logmdct[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;j<n/2;j++)
logmdct[j]=todB(mdct+j);
- //_analysis_output("mdct",seq+i,logmdct,n/2,1,0);
+ /*_analysis_output_always("mdct",seq+i,logmdct,n/2,1,0,total-n/2);*/
/* perform psychoacoustics; do masking */
local_ampmax[i],
bm->avgnoise);
- //_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],
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);*/
}
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);
}
********************************************************************
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 $
********************************************************************/
{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,
},
};
********************************************************************
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 $
********************************************************************/
}
}
-
void _vp_quantize_couple(vorbis_look_psy *p,
vorbis_info_mapping0 *vi,
float **pcm,
********************************************************************
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 $
********************************************************************/
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);