A single page audio stream that was also a short page would decode too far.
authorMonty <xiphmont@xiph.org>
Fri, 11 Oct 2002 11:14:42 +0000 (11:14 +0000)
committerMonty <xiphmont@xiph.org>
Fri, 11 Oct 2002 11:14:42 +0000 (11:14 +0000)
svn path=/trunk/vorbis/; revision=3996

examples/chaining_example.c
lib/bitrate.c
lib/block.c
lib/codec_internal.h
lib/envelope.c
lib/info.c
lib/mapping0.c
lib/modes/psych_16.h
lib/modes/setup_16.h
lib/synthesis.c

index 0a855a2..3910d31 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: illustrate simple use of chained bitstream and vorbisfile.a
- last mod: $Id: chaining_example.c,v 1.17 2002/07/11 06:40:47 xiphmont Exp $
+ last mod: $Id: chaining_example.c,v 1.18 2002/10/11 11:14:41 xiphmont Exp $
 
  ********************************************************************/
 
@@ -45,6 +45,8 @@ int main(){
   if(ov_seekable(&ov)){
     printf("Input bitstream contained %ld logical bitstream section(s).\n",
           ov_streams(&ov));
+    printf("Total bitstream samples: %ld\n\n",
+          (long)ov_pcm_total(&ov,-1));
     printf("Total bitstream playing time: %ld seconds\n\n",
           (long)ov_time_total(&ov,-1));
 
index 927e461..0404b82 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: bitrate tracking and management
- last mod: $Id: bitrate.c,v 1.20 2002/07/18 02:12:20 xiphmont Exp $
+ last mod: $Id: bitrate.c,v 1.21 2002/10/11 11:14:41 xiphmont Exp $
 
  ********************************************************************/
 
@@ -170,7 +170,7 @@ void vorbis_bitrate_clear(bitrate_manager_state *bm){
 
 int vorbis_bitrate_managed(vorbis_block *vb){
   vorbis_dsp_state      *vd=vb->vd;
-  backend_lookup_state  *b=vd->backend_state; 
+  private_state         *b=vd->backend_state; 
   bitrate_manager_state *bm=&b->bms;
 
   if(bm->queue_binned)return(1);
@@ -182,7 +182,7 @@ int vorbis_bitrate_addblock(vorbis_block *vb){
   int i; 
   vorbis_block_internal *vbi=vb->internal;
   vorbis_dsp_state      *vd=vb->vd;
-  backend_lookup_state  *b=vd->backend_state; 
+  private_state         *b=vd->backend_state; 
   bitrate_manager_state *bm=&b->bms;
   vorbis_info           *vi=vd->vi;
   codec_setup_info      *ci=vi->codec_setup;
@@ -493,7 +493,7 @@ int vorbis_bitrate_addblock(vorbis_block *vb){
 }
 
 int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,ogg_packet *op){
-  backend_lookup_state  *b=vd->backend_state;
+  private_state         *b=vd->backend_state;
   bitrate_manager_state *bm=&b->bms;
 
   if(bm->queue_size==0){
index dc5fcb3..81b4fd0 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: PCM data vector blocking, windowing and dis/reassembly
- last mod: $Id: block.c,v 1.67 2002/07/11 06:40:48 xiphmont Exp $
+ last mod: $Id: block.c,v 1.68 2002/10/11 11:14:41 xiphmont Exp $
 
  Handle windowing, overlap-add, etc of the PCM vectors.  This is made
  more amusing by Vorbis' current two allowed block sizes.
@@ -167,7 +167,7 @@ int vorbis_block_clear(vorbis_block *vb){
 static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
   int i;
   codec_setup_info *ci=vi->codec_setup;
-  backend_lookup_state *b=NULL;
+  private_state *b=NULL;
 
   memset(v,0,sizeof(*v));
   b=v->backend_state=_ogg_calloc(1,sizeof(*b));
@@ -263,7 +263,7 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
 
 /* arbitrary settings and spec-mandated numbers get filled in here */
 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
-  backend_lookup_state *b=NULL;
+  private_state *b=NULL;
 
   _vds_shared_init(v,vi,1);
   b=v->backend_state;
@@ -283,7 +283,7 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){
   if(v){
     vorbis_info *vi=v->vi;
     codec_setup_info *ci=(vi?vi->codec_setup:NULL);
-    backend_lookup_state *b=v->backend_state;
+    private_state *b=v->backend_state;
 
     if(b){
       if(b->window[0])
@@ -355,7 +355,7 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){
 float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
   int i;
   vorbis_info *vi=v->vi;
-  backend_lookup_state *b=v->backend_state;
+  private_state *b=v->backend_state;
 
   /* free header, header1, header2 */
   if(b->header)_ogg_free(b->header);b->header=NULL;
@@ -415,7 +415,6 @@ static void _preextrapolate_helper(vorbis_dsp_state *v){
 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
   vorbis_info *vi=v->vi;
   codec_setup_info *ci=vi->codec_setup;
-  /*backend_lookup_state *b=v->backend_state;*/
 
   if(vals<=0){
     int order=32;
@@ -481,9 +480,8 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
   int i;
   vorbis_info *vi=v->vi;
   codec_setup_info *ci=vi->codec_setup;
-  backend_lookup_state *b=v->backend_state;
+  private_state *b=v->backend_state;
   vorbis_look_psy_global *g=b->psy_g_look;
-  vorbis_info_psy_global *gi=&ci->psy_g_param;
   long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
   vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
 
@@ -645,6 +643,7 @@ int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
   v->pcm_returned=-1;
   v->granulepos=-1;
   v->sequence=-1;
+  ((private_state *)(v->backend_state))->sample_count=-1;
 
   return(0);
 }
@@ -656,6 +655,7 @@ int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
   vorbis_info *vi=v->vi;
   codec_setup_info *ci=vi->codec_setup;
+  private_state *b=v->backend_state;
   int i,j;
 
   if(!vb)return(OV_EINVAL);
@@ -665,8 +665,12 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
   v->W=vb->W;
   v->nW=-1;
   
-  if(v->sequence+1 != vb->sequence)v->granulepos=-1; /* out of sequence;
-                                                       lose count */
+  if((v->sequence==-1)||
+     (v->sequence+1 != vb->sequence)){
+    v->granulepos=-1; /* out of sequence; lose count */
+    b->sample_count=-1;
+  }
+
   v->sequence=vb->sequence;
   
   if(vb->pcm){  /* not pcm to process if vorbis_synthesis_trackonly 
@@ -771,10 +775,39 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
      we don't have a starting point to judge where the last frame
      is.  For this reason, vorbisfile will always try to make sure
      it reads the last two marked pages in proper sequence */
+
+  if(b->sample_count==-1){
+    b->sample_count=0;
+  }else{
+    b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
+  }
   
   if(v->granulepos==-1){
     if(vb->granulepos!=-1){ /* only set if we have a position to set to */
+
       v->granulepos=vb->granulepos;
+
+      /* is this a short page? */
+      if(b->sample_count>v->granulepos){
+       /* corner case; if this is both the first and last audio page,
+          then spec says the end is cut, not beginning */
+       if(vb->eofflag){
+         /* trim the end */
+         /* no preceeding granulepos; assume we started at zero (we'd
+            have to in a short single-page stream) */
+         /* granulepos could be -1 due to a seek, but that would result
+            in a long coun`t, not short count */
+         
+         v->pcm_current-=(b->sample_count-v->granulepos);
+       }else{
+         /* trim the beginning */
+         v->pcm_returned+=(b->sample_count-v->granulepos);
+         if(v->pcm_returned>v->pcm_current)
+           v->pcm_returned=v->pcm_current;
+       }
+
+      }
+
     }
   }else{
     v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
@@ -782,21 +815,13 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
       
       if(v->granulepos>vb->granulepos){
        long extra=v->granulepos-vb->granulepos;
-       
-       if(vb->eofflag){
-         /* partial last frame.  Strip the extra samples off */
-         v->pcm_current-=extra;
-       }else if(vb->sequence == 1){
-         /* ^^^ argh, this can be 1 from seeking! */
-         
-         
-         /* partial first frame.  Discard extra leading samples */
-         v->pcm_returned+=extra;
-         if(v->pcm_returned>v->pcm_current)
-           v->pcm_returned=v->pcm_current;
-         
-       } /* else {Shouldn't happen *unless* the bitstream is out of
-            spec.  Either way, believe the bitstream } */
+
+       if(extra)
+         if(vb->eofflag){
+           /* partial last frame.  Strip the extra samples off */
+           v->pcm_current-=extra;
+         } /* else {Shouldn't happen *unless* the bitstream is out of
+              spec.  Either way, believe the bitstream } */
       } /* else {Shouldn't happen *unless* the bitstream is out of
           spec.  Either way, believe the bitstream } */
       v->granulepos=vb->granulepos;
index 4ae0751..392df91 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: libvorbis codec headers
- last mod: $Id: codec_internal.h,v 1.15 2002/06/28 22:19:35 xiphmont Exp $
+ last mod: $Id: codec_internal.h,v 1.16 2002/10/11 11:14:41 xiphmont Exp $
 
  ********************************************************************/
 
@@ -55,7 +55,7 @@ typedef void vorbis_info_mapping;
 #include "psy.h"
 #include "bitrate.h"
 
-typedef struct backend_lookup_state {
+typedef struct private_state {
   /* local lookup storage */
   envelope_lookup        *ve; /* envelope lookup */    
   float                  *window[2];
@@ -78,7 +78,9 @@ typedef struct backend_lookup_state {
 
   bitrate_manager_state bms;
 
-} backend_lookup_state;
+  ogg_int64_t sample_count;
+
+} private_state;
 
 /* codec_setup_info contains all the setup information specific to the
    specific compression/decompression mode in progress (eg,
index 59ebab5..21dcbee 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: PCM data envelope analysis 
- last mod: $Id: envelope.c,v 1.52 2002/07/13 10:18:33 giles Exp $
+ last mod: $Id: envelope.c,v 1.53 2002/10/11 11:14:41 xiphmont Exp $
 
  ********************************************************************/
 
@@ -218,7 +218,7 @@ 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;
-  envelope_lookup *ve=((backend_lookup_state *)(v->backend_state))->ve;
+  envelope_lookup *ve=((private_state *)(v->backend_state))->ve;
   long i,j;
 
   int first=ve->current/ve->searchstep;
@@ -329,7 +329,7 @@ long _ve_envelope_search(vorbis_dsp_state *v){
 }
 
 int _ve_envelope_mark(vorbis_dsp_state *v){
-  envelope_lookup *ve=((backend_lookup_state *)(v->backend_state))->ve;
+  envelope_lookup *ve=((private_state *)(v->backend_state))->ve;
   vorbis_info *vi=v->vi;
   codec_setup_info *ci=vi->codec_setup;
   long centerW=v->centerW;
index d00d0a9..9dca3da 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: maintain the info structure, info <-> header packets
- last mod: $Id: info.c,v 1.60 2002/09/23 21:46:59 xiphmont Exp $
+ last mod: $Id: info.c,v 1.61 2002/10/11 11:14:41 xiphmont Exp $
 
  ********************************************************************/
 
@@ -529,7 +529,7 @@ int vorbis_analysis_headerout(vorbis_dsp_state *v,
   int ret=OV_EIMPL;
   vorbis_info *vi=v->vi;
   oggpack_buffer opb;
-  backend_lookup_state *b=v->backend_state;
+  private_state *b=v->backend_state;
 
   if(!b){
     ret=OV_EFAULT;
index 0e491b9..938db89 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: channel mapping 0 implementation
- last mod: $Id: mapping0.c,v 1.53 2002/07/13 06:12:46 xiphmont Exp $
+ last mod: $Id: mapping0.c,v 1.54 2002/10/11 11:14:41 xiphmont Exp $
 
  ********************************************************************/
 
@@ -243,7 +243,7 @@ static int mapping0_forward(vorbis_block *vb){
   vorbis_dsp_state      *vd=vb->vd;
   vorbis_info           *vi=vd->vi;
   codec_setup_info      *ci=vi->codec_setup;
-  backend_lookup_state  *b=vb->vd->backend_state;
+  private_state         *b=vb->vd->backend_state;
   vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
   int                    n=vb->pcmend;
   int i,j,k;
@@ -652,7 +652,7 @@ static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){
   vorbis_dsp_state     *vd=vb->vd;
   vorbis_info          *vi=vd->vi;
   codec_setup_info     *ci=vi->codec_setup;
-  backend_lookup_state *b=vd->backend_state;
+  private_state        *b=vd->backend_state;
   vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l;
 
   int                   i,j;
index c4f206d..0e9870a 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: 16kHz settings 
- last mod: $Id: psych_16.h,v 1.1 2002/07/10 03:04:22 xiphmont Exp $
+ last mod: $Id: psych_16.h,v 1.2 2002/10/11 11:14:42 xiphmont Exp $
 
  ********************************************************************/
 
@@ -114,7 +114,6 @@ static noise3 _psy_noisebias_16[4]={
 
 static double _noise_thresh_16[4]={ .3,.5,.5,.5 };
 
-static int _noise_start_16_short[3]={ 256,128,9999 };
 static int _noise_start_16[3]={ 256,256,9999 };
 static int _noise_part_16[4]={ 8,8,8,8 };
 
index 1f349c7..d7ed5b6 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: 16kHz settings 
- last mod: $Id: setup_16.h,v 1.4 2002/07/11 10:02:29 xiphmont Exp $
+ last mod: $Id: setup_16.h,v 1.5 2002/10/11 11:14:42 xiphmont Exp $
 
  ********************************************************************/
 
@@ -73,8 +73,8 @@ ve_setup_data_template ve_setup_16_stereo={
   _psy_noise_suppress,
   
   _psy_compand_8,
-  _psy_compand_8_mapping,
-  _psy_compand_8_mapping,
+  _psy_compand_16_mapping,
+  _psy_compand_16_mapping,
 
   {_noise_start_16,_noise_start_16},
   { _noise_part_16, _noise_part_16},
@@ -124,8 +124,8 @@ ve_setup_data_template ve_setup_16_uncoupled={
   _psy_noise_suppress,
   
   _psy_compand_8,
-  _psy_compand_8_mapping,
-  _psy_compand_8_mapping,
+  _psy_compand_16_mapping,
+  _psy_compand_16_mapping,
 
   {_noise_start_16,_noise_start_16},
   { _noise_part_16, _noise_part_16},
index 29b4e34..ec3f5bf 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: single-block PCM synthesis
- last mod: $Id: synthesis.c,v 1.28 2002/07/11 06:40:50 xiphmont Exp $
+ last mod: $Id: synthesis.c,v 1.29 2002/10/11 11:14:41 xiphmont Exp $
 
  ********************************************************************/
 
@@ -25,7 +25,7 @@
 
 int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
   vorbis_dsp_state     *vd=vb->vd;
-  backend_lookup_state *b=vd->backend_state;
+  private_state        *b=vd->backend_state;
   vorbis_info          *vi=vd->vi;
   codec_setup_info     *ci=vi->codec_setup;
   oggpack_buffer       *opb=&vb->opb;
@@ -61,7 +61,7 @@ int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
   
   /* more setup */
   vb->granulepos=op->granulepos;
-  vb->sequence=op->packetno-3; /* first block is third packet */
+  vb->sequence=op->packetno;
   vb->eofflag=op->e_o_s;
 
   /* alloc pcm passback storage */
@@ -81,7 +81,7 @@ int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
    Useful for sequential 'fast forward' */
 int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){
   vorbis_dsp_state     *vd=vb->vd;
-  backend_lookup_state *b=vd->backend_state;
+  private_state        *b=vd->backend_state;
   vorbis_info          *vi=vd->vi;
   codec_setup_info     *ci=vi->codec_setup;
   oggpack_buffer       *opb=&vb->opb;
@@ -114,7 +114,7 @@ int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){
   
   /* more setup */
   vb->granulepos=op->granulepos;
-  vb->sequence=op->packetno-3; /* first block is third packet */
+  vb->sequence=op->packetno;
   vb->eofflag=op->e_o_s;
 
   /* no pcm */