- /* add encoded packet to head */
- if(next_head>=bm->queue_size)next_head=0;
- head_ptr=bm->queue_binned+bins*head;
-
- /* is there room to add a block? In proper use of the API, this will
- never come up... but guard it anyway */
- if(next_head==bm->avg_tail || next_head==bm->minmax_tail)return(-1);
-
- /* add the block to the toplevel queue */
- bm->queue_head=next_head;
- bm->queue_actual[head]=(vb->W?0x80000000UL:0);
-
- /* buffer packet fields */
- bm->queue_packets[head].packet=oggpack_get_buffer(&vb->opb);
- bm->queue_packets[head].bytes=oggpack_bytes(&vb->opb);
- bm->queue_packets[head].b_o_s=0;
- bm->queue_packets[head].e_o_s=vb->eofflag;
- bm->queue_packets[head].granulepos=vb->granulepos;
- bm->queue_packets[head].packetno=vb->sequence; /* for sake of completeness */
-
- /* swap packet buffers */
- memcpy(&temp,bm->queue_packet_buffers+head,sizeof(vb->opb));
- memcpy(bm->queue_packet_buffers+head,&vb->opb,sizeof(vb->opb));
- memcpy(&vb->opb,&temp,sizeof(vb->opb));
-
- /* save markers */
- memcpy(head_ptr,vbi->packet_markers,sizeof(*head_ptr)*bins);
-
- if(bm->avg_binacc)
- new_minmax_head=minmax_head=bm->avg_center;
- else
- new_minmax_head=minmax_head=head;
-
- /* the average tracking queue is updated first; its results (if it's
- in use) are taken into account by the min/max limiter (if min/max
- is in use) */
- if(bm->avg_binacc){
- unsigned long desired_center=bm->avg_centerdesired;
- if(eofflag)desired_center=0;
-
- /* update the avg head */
- for(i=0;i<bins;i++)
- bm->avg_binacc[i]+=LACING_ADJUST(head_ptr[i]);
- 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;
- }
-
- /* apply the average floater to new blocks */
- bin=bm->avgfloat*BITTRACK_DIVISOR; /* truncate on purpose */
- while(bm->avg_centeracc>desired_center){
- int samples=
- 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;
+ bm->vb=vb;
+
+ /* look ahead for avg floater */
+ if(bm->avg_bitsper>0){
+ double slew=0.;
+ long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper);
+ double slewlimit= 15./bi->slew_damp;
+
+ /* choosing a new floater:
+ if we're over target, we slew down
+ if we're under target, we slew up
+
+ choose slew as follows: look through packetblobs of this frame
+ and set slew as the first in the appropriate direction that
+ gives us the slew we want. This may mean no slew if delta is
+ already favorable.
+
+ Then limit slew to slew max */
+
+ if(bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){
+ while(choice>0 && this_bits>avg_target_bits &&
+ bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){
+ choice--;
+ this_bits=oggpack_bytes(vbi->packetblob[choice])*8;