OK, libvorbis encodes and decodes bitstreams (not complete Vorbis
authorMonty <xiphmont@xiph.org>
Sun, 10 Oct 1999 20:32:30 +0000 (20:32 +0000)
committerMonty <xiphmont@xiph.org>
Sun, 10 Oct 1999 20:32:30 +0000 (20:32 +0000)
bitstreams, but they work).  Lib and examples debugged.  Lib does not
yet do *any* backend compression and it's slow as hell.  We address
both next.

Monty

svn path=/trunk/vorbis/; revision=143

16 files changed:
lib/Makefile.in
lib/analysis.c
lib/bitwise.c
lib/bitwise.h
lib/block.c
lib/codec.h
lib/decoder_example.c
lib/envelope.c
lib/envelope.h
lib/info.c
lib/mdct.c
lib/modes.h
lib/psy.c
lib/spectrum.c [new file with mode: 0644]
lib/spectrum.h [new file with mode: 0644]
lib/synthesis.c

index 96a046a..2d3cdc4 100644 (file)
@@ -1,6 +1,6 @@
 # vorbis makefile configured for use with gcc on any platform
 
-# $Id: Makefile.in,v 1.10 1999/10/05 15:34:56 xiphmont Exp $
+# $Id: Makefile.in,v 1.11 1999/10/10 20:32:17 xiphmont Exp $
 
 ###############################################################################
 #                                                                             #
@@ -31,7 +31,8 @@ HFILES =      mdct.h codec.h bitwise.h envelope.h lpc.h lsp.h modes.h\
                psy.h smallft.h window.h xlogmap.h
 
 LFILES =       framing.o mdct.o smallft.o block.o envelope.o window.o\
-               lsp.o lpc.o analysis.o synthesis.o psy.o info.o bitwise.o
+               lsp.o lpc.o analysis.o synthesis.o psy.o info.o bitwise.o\
+               spectrum.o
 
 EFILES =       encoder_example.o decoder_example.o
 
index 7f54a20..d617d6a 100644 (file)
@@ -14,7 +14,7 @@
  function: single-block PCM analysis
  author: Monty <xiphmont@mit.edu>
  modifications by: Monty
- last modification date: Oct 4 1999
+ last modification date: Oct 7 1999
 
  ********************************************************************/
 
 #include "envelope.h"
 #include "mdct.h"
 #include "psy.h"
+#include "bitwise.h"
+#include "spectrum.h"
 
 /* this code is still seriously abbreviated.  I'm filling in pieces as
    we go... --Monty 19991004 */
 
 int vorbis_analysis(vorbis_block *vb,ogg_packet *op){
+  static int frameno=0;
+  
   int i;
   double           *window=vb->vd->window[vb->W][vb->lW][vb->nW];
   lpc_lookup       *vl=&vb->vd->vl[vb->W];
-  vorbis_dsp_state *vd=vi->vd;
+  vorbis_dsp_state *vd=vb->vd;
   vorbis_info      *vi=vd->vi;
+  oggpack_buffer   *opb=&vb->opb;
+
   int              n=vb->pcmend;
+  int              spectral_order=vi->floororder[vb->W];
 
   /*lpc_lookup       *vbal=&vb->vd->vbal[vb->W];
     double balance_v[vbal->m];
     double balance_amp;*/
 
-  /* we have the preecho metrics; decie what to do with them */
-  _ve_envelope_sparsify(vb);
-  _ve_envelope_apply(vb,0);
+  /* first things first.  Make sure encode is ready*/
+  _oggpack_reset(opb);
+  /* Encode the packet type */
+  _oggpack_write(opb,0,1);
+  /* Encode the block size */
+  _oggpack_write(opb,vb->W,1);
+
+  /* we have the preecho metrics; decide what to do with them */
+  /*_ve_envelope_sparsify(vb);
+    _ve_envelope_apply(vb,0);*/
+
+  /* Encode the envelope */
+  /*if(_ve_envelope_encode(vb))return(-1);*/
   
+  /* time domain PCM -> MDCT domain */
   for(i=0;i<vi->channels;i++)
     mdct_forward(&vd->vm[vb->W],vb->pcm[i],vb->pcm[i],window);
 
+  /* no balance yet */
+    
+  /* extract the spectral envelope and residue */
+  /* just do by channel.  No coupling yet */
+  {
+    for(i=0;i<vi->channels;i++){
+      double floor[n/2];
+      double curve[n/2];
+      double *lpc=vb->lpc[i];
+      double *lsp=vb->lsp[i];
+
+      memset(floor,0,sizeof(double)*n/2);
+      
+      _vp_noise_floor(vb->pcm[i],floor,n/2);
+      _vp_mask_floor(vb->pcm[i],floor,n/2);
+
+      /* Convert our floor to a set of lpc coefficients */
+      vb->amp[i]=sqrt(vorbis_curve_to_lpc(floor,lpc,vl));
+
+      /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
+      vorbis_lpc_to_lsp(lpc,lsp,vl->m);
+
+      /* code the spectral envelope; mutates the lsp coeffs to reflect
+         what was actually encoded */
+      _vs_spectrum_encode(vb,vb->amp[i],lsp);
+
+      /* Generate residue from the decoded envelope, which will be
+         slightly different to the pre-encoding floor due to
+         quantization.  Slow, yes, but perhaps more accurate */
+
+      vorbis_lsp_to_lpc(lsp,lpc,vl->m); 
+      vorbis_lpc_to_curve(curve,lpc,vb->amp[i],vl);
+      
+      /* this may do various interesting massaging too...*/
+      _vs_residue_quantize(vb->pcm[i],curve,vi,n/2);
+
+      /* encode the residue */
+      _vs_residue_encode(vb,vb->pcm[i]);
+
+    }
+  }
+
+  /* set up the packet wrapper */
+
+  op->packet=opb->buffer;
+  op->bytes=_oggpack_bytes(opb);
+  op->b_o_s=0;
+  op->e_o_s=vb->eofflag;
+  op->frameno=vb->frameno;
+
+  return(0);
+}
+
+
+
 
-  /* no balance or channel coupling yet */
+/* commented out, relocated balance stuff */
   /*{
     double *C=vb->pcm[0];
     double *D=vb->pcm[1];
@@ -115,103 +188,3 @@ int vorbis_analysis(vorbis_block *vb,ogg_packet *op){
       
     }
   }*/
-    
-  /* extract the spectral envelope and residue */
-  /* just do by channel.  No coupling yet */
-  {
-    for(i=0;i<vi->channels;vi++){
-      double floor[n/2];
-      double curve[n/2];
-      double *lpc=vb->lpc[i];
-      double *lsp=vb->lsp[i];
-
-      memset(floor,0,sizeof(double)*n/2);
-      
-      _vp_noise_floor(vb->pcm[i],floor,n/2);
-      _vp_mask_floor(vb->pcm[i],floor,n/2);
-      vb->amp[i]=sqrt(vorbis_curve_to_lpc(floor,lpc,vl));
-
-      vorbis_lpc_to_lsp(lpc,lsp,vl->m);
-      
-      {
-       /* make this scale configurable */
-       int scale=1020;
-       int last=0;
-       for(i=0;i<vl->m;i++){
-         double q=lsp[i]/M_PI*scale;
-         int val=rint(q-last);
-         
-         last+=val;
-         lsp[i]=val;
-         
-       }
-      }
-      
-      /* make residue.  Get the floor curve back from LPC (do we want
-         to recover all the way from LSP in the future?  Yes, once the
-         residue massaging is smarter) */
-
-     vorbis_lpc_to_curve(work,lpc1,amp1,vl);
-      
-      _vp_psy_quantize(C,work,n/2);
-      _vp_psy_quantize(D,work,n/2);
-      
-      _vp_psy_unquantize(C,work,n/2);
-      _vp_psy_unquantize(D,work,n/2);
-      
-      
-      {
-       FILE *out;
-       char buffer[80];
-       
-       
-       /*sprintf(buffer,"qC%d.m",frameno);
-         out=fopen(buffer,"w+");
-         for(i=0;i<n/2;i++)
-         fprintf(out,"%g\n",fabs(C[i]));
-         fclose(out);
-         
-         sprintf(buffer,"qD%d.m",frameno);
-         out=fopen(buffer,"w+");
-         for(i=0;i<n/2;i++)
-         fprintf(out,"%g\n",fabs(D[i]));
-         fclose(out);
-         
-         sprintf(buffer,"floor%d.m",frameno);
-         out=fopen(buffer,"w+");
-         for(i=0;i<n/2;i++)
-         fprintf(out,"%g\n",floor1[i]);
-         fclose(out);
-         
-         sprintf(buffer,"lpc%d.m",frameno);
-         out=fopen(buffer,"w+");
-         for(i=0;i<n/2;i++)
-         fprintf(out,"%g\n",work[i]);
-         fclose(out);
-         
-         sprintf(buffer,"curve%d.m",frameno);
-         out=fopen(buffer,"w+");
-         for(i=0;i<n/2;i++)
-         fprintf(out,"%g\n",curve[i]);
-         fclose(out);
-         
-         sprintf(buffer,"lsp%d.m",frameno);
-         out=fopen(buffer,"w+");
-         for(i=0;i<30;i++){
-         fprintf(out,"%g 0.\n",lsp1[i]);
-         fprintf(out,"%g .1\n",lsp1[i]);
-         fprintf(out,"\n");
-         fprintf(out,"\n");
-         }
-         fclose(out);*/
-       
-       frameno++;
-      }
-    }
-    /* unmix */
-    _vp_balance_apply(D,C,balance_v,balance_amp,vbal,0);
-  }
-
-  return(0);
-}
-
index ffc02ce..ec4bd67 100644 (file)
@@ -48,7 +48,7 @@ void _oggpack_reset(oggpack_buffer *b){
   b->endbit=b->endbyte=0;
 }
 
-void _oggpack_writefree(oggpack_buffer *b){
+void _oggpack_writeclear(oggpack_buffer *b){
   free(b->buffer);
   memset(b,0,sizeof(oggpack_buffer));
 }
index 19a5d4e..c614946 100644 (file)
@@ -22,7 +22,7 @@
 
 extern void _oggpack_writeinit(oggpack_buffer *b);
 extern void _oggpack_reset(oggpack_buffer *b);
-extern void _oggpack_writefree(oggpack_buffer *b);
+extern void _oggpack_writeclear(oggpack_buffer *b);
 extern void _oggpack_readinit(oggpack_buffer *b,char *buf,int bytes);
 extern void _oggpack_write(oggpack_buffer *b,unsigned long value,int bits);
 extern long _oggpack_look(oggpack_buffer *b,int bits);
index 3dafdab..eb003a9 100644 (file)
 
 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
   int i;
+  vorbis_info *vi=v->vi;
   memset(vb,0,sizeof(vorbis_block));
   vb->vd=v;
 
-  vb->pcm_storage=v->block_size[1];
-  vb->pcm_channels=v->pcm_channels;
-  vb->mult_storage=v->block_size[1]/v->samples_per_envelope_step;
-  vb->mult_channels=v->envelope_channels;
-  vb->floor_channels=v->vi.floorch;
-  vb->floor_storage=v->vi.floororder;
+  vb->pcm_storage=vi->blocksize[1];
+  vb->pcm_channels=vi->channels;
+  vb->mult_storage=vi->blocksize[1]/vi->envelopesa;
+  vb->mult_channels=vi->envelopech;
+  vb->floor_channels=vi->floorch;
+  vb->floor_storage=max(vi->floororder[0],vi->floororder[1]);
   
   vb->pcm=malloc(vb->pcm_channels*sizeof(double *));
   for(i=0;i<vb->pcm_channels;i++)
@@ -100,6 +101,8 @@ int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
     vb->lsp[i]=malloc(vb->floor_storage*sizeof(double));
     vb->lpc[i]=malloc(vb->floor_storage*sizeof(double));
   }
+  if(v->analysisp)
+    _oggpack_writeinit(&vb->opb);
 
   return(0);
 }
@@ -116,6 +119,9 @@ int vorbis_block_clear(vorbis_block *vb){
       free(vb->mult[i]);
     free(vb->mult);
   }
+  if(vb->vd->analysisp)
+    _oggpack_writeclear(&vb->opb);
+
   memset(vb,0,sizeof(vorbis_block));
   return(0);
 }
@@ -127,29 +133,25 @@ int vorbis_block_clear(vorbis_block *vb){
 static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi){
   memset(v,0,sizeof(vorbis_dsp_state));
 
-  memcpy(&v->vi,vi,sizeof(vorbis_info));
+  v->vi=vi;
   _ve_envelope_init(&v->ve,vi->envelopesa);
-  mdct_init(&v->vm[0],vi->smallblock);
-  mdct_init(&v->vm[1],vi->largeblock);
+  mdct_init(&v->vm[0],vi->blocksize[0]);
+  mdct_init(&v->vm[1],vi->blocksize[1]);
 
-  v->samples_per_envelope_step=vi->envelopesa;
-  v->block_size[0]=vi->smallblock;
-  v->block_size[1]=vi->largeblock;
-  
-  v->window[0][0][0]=_vorbis_window(v->block_size[0],
-                                  v->block_size[0]/2,v->block_size[0]/2);
+  v->window[0][0][0]=_vorbis_window(vi->blocksize[0],
+                                  vi->blocksize[0]/2,vi->blocksize[0]/2);
   v->window[0][0][1]=v->window[0][0][0];
   v->window[0][1][0]=v->window[0][0][0];
   v->window[0][1][1]=v->window[0][0][0];
 
-  v->window[1][0][0]=_vorbis_window(v->block_size[1],
-                                  v->block_size[0]/2,v->block_size[0]/2);
-  v->window[1][0][1]=_vorbis_window(v->block_size[1],
-                                  v->block_size[0]/2,v->block_size[1]/2);
-  v->window[1][1][0]=_vorbis_window(v->block_size[1],
-                                  v->block_size[1]/2,v->block_size[0]/2);
-  v->window[1][1][1]=_vorbis_window(v->block_size[1],
-                                   v->block_size[1]/2,v->block_size[1]/2);
+  v->window[1][0][0]=_vorbis_window(vi->blocksize[1],
+                                  vi->blocksize[0]/2,vi->blocksize[0]/2);
+  v->window[1][0][1]=_vorbis_window(vi->blocksize[1],
+                                  vi->blocksize[0]/2,vi->blocksize[1]/2);
+  v->window[1][1][0]=_vorbis_window(vi->blocksize[1],
+                                  vi->blocksize[1]/2,vi->blocksize[0]/2);
+  v->window[1][1][1]=_vorbis_window(vi->blocksize[1],
+                                   vi->blocksize[1]/2,vi->blocksize[1]/2);
 
   /* initialize the storage vectors to a decent size greater than the
      minimum */
@@ -157,7 +159,6 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi){
   v->pcm_storage=8192; /* we'll assume later that we have
                          a minimum of twice the blocksize of
                          accumulated samples in analysis */
-  v->pcm_channels=v->vi.channels=vi->channels;
   v->pcm=malloc(vi->channels*sizeof(double *));
   v->pcmret=malloc(vi->channels*sizeof(double *));
   {
@@ -169,12 +170,11 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi){
   /* Initialize the envelope multiplier storage */
 
   if(vi->envelopech){
-    v->envelope_storage=v->pcm_storage/v->samples_per_envelope_step;
-    v->envelope_channels=vi->envelopech;
-    v->multipliers=calloc(v->envelope_channels,sizeof(double *));
+    v->envelope_storage=v->pcm_storage/vi->envelopesa;
+    v->multipliers=calloc(vi->envelopech,sizeof(double *));
     {
       int i;
-      for(i=0;i<v->envelope_channels;i++){
+      for(i=0;i<vi->envelopech;i++){
        v->multipliers[i]=calloc(v->envelope_storage,sizeof(double));
       }
     }
@@ -186,10 +186,10 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi){
   v->W=0;  /* current window size */
 
   /* all vector indexes; multiples of samples_per_envelope_step */
-  v->centerW=v->block_size[1]/2;
+  v->centerW=vi->blocksize[1]/2;
 
   v->pcm_current=v->centerW;
-  v->envelope_current=v->centerW/v->samples_per_envelope_step;
+  v->envelope_current=v->centerW/vi->envelopesa;
   return(0);
 }
 
@@ -197,17 +197,20 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi){
 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
   _vds_shared_init(v,vi);
 
+  /* the coder init is different for read/write */
+  v->analysisp=1;
+
   /* Yes, wasteful to have four lookups.  This will get collapsed once
      things crystallize */
-  lpc_init(&v->vl[0],vi->smallblock/2,vi->smallblock/2,
-          vi->floororder,vi->flooroctaves,1);
-  lpc_init(&v->vl[1],vi->largeblock/2,vi->largeblock/2,
-          vi->floororder,vi->flooroctaves,1);
+  lpc_init(&v->vl[0],vi->blocksize[0]/2,vi->blocksize[0]/2,
+          vi->floororder[0],vi->flooroctaves[0],1);
+  lpc_init(&v->vl[1],vi->blocksize[1]/2,vi->blocksize[1]/2,
+          vi->floororder[0],vi->flooroctaves[0],1);
 
-  lpc_init(&v->vbal[0],vi->smallblock/2,256,
-          vi->balanceorder,vi->balanceoctaves,1);
-  lpc_init(&v->vbal[1],vi->largeblock/2,256,
+  /*lpc_init(&v->vbal[0],vi->blocksize[0]/2,256,
           vi->balanceorder,vi->balanceoctaves,1);
+  lpc_init(&v->vbal[1],vi->blocksize[1]/2,256,
+           vi->balanceorder,vi->balanceoctaves,1);*/
 
   return(0);
 }
@@ -215,19 +218,20 @@ int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
 void vorbis_dsp_clear(vorbis_dsp_state *v){
   int i,j,k;
   if(v){
+    vorbis_info *vi=v->vi;
 
     if(v->window[0][0][0])free(v->window[0][0][0]);
     for(j=0;j<2;j++)
       for(k=0;k<2;k++)
        if(v->window[1][j][k])free(v->window[1][j][k]);
     if(v->pcm){
-      for(i=0;i<v->pcm_channels;i++)
+      for(i=0;i<vi->channels;i++)
        if(v->pcm[i])free(v->pcm[i]);
       free(v->pcm);
       if(v->pcmret)free(v->pcmret);
     }
     if(v->multipliers){
-      for(i=0;i<v->envelope_channels;i++)
+      for(i=0;i<vi->envelopech;i++)
        if(v->multipliers[i])free(v->multipliers[i]);
       free(v->multipliers);
     }
@@ -236,32 +240,33 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){
     mdct_clear(&v->vm[1]);
     lpc_clear(&v->vl[0]);
     lpc_clear(&v->vl[1]);
-    lpc_clear(&v->vbal[0]);
-    lpc_clear(&v->vbal[1]);
+    /*lpc_clear(&v->vbal[0]);
+      lpc_clear(&v->vbal[1]);*/
     memset(v,0,sizeof(vorbis_dsp_state));
   }
 }
 
 double **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
   int i;
+  vorbis_info *vi=v->vi;
 
   /* Do we have enough storage space for the requested buffer? If not,
      expand the PCM (and envelope) storage */
     
   if(v->pcm_current+vals>=v->pcm_storage){
     v->pcm_storage=v->pcm_current+vals*2;
-    v->envelope_storage=v->pcm_storage/v->samples_per_envelope_step;
+    v->envelope_storage=v->pcm_storage/v->vi->envelopesa;
    
-    for(i=0;i<v->pcm_channels;i++){
+    for(i=0;i<vi->channels;i++){
       v->pcm[i]=realloc(v->pcm[i],v->pcm_storage*sizeof(double));
     }
-    for(i=0;i<v->envelope_channels;i++){
+    for(i=0;i<vi->envelopech;i++){
       v->multipliers[i]=realloc(v->multipliers[i],
                                v->envelope_storage*sizeof(double));
     }
   }
 
-  for(i=0;i<v->pcm_channels;i++)
+  for(i=0;i<vi->channels;i++)
     v->pcmret[i]=v->pcm[i]+v->pcm_current;
     
   return(v->pcmret);
@@ -270,15 +275,16 @@ double **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
 /* call with val<=0 to set eof */
 
 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
+  vorbis_info *vi=v->vi;
   if(vals<=0){
     /* We're encoding the end of the stream.  Just make sure we have
        [at least] a full block of zeroes at the end. */
 
     int i;
-    vorbis_analysis_buffer(v,v->block_size[1]*2);
+    vorbis_analysis_buffer(v,v->vi->blocksize[1]*2);
     v->eofflag=v->pcm_current;
-    v->pcm_current+=v->block_size[1]*2;
-    for(i=0;i<v->pcm_channels;i++)
+    v->pcm_current+=v->vi->blocksize[1]*2;
+    for(i=0;i<vi->channels;i++)
       memset(v->pcm[i]+v->eofflag,0,
             (v->pcm_current-v->eofflag)*sizeof(double));
   }else{
@@ -295,8 +301,9 @@ int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
    the next block on which to continue analysis */
 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
   int i,j;
-  long beginW=v->centerW-v->block_size[v->W]/2,centerNext;
-  long beginM=beginW/v->samples_per_envelope_step;
+  vorbis_info *vi=v->vi;
+  long beginW=v->centerW-vi->blocksize[v->W]/2,centerNext;
+  long beginM=beginW/vi->envelopesa;
 
   /* check to see if we're done... */
   if(v->eofflag==-1)return(0);
@@ -304,7 +311,7 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
   /* if we have any unfilled envelope blocks for which we have PCM
      data, fill them up in before proceeding. */
 
-  if(v->pcm_current/v->samples_per_envelope_step>v->envelope_current){
+  if(v->pcm_current/vi->envelopesa>v->envelope_current){
     /* This generates the multipliers, but does not sparsify the vector.
        That's done by block before coding */
     _ve_envelope_multipliers(v);
@@ -317,22 +324,22 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
   /* overconserve for now; any block with a non-placeholder multiplier
      should be minimal size. We can be greedy and only look at nW size */
   
-  if(v->vi.smallblock<v->vi.largeblock){
+  if(vi->blocksize[0]<vi->blocksize[1]){
     
     if(v->W)
       /* this is a long window; we start the search forward of centerW
         because that's the fastest we could react anyway */
-      i=v->centerW+v->block_size[1]/4-v->block_size[0]/4;
+      i=v->centerW+vi->blocksize[1]/4-vi->blocksize[0]/4;
     else
       /* short window.  Search from centerW */
       i=v->centerW;
-    i/=v->samples_per_envelope_step;
+    i/=vi->envelopesa;
     
     for(;i<v->envelope_current;i++){
-      for(j=0;j<v->envelope_channels;j++)
-       if(v->multipliers[j][i-1]*v->vi.preecho_thresh<  
+      for(j=0;j<vi->envelopech;j++)
+       if(v->multipliers[j][i-1]*vi->preecho_thresh<  
           v->multipliers[j][i])break;
-      if(j<v->envelope_channels)break;
+      if(j<vi->envelopech)break;
     }
     
     if(i<v->envelope_current){
@@ -340,10 +347,10 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
         upcoming block large ? */
       long largebound;
       if(v->W)
-       largebound=v->centerW+v->block_size[1];
+       largebound=v->centerW+vi->blocksize[1];
       else
-       largebound=v->centerW+v->block_size[0]/4+v->block_size[1]*3/4;
-      largebound/=v->samples_per_envelope_step;
+       largebound=v->centerW+vi->blocksize[0]/4+vi->blocksize[1]*3/4;
+      largebound/=vi->envelopesa;
       
       if(i>=largebound)
        v->nW=1;
@@ -365,10 +372,10 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
      know the size of the next block for sure and we need that now to
      figure out the window shape of this block */
   
-  centerNext=v->centerW+v->block_size[v->W]/4+v->block_size[v->nW]/4;
+  centerNext=v->centerW+vi->blocksize[v->W]/4+vi->blocksize[v->nW]/4;
 
   {
-    long blockbound=centerNext+v->block_size[v->nW]/2;
+    long blockbound=centerNext+vi->blocksize[v->nW]/2;
     if(v->pcm_current<blockbound)return(0); /* not enough data yet */    
   }
 
@@ -378,28 +385,15 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
   vb->nW=v->nW;
   vb->vd=v;
 
-  vb->pcmend=v->block_size[v->W];
-  vb->multend=vb->pcmend / v->samples_per_envelope_step;
-
-  if(vb->floor_channels!=v->vi.floorch ||
-     vb->floor_storage!=v->vi.floororder ||
-     v->pcm_channels!=vb->pcm_channels ||
-     v->block_size[1]!=vb->pcm_storage ||
-     v->envelope_channels!=vb->mult_channels){
-
-    /* Storage not initialized or initilized for some other codec
-       instance with different settings */
-
-    vorbis_block_clear(vb);
-    vorbis_block_init(v,vb);
-  }
+  vb->pcmend=vi->blocksize[v->W];
+  vb->multend=vb->pcmend / vi->envelopesa;
 
   /* copy the vectors */
-  for(i=0;i<v->pcm_channels;i++)
-    memcpy(vb->pcm[i],v->pcm[i]+beginW,v->block_size[v->W]*sizeof(double));
-  for(i=0;i<v->envelope_channels;i++)
-    memcpy(vb->mult[i],v->multipliers[i]+beginM,v->block_size[v->W]/
-          v->samples_per_envelope_step*sizeof(double));
+  for(i=0;i<vi->channels;i++)
+    memcpy(vb->pcm[i],v->pcm[i]+beginW,vi->blocksize[v->W]*sizeof(double));
+  for(i=0;i<vi->envelopech;i++)
+    memcpy(vb->mult[i],v->multipliers[i]+beginM,vi->blocksize[v->W]/
+          vi->envelopesa*sizeof(double));
 
   vb->frameno=v->frame;
 
@@ -416,19 +410,19 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
 
   /* advance storage vectors and clean up */
   {
-    int new_centerNext=v->block_size[1]/2;
+    int new_centerNext=vi->blocksize[1]/2;
     int movementW=centerNext-new_centerNext;
-    int movementM=movementW/v->samples_per_envelope_step;
+    int movementM=movementW/vi->envelopesa;
 
     /* the multipliers and pcm stay synced up because the blocksizes
        must be multiples of samples_per_envelope_step (minimum
        multiple is 2) */
 
-    for(i=0;i<v->pcm_channels;i++)
+    for(i=0;i<vi->channels;i++)
       memmove(v->pcm[i],v->pcm[i]+movementW,
              (v->pcm_current-movementW)*sizeof(double));
     
-    for(i=0;i<v->envelope_channels;i++){
+    for(i=0;i<vi->envelopech;i++){
       memmove(v->multipliers[i],v->multipliers[i]+movementM,
              (v->envelope_current-movementM)*sizeof(double));
     }
@@ -459,19 +453,19 @@ int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
 
   /* Yes, wasteful to have four lookups.  This will get collapsed once
      things crystallize */
-  lpc_init(&v->vl[0],vi->smallblock/2,vi->smallblock/2,
-          vi->floororder,vi->flooroctaves,0);
-  lpc_init(&v->vl[1],vi->largeblock/2,vi->largeblock/2,
-          vi->floororder,vi->flooroctaves,0);
-  lpc_init(&v->vbal[0],vi->smallblock/2,256,
-          vi->balanceorder,vi->balanceoctaves,0);
-  lpc_init(&v->vbal[1],vi->largeblock/2,256,
+  lpc_init(&v->vl[0],vi->blocksize[0]/2,vi->blocksize[0]/2,
+          vi->floororder[0],vi->flooroctaves[0],0);
+  lpc_init(&v->vl[1],vi->blocksize[1]/2,vi->blocksize[1]/2,
+          vi->floororder[1],vi->flooroctaves[1],0);
+  /*lpc_init(&v->vbal[0],vi->blocksize[0]/2,256,
           vi->balanceorder,vi->balanceoctaves,0);
+  lpc_init(&v->vbal[1],vi->blocksize[1]/2,256,
+           vi->balanceorder,vi->balanceoctaves,0);*/
 
 
   /* Adjust centerW to allow an easier mechanism for determining output */
   v->pcm_returned=v->centerW;
-  v->centerW-= v->block_size[v->W]/4+v->block_size[v->lW]/4;
+  v->centerW-= vi->blocksize[v->W]/4+vi->blocksize[v->lW]/4;
   return(0);
 }
 
@@ -480,15 +474,16 @@ int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
    each block) */
 
 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
+  vorbis_info *vi=v->vi;
 
   /* Shift out any PCM that we returned previously */
 
-  if(v->pcm_returned  && v->centerW>v->block_size[1]/2){
+  if(v->pcm_returned  && v->centerW>vi->blocksize[1]/2){
 
     /* don't shift too much; we need to have a minimum PCM buffer of
        1/2 long block */
 
-    int shift=v->centerW-v->block_size[1]/2;
+    int shift=v->centerW-vi->blocksize[1]/2;
     shift=(v->pcm_returned<shift?v->pcm_returned:shift);
 
     v->pcm_current-=shift;
@@ -497,15 +492,18 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
     
     if(shift){
       int i;
-      for(i=0;i<v->pcm_channels;i++)
+      for(i=0;i<vi->channels;i++)
        memmove(v->pcm[i],v->pcm[i]+shift,
                v->pcm_current*sizeof(double));
     }
   }
 
+  v->lW=v->W;
+  v->W=vb->W;
+
   {
-    int sizeW=v->block_size[vb->W];
-    int centerW=v->centerW+v->block_size[vb->lW]/4+sizeW/4;
+    int sizeW=vi->blocksize[v->W];
+    int centerW=v->centerW+vi->blocksize[v->lW]/4+sizeW/4;
     int beginW=centerW-sizeW/2;
     int endW=beginW+sizeW;
     int beginSl;
@@ -517,27 +515,27 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
     if(endW>v->pcm_storage){
       /* expand the PCM storage */
 
-      v->pcm_storage=endW+v->block_size[1];
+      v->pcm_storage=endW+vi->blocksize[1];
    
-      for(i=0;i<v->pcm_channels;i++)
+      for(i=0;i<vi->channels;i++)
        v->pcm[i]=realloc(v->pcm[i],v->pcm_storage*sizeof(double)); 
     }
 
     /* Overlap/add */
-    switch(vb->W){
+    switch(v->W){
     case 0:
       beginSl=0;
-      endSl=v->block_size[0]/2;
+      endSl=vi->blocksize[0]/2;
       break;
     case 1:
-      beginSl=v->block_size[1]/4-v->block_size[vb->lW]/4;
-      endSl=beginSl+v->block_size[vb->lW]/2;
+      beginSl=vi->blocksize[1]/4-vi->blocksize[v->lW]/4;
+      endSl=beginSl+vi->blocksize[v->lW]/2;
       break;
     }
 
-    window=v->window[vb->W][0][vb->lW]+v->block_size[vb->W]/2;
+    window=v->window[v->W][0][v->lW]+vi->blocksize[v->W]/2;
 
-    for(j=0;j<v->pcm_channels;j++){
+    for(j=0;j<vi->channels;j++){
       double *pcm=v->pcm[j]+beginW;
 
       /* the add section */
@@ -559,9 +557,10 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
 }
 
 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,double ***pcm){
+  vorbis_info *vi=v->vi;
   if(v->pcm_returned<v->centerW){
     int i;
-    for(i=0;i<v->pcm_channels;i++)
+    for(i=0;i<vi->channels;i++)
       v->pcmret[i]=v->pcm[i]+v->pcm_returned;
     *pcm=v->pcmret;
     return(v->centerW-v->pcm_returned);
index cd34444..d72056e 100644 (file)
@@ -14,7 +14,7 @@
  function: codec headers
  author: Monty <xiphmont@mit.edu>
  modifications by: Monty
- last modification date: Oct 4 1999
+ last modification date: Oct 6 1999
 
  ********************************************************************/
 
@@ -96,18 +96,25 @@ typedef struct vorbis_info{
   int    comments;
   char *vendor;
 
-  int smallblock;
-  int largeblock;
+  int blocksize[2];
+  int floororder[2];
+  int flooroctaves[2];
+
   int envelopesa;
   int envelopech;
+  int floorch;
+
+  /*  int smallblock;
+  int largeblock;
   int floororder;
   int flooroctaves;
-  int floorch;
+  int floorch;*/
 
-  /* no mapping, copuling, balance yet. */
+  /* no mapping, coupling, balance yet. */
 
-  int balanceorder;
-  int balanceoctaves;
+  /*int balanceorder;
+    int balanceoctaves; 
+    this would likely need to be by channel and blocksize anyway*/
 
   double preecho_thresh;
   double preecho_clamp;
@@ -191,27 +198,23 @@ typedef struct {
    logical bitstream ****************************************************/
 
 typedef struct vorbis_dsp_state{
-  int samples_per_envelope_step;
-  int block_size[2];
-  double *window[2][2][2]; /* windowsize, leadin, leadout */
+  int analysisp;
+  vorbis_info *vi;
 
+  double *window[2][2][2]; /* windowsize, leadin, leadout */
   envelope_lookup ve;
   mdct_lookup vm[2];
   lpc_lookup vl[2];
   lpc_lookup vbal[2];
 
-  vorbis_info vi;
-
   double **pcm;
   double **pcmret;
   int      pcm_storage;
-  int      pcm_channels;
   int      pcm_current;
   int      pcm_returned;
 
   double **multipliers;
   int      envelope_storage;
-  int      envelope_channels;
   int      envelope_current;
 
   int  eofflag;
@@ -237,6 +240,7 @@ typedef struct vorbis_block{
   double **lpc;
   double **lsp;
   double *amp;
+  oggpack_buffer opb;
   
   int    pcm_channels;  /* allocated, not used */
   int    pcm_storage;   /* allocated, not used */
index addfa18..62acc70 100644 (file)
@@ -145,13 +145,13 @@ int main(){
   /* Throw the comments plus a few lines about the bitstream we're
      decoding */
   {
-    char **ptr=vi->user_comments;
+    char **ptr=vi.user_comments;
     while(*ptr){
       fprintf(stderr,"%s\n",*ptr);
       ++ptr;
     }
-    fprintf(stderr,"\nBitstream is %d channel, %dHz\n",vi->channels,vi->rate);
-    fprintf(stderr,"Encoded by: %s\n\n",vi->vendor);
+    fprintf(stderr,"\nBitstream is %d channel, %dHz\n",vi.channels,vi.rate);
+    fprintf(stderr,"Encoded by: %s\n\n",vi.vendor);
   }
 
   convsize=4096/vi.channels;
@@ -213,6 +213,7 @@ int main(){
                  ptr+=2;
                }
              }
+             fwrite(convbuffer,2*vi.channels,out,stdout);
              
              vorbis_synthesis_read(&vd,out); /* tell libvorbis how
                                                 many samples we
@@ -226,9 +227,9 @@ int main(){
     if(!eos){
       buffer=ogg_sync_buffer(&oy,4096);
       bytes=fread(buffer,1,4096,stdin);
-      if(bytes==0)eos=1;
-    }else
       ogg_sync_wrote(&oy,bytes);
+      if(bytes==0)eos=1;
+    }
   }
   
   /* clean up and exit (this example doesn't deal with the possibility
index 5c41382..514ef89 100644 (file)
@@ -14,7 +14,7 @@
  function: PCM data envelope analysis and manipulation
  author: Monty <xiphmont@mit.edu>
  modifications by: Monty
- last modification date: Oct 02 1999
+ last modification date: Oct 06 1999
 
  Vorbis manipulates the dynamic range of the incoming PCM data
  envelope to minimise time-domain energy leakage from percussive and
@@ -29,6 +29,7 @@
 
 #include "codec.h"
 #include "envelope.h"
+#include "bitwise.h"
 
 void _ve_envelope_init(envelope_lookup *e,int samples_per){
   int i;
@@ -120,17 +121,17 @@ static void _ve_deltas(double *deltas,double *pcm,int n,double *win,
 }
 
 void _ve_envelope_multipliers(vorbis_dsp_state *v){
-  int step=v->samples_per_envelope_step;
+  vorbis_info *vi=v->vi;
+  int step=vi->envelopesa;
   static int frame=0;
 
   /* we need a 1-1/4 envelope window overlap begin and 1/4 end */
-  int dtotal=(v->pcm_current-step/2)/v->samples_per_envelope_step;
+  int dtotal=(v->pcm_current-step/2)/vi->envelopesa;
   int dcurr=v->envelope_current;
   double *window=v->ve.window;
   int winlen=v->ve.winlen;
   int pch,ech;
-  vorbis_info *vi=&v->vi;
-
+  
   if(dtotal>dcurr){
     for(ech=0;ech<vi->envelopech;ech++){
       double *mult=v->multipliers[ech]+dcurr;
@@ -159,8 +160,9 @@ void _ve_envelope_multipliers(vorbis_dsp_state *v){
    coefficients */
 
 void _ve_envelope_sparsify(vorbis_block *vb){
+  vorbis_info *vi=vb->vd->vi;
   int ch;
-  for(ch=0;ch<vb->vd->vi.envelopech;ch++){
+  for(ch=0;ch<vi->envelopech;ch++){
     int flag=0;
     double *mult=vb->mult[ch];
     int n=vb->multend;
@@ -172,11 +174,11 @@ void _ve_envelope_sparsify(vorbis_block *vb){
     /* are we going to multiply anything? */
     
     for(i=1;i<n;i++){
-      if(mult[i]>=last*vb->vd->vi.preecho_thresh){
+      if(mult[i]>=last*vi->preecho_thresh){
        flag=1;
        break;
       }
-      if(i<n-1 && mult[i+1]>=last*vb->vd->vi.preecho_thresh){
+      if(i<n-1 && mult[i+1]>=last*vi->preecho_thresh){
        flag=1;
        break;
       }
@@ -193,10 +195,10 @@ void _ve_envelope_sparsify(vorbis_block *vb){
       
       last=1;
       for(;i<n;i++){
-       if(mult[i]/last>clamp*vb->vd->vi.preecho_thresh){
-         last=mult[i]/vb->vd->vi.preecho_clamp;
+       if(mult[i]/last>clamp*vi->preecho_thresh){
+         last=mult[i]/vi->preecho_clamp;
          
-         mult[i]=floor(log(mult[i]/clamp/vb->vd->vi.preecho_clamp)/log(2))-1;
+         mult[i]=floor(log(mult[i]/clamp/vi->preecho_clamp)/log(2))-1;
          if(mult[i]>15)mult[i]=15;
        }else{
          mult[i]=0;
@@ -208,7 +210,7 @@ void _ve_envelope_sparsify(vorbis_block *vb){
 }
 
 void _ve_envelope_apply(vorbis_block *vb,int multp){
-  vorbis_info *vi=&vb->vd->vi;
+  vorbis_info *vi=vb->vd->vi;
   double env[vb->multend*vi->envelopesa];
   envelope_lookup *look=&vb->vd->ve;
   int i,j,k;
@@ -249,3 +251,40 @@ void _ve_envelope_apply(vorbis_block *vb,int multp){
   }
 }
 
+int _ve_envelope_encode(vorbis_block *vb){
+  /* Not huffcoded yet. */
+
+  vorbis_info *vi=vb->vd->vi;
+  int scale=vb->W;
+  int n=vb->multend;
+  int i,j;
+
+  /* range is 0-15 */
+
+  for(i=0;i<vi->envelopech;i++){
+    double *mult=vb->mult[i];
+    for(j=0;j<n;j++)
+      _oggpack_write(&vb->opb,(int)(mult[j]),4);
+  }
+  return(0);
+}
+
+/* synthesis expands the buffers in vb if needed.  We can assume we
+   have enough storage handed to us. */
+int _ve_envelope_decode(vorbis_block *vb){
+  vorbis_info *vi=vb->vd->vi;
+  int scale=vb->W;
+  int n=vb->multend;
+  int i,j;
+
+  /* range is 0-15 */
+
+  for(i=0;i<vi->envelopech;i++){
+    double *mult=vb->mult[i];
+    for(j=0;j<n;j++)
+      mult[j]=_oggpack_read(&vb->opb,4);
+  }
+  return(0);
+}
+
+
index fd92685..a21c771 100644 (file)
@@ -14,7 +14,7 @@
  function: PCM data envelope analysis and manipulation
  author: Monty <xiphmont@mit.edu>
  modifications by: Monty
- last modification date: Aug 07 1999
+ last modification date: Oct 07 1999
 
  ********************************************************************/
 
@@ -27,5 +27,9 @@ extern void _ve_envelope_sparsify(vorbis_block *vb);
 extern void _ve_envelope_init(envelope_lookup *e,int samples_per);
 extern void _ve_envelope_clear(envelope_lookup *e);
 
+
+extern int _ve_envelope_encode(vorbis_block *vb);
+extern int _ve_envelope_decode(vorbis_block *vb);
+
 #endif
 
index 5dc6d53..f2bce56 100644 (file)
@@ -14,7 +14,7 @@
  function: maintain the info structure, info <-> header packets
  author: Monty <xiphmont@mit.edu>
  modifications by: Monty
- last modification date: Oct 04 1999
+ last modification date: Oct 06 1999
 
  ********************************************************************/
 
@@ -88,7 +88,7 @@ int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
        return(-1);
       }
       switch(_oggpack_read(&opb,8)){
-      case 0:
+      case 0x80:
        if(!op->b_o_s){
          /* Not the initial packet */
          return(-1);
@@ -98,18 +98,26 @@ int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
          return(-1);
        }
 
+       if(_oggpack_read(&opb,32)!=0){
+         return(-1);
+       }
        vi->channels=_oggpack_read(&opb,32);
        vi->rate=_oggpack_read(&opb,32);
-       vi->smallblock=_oggpack_read(&opb,32);
-       vi->largeblock=_oggpack_read(&opb,32);
+
+       vi->blocksize[0]=_oggpack_read(&opb,32);
+       vi->blocksize[1]=_oggpack_read(&opb,32);
+
+       vi->floororder[0]=_oggpack_read(&opb,8);
+       vi->floororder[1]=_oggpack_read(&opb,8);
+       vi->flooroctaves[0]=_oggpack_read(&opb,8);
+       vi->flooroctaves[1]=_oggpack_read(&opb,8);
+
        vi->envelopesa=_oggpack_read(&opb,32);
        vi->envelopech=_oggpack_read(&opb,16);
-       vi->floororder=_oggpack_read(&opb,8);
-       vi->flooroctaves=_oggpack_read(&opb,8);
        vi->floorch=_oggpack_read(&opb,16);
 
        return(0);
-      case 1:
+      case 0x81:
        if(vi->rate==0){
          /* um... we didn;t get the initial header */
          return(-1);
@@ -124,7 +132,7 @@ int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
          vi->comments=_oggpack_read(&opb,32);
          vi->user_comments=calloc(vi->comments+1,sizeof(char **));
            
-         for(i=0;i<=vi->comments;i++){
+         for(i=0;i<vi->comments;i++){
            int len=_oggpack_read(&opb,32);
            vi->user_comments[i]=calloc(len+1,1);
            _v_readstring(&opb,vi->user_comments[i],len);
@@ -132,7 +140,7 @@ int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
        }
 
        return(0);
-      case 2:
+      case 0x82:
        if(vi->rate==0){
          /* um... we didn;t get the initial header */
          return(-1);
@@ -160,34 +168,39 @@ int vorbis_info_headerout(vorbis_info *vi,
   /* initial header:
 
      codec id     "vorbis"
-     header id    0 (byte)
+     header id    0x80 (byte)
      codec ver    (4 octets, lsb first: currently 0x00)
      pcm channels (4 octets, lsb first)
      pcm rate     (4 octets, lsb first)
      
      small block  (4 octets, lsb first)
      large block  (4 octets, lsb first)
+     floor order for small block (octet)
+     floor order for large block (octet)
+     floor octaves for small block (octet)
+     floor octaves for large block (octet)
+
      envelopesa   (4 octets, lsb first)
      envelopech   (4 octets, lsb first)
-     floororder   octet
-     flooroctaves octet
      floorch      (4 octets, lsb first)
    */
 
   _oggpack_writeinit(&opb);
   _v_writestring(&opb,"vorbis");
-  _oggpack_write(&opb,0x00,8);
+  _oggpack_write(&opb,0x80,8);
 
   _oggpack_write(&opb,0x00,32);
 
   _oggpack_write(&opb,vi->channels,32);
   _oggpack_write(&opb,vi->rate,32);
-  _oggpack_write(&opb,vi->smallblock,32);
-  _oggpack_write(&opb,vi->largeblock,32);
+  _oggpack_write(&opb,vi->blocksize[0],32);
+  _oggpack_write(&opb,vi->blocksize[1],32);
+  _oggpack_write(&opb,vi->floororder[0],8);
+  _oggpack_write(&opb,vi->floororder[1],8);
+  _oggpack_write(&opb,vi->flooroctaves[0],8);
+  _oggpack_write(&opb,vi->flooroctaves[1],8);
   _oggpack_write(&opb,vi->envelopesa,32);
   _oggpack_write(&opb,vi->envelopech,16);
-  _oggpack_write(&opb,vi->floororder,8);
-  _oggpack_write(&opb,vi->flooroctaves,8);
   _oggpack_write(&opb,vi->floorch,16);
 
   /* build the packet */
@@ -202,7 +215,7 @@ int vorbis_info_headerout(vorbis_info *vi,
 
   /* comment header:
      codec id       "vorbis"
-     header id      1 (byte)
+     header id      0x81 (byte)
      vendor len     (4 octets, lsb first)
      vendor and id  (n octects as above)
      comments       (4 octets, lsb first)
@@ -215,7 +228,7 @@ int vorbis_info_headerout(vorbis_info *vi,
 
   _oggpack_reset(&opb);
   _v_writestring(&opb,"vorbis");
-  _oggpack_write(&opb,0x01,8);
+  _oggpack_write(&opb,0x81,8);
 
   if(vi->vendor){
     _oggpack_write(&opb,strlen(vi->vendor),32);
@@ -248,12 +261,12 @@ int vorbis_info_headerout(vorbis_info *vi,
 
   /* codebook header:
      codec id       "vorbis"
-     header id      2 (byte)
+     header id      0x82 (byte)
      nul so far; not encoded yet */
 
   _oggpack_reset(&opb);
   _v_writestring(&opb,"vorbis");
-  _oggpack_write(&opb,0x02,8);
+  _oggpack_write(&opb,0x82,8);
 
   if(vi->header2)free(vi->header2);
   vi->header2=malloc(_oggpack_bytes(&opb));
@@ -264,7 +277,7 @@ int vorbis_info_headerout(vorbis_info *vi,
   op_code->e_o_s=0;
   op_code->frameno=0;
 
-  _oggpack_writefree(&opb);
+  _oggpack_writeclear(&opb);
 
   return(0);
 }
index 2131b84..ccd943d 100644 (file)
@@ -16,7 +16,7 @@
 
  author: Monty <xiphmont@mit.edu>
  modifications by: Monty
- last modification date: Jul 29 1999
+ last modification date: Oct 10 1999
 
  Algorithm adapted from _The use of multirate filter banks for coding
  of high quality digital audio_, by T. Sporer, K. Brandenburg and
@@ -36,9 +36,6 @@
 
  ********************************************************************/
 
-/* Undef the following if you want a normal MDCT */
-#define VORBIS_SPECIFIC_MODIFICATIONS
-
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
@@ -262,9 +259,10 @@ void mdct_forward(mdct_lookup *init, double *in, double *out, double *window){
     double *BE=init->trig+n2;
     double *BO=BE+n4;
     double *out2=out+n2;
+    double scale=4./n;
     for(i=0;i<n4;i++){
-      out[i]   =x[0]* *BE+x[2]* *BO;
-      *(--out2)=x[0]* *BO-x[2]* *BE;
+      out[i]   =(x[0]* *BE+x[2]* *BO)*scale;
+      *(--out2)=(x[0]* *BO-x[2]* *BE)*scale;
       x+=4;
       BO++;
       BE++;
@@ -318,31 +316,19 @@ void mdct_backward(mdct_lookup *init, double *in, double *out, double *window){
     double *BO=BE+n4;
     int o1=n4,o2=o1-1;
     int o3=n4+n2,o4=o3-1;
-    double scale=n/4.;
     
     for(i=0;i<n4;i++){
-      double BEv=BE[i];
-      double BOv=BO[i];
-#ifdef VORBIS_SPECIFIC_MODIFICATIONS
-      double temp= (*x * BOv - *(x+2) * BEv)/ scale;
-      out[o3]=out[o4]=(*x * BEv + *(x+2) * BOv)/ -scale;
+      double temp= (*x * *BO - *(x+2) * *BE);
+      out[o3]=out[o4]= -(*x * *BE + *(x+2) * *BO);
       out[o1]=-temp*window[o1];
       out[o2]=temp*window[o2];
-#else
-      double temp1= (*x * BOv - *(x+2) * BEv)* scale;
-      double temp2= (*x * BEv + *(x+2) * BOv)* -scale;
-    
-      out[o1]=-temp1*window[o1];
-      out[o2]=temp1*window[o2];
-      out[o3]=temp2*window[o3];
-      out[o4]=temp2*window[o4];
-#endif
 
       o1++;
       o2--;
       o3++;
       o4--;
       x+=4;
+      BE++;BO++;
     }
   }
 }
@@ -351,11 +337,3 @@ void mdct_backward(mdct_lookup *init, double *in, double *out, double *window){
 
 
 
-
-
-
-
-
-
-
-
index 6927adf..5187087 100644 (file)
@@ -26,7 +26,7 @@
 
 vorbis_info predef_modes[]={
   /* CD quality stereo, no channel coupling */
-  { 2, 44100, 0, NULL, 0, NULL, 512, 2048, 64, 2, 30, 5, 2, 0, 0, 10, .5,
+  { 2, 44100, 0, NULL, 0, NULL, {512, 2048}, {30,30}, {5,5}, 64,2,2, 10, .5,
                                             NULL,NULL,NULL},
 
 };
index 188f138..13574b7 100644 (file)
--- a/lib/psy.c
+++ b/lib/psy.c
@@ -27,7 +27,7 @@
 #include "smallft.h"
 #include "xlogmap.h"
 
-#define NOISEdB 10
+#define NOISEdB 0
 
 #define MASKdB  18
 #define HROLL   60
@@ -116,35 +116,6 @@ void _vp_mask_floor(double *f, double *m,int n){
   }
 }
 
-void _vp_psy_quantize(double *f, double *m,int n){
-  int i;
-  for(i=0;i<n;i++){
-    int val=rint(f[i]/m[i]);
-    if(val>16)val=16;
-    if(val<-16)val=-16;
-    if(val==0 || val==2){
-      if(f[i]<0){
-       f[i]=-1;
-      }else{
-       f[i]=1;
-      }
-    }
-
-    f[i]=val;
-  }
-}
-void _vp_psy_unquantize(double *f, double *m,int n){
-  int i;
-  for(i=0;i<n;i++)
-    f[i]*=m[i];
-}
-
-void _vp_psy_sparsify(double *f, double *m,int n){
-  int i;
-  for(i=0;i<n;i++)
-    if(fabs(f[i])<m[i]*.5)f[i]=0;
-}
-
 /* s must be padded at the end with m-1 zeroes */
 static void time_convolve(double *s,double *r,int n,int m){
   int i;
diff --git a/lib/spectrum.c b/lib/spectrum.c
new file mode 100644 (file)
index 0000000..f6c25af
--- /dev/null
@@ -0,0 +1,122 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
+ * PLEASE READ THESE TERMS DISTRIBUTING.                            *
+ *                                                                  *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999             *
+ * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company       *
+ * http://www.xiph.org/                                             *
+ *                                                                  *
+ ********************************************************************
+
+ function: spectrum envelope and residue code/decode
+ author: Monty <xiphmont@mit.edu>
+ modifications by: Monty
+ last modification date: Oct 10 1999
+
+ ********************************************************************/
+
+#include <stdio.h>
+#include <math.h>
+#include "codec.h"
+#include "bitwise.h"
+#include "spectrum.h"
+
+/* this code is still seriously abbreviated.  I'm filling in pieces as
+   we go... --Monty 19991004 */
+
+int _vs_spectrum_encode(vorbis_block *vb,double amp,double *lsp){
+  /* no real coding yet.  Just write out full sized words for now
+     because people need bitstreams to work with */
+
+  int scale=vb->W;
+  int n=vb->pcmend/2;
+  int last=0;
+  int bits=rint(log(n)/log(2));
+  int i;
+  
+  _oggpack_write(&vb->opb,amp*32768,15);
+  
+  for(i=0;i<vb->vd->vi->floororder[scale];i++){
+    int val=rint(lsp[i]/M_PI*n-last);
+    lsp[i]=(last+=val)*M_PI/n;
+    _oggpack_write(&vb->opb,val,bits);
+  }
+  return(0);
+}
+
+int _vs_spectrum_decode(vorbis_block *vb,double *amp,double *lsp){
+  int scale=vb->W;
+  int n=vb->pcmend/2;
+  int last=0;
+  int bits=rint(log(n)/log(2));
+  int i;
+
+  *amp=_oggpack_read(&vb->opb,15)/32768.;
+
+  for(i=0;i<vb->vd->vi->floororder[scale];i++){
+    int val=_oggpack_read(&vb->opb,bits);
+    lsp[i]=(last+=val)*M_PI/n;
+  }
+  return(0);
+}
+
+
+void _vs_residue_quantize(double *data,double *curve,
+                                vorbis_info *vi,int n){
+
+  /* The following is temporary, hardwired bullshit */
+  int i;
+
+  for(i=0;i<n;i++){
+
+    int val=rint(data[i]/curve[i]);
+    if(val>16)val=16;
+    if(val<-16)val=-16;
+
+    /*if(val==0){
+      if(data[i]<0){
+       val=-1;
+      }else{
+       val=1;
+      }
+      }*/
+    
+    data[i]=val;
+    /*if(val<0){
+    }else{
+      data[i]=val+15;
+      }*/
+  }
+}
+
+int _vs_residue_encode(vorbis_block *vb,double *data){
+  /* no real coding yet.  Just write out full sized words for now
+     because people need bitstreams to work with */
+
+  int              n=vb->pcmend/2;
+  int i;
+
+  for(i=0;i<n;i++){
+    _oggpack_write(&vb->opb,(int)(data[i]+16),6);
+  }
+
+  return(0);
+}
+
+int _vs_residue_decode(vorbis_block *vb,double *data){
+  /* no real coding yet.  Just write out full sized words for now
+     because people need bitstreams to work with */
+
+  int              n=vb->pcmend/2;
+  int i;
+
+  for(i=0;i<n;i++){
+    data[i]=_oggpack_read(&vb->opb,6)-16;
+    /*if(data[i]>=0)data[i]+=1;*/
+  }
+  return(0);
+}
+
diff --git a/lib/spectrum.h b/lib/spectrum.h
new file mode 100644 (file)
index 0000000..a369d86
--- /dev/null
@@ -0,0 +1,23 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
+ * PLEASE READ THESE TERMS DISTRIBUTING.                            *
+ *                                                                  *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999             *
+ * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company       *
+ * http://www.xiph.org/                                             *
+ *                                                                  *
+ ********************************************************************/
+
+#ifndef _V_SPECT_H_
+#define _V_SPECT_H_
+
+extern int  _vs_spectrum_encode(vorbis_block *vb,double amp,double *lsp);
+extern int  _vs_spectrum_decode(vorbis_block *vb,double *amp,double *lsp);
+extern void _vs_residue_quantize(double *data,double *curve,
+                                vorbis_info *vi,int n);
+extern int  _vs_residue_encode(vorbis_block *vb,double *data);
+
+#endif
index aa5d927..5faa705 100644 (file)
  function: single-block PCM synthesis
  author: Monty <xiphmont@mit.edu>
  modifications by: Monty
- last modification date: Aug 08 1999
+ last modification date: Oct 07 1999
 
  ********************************************************************/
 
+#include <stdio.h>
 #include "codec.h"
 #include "envelope.h"
 #include "mdct.h"
 #include "lpc.h"
 #include "lsp.h"
+#include "bitwise.h"
+#include "spectrum.h"
 
 int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
-  int i;
-  vorbis_info *vi=&vb->vd->vi;
-  double *window=vb->vd->window[vb->W][vb->lW][vb->nW];
-  lpc_lookup *vl=&vb->vd->vl[vb->W];
-
-  /* get the LSP params back to LPC params. This will be for each
-     spectral floor curve */
-
-      
-  /*      {
-      int scale=1020;
-       double last=0;
-       for(i=0;i<30;i++){
-         last+=lsp1[i];
-         lsp2[i]=last*M_PI/scale;
-       }
-      }
-
-
-
-      vorbis_lsp_to_lpc(lsp2,lpc1,30);*/
-
-
-  /*for(i=0;i<vi->floorch;i++)
-    vorbis_lsp_to_lpc(vb->lsp[i],vb->lpc[i],vi->floororder);*/
-
-  /* Map the resulting floors back to the appropriate channels */
-
-  /*for(i=0;i<vi->channels;i++)
-    vorbis_lpc_apply(vb->pcm[i],vb->pcmend,vb->lpc[vi->floormap[i]],
-    vb->amp[vi->floormap[i]],vi->floororder);*/
+  static int frameno=0;
+  vorbis_dsp_state *vd=vb->vd;
+  vorbis_info      *vi=vd->vi;
+  oggpack_buffer   *opb=&vb->opb;
+  lpc_lookup       *vl;
+  double           *window;
+  int              spectral_order;
+  int              n,i;
+
+  /* first things first.  Make sure decode is ready */
+  _oggpack_readinit(opb,op->packet,op->bytes);
+
+  /* Check the packet type */
+  if(_oggpack_read(opb,1)!=0){
+    /* Oops.  This is not an audio data packet */
+    return(-1);
+  }
+
+  /* Encode the block size */
+  vb->W=_oggpack_read(opb,1);
+
+  /* other random setup */
+  vb->frameno=op->frameno;
+  vb->eofflag=op->e_o_s;
+  vl=&vb->vd->vl[vb->W];
+  spectral_order=vi->floororder[vb->W];
+
+  /* The storage vectors are large enough; set the use markers */
+  n=vb->pcmend=vi->blocksize[vb->W];
+  vb->multend=vb->pcmend/vi->envelopesa;
+  
+  /* we don't know the size of the following window, but we don't need
+     it yet.  We only use the first half of the window */
+  window=vb->vd->window[vb->W][vb->lW][0];
   
-  for(i=0;i<vb->pcm_channels;i++)
+  /* recover the time envelope */
+  /*if(_ve_envelope_decode(vb)<0)return(-1);*/
+
+  for(i=0;i<vi->channels;i++){
+    double *lpc=vb->lpc[i];
+    double *lsp=vb->lsp[i];
+    
+    /* recover the spectral envelope */
+    if(_vs_spectrum_decode(vb,&vb->amp[i],lsp)<0)return(-1);
+    
+    /* recover the spectral residue */  
+    if(_vs_residue_decode(vb,vb->pcm[i])<0)return(-1);
+
+    /* LSP->LPC */
+    vorbis_lsp_to_lpc(lsp,lpc,vl->m); 
+
+    /* apply envelope to residue */
+    
+    vorbis_lpc_apply(vb->pcm[i],lpc,vb->amp[i],vl);
+      
+    /* MDCT->time */
     mdct_backward(&vb->vd->vm[vb->W],vb->pcm[i],vb->pcm[i],window);
-  _ve_envelope_apply(vb,1);
-
+    
+    /* apply time domain envelope */
+    /*_ve_envelope_apply(vb,1);*/
+  }
+  
+  return(0);
 }