Commit cab466d0 authored by Monty's avatar Monty
Browse files

It's all coming back together slowly.  Incremental update.

Monty

svn path=/trunk/vorbis/; revision=240
parent 0f361eca
# vorbis makefile configured for use with gcc on any platform
# $Id: Makefile.in,v 1.2 2000/01/05 03:10:23 xiphmont Exp $
# $Id: Makefile.in,v 1.3 2000/01/22 13:28:07 xiphmont Exp $
###############################################################################
# #
......@@ -27,7 +27,9 @@ AR=@AR@
RANLIB=@RANLIB@
LIBS=@LIBS@ -lm
HFILES = ../include/vorbis/codec.h ../include/vorbis/vorbisfile.h
HFILES = ../include/vorbis/codec.h ../include/vorbis/vorbisfile.h \
../include/vorbis/internal.h ../include/vorbis/backend.h \
../include/vorbis/codebook.h
OFILES = encoder_example.o decoder_example.o chaining_example.o
BINFILES = encoder_example decoder_example chaining_example
......
......@@ -12,7 +12,7 @@
********************************************************************
function: simple example decoder
last mod: $Id: decoder_example.c,v 1.3 2000/01/05 03:10:25 xiphmont Exp $
last mod: $Id: decoder_example.c,v 1.4 2000/01/22 13:28:08 xiphmont Exp $
********************************************************************/
......@@ -259,8 +259,8 @@ int main(){
/* ogg_page and ogg_packet structs always point to storage in
libvorbis. They're never freed or manipulated directly */
vorbis_dsp_clear(&vd);
vorbis_block_clear(&vb);
vorbis_dsp_clear(&vd);
vorbis_info_clear(&vi); /* must be called last */
}
......
......@@ -12,7 +12,7 @@
********************************************************************
function: simple example encoder
last mod: $Id: encoder_example.c,v 1.3 2000/01/05 03:10:26 xiphmont Exp $
last mod: $Id: encoder_example.c,v 1.4 2000/01/22 13:28:09 xiphmont Exp $
********************************************************************/
......@@ -148,8 +148,8 @@ int main(){
/* clean up and exit. vorbis_info_clear() must be called last */
ogg_stream_clear(&os);
vorbis_dsp_clear(&vd);
vorbis_block_clear(&vb);
vorbis_dsp_clear(&vd);
vorbis_info_clear(&vi);
/* ogg_page and ogg_packet structs always point to storage in
......
......@@ -13,7 +13,7 @@
function: libvorbis backend and mapping structures; needed for
static mode headers
last mod: $Id: backends.h,v 1.1 2000/01/22 10:40:36 xiphmont Exp $
last mod: $Id: backends.h,v 1.2 2000/01/22 13:28:10 xiphmont Exp $
********************************************************************/
......@@ -25,36 +25,23 @@
#define _vorbis_time_backend_h_
/* this would all be simpler/shorter with templates, but.... */
/* mode setup ******************************************************/
typedef struct {
int blockflag;
int windowtype;
int transformtype;
int mapping;
} vorbis_info_mode;
/* Transform backend generic *************************************/
typedef void vorbis_look_transform;
typedef struct{
void (*forward)(vorbis_look_transform *,double *in,double *out);
void (*inverse)(vorbis_look_transform *,double *in,double *out);
} vorbis_func_transform;
/* only mdct right now. Flesh it out more if we ever transcend mdct
in the transform domain */
/* Time backend generic ******************************************/
typedef void vorbis_info_time;
typedef void vorbis_look_time;
typedef struct{
void (*pack) (vorbis_info_time *,oggpack_buffer *);
vorbis_info_time *(*unpack)(oggpack_buffer *);
vorbis_info_time *(*unpack)(vorbis_info *,oggpack_buffer *);
vorbis_look_time *(*look) (vorbis_info *,vorbis_info_mode *,
vorbis_info_time *);
void (*free_info) (vorbis_info_time *);
void (*free_look) (vorbis_look_time *);
void (*forward) (vorbis_info *,vorbis_look_time *,double *,double *);
void (*inverse) (vorbis_info *,vorbis_look_time *,double *,double *);
int (*forward) (struct vorbis_block *,vorbis_look_time *,
double *,double *);
int (*inverse) (struct vorbis_block *,vorbis_look_time *,
double *,double *);
} vorbis_func_time;
typedef struct{
......@@ -62,19 +49,17 @@ typedef struct{
} vorbis_info_time0;
/* Floor backend generic *****************************************/
typedef void vorbis_info_floor;
typedef void vorbis_look_floor;
typedef struct{
void (*pack) (vorbis_info_floor *,oggpack_buffer *);
vorbis_info_floor *(*unpack)(oggpack_buffer *);
vorbis_info_floor *(*unpack)(vorbis_info *,oggpack_buffer *);
vorbis_look_floor *(*look) (vorbis_info *,vorbis_info_mode *,
vorbis_info_floor *);
void (*free_info) (vorbis_info_floor *);
void (*free_look) (vorbis_look_floor *);
void (*forward) (vorbis_info *,vorbis_look_floor *,double *,double *);
void (*inverse) (vorbis_info *,vorbis_look_floor *,double *,double *);
int (*forward) (struct vorbis_block *,vorbis_look_floor *,
double *,double *);
int (*inverse) (struct vorbis_block *,vorbis_look_floor *,
double *,double *);
} vorbis_func_floor;
typedef struct{
......@@ -86,21 +71,20 @@ typedef struct{
} vorbis_info_floor0;
/* Residue backend generic *****************************************/
typedef void vorbis_info_residue;
typedef void vorbis_look_residue;
typedef struct{
void (*pack) (vorbis_info_residue *,oggpack_buffer *);
vorbis_info_residue *(*unpack)(oggpack_buffer *);
vorbis_info_residue *(*unpack)(vorbis_info *,oggpack_buffer *);
vorbis_look_residue *(*look) (vorbis_info *,vorbis_info_mode *,
vorbis_info_residue *);
void (*free_info) (vorbis_info_residue *);
void (*free_look) (vorbis_look_residue *);
void (*forward) (vorbis_info *,vorbis_look_residue *,double *,double *);
void (*inverse) (vorbis_info *,vorbis_look_residue *,double *,double *);
int (*forward) (struct vorbis_block *,vorbis_look_residue *,
double *,double *);
int (*inverse) (struct vorbis_block *,vorbis_look_residue *,
double *,double *);
} vorbis_func_residue;
typedef struct vorbis_info_res0{
typedef struct vorbis_info_residue0{
/* block-partitioned VQ coded straight residue */
long begin;
long end;
......@@ -108,29 +92,19 @@ typedef struct vorbis_info_res0{
/* way unfinished, just so you know while poking around CVS ;-) */
int stages;
int *books;
} vorbis_info_res0;
/* psychoacoustic setup ********************************************/
typedef struct vorbis_info_psy{
double maskthresh[MAX_BARK];
double lrolldB;
double hrolldB;
} vorbis_info_psy;
} vorbis_info_residue0;
/* Mapping backend generic *****************************************/
typedef void vorbis_info_mapping;
typedef void vorbis_look_mapping;
typedef struct{
void (*pack) (vorbis_info_mapping *,oggpack_buffer *);
vorbis_info_mapping *(*unpack)(oggpack_buffer *);
vorbis_info_mapping *(*unpack)(vorbis_info *,oggpack_buffer *);
vorbis_look_mapping *(*look) (vorbis_info *,vorbis_info_mode *,
vorbis_info_mapping *);
void (*free_info) (vorbis_info_mapping *);
void (*free_look) (vorbis_look_mapping *);
void (*forward) (int mode,struct vorbis_block *vb);
void (*inverse) (int mode,struct vorbis_block *vb);
} vorbis_func_residue;
int (*forward) (struct vorbis_block *vb,vorbis_look_mapping *);
int (*inverse) (struct vorbis_block *vb,vorbis_look_mapping *);
} vorbis_func_mapping;
typedef struct vorbis_info_mapping0{
int submaps;
......
......@@ -12,7 +12,7 @@
********************************************************************
function: libvorbis codec headers
last mod: $Id: codec.h,v 1.4 2000/01/22 10:40:37 xiphmont Exp $
last mod: $Id: codec.h,v 1.5 2000/01/22 13:28:11 xiphmont Exp $
********************************************************************/
......@@ -24,12 +24,36 @@
#include <sys/types.h>
#include "vorbis/codebook.h"
#include "vorbis/internal.h"
#include "vorbis/backends.h"
/* vobis_info contains all the setup information specific to the
typedef void vorbis_look_transform;
typedef void vorbis_info_time;
typedef void vorbis_look_time;
typedef void vorbis_info_floor;
typedef void vorbis_look_floor;
typedef void vorbis_info_residue;
typedef void vorbis_look_residue;
typedef void vorbis_info_mapping;
typedef void vorbis_look_mapping;
/* mode ************************************************************/
typedef struct {
int blockflag;
int windowtype;
int transformtype;
int mapping;
} vorbis_info_mode;
/* psychoacoustic setup ********************************************/
typedef struct vorbis_info_psy{
double maskthresh[MAX_BARK];
double lrolldB;
double hrolldB;
} vorbis_info_psy;
/* vorbis_info contains all the setup information specific to the
specific compression/decompression mode in progress (eg,
psychoacoustic settings, channel setup, options, codebook
etc). Substructures are in backends.h.
etc).
*********************************************************************/
typedef struct vorbis_info{
......@@ -82,7 +106,7 @@ typedef struct vorbis_info{
int *floor_type;
vorbis_info_floor **floor_param;
int *residue_type;
vorbis_info_res **residue_param;
vorbis_info_residue **residue_param;
static_codebook **book_param;
vorbis_info_psy **psy_param; /* encode only */
......@@ -92,17 +116,6 @@ typedef struct vorbis_info{
double preecho_clamp;
} vorbis_info;
/* the comments are not part of vorbis_info so that vorbis_info can be
static storage */
typedef struct vorbis_comments{
/* unlimited user comment fields. libvorbis writes 'libvorbis'
whatever vendor is set to in encode */
char **user_comments;
int comments;
char *vendor;
} vorbis_comments;
/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
......@@ -271,6 +284,26 @@ typedef struct vorbis_block{
} vorbis_block;
#include "vorbis/backends.h"
/* vorbis_info contains all the setup information specific to the
specific compression/decompression mode in progress (eg,
psychoacoustic settings, channel setup, options, codebook
etc). vorbis_info and substructures are in backends.h.
*********************************************************************/
/* the comments are not part of vorbis_info so that vorbis_info can be
static storage */
typedef struct vorbis_comments{
/* unlimited user comment fields. libvorbis writes 'libvorbis'
whatever vendor is set to in encode */
char **user_comments;
int comments;
char *vendor;
} vorbis_comments;
/* libvorbis encodes in two abstraction layers; first we perform DSP
and produce a packet (see docs/analysis.txt). The packet is then
coded into a framed OggSquish bitstream by the second layer (see
......
......@@ -13,7 +13,7 @@
function: libvorbis codec internal types. These structures are
'visible', but generally uninteresting to the developer
last mod: $Id: internal.h,v 1.3 2000/01/22 10:40:38 xiphmont Exp $
last mod: $Id: internal.h,v 1.4 2000/01/22 13:28:12 xiphmont Exp $
********************************************************************/
......@@ -49,10 +49,6 @@ typedef struct {
} oggpack_buffer;
/* internal use */
extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes);
extern void _vorbis_block_ripcord(vorbis_block *vb);
#endif
......
# vorbis makefile configured for use with gcc on any platform
# $Id: Makefile.in,v 1.22 2000/01/20 04:42:50 xiphmont Exp $
# $Id: Makefile.in,v 1.23 2000/01/22 13:28:13 xiphmont Exp $
###############################################################################
# #
......@@ -28,9 +28,10 @@ RANLIB=@RANLIB@
LIBS=@LIBS@ -lm
HFILES = ../include/vorbis/codec.h ../include/vorbis/vorbisfile.h \
bitwise.h envelope.h lpc.h lsp.h bookinternal.h\
psy.h smallft.h window.h scales.h os.h mdct.h\
time0.h floor0.h res0.h mapping0.h registry.h
../include/vorbis/internal.h ../include/vorbis/backend.h \
../include/vorbis/codebook.h \
bitwise.h envelope.h lpc.h lsp.h bookinternal.h misc.h\
psy.h smallft.h window.h scales.h os.h mdct.h registry.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\
time0.o floor0.o res0.o mapping0.o registry.o\
......
......@@ -12,7 +12,7 @@
********************************************************************
function: single-block PCM analysis mode dispatch
last mod: $Id: analysis.c,v 1.21 2000/01/20 04:42:51 xiphmont Exp $
last mod: $Id: analysis.c,v 1.22 2000/01/22 13:28:14 xiphmont Exp $
********************************************************************/
......@@ -43,11 +43,16 @@ int vorbis_analysis(vorbis_block *vb,ogg_packet *op){
/* currently lazy. Short block dispatches to 0, long to 1. */
if(vb->W &&vi->modes>1)mode=1;
type=vi->mappingtypes[mode];
type=vi->map_type[vi->mode_param[mode]->mapping];
/* Encode frame mode and dispatch */
/* Encode frame mode, pre,post windowsize, then dispatch */
_oggpack_write(&vb->opb,mode,vd->modebits);
if(vorbis_map_analysis_P[type](vb,vi->modelist[mode],op))
if(vb->W){
_oggpack_write(&vb->opb,vb->lW,1);
_oggpack_write(&vb->opb,vb->nW,1);
}
if(_mapping_P[type]->forward(vb,vd->mode[mode]))
return(-1);
/* set up the packet wrapper */
......
......@@ -12,7 +12,7 @@
********************************************************************
function: PCM data vector blocking, windowing and dis/reassembly
last mod: $Id: block.c,v 1.22 2000/01/20 04:42:52 xiphmont Exp $
last mod: $Id: block.c,v 1.23 2000/01/22 13:28:15 xiphmont Exp $
Handle windowing, overlap-add, etc of the PCM vectors. This is made
more amusing by Vorbis' current two allowed block sizes.
......@@ -33,8 +33,8 @@
#include "mdct.h"
#include "lpc.h"
#include "bitwise.h"
#include "psy.h"
#include "scales.h"
#include "registry.h"
#include "bookinternal.h"
static int ilog2(unsigned int v){
int ret=0;
......@@ -92,8 +92,8 @@ static int ilog2(unsigned int v){
int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
memset(vb,0,sizeof(vorbis_block));
vb->vd=v;
vb->localalloc=64*1024;
vb->localstore=malloc(vb->localalloc);
vb->localalloc=0;
vb->localstore=NULL;
if(v->analysisp)
_oggpack_writeinit(&vb->opb);
......@@ -103,21 +103,50 @@ int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
if(bytes+vb->localtop>vb->localalloc){
/* eh, conservative. After the first few frames, it won't grow */
vb->localalloc+=bytes;
vb->localstore=realloc(vb->localstore,vb->localalloc);
/* can't just realloc... there are outstanding pointers */
if(vb->localstore){
struct alloc_chain *link=malloc(sizeof(struct alloc_chain));
vb->totaluse+=vb->localtop;
link->next=vb->reap;
link->ptr=vb->localstore;
vb->reap=link;
}
/* highly conservative */
vb->localalloc=bytes;
vb->localstore=malloc(vb->localalloc);
vb->localtop=0;
}
return(vb->localstore+vb->localtop);
}
/* reap the chain, pull the ripcord */
void _vorbis_block_ripcord(vorbis_block *vb){
/* reap the chain */
struct alloc_chain *reap=vb->reap;
while(reap){
struct alloc_chain *next=reap->next;
free(reap->ptr);
memset(reap,0,sizeof(struct alloc_chain));
free(reap);
reap=next;
}
/* consolidate storage */
if(vb->totaluse){
vb->localstore=realloc(vb->localstore,vb->totaluse+vb->localalloc);
vb->localalloc+=vb->totaluse;
vb->totaluse=0;
}
/* pull the ripcord */
vb->localtop=0;
vb->reap=NULL;
}
int vorbis_block_clear(vorbis_block *vb){
if(vb->vd)
if(vb->vd->analysisp)
_oggpack_writeclear(&vb->opb);
_vorbis_block_ripcord(vb);
if(vb->localstore)free(vb->localstore);
memset(vb,0,sizeof(vorbis_block));
......@@ -129,28 +158,56 @@ int vorbis_block_clear(vorbis_block *vb){
The init is here because some of it is shared */
static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi){
int i;
memset(v,0,sizeof(vorbis_dsp_state));
v->vi=vi;
v->modebits=ilog2(vi->modes);
mdct_init(&v->vm[0],vi->blocksizes[0]);
mdct_init(&v->vm[1],vi->blocksizes[1]);
v->transform[0]=calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
v->transform[1]=calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
/* MDCT is tranform 0 */
v->window[0][0][0]=_vorbis_window(vi->blocksizes[0],
vi->blocksizes[0]/2,vi->blocksizes[0]/2);
v->transform[0][0]=calloc(1,sizeof(mdct_lookup));
v->transform[1][0]=calloc(1,sizeof(mdct_lookup));
mdct_init(v->transform[0][0],vi->blocksizes[0]);
mdct_init(v->transform[1][0],vi->blocksizes[1]);
v->window[0][0][0]=calloc(VI_WINDOWB,sizeof(double *));
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]=calloc(VI_WINDOWB,sizeof(double *));
v->window[1][0][1]=calloc(VI_WINDOWB,sizeof(double *));
v->window[1][1][0]=calloc(VI_WINDOWB,sizeof(double *));
v->window[1][1][1]=calloc(VI_WINDOWB,sizeof(double *));
for(i=0;i<VI_WINDOWB;i++){
v->window[0][0][0][i]=
_vorbis_window(i,vi->blocksizes[0],vi->blocksizes[0]/2,vi->blocksizes[0]/2);
v->window[1][0][0][i]=
_vorbis_window(i,vi->blocksizes[1],vi->blocksizes[0]/2,vi->blocksizes[0]/2);
v->window[1][0][1][i]=
_vorbis_window(i,vi->blocksizes[1],vi->blocksizes[0]/2,vi->blocksizes[1]/2);
v->window[1][1][0][i]=
_vorbis_window(i,vi->blocksizes[1],vi->blocksizes[1]/2,vi->blocksizes[0]/2);
v->window[1][1][1][i]=
_vorbis_window(i,vi->blocksizes[1],vi->blocksizes[1]/2,vi->blocksizes[1]/2);
}
v->window[1][0][0]=_vorbis_window(vi->blocksizes[1],
vi->blocksizes[0]/2,vi->blocksizes[0]/2);
v->window[1][0][1]=_vorbis_window(vi->blocksizes[1],
vi->blocksizes[0]/2,vi->blocksizes[1]/2);
v->window[1][1][0]=_vorbis_window(vi->blocksizes[1],
vi->blocksizes[1]/2,vi->blocksizes[0]/2);
v->window[1][1][1]=_vorbis_window(vi->blocksizes[1],
vi->blocksizes[1]/2,vi->blocksizes[1]/2);
/* initialize all the mapping/backend lookups */
v->mode=calloc(vi->modes,sizeof(vorbis_look_mapping *));
for(i=0;i<vi->modes;i++){
int maptype=vi->mode_param[i]->mapping;
v->mode[i]=_mapping_P[maptype]->look(vi,vi->mode_param[i],
vi->map_param[maptype]);
}
/* finish the codebooks */
v->fullbooks=calloc(vi->books,sizeof(codebook));
for(i=0;i<vi->books;i++)
vorbis_book_finish(v->fullbooks+i,vi->book_param[i]);
/* initialize the storage vectors to a decent size greater than the
minimum */
......@@ -180,6 +237,7 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi){
/* arbitrary settings and spec-mandated numbers get filled in here */
int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
_vds_shared_init(v,vi);
/* Initialize the envelope multiplier storage */
......@@ -200,10 +258,12 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){
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]);
for(i=0;i<VI_WINDOWB;i++){
if(v->window[0][0][0][i])free(v->window[0][0][0][i]);
for(j=0;j<2;j++)
for(k=0;k<2;k++)
if(v->window[1][j][k][i])free(v->window[1][j][k][i]);
}
if(v->pcm){
for(i=0;i<vi->channels;i++)
if(v->pcm[i])free(v->pcm[i]);
......@@ -213,8 +273,31 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){
if(v->multipliers)free(v->multipliers);
_ve_envelope_clear(&v->ve);
mdct_clear(&v->vm[0]);
mdct_clear(&v->vm[1]);
mdct_clear(v->transform[0][0]);
mdct_clear(v->transform[1][0]);
free(v->transform[0][0]);
free(v->transform[1][0]);
free(v->transform[0]);
free(v->transform[1]);
/* free mode lookups */
for(i=0;i<vi->modes;i++){
int maptype=vi->mode_param[i]->mapping;
_mapping_P[maptype]->free_look(v->mode[i]);
}
if(v->mode)free(v->mode);
/* free codebooks */
for(i=0;i<vi->books;i++)
vorbis_book_clear(v->fullbooks+i);
if(v->fullbooks)free(v->fullbooks);
/* free header, header1, header2 */
if(v->header)free(v->header);
if(v->header1)free(v->header1);
if(v->header2)free(v->header2);
memset(v,0,sizeof(vorbis_dsp_state));
}
}
......@@ -223,6 +306,11 @@ double **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
int i;
vorbis_info *vi=v->vi;
/* free header, header1, header2 */
if(v->header)free(v->header);v->header=NULL;
if(v->header1)free(v->header1);v->header1=NULL;
if(v->header2)free(v->header2);v->header2=NULL;
/* Do we have enough storage space for the requested buffer? If not,
expand the PCM (and envelope) storage */
......
......@@ -12,7 +12,7 @@
********************************************************************
function: basic codebook pack/unpack/code/decode operations
last mod: $Id: bookinternal.h,v 1.3 2000/01/20 04:42:54 xiphmont Exp $
last mod: $Id: bookinternal.h,v 1.4 2000/01/22 13:28:16 xiphmont Exp $
********************************************************************/
......@@ -22,17 +22,7 @@
#include "vorbis/codebook.h"
#include "bitwise.h"
/* some elements in the codebook structure are assumed to be pointers
to static/shared storage (the pointers are duped, and free below
does not touch them. The fields are unused by decode):
quantlist,
lengthlist,
encode_tree