[xiph-cvs] cvs commit: vorbis/lib/modes residue_44.h
Monty
xiphmont at xiph.org
Sun Dec 23 02:12:05 PST 2001
xiphmont 01/12/23 02:12:04
Modified: examples encoder_example.c
lib bitrate.c bitrate.h vorbisenc.c
lib/modes residue_44.h
Log:
bitrate management bugfixes and tuning
Revision Changes Path
1.33 +15 -3 vorbis/examples/encoder_example.c
Index: encoder_example.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/examples/encoder_example.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- encoder_example.c 2001/12/20 01:00:24 1.32
+++ encoder_example.c 2001/12/23 10:12:02 1.33
@@ -11,7 +11,7 @@
********************************************************************
function: simple example encoder
- last mod: $Id: encoder_example.c,v 1.32 2001/12/20 01:00:24 segher Exp $
+ last mod: $Id: encoder_example.c,v 1.33 2001/12/23 10:12:02 xiphmont Exp $
********************************************************************/
@@ -73,6 +73,18 @@
_setmode( _fileno( stdout ), _O_BINARY );
#endif
+
+# include <fpu_control.h>
+ unsigned int mask;
+ _FPU_GETCW(mask);
+ /* Set the Linux mask to abort on most FPE's */
+ /* if bit is set, we _mask_ SIGFPE on that error! */
+ /* mask &= ~( _FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM
++);*/
+ mask &= ~( _FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM );
+ _FPU_SETCW(mask);
+
+
/* we cheat on the WAV header; we just bypass the header and never
verify that it matches 16bit/stereo/44.1kHz. This is just an
example, after all. */
@@ -96,8 +108,8 @@
/* (quality mode .4: 44kHz stereo coupled, roughly 128kbps VBR) */
vorbis_info_init(&vi);
- vorbis_encode_init_vbr(&vi,2,44100,.1);
- /*vorbis_encode_init(&vi,2,44100,70000,64000,-1);*/
+ vorbis_encode_init_vbr(&vi,1,44100,.4);
+ /*vorbis_encode_init(&vi,2,44100,64000,-1,-1);*/
/* add a comment */
vorbis_comment_init(&vc);
1.7 +145 -107 vorbis/lib/bitrate.c
Index: bitrate.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/bitrate.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- bitrate.c 2001/12/19 08:10:03 1.6
+++ bitrate.c 2001/12/23 10:12:03 1.7
@@ -11,7 +11,7 @@
********************************************************************
function: bitrate tracking and management
- last mod: $Id: bitrate.c,v 1.6 2001/12/19 08:10:03 xiphmont Exp $
+ last mod: $Id: bitrate.c,v 1.7 2001/12/23 10:12:03 xiphmont Exp $
********************************************************************/
@@ -25,7 +25,26 @@
#include "os.h"
#include "bitrate.h"
-#define BINBITS(pos,bin) ((bin)>0?bm->queue_binned[(pos)*bins+(bin)-1]:0)
+
+static long BINBITS(bitrate_manager_state *bm,long pos,long inbin){
+ int bins=bm->queue_bins;
+ int bin=((inbin&0x7fffffffUL)>>BITTRACK_BPT);
+ ogg_uint32_t lobits=0;
+ ogg_uint32_t hibits=0;
+ ogg_uint32_t bitdel;
+
+ if(bin>0)lobits=bm->queue_binned[pos*bins+bin-1];
+ if(bin<bins)
+ hibits=bm->queue_binned[pos*bins+bin];
+ else
+ hibits=lobits;
+
+ bitdel=hibits-lobits;
+
+ return(lobits+bitdel*(inbin&((1<<BITTRACK_BPT)-1))/(1<<BITTRACK_BPT));
+
+}
+
#define LIMITBITS(pos,bin) ((bin)>-bins?\
bm->minmax_binstack[(pos)*bins*2+((bin)+bins)-1]:0)
@@ -59,7 +78,7 @@
return bin/(double)BITTRACK_DIVISOR;
}else{
double delta=(desired_rate-lobitrate)/(hibitrate-lobitrate);
- return (bin+delta)/(double)BITTRACK_DIVISOR;
+ return (bin+delta)/BITTRACK_DIVISOR;
}
}
@@ -124,11 +143,11 @@
if((bi->queue_hardmin>0 || bi->queue_hardmax>0) &&
bi->queue_minmax_time>0){
- bm->minmax_binstack=_ogg_malloc((bins+1)*bins*2*
+ bm->minmax_binstack=_ogg_calloc((bins+1)*bins*2,
sizeof(bm->minmax_binstack));
- bm->minmax_posstack=_ogg_malloc((bins+1)*
+ bm->minmax_posstack=_ogg_calloc((bins+1),
sizeof(bm->minmax_posstack));
- bm->minmax_limitstack=_ogg_malloc((bins+1)*
+ bm->minmax_limitstack=_ogg_calloc((bins+1),
sizeof(bm->minmax_limitstack));
}else{
bm->minmax_tail= -1;
@@ -273,102 +292,106 @@
bm->avg_sampleacc+=ci->blocksizes[vb->W]>>1;
bm->avg_centeracc+=ci->blocksizes[vb->W]>>1;
- /* update the avg tail if needed */
- while(bm->avg_sampleacc>bm->avg_sampledesired){
- int samples=
- ci->blocksizes[bm->queue_actual[bm->avg_tail]&0x80000000UL?1:0]>>1;
- for(i=0;i<bm->queue_bins;i++)
- bm->avg_binacc[i]-=LACING_ADJUST(bm->queue_binned[bins*bm->avg_tail+i]);
- bm->avg_sampleacc-=samples;
- bm->avg_tail++;
- if(bm->avg_tail>=bm->queue_size)bm->avg_tail=0;
- }
-
- /* update the avg center */
- if(bm->avg_centeracc>desired_center){
- /* choose the new average floater */
- double upper=floater_interpolate(bm,vi,bi->queue_avgmax);
- double lower=floater_interpolate(bm,vi,bi->queue_avgmin);
- double new=bi->avgfloat_initial,slew;
- int bin;
-
- if(upper>0. && upper<new)new=upper;
- if(lower<bi->avgfloat_minimum)
- lower=bi->avgfloat_minimum;
- if(lower>new)new=lower;
-
- slew=new-bm->avgfloat;
-
- if(slew<bi->avgfloat_downhyst || slew>bi->avgfloat_uphyst){
- if(slew<bi->avgfloat_downslew_max)
- new=bm->avgfloat+bi->avgfloat_downslew_max;
- if(slew>bi->avgfloat_upslew_max)
- new=bm->avgfloat+bi->avgfloat_upslew_max;
-
- bm->avgfloat=new;
+ if(bm->avg_sampleacc>bm->avg_sampledesired || eofflag){
+
+ /* update the avg tail if needed */
+ while(bm->avg_sampleacc>bm->avg_sampledesired){
+ int samples=
+ ci->blocksizes[bm->queue_actual[bm->avg_tail]&0x80000000UL?1:0]>>1;
+ for(i=0;i<bm->queue_bins;i++)
+ bm->avg_binacc[i]-=LACING_ADJUST(bm->queue_binned[bins*bm->avg_tail+i]);
+ bm->avg_sampleacc-=samples;
+ bm->avg_tail++;
+ if(bm->avg_tail>=bm->queue_size)bm->avg_tail=0;
}
- /* apply the average floater to new blocks */
- bin=bm->avgfloat*BITTRACK_DIVISOR; /* truncate on purpose */
- while(bm->avg_centeracc>desired_center){
- int samples=
+ /* update the avg center */
+ if(bm->avg_centeracc>desired_center){
+ /* choose the new average floater */
+ int samples=ci->blocksizes[vb->W]>>1;
+ double upper=floater_interpolate(bm,vi,bi->queue_avgmax);
+ double lower=floater_interpolate(bm,vi,bi->queue_avgmin);
+ double new=bi->avgfloat_initial,slew;
+ int bin;
+
+ if(upper>0. && upper<new)new=upper;
+ if(lower<bi->avgfloat_minimum)
+ lower=bi->avgfloat_minimum;
+ if(lower>new)new=lower;
+
+ slew=(new-bm->avgfloat)/samples*vi->rate;
+
+ if(slew<bi->avgfloat_downhyst || slew>bi->avgfloat_uphyst){
+ if(slew<bi->avgfloat_downslew_max)
+ new=bm->avgfloat+bi->avgfloat_downslew_max/vi->rate*samples;
+ if(slew>bi->avgfloat_upslew_max)
+ new=bm->avgfloat+bi->avgfloat_upslew_max/vi->rate*samples;
+
+ bm->avgfloat=new;
+ }
+
+ /* apply the average floater to new blocks */
+ bin=bm->avgfloat*(BITTRACK_DIVISOR<<BITTRACK_BPT);
+
+ while(bm->avg_centeracc>desired_center){
samples=ci->blocksizes[bm->queue_actual[bm->avg_center]&
0x80000000UL?1:0]>>1;
+
+ bm->queue_actual[bm->avg_center]|=bin;
+
+ bm->avg_centeracc-=samples;
+ bm->avg_center++;
+ if(bm->noisetrigger_postpone)bm->noisetrigger_postpone-=samples;
+ if(bm->avg_center>=bm->queue_size)bm->avg_center=0;
+ }
+ new_minmax_head=bm->avg_center;
- bm->queue_actual[bm->avg_center]|=bin;
+ /* track noise bias triggers and noise bias */
+ if(bm->avgfloat<bi->avgfloat_noise_lowtrigger)
+ bm->noisetrigger_request+=1.f;
+ else
+ if(bm->noisetrigger_request>0. && bm->avgnoise>0.)
+ bm->noisetrigger_request-=.2f;
- bm->avg_centeracc-=samples;
- bm->avg_center++;
- if(bm->noisetrigger_postpone)bm->noisetrigger_postpone-=samples;
- if(bm->avg_center>=bm->queue_size)bm->avg_center=0;
- }
- new_minmax_head=bm->avg_center;
-
- /* track noise bias triggers and noise bias */
- if(bm->avgfloat<bi->avgfloat_noise_lowtrigger)
- bm->noisetrigger_request+=1.f;
- else
- if(bm->noisetrigger_request>0. && bm->avgnoise>0.)
- bm->noisetrigger_request-=.2f;
-
- if(bm->avgfloat>bi->avgfloat_noise_hightrigger)
- bm->noisetrigger_request-=1.f;
- else
- if(bm->noisetrigger_request<0 && bm->avgnoise<0.)
- bm->noisetrigger_request+=.2f;
-
- if(bm->noisetrigger_postpone<=0){
- if(bm->noisetrigger_request<0.){
- bm->avgnoise-=1.f;
- if(-bm->noisetrigger_request>(signed long)(bm->avg_sampleacc)/2)
- bm->avgnoise-=1.f;
- bm->noisetrigger_postpone=bm->avg_sampleacc/2;
- }
- if(bm->noisetrigger_request>0.){
- bm->avgnoise+=1.f;
- if(bm->noisetrigger_request>(signed long)(bm->avg_sampleacc)/2)
+ if(bm->avgfloat>bi->avgfloat_noise_hightrigger)
+ bm->noisetrigger_request-=1.f;
+ else
+ if(bm->noisetrigger_request<0 && bm->avgnoise<0.)
+ bm->noisetrigger_request+=.2f;
+
+ if(bm->noisetrigger_postpone<=0){
+ if(bm->noisetrigger_request<0.){
+ bm->avgnoise-=1.f;
+ if(-bm->noisetrigger_request>(signed long)(bm->avg_sampleacc)/2)
+ bm->avgnoise-=1.f;
+ bm->noisetrigger_postpone=bm->avg_sampleacc/2;
+ }
+ if(bm->noisetrigger_request>0.){
bm->avgnoise+=1.f;
- bm->noisetrigger_postpone=bm->avg_sampleacc/2;
- }
+ if(bm->noisetrigger_request>(signed long)(bm->avg_sampleacc)/2)
+ bm->avgnoise+=1.f;
+ bm->noisetrigger_postpone=bm->avg_sampleacc/2;
+ }
- /* we generally want the noise bias to drift back to zero */
- bm->noisetrigger_request=0.f;
- if(bm->avgnoise>0)
- bm->noisetrigger_request= -1.;
- if(bm->avgnoise<0)
- bm->noisetrigger_request= +1.;
-
- if(bm->avgnoise<bi->avgfloat_noise_minval)
- bm->avgnoise=bi->avgfloat_noise_minval;
- if(bm->avgnoise>bi->avgfloat_noise_maxval)
- bm->avgnoise=bi->avgfloat_noise_maxval;
+ /* we generally want the noise bias to drift back to zero */
+ bm->noisetrigger_request=0.f;
+ if(bm->avgnoise>0)
+ bm->noisetrigger_request= -1.;
+ if(bm->avgnoise<0)
+ bm->noisetrigger_request= +1.;
+
+ if(bm->avgnoise<bi->avgfloat_noise_minval)
+ bm->avgnoise=bi->avgfloat_noise_minval;
+ if(bm->avgnoise>bi->avgfloat_noise_maxval)
+ bm->avgnoise=bi->avgfloat_noise_maxval;
+ }
}
}
}else{
/* if we're not using an average tracker, the 'float' is nailed to
the avgfloat_initial value. It needs to be set for the min/max
to deal properly */
- long bin=bi->avgfloat_initial*BITTRACK_DIVISOR; /* truncate on purpose */
+ long bin=bi->avgfloat_initial*(BITTRACK_DIVISOR<<BITTRACK_BPT);
bm->queue_actual[head]|=bin;
new_minmax_head=next_head;
}
@@ -406,15 +429,19 @@
for(i=0;i<(unsigned int)bins;i++){
bm->minmax_binstack[bm->minmax_stackptr*bins*2+bins+i]+=
LACING_ADJUST(
- BINBITS(minmax_head,
- (bm->queue_actual[minmax_head]&0x7fffffffUL)>i+1?
- (bm->queue_actual[minmax_head]&0x7fffffffUL):i+1));
+ BINBITS(bm,minmax_head,
+ (bm->queue_actual[minmax_head]&0x7fffffffUL)>
+ ((i+1)<<BITTRACK_BPT)?
+ bm->queue_actual[minmax_head]:
+ ((i+1)<<BITTRACK_BPT)));
bm->minmax_binstack[bm->minmax_stackptr*bins*2+i]+=
LACING_ADJUST(
- BINBITS(minmax_head,
- (bm->queue_actual[minmax_head]&0x7fffffffUL)<i+1?
- (bm->queue_actual[minmax_head]&0x7fffffffUL):i+1));
+ BINBITS(bm,minmax_head,
+ (bm->queue_actual[minmax_head]&0x7fffffffUL)<
+ ((i+1)<<BITTRACK_BPT)?
+ bm->queue_actual[minmax_head]:
+ ((i+1)<<BITTRACK_BPT)));
}
bm->minmax_posstack[bm->minmax_stackptr]=minmax_head; /* not one
@@ -425,7 +452,7 @@
bm->minmax_sampleacc+=samples;
bm->minmax_acctotal+=
LACING_ADJUST(
- BINBITS(minmax_head,(bm->queue_actual[minmax_head]&0x7fffffffUL)));
+ BINBITS(bm,minmax_head,bm->queue_actual[minmax_head]));
minmax_head++;
if(minmax_head>=bm->queue_size)minmax_head=0;
@@ -441,8 +468,9 @@
int newstack;
int stackctr;
long bitsum=limit_sum(bm,0);
+
bitrate=(double)bitsum/bm->minmax_sampleacc*vi->rate;
-
+
/* we're off rate. Iteratively try out new hard floater
limits until we find one that brings us inside. Here's
where we see the whole point of the limit stacks. */
@@ -461,6 +489,11 @@
if(bitrate>bi->queue_hardmax)limit--;
}
+ for(i=limit-1;i>-bins;i--){
+ long bitsum=limit_sum(bm,i);
+ bitrate=(double)bitsum/bm->minmax_sampleacc*vi->rate;
+ }
+
bitsum=limit_sum(bm,limit);
bitrate=(double)bitsum/bm->minmax_sampleacc*vi->rate;
@@ -510,22 +543,27 @@
for(i=0;i<bins;i++){
bm->minmax_binstack[bins+i]-= /* always comes off the stack bottom */
- LACING_ADJUST(BINBITS(bm->minmax_tail,actual>i+1?actual:i+1));
+ LACING_ADJUST(BINBITS(bm,bm->minmax_tail,
+ actual>((i+1)<<BITTRACK_BPT)?
+ actual:((i+1)<<BITTRACK_BPT)));
bm->minmax_binstack[i]-=
- LACING_ADJUST(BINBITS(bm->minmax_tail,actual<i+1?actual:i+1));
+ LACING_ADJUST(BINBITS(bm,bm->minmax_tail,
+ actual<((i+1)<<BITTRACK_BPT)?
+ actual:((i+1)<<BITTRACK_BPT)));
}
/* always perform in this order; max overrules min */
- if(bm->minmax_limitstack[0]>actual)
- actual=bm->minmax_limitstack[0];
- if(bins+bm->minmax_limitstack[0]<actual)
- actual=bins+bm->minmax_limitstack[0];
+ if((bm->minmax_limitstack[0]<<BITTRACK_BPT)>actual)
+ actual=(bm->minmax_limitstack[0]<<BITTRACK_BPT);
+ if(((bins+bm->minmax_limitstack[0])<<BITTRACK_BPT)<actual)
+ actual=(bins+bm->minmax_limitstack[0])<<BITTRACK_BPT;
- bm->minmax_acctotal-=LACING_ADJUST(BINBITS(bm->minmax_tail,actual));
+ bm->minmax_acctotal-=LACING_ADJUST(BINBITS(bm,bm->minmax_tail,actual));
bm->minmax_sampleacc-=samples;
/* revise queue_actual to reflect the limit */
- bm->queue_actual[bm->minmax_tail]=actual;
+ bm->queue_actual[bm->minmax_tail]&=0x80000000UL;
+ bm->queue_actual[bm->minmax_tail]|=actual;
if(bm->minmax_tail==bm->minmax_posstack[0]){
/* the stack becomes a FIFO; the first data has fallen off */
@@ -563,14 +601,13 @@
bm->queue_head=0;
}else{
- long bins=bm->queue_bins;
long bin;
long bytes;
if(bm->next_to_flush==bm->last_to_flush)return(0);
- bin=bm->queue_actual[bm->next_to_flush]&0x7fffffffUL;
- bytes=(BINBITS(bm->next_to_flush,bin)+7)/8;
+ bin=bm->queue_actual[bm->next_to_flush];
+ bytes=(BINBITS(bm,bm->next_to_flush,bin)+7)/8;
memcpy(op,bm->queue_packets+bm->next_to_flush,sizeof(*op));
if(bytes<op->bytes)op->bytes=bytes;
@@ -578,6 +615,7 @@
bm->next_to_flush++;
if(bm->next_to_flush>=bm->queue_size)bm->next_to_flush=0;
+ if(bytes==0)exit(1);
}
return(1);
1.4 +2 -1 vorbis/lib/bitrate.h
Index: bitrate.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/bitrate.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- bitrate.h 2001/12/19 07:33:51 1.3
+++ bitrate.h 2001/12/23 10:12:03 1.4
@@ -11,7 +11,7 @@
********************************************************************
function: bitrate tracking and management
- last mod: $Id: bitrate.h,v 1.3 2001/12/19 07:33:51 xiphmont Exp $
+ last mod: $Id: bitrate.h,v 1.4 2001/12/23 10:12:03 xiphmont Exp $
********************************************************************/
@@ -24,6 +24,7 @@
/* encode side bitrate tracking */
#define BITTRACK_DIVISOR 16
+#define BITTRACK_BPT 6
typedef struct bitrate_manager_state {
ogg_uint32_t *queue_binned;
ogg_uint32_t *queue_actual;
1.32 +5 -15 vorbis/lib/vorbisenc.c
Index: vorbisenc.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/vorbisenc.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- vorbisenc.c 2001/12/22 09:40:39 1.31
+++ vorbisenc.c 2001/12/23 10:12:03 1.32
@@ -11,7 +11,7 @@
********************************************************************
function: simple programmatic interface for encoder mode setup
- last mod: $Id: vorbisenc.c,v 1.31 2001/12/22 09:40:39 xiphmont Exp $
+ last mod: $Id: vorbisenc.c,v 1.32 2001/12/23 10:12:03 xiphmont Exp $
********************************************************************/
@@ -914,6 +914,7 @@
long nominal_bitrate,
long min_bitrate){
+ double tnominal=nominal_bitrate;
double approx_vbr=approx_bitrate_to_vbr(channels,(channels==2),
(float)nominal_bitrate,rate);
int ret=0;
@@ -973,18 +974,15 @@
ci->bi.queue_hardmin=min_bitrate;
ci->bi.queue_hardmax=max_bitrate;
- ci->bi.queue_avgmin=nominal_bitrate;
- ci->bi.queue_avgmax=nominal_bitrate;
+ ci->bi.queue_avgmin=tnominal;
+ ci->bi.queue_avgmax=tnominal;
/* adjust management */
if(max_bitrate<=0. && min_bitrate<=0.){
/* just an average tracker; no reason for the window to be as small as 2s. */
- ci->bi.queue_avg_time=4.;
+ //ci->bi.queue_avg_time=4.;
}
ci->bi.avgfloat_noise_maxval=_bm_max_noise_offset[(int)approx_vbr];
- /*if(max_bitrate>0.){
- ci->bi.avgfloat_minimum=0.;
- }*/
}
return(ret);
@@ -1016,11 +1014,3 @@
int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){
return(OV_EIMPL);
}
-
-
-
-
-
-
-
-
1.10 +5 -5 vorbis/lib/modes/residue_44.h
Index: residue_44.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/modes/residue_44.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- residue_44.h 2001/12/20 01:00:38 1.9
+++ residue_44.h 2001/12/23 10:12:04 1.10
@@ -11,7 +11,7 @@
********************************************************************
function: toplevel residue templates for 32/44.1/48kHz
- last mod: $Id: residue_44.h,v 1.9 2001/12/20 01:00:38 segher Exp $
+ last mod: $Id: residue_44.h,v 1.10 2001/12/23 10:12:04 xiphmont Exp $
********************************************************************/
@@ -20,14 +20,14 @@
static bitrate_manager_info _bm_44_default={
/* progressive coding and bitrate controls */
- 2.,.5,
+ 4.,.0,
2., 0, 0,
0, 0,
- 4.0,2.3, -1., .05,
- -.05, .05,
+ 4.0,2.3, -350, .02,
+ -.00, .00,
3.2,5.0,
- -6.f,+2.f
+ 0.,0.
};
/***** residue backends *********************************************/
--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list