Continuing to flesh out the programmatic API in libvorbis.
authorMonty <xiphmont@xiph.org>
Sat, 2 Oct 1999 21:21:24 +0000 (21:21 +0000)
committerMonty <xiphmont@xiph.org>
Sat, 2 Oct 1999 21:21:24 +0000 (21:21 +0000)
Incremental update.

Monty

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

lib/Makefile.in
lib/analysis.c
lib/block.c
lib/codec.h
lib/dsptest.c
lib/envelope.c
lib/info.c [new file with mode: 0644]
lib/modes.h [new file with mode: 0644]
lib/synthesis.c

index 34d3c2f..3b56998 100644 (file)
@@ -1,6 +1,6 @@
 # vorbis makefile configured for use with gcc on any platform
 
-# $Id: Makefile.in,v 1.8 1999/08/09 21:11:38 xiphmont Exp $
+# $Id: Makefile.in,v 1.9 1999/10/02 21:21:18 xiphmont Exp $
 
 ###############################################################################
 #                                                                             #
@@ -28,7 +28,7 @@ RANLIB=@RANLIB@
 LIBS=@LIBS@ -lm
 
 OFILES =       framing.o mdct.o smallft.o block.o envelope.o window.o\
-               lsp.o lpc.o analysis.o synthesis.o psy.o
+               lsp.o lpc.o analysis.o synthesis.o psy.o info.o bitwise.o
 TARGETFILES =  libvorbis.a
 
 all:
index 6004e43..b14515a 100644 (file)
@@ -14,7 +14,7 @@
  function: single-block PCM analysis
  author: Monty <xiphmont@mit.edu>
  modifications by: Monty
- last modification date: Aug 22 1999
+ last modification date: Oct 2 1999
 
  ********************************************************************/
 
@@ -30,7 +30,7 @@
 
 extern void compute_balance(double *A, double *B, double *phi,int n);
 
-int vorbis_analysis(vorbis_block *vb){
+int vorbis_analysis(vorbis_block *vb,ogg_packet *op){
   int i;
   double *window=vb->vd->window[vb->W][vb->lW][vb->nW];
   lpc_lookup *vl=&vb->vd->vl[vb->W];
@@ -231,20 +231,3 @@ int vorbis_analysis(vorbis_block *vb){
   return(0);
 }
 
-int vorbis_analysis_packetout(vorbis_block *vb, ogg_packet *op){
-
-  /* find block's envelope vector and apply it */
-
-
-  /* the real analysis begins; forward MDCT with window */
-
-  
-  /* Noise floor, resolution floor */
-
-  /* encode the floor into LSP; get the actual floor back for quant */
-
-  /* use noise floor, res floor for culling, actual floor for quant */
-
-  /* encode residue */
-
-}
index 508e6c4..85b75ca 100644 (file)
@@ -14,7 +14,7 @@
  function: PCM data vector blocking, windowing and dis/reassembly
  author: Monty <xiphmont@mit.edu>
  modifications by: Monty
- last modification date: Aug 05 1999
+ last modification date: Oct 2 1999
 
  Handle windowing, overlap-add, etc of the PCM vectors.  This is made
  more amusing by Vorbis' current two allowed block sizes.
                          |beginW
 */
 
+/* block abstraction setup *********************************************/
+
+int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
+  int i;
+  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=malloc(vb->pcm_channels*sizeof(double *));
+  for(i=0;i<vb->pcm_channels;i++)
+    vb->pcm[i]=malloc(vb->pcm_storage*sizeof(double));
+  
+  vb->mult=malloc(vb->mult_channels*sizeof(double *));
+  for(i=0;i<vb->mult_channels;i++)
+    vb->mult[i]=malloc(vb->mult_storage*sizeof(double));
+
+  vb->lsp=malloc(vb->floor_channels*sizeof(double *));
+  vb->lpc=malloc(vb->floor_channels*sizeof(double *));
+  vb->amp=malloc(vb->floor_channels*sizeof(double));
+  for(i=0;i<vb->floor_channels;i++){
+    vb->lsp[i]=malloc(vb->floor_storage*sizeof(double));
+    vb->lpc[i]=malloc(vb->floor_storage*sizeof(double));
+  }
+
+  return(0);
+}
+
+int vorbis_block_clear(vorbis_block *vb){
+  int i;
+  if(vb->pcm){
+    for(i=0;i<vb->pcm_channels;i++)
+      free(vb->pcm[i]);
+    free(vb->pcm);
+  }
+  if(vb->mult){
+    for(i=0;i<vb->mult_channels;i++)
+      free(vb->mult[i]);
+    free(vb->mult);
+  }
+  memset(vb,0,sizeof(vorbis_block));
+  return(0);
+}
+
+/* Analysis side code, but directly related to blocking.  Thus it's
+   here and not in analysis.c (which is for analysis transforms only).
+   The init is here because some of it is shared */
+
 static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi){
   memset(v,0,sizeof(vorbis_dsp_state));
 
@@ -233,51 +286,6 @@ int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
   return(0);
 }
 
-int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
-  int i;
-  memset(vb,0,sizeof(vorbis_block));
-  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=malloc(vb->pcm_channels*sizeof(double *));
-  for(i=0;i<vb->pcm_channels;i++)
-    vb->pcm[i]=malloc(vb->pcm_storage*sizeof(double));
-  
-  vb->mult=malloc(vb->mult_channels*sizeof(double *));
-  for(i=0;i<vb->mult_channels;i++)
-    vb->mult[i]=malloc(vb->mult_storage*sizeof(double));
-
-  vb->lsp=malloc(vb->floor_channels*sizeof(double *));
-  vb->lpc=malloc(vb->floor_channels*sizeof(double *));
-  vb->amp=malloc(vb->floor_channels*sizeof(double));
-  for(i=0;i<vb->floor_channels;i++){
-    vb->lsp[i]=malloc(vb->floor_storage*sizeof(double));
-    vb->lpc[i]=malloc(vb->floor_storage*sizeof(double));
-  }
-
-  return(0);
-}
-
-int vorbis_block_clear(vorbis_block *vb){
-  int i;
-  if(vb->pcm){
-    for(i=0;i<vb->pcm_channels;i++)
-      free(vb->pcm[i]);
-    free(vb->pcm);
-  }
-  if(vb->mult){
-    for(i=0;i<vb->mult_channels;i++)
-      free(vb->mult[i]);
-    free(vb->mult);
-  }
-  memset(vb,0,sizeof(vorbis_block));
-  return(0);
-}
-
 /* do the deltas, envelope shaping, pre-echo and determine the size of
    the next block on which to continue analysis */
 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
index 7247fed..db97004 100644 (file)
  function: codec headers
  author: Monty <xiphmont@mit.edu>
  modifications by: Monty
- last modification date: Aug 21 1999
+ last modification date: Oct 2 1999
 
  ********************************************************************/
 
 #ifndef _vorbis_codec_h_
 #define _vorbis_codec_h_
 
+/* lookup structures for various simple transforms *****************/
+
 typedef struct {
   int n;
   int log2n;
@@ -56,6 +58,7 @@ typedef struct lpclook{
 
 } lpc_lookup;
 
+/* structures for various internal data abstractions ********************/
 
 typedef struct {
   long endbyte;     
@@ -67,25 +70,28 @@ typedef struct {
   
 } oggpack_buffer;
 
+/* vobis_info contains all the setup information specific to the specific
+   compression/decompression mode in progress (eg, psychoacoustic settings,
+   channel setup, options, codebook etc) *********************************/
+
 typedef struct vorbis_info{
   int channels;
   int rate;
   int version;
-  int mode;
+
   char **user_comments;
+  int    max_comment;
   char *vendor;
 
   int smallblock;
   int largeblock;
   int envelopesa;
   int envelopech;
-  int *envelopemap; /* which envelope applies to what pcm channel */
-  int **Echannelmap; /* which encoding channels produce what pcm (decode) */
-  int **channelmap;   /* which pcm channels produce what floors   (encode) */
   int floororder;
   int flooroctaves;
   int floorch;
-  int *floormap;
+
+  /* no mapping, copuling, balance yet. */
 
   int balanceorder;
   int balanceoctaves;
@@ -94,6 +100,8 @@ typedef struct vorbis_info{
   double preecho_clamp;
 } vorbis_info;
  
+/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
+
 typedef struct {
   unsigned char *header;
   long header_len;
@@ -101,6 +109,9 @@ typedef struct {
   long body_len;
 } ogg_page;
 
+/* ogg_stream_state contains the current encode/decode state of a logical
+   Ogg bitstream **********************************************************/
+
 typedef struct {
   unsigned char   *body_data;    /* bytes from packet bodies */
   long    body_storage;          /* storage elements allocated */
@@ -130,6 +141,9 @@ typedef struct {
 
 } ogg_stream_state;
 
+/* ogg_packet is used to encapsulate the data and metadata belonging
+   to a single raw Ogg/Vorbis packet *************************************/
+
 typedef struct {
   unsigned char *packet;
   long  bytes;
@@ -151,6 +165,10 @@ typedef struct {
   int bodybytes;
 } ogg_sync_state;
 
+/* vorbis_dsp_state buffers the current vorbis audio
+   analysis/synthesis state.  The DSP state belongs to a specific
+   logical bitstream ****************************************************/
+
 typedef struct vorbis_dsp_state{
   int samples_per_envelope_step;
   int block_size[2];
@@ -187,6 +205,11 @@ typedef struct vorbis_dsp_state{
 
 } vorbis_dsp_state;
 
+/* vorbis_block is a single block of data to be processed as part of
+the analysis/synthesis stream; it belongs to a specific logical
+bitstream, but is independant from other vorbis_blocks belonging to
+that logical bitstream. *************************************************/
+
 typedef struct vorbis_block{
   double **pcm;
   double **mult;
@@ -194,8 +217,8 @@ typedef struct vorbis_block{
   double **lsp;
   double *amp;
   
-  int    pcm_channels; /* allocated, not used */
-  int    pcm_storage;  /* allocated, not used */
+  int    pcm_channels;  /* allocated, not used */
+  int    pcm_storage;   /* allocated, not used */
   int    mult_channels; /* allocated, not used */
   int    mult_storage;  /* allocated, not used */
   int    floor_channels;
@@ -258,33 +281,35 @@ extern size64 ogg_page_frameno(ogg_page *og);
 extern int    ogg_page_serialno(ogg_page *og);
 extern int    ogg_page_pageno(ogg_page *og);
 
+/* Vorbis PRIMITIVES: general ***************************************/
+
+extern int vorbis_info_clear(vorbis_info *vi); 
+extern int vorbis_info_modeset(vorbis_info *vi, int mode); 
+extern int vorbis_info_addcomment(vorbis_info *vi, char *comment); 
+extern int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op);
+extern int vorbis_info_headerout(vorbis_info *vi,ogg_packet *op);
+
+extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb);
+extern int vorbis_block_clear(vorbis_block *vb);
+
 /* Vorbis PRIMITIVES: analysis/DSP layer ****************************/
+extern int      vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi);
+extern void     vorbis_analysis_clear(vorbis_dsp_state *v);
 
-extern int      vorbis_analysis_init(vorbis_dsp_state *vd,vorbis_info *vi);
-extern int      vorbis_analysis_reset(vorbis_dsp_state *vd);
-extern void     vorbis_analysis_free(vorbis_dsp_state *vd);
-extern double **vorbis_analysis_buffer(vorbis_dsp_state *vd,int vals);
-extern int      vorbis_analysis_wrote(vorbis_dsp_state *vd,int vals);
-extern int      vorbis_analysis_blockout(vorbis_dsp_state *vd,
-                                        vorbis_block *vb);
-extern int      vorbis_analysis(vorbis_block *vb);
-extern int      vorbis_analysis_packetout(vorbis_block *vb,
-                                         ogg_packet *op);
+extern double **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals);
+extern int      vorbis_analysis_wrote(vorbis_dsp_state *v,int vals);
+extern int      vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb);
+extern int      vorbis_analysis(vorbis_block *vb,ogg_packet *op);
 
 /* Vorbis PRIMITIVES: synthesis layer *******************************/
+extern int  vorbis_synthesis_clear(vorbis_dsp_state *v);
+extern int  vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi);
 
-extern void vorbis_synthesis_free(vorbis_dsp_state *vd);
-extern int  vorbis_synthesis_init(vorbis_dsp_state *vd,vorbis_info *vi);
-
-extern int vorbis_synthesis(vorbis_block *vb);
+extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op);
 extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb);
 extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,double ***pcm);
 extern int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes);
 
-
-extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb);
-
-
 #define min(x,y)  ((x)>(y)?(y):(x))
 #define max(x,y)  ((x)<(y)?(y):(x))
 #define todB(x)   (x==0?-9.e40:log(fabs(x))*8.6858896)  /* 20log10(x) */
index 67d0b2a..2a8abe2 100644 (file)
@@ -72,6 +72,7 @@ int main(){
        /* analysis */
 
        vorbis_analysis(&vb);
+       vorbis_analysis_packetout(&vb,&op);
 
        /* synthesis */
 
index 6cc27a7..5c41382 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 02 1999
 
  Vorbis manipulates the dynamic range of the incoming PCM data
  envelope to minimise time-domain energy leakage from percussive and
@@ -139,7 +139,8 @@ void _ve_envelope_multipliers(vorbis_dsp_state *v){
       for(pch=0;pch<vi->channels;pch++){
        
        /* does this channel contribute to the envelope analysis */
-       if(vi->envelopemap[pch]==ech){
+       /*if(vi->envelopemap[pch]==ech){ not mapping yet */
+       if(pch==ech){
 
          /* we need a 1/4 envelope window overlap front and back */
          double *pcm=v->pcm[pch]+dcurr*step-step/2;
@@ -233,7 +234,8 @@ void _ve_envelope_apply(vorbis_block *vb,int multp){
       for(j=0;j<vi->channels;j++){
        
        /* check to see if the generated envelope applies to this channel */
-       if(vi->envelopemap[j]==i){
+       /*if(vi->envelopemap[j]==i){ not mapping yet */
+       if(j==i){
          
          if(multp)
            for(k=0;k<vb->multend*vi->envelopesa;k++)
diff --git a/lib/info.c b/lib/info.c
new file mode 100644 (file)
index 0000000..e21bd2d
--- /dev/null
@@ -0,0 +1,82 @@
+/********************************************************************
+ *                                                                  *
+ * 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: maintain the info structure, info <-> header packets
+ author: Monty <xiphmont@mit.edu>
+ modifications by: Monty
+ last modification date: Oct 02 1999
+
+ ********************************************************************/
+
+/* This fills in a vorbis_info structure with settings from a few
+   pre-defined encoding modes.  Also handles choosing/blowing in the
+   codebook */
+
+#include <stdlib.h>
+#include <string.h>
+#include "modes.h"
+
+/* one test mode for now; temporary of course */
+int vorbis_info_modeset(vorbis_info *vi, int mode){
+  if(mode<0 || mode>predef_mode_max)return(-1);
+
+  /* handle the flat settings first */
+  memcpy(vi,&(predef_modes[mode]),sizeof(vorbis_info));
+  vi->user_comments=calloc(1,sizeof(char *));
+
+  return(0);
+}
+
+/* convenience function */
+int vorbis_info_add_comment(vorbis_info *vi,char *comment){
+  vi->user_comments=realloc(vi->user_comments,
+                           (vi->max_comment+2)*sizeof(char *));
+  vi->user_comments[vi->max_comment]=strdup(comment);
+  vi->max_comment++;
+  vi->user_comments[vi->max_comment]=NULL;
+  return(0);
+}
+
+/* The Vorbis header is in three packets; the initial small packet in
+   the first page that identifies basic parameters, a second
+   [optional] packet with bitstream comments and a third packet that
+   holds the codebook. */
+
+int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
+
+}
+
+int vorbis_info_headerout(vorbis_info *vi,ogg_packet *op){
+
+
+}
+
+int vorbis_info_clear(vorbis_info *vi){
+  /* clear the non-flat storage before zeroing */
+
+  /* comments */
+  if(vi->user_comments){
+    char **ptr=vi->user_comments;
+    while(*ptr){
+      free(*(ptr++));
+    }
+    free(vi->user_comments);
+  }
+
+  /* vendor string */
+  if(vi->vendor)free(vi->vendor);
+
+  memset(vi,0,sizeof(vorbis_info));
+}
+  
+
diff --git a/lib/modes.h b/lib/modes.h
new file mode 100644 (file)
index 0000000..d5ad4e1
--- /dev/null
@@ -0,0 +1,36 @@
+/********************************************************************
+ *                                                                  *
+ * 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: predefined encoding modes
+ author: Monty <xiphmont@mit.edu>
+ modifications by: Monty
+ last modification date: Oct 2 1999
+
+ ********************************************************************/
+
+#ifndef _V_MODES_H_
+#define _V_MODES_H_
+
+#include <stdio.h>
+#include "codec.h"
+
+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 },
+
+};
+
+#define predef_mode_max 0
+
+#endif
+
index 52dd538..89136e2 100644 (file)
@@ -24,7 +24,7 @@
 #include "lpc.h"
 #include "lsp.h"
 
-int vorbis_synthesis(vorbis_block *vb){
+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];