[xiph-cvs] cvs commit: vorbis/lib block.c codec_internal.h mapping0.c synthesis.c vorbisfile.c window.c window.h

Monty xiphmont at xiph.org
Sun Aug 17 22:34:02 PDT 2003



xiphmont    03/08/18 01:34:02

  Modified:    include/vorbis codec.h vorbisfile.h
               lib      block.c codec_internal.h mapping0.c synthesis.c
                        vorbisfile.c window.c window.h
  Log:
  Vorbisfile API addition for game and mod coders;
  
  Do a 'free' sample rate conversion from source rate to half source
  rate by calling ov_halfrate() after ov_open(); Although this is solid
  for immediately desired usage, I want to clean it up a bit before
  advertising it's existence, so no doc addition yet.
  
  Does not break binary API.
  
  Monty

Revision  Changes    Path
1.44      +4 -1      vorbis/include/vorbis/codec.h

Index: codec.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/include/vorbis/codec.h,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- codec.h	4 Mar 2003 21:23:37 -0000	1.43
+++ codec.h	18 Aug 2003 05:34:01 -0000	1.44
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: libvorbis codec headers
- last mod: $Id: codec.h,v 1.43 2003/03/04 21:23:37 xiphmont Exp $
+ last mod: $Id: codec.h,v 1.44 2003/08/18 05:34:01 xiphmont Exp $
 
  ********************************************************************/
 
@@ -212,6 +212,9 @@
 extern int      vorbis_synthesis_read(vorbis_dsp_state *v,int samples);
 extern long     vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op);
 
+extern int      vorbis_synthesis_halfrate(vorbis_info *v,int flag);
+extern int      vorbis_synthesis_halfrate_p(vorbis_info *v);
+
 /* Vorbis ERRORS and return codes ***********************************/
 
 #define OV_FALSE      -1  

<p><p>1.20      +4 -1      vorbis/include/vorbis/vorbisfile.h

Index: vorbisfile.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/include/vorbis/vorbisfile.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- vorbisfile.h	6 Mar 2003 22:03:42 -0000	1.19
+++ vorbisfile.h	18 Aug 2003 05:34:01 -0000	1.20
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.h,v 1.19 2003/03/06 22:03:42 xiphmont Exp $
+ last mod: $Id: vorbisfile.h,v 1.20 2003/08/18 05:34:01 xiphmont Exp $
 
  ********************************************************************/
 
@@ -131,6 +131,9 @@
                     int bigendianp,int word,int sgned,int *bitstream);
 extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2);
 
+extern int ov_halfrate(OggVorbis_File *vf,int flag);
+extern int ov_halfrate_p(OggVorbis_File *vf);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

<p><p>1.73      +32 -27    vorbis/lib/block.c

Index: block.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/block.c,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -r1.72 -r1.73
--- block.c	6 Mar 2003 22:05:26 -0000	1.72
+++ block.c	18 Aug 2003 05:34:01 -0000	1.73
@@ -5,13 +5,13 @@
  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  *                                                                  *
- * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2003             *
  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
 
  function: PCM data vector blocking, windowing and dis/reassembly
- last mod: $Id: block.c,v 1.72 2003/03/06 22:05:26 xiphmont Exp $
+ last mod: $Id: block.c,v 1.73 2003/08/18 05:34:01 xiphmont Exp $
 
  Handle windowing, overlap-add, etc of the PCM vectors.  This is made
  more amusing by Vorbis' current two allowed block sizes.
@@ -168,6 +168,7 @@
   int i;
   codec_setup_info *ci=vi->codec_setup;
   private_state *b=NULL;
+  int hs=ci->halfrate_flag; 
 
   memset(v,0,sizeof(*v));
   b=v->backend_state=_ogg_calloc(1,sizeof(*b));
@@ -182,12 +183,12 @@
 
   b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
   b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
-  mdct_init(b->transform[0][0],ci->blocksizes[0]);
-  mdct_init(b->transform[1][0],ci->blocksizes[1]);
+  mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs);
+  mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs);
 
   /* Vorbis I uses only window type 0 */
-  b->window[0]=_vorbis_window_get(0,ci->blocksizes[0]/2);
-  b->window[1]=_vorbis_window_get(0,ci->blocksizes[1]/2);
+  b->window[0]=ilog2(ci->blocksizes[0])-6;
+  b->window[1]=ilog2(ci->blocksizes[1])-6;
 
   if(encp){ /* encode/decode differ here */
 
@@ -636,14 +637,16 @@
 int vorbis_synthesis_restart(vorbis_dsp_state *v){
   vorbis_info *vi=v->vi;
   codec_setup_info *ci;
+  int hs;
 
   if(!v->backend_state)return -1;
   if(!vi)return -1;
   ci=vi->codec_setup;
   if(!ci)return -1;
+  hs=ci->halfrate_flag; 
 
-  v->centerW=ci->blocksizes[1]/2;
-  v->pcm_current=v->centerW;
+  v->centerW=ci->blocksizes[1]>>(hs+1);
+  v->pcm_current=v->centerW>>hs;
   
   v->pcm_returned=-1;
   v->granulepos=-1;
@@ -669,6 +672,7 @@
   vorbis_info *vi=v->vi;
   codec_setup_info *ci=vi->codec_setup;
   private_state *b=v->backend_state;
+  int hs=ci->halfrate_flag; 
   int i,j;
 
   if(!vb)return(OV_EINVAL);
@@ -688,10 +692,10 @@
   
   if(vb->pcm){  /* no pcm to process if vorbis_synthesis_trackonly 
                    was called on block */
-    int n=ci->blocksizes[v->W]/2;
-    int n0=ci->blocksizes[0]/2;
-    int n1=ci->blocksizes[1]/2;
-    
+    int n=ci->blocksizes[v->W]>>(hs+1);
+    int n0=ci->blocksizes[0]>>(hs+1);
+    int n1=ci->blocksizes[1]>>(hs+1);
+
     int thisCenter;
     int prevCenter;
     
@@ -712,21 +716,19 @@
        to have to constantly shift *or* adjust memory usage.  Don't
        accept a new block until the old is shifted out */
     
-    /* overlap/add PCM */
-    
     for(j=0;j<vi->channels;j++){
       /* the overlap/add section */
       if(v->lW){
         if(v->W){
           /* large/large */
-	  float *w=b->window[1];
+	  float *w=_vorbis_window_get(b->window[1]-hs);
           float *pcm=v->pcm[j]+prevCenter;
           float *p=vb->pcm[j];
           for(i=0;i<n1;i++)
             pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
         }else{
           /* large/small */
-	  float *w=b->window[0];
+	  float *w=_vorbis_window_get(b->window[0]-hs);
           float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
           float *p=vb->pcm[j];
           for(i=0;i<n0;i++)
@@ -735,7 +737,7 @@
       }else{
         if(v->W){
           /* small/large */
-	  float *w=b->window[0];
+	  float *w=_vorbis_window_get(b->window[0]-hs);
           float *pcm=v->pcm[j]+prevCenter;
           float *p=vb->pcm[j]+n1/2-n0/2;
           for(i=0;i<n0;i++)
@@ -744,7 +746,7 @@
             pcm[i]=p[i];
         }else{
           /* small/small */
-	  float *w=b->window[0];
+	  float *w=_vorbis_window_get(b->window[0]-hs);
           float *pcm=v->pcm[j]+prevCenter;
           float *p=vb->pcm[j];
           for(i=0;i<n0;i++)
@@ -776,8 +778,8 @@
     }else{
       v->pcm_returned=prevCenter;
       v->pcm_current=prevCenter+
-	ci->blocksizes[v->lW]/4+
-	ci->blocksizes[v->W]/4;
+	((ci->blocksizes[v->lW]/4+
+	ci->blocksizes[v->W]/4)>>hs);
     }
     
   }
@@ -815,10 +817,10 @@
           /* granulepos could be -1 due to a seek, but that would result
              in a long count, not short count */
           
-	  v->pcm_current-=(b->sample_count-v->granulepos);
+	  v->pcm_current-=(b->sample_count-v->granulepos)>>hs;
         }else{
           /* trim the beginning */
-	  v->pcm_returned+=(b->sample_count-v->granulepos);
+	  v->pcm_returned+=(b->sample_count-v->granulepos)>>hs;
           if(v->pcm_returned>v->pcm_current)
             v->pcm_returned=v->pcm_current;
         }
@@ -836,7 +838,7 @@
         if(extra)
           if(vb->eofflag){
             /* partial last frame.  Strip the extra samples off */
-	    v->pcm_current-=extra;
+	    v->pcm_current-=extra>>hs;
           } /* 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
@@ -855,6 +857,7 @@
 /* pcm==NULL indicates we just want the pending samples, no more */
 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
   vorbis_info *vi=v->vi;
+
   if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
     if(pcm){
       int i;
@@ -881,10 +884,11 @@
 int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
   vorbis_info *vi=v->vi;
   codec_setup_info *ci=vi->codec_setup;
+  int hs=ci->halfrate_flag; 
   
-  int n=ci->blocksizes[v->W]/2;
-  int n0=ci->blocksizes[0]/2;
-  int n1=ci->blocksizes[1]/2;
+  int n=ci->blocksizes[v->W]>>(hs+1);
+  int n0=ci->blocksizes[0]>>(hs+1);
+  int n1=ci->blocksizes[1]>>(hs+1);
   int i,j;
 
   if(v->pcm_returned<0)return 0;
@@ -916,6 +920,7 @@
     v->centerW=0;
   }
   
+  /* solidify buffer into contiguous space */
   if((v->lW^v->W)==1){
     /* long/short or short/long */
     for(j=0;j<vi->channels;j++){
@@ -953,6 +958,6 @@
 
 float *vorbis_window(vorbis_dsp_state *v,int W){
   private_state *b=v->backend_state;
-  return b->window[W];
+  return _vorbis_window_get(b->window[W]);
 }
         

<p><p>1.17      +3 -4      vorbis/lib/codec_internal.h

Index: codec_internal.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/codec_internal.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- codec_internal.h	11 Oct 2002 11:14:41 -0000	1.16
+++ codec_internal.h	18 Aug 2003 05:34:01 -0000	1.17
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: libvorbis codec headers
- last mod: $Id: codec_internal.h,v 1.16 2002/10/11 11:14:41 xiphmont Exp $
+ last mod: $Id: codec_internal.h,v 1.17 2003/08/18 05:34:01 xiphmont Exp $
 
  ********************************************************************/
 
@@ -58,7 +58,7 @@
 typedef struct private_state {
   /* local lookup storage */
   envelope_lookup        *ve; /* envelope lookup */    
-  float                  *window[2];
+  int                     window[2];
   vorbis_look_transform **transform[2];    /* block, type */
   drft_lookup             fft_look[2];
 
@@ -79,7 +79,6 @@
   bitrate_manager_state bms;
 
   ogg_int64_t sample_count;
-
 } private_state;
 
 /* codec_setup_info contains all the setup information specific to the
@@ -125,7 +124,7 @@
   highlevel_encode_setup hi; /* used only by vorbisenc.c.  It's a
                                 highly redundant structure, but
                                 improves clarity of program flow. */
-  
+  int         halfrate_flag; /* painless downsample for decode */  
 } codec_setup_info;
 
 extern vorbis_look_psy_global *_vp_global_look(vorbis_info *vi);

<p><p>1.58      +2 -1      vorbis/lib/mapping0.c

Index: mapping0.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/mapping0.c,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -r1.57 -r1.58
--- mapping0.c	2 Mar 2003 11:45:17 -0000	1.57
+++ mapping0.c	18 Aug 2003 05:34:01 -0000	1.58
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: channel mapping 0 implementation
- last mod: $Id: mapping0.c,v 1.57 2003/03/02 11:45:17 xiphmont Exp $
+ last mod: $Id: mapping0.c,v 1.58 2003/08/18 05:34:01 xiphmont Exp $
 
  ********************************************************************/
 
@@ -654,6 +654,7 @@
   codec_setup_info     *ci=vi->codec_setup;
   private_state        *b=vd->backend_state;
   vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l;
+  int hs=ci->halfrate_flag; 
 
   int                   i,j;
   long                  n=vb->pcmend=ci->blocksizes[vb->W];

<p><p>1.30      +16 -1     vorbis/lib/synthesis.c

Index: synthesis.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/synthesis.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- synthesis.c	11 Oct 2002 11:14:41 -0000	1.29
+++ synthesis.c	18 Aug 2003 05:34:01 -0000	1.30
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: single-block PCM synthesis
- last mod: $Id: synthesis.c,v 1.29 2002/10/11 11:14:41 xiphmont Exp $
+ last mod: $Id: synthesis.c,v 1.30 2003/08/18 05:34:01 xiphmont Exp $
 
  ********************************************************************/
 
@@ -152,4 +152,19 @@
   return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
 }
 
+int vorbis_synthesis_halfrate(vorbis_info *vi,int flag){
+  /* set / clear half-sample-rate mode */
+  codec_setup_info     *ci=vi->codec_setup;
+  
+  /* right now, our MDCT can't handle < 64 sample windows. */
+  if(ci->blocksizes[0]<=64 && flag)return -1;
+  ci->halfrate_flag=(flag?1:0);
+  return 0;
+}
+
+int vorbis_synthesis_halfrate_p(vorbis_info *vi){
+  codec_setup_info     *ci=vi->codec_setup;
+  return ci->halfrate_flag;
+}
+
 

<p><p>1.70      +29 -1     vorbis/lib/vorbisfile.c

Index: vorbisfile.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/vorbisfile.c,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -r1.69 -r1.70
--- vorbisfile.c	11 Mar 2003 23:52:02 -0000	1.69
+++ vorbisfile.c	18 Aug 2003 05:34:01 -0000	1.70
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.c,v 1.69 2003/03/11 23:52:02 xiphmont Exp $
+ last mod: $Id: vorbisfile.c,v 1.70 2003/08/18 05:34:01 xiphmont Exp $
 
  ********************************************************************/
 
@@ -735,7 +735,35 @@
 
   return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
 }
+ 
+/* cheap hack for game usage where downsampling is desirable; there's
+   no need for SRC as we can just do it cheaply in libvorbis. */
+ 
+int ov_halfrate(OggVorbis_File *vf,int flag){
+  int i;
+  if(vf->vi==NULL)return OV_EINVAL;
+  if(!vf->seekable)return OV_EINVAL;
+  if(vf->ready_state>=STREAMSET)
+    _decode_clear(vf); /* clear out stream state; later on libvorbis
+                          will be able to swap this on the fly, but
+                          for now dumping the decode machine is needed
+                          to reinit the MDCT lookups.  1.1 libvorbis
+                          is planned to be able to switch on the fly */
   
+  for(i=0;i<vf->links;i++){
+    if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
+      ov_halfrate(vf,0);
+      return OV_EINVAL;
+    }
+  }
+  return 0;
+}
+
+int ov_halfrate_p(OggVorbis_File *vf){
+  if(vf->vi==NULL)return OV_EINVAL;
+  return vorbis_synthesis_halfrate_p(vf->vi);
+}
+
 /* Only partially open the vorbis file; test for Vorbisness, and load
    the headers for the first chain.  Do not seek (although test for
    seekability).  Use ov_test_open to finish opening the file, else

<p><p>1.22      +20 -29    vorbis/lib/window.c

Index: window.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/window.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- window.c	6 Mar 2003 22:05:26 -0000	1.21
+++ window.c	18 Aug 2003 05:34:01 -0000	1.22
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: window functions
- last mod: $Id: window.c,v 1.21 2003/03/06 22:05:26 xiphmont Exp $
+ last mod: $Id: window.c,v 1.22 2003/08/18 05:34:01 xiphmont Exp $
 
  ********************************************************************/
 
@@ -2084,35 +2084,26 @@
   1.0000000000F, 1.0000000000F, 1.0000000000F, 1.0000000000F, 
 };
 
-float *_vorbis_window_get(int type, int left){
-  switch(type){
-  case 0:
-    /* The 'vorbis window' (window 0) is sin(sin(x)*sin(x)*pi*.5) */
-    switch(left){
-    case 32:
-      return(vwin64);
-    case 64:
-      return(vwin128);
-    case 128:
-      return(vwin256);
-    case 256:
-      return(vwin512);
-    case 512:
-      return(vwin1024);
-    case 1024:
-      return(vwin2048);
-    case 2048:
-      return(vwin4096);
-    case 4096:
-      return(vwin8192);
-    }
-  default:
-    return(NULL);
-  }
+static float *vwin[8] = {
+  vwin64,
+  vwin128,
+  vwin256,
+  vwin512,
+  vwin1024,
+  vwin2048,
+  vwin4096,
+  vwin8192,
+};
+
+float *_vorbis_window_get(int n){
+  return vwin[n];
 }
 
-void _vorbis_apply_window(float *d,float *window[2],long *blocksizes,
+void _vorbis_apply_window(float *d,int *winno,long *blocksizes,
                           int lW,int W,int nW){
+  float *windowLW=vwin[winno[lW]];
+  float *windowNW=vwin[winno[nW]];
+
   lW=(W?lW:0);
   nW=(W?nW:0);
 
@@ -2133,10 +2124,10 @@
       d[i]=0.f;
     
     for(p=0;i<leftend;i++,p++)
-      d[i]*=window[lW][p];
+      d[i]*=windowLW[p];
     
     for(i=rightbegin,p=rn/2-1;i<rightend;i++,p--)
-      d[i]*=window[nW][p];
+      d[i]*=windowNW[p];
     
     for(;i<n;i++)
       d[i]=0.f;

<p><p>1.13      +2 -2      vorbis/lib/window.h

Index: window.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/window.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- window.h	6 Mar 2003 22:05:26 -0000	1.12
+++ window.h	18 Aug 2003 05:34:01 -0000	1.13
@@ -11,14 +11,14 @@
  ********************************************************************
 
  function: window functions
- last mod: $Id: window.h,v 1.12 2003/03/06 22:05:26 xiphmont Exp $
+ last mod: $Id: window.h,v 1.13 2003/08/18 05:34:01 xiphmont Exp $
 
  ********************************************************************/
 
 #ifndef _V_WINDOW_
 #define _V_WINDOW_
 
-extern float *_vorbis_window_get(int type,int left);
+extern float *_vorbis_window_get(int n);
 extern void _vorbis_apply_window(float *d,float *window[2],long *blocksizes,
                                  int lW,int W,int nW);
 

<p><p>--- >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