# vorbis makefile configured for use with gcc on any platform
-# $Id: Makefile.in,v 1.21 2000/01/12 11:34:39 xiphmont Exp $
+# $Id: Makefile.in,v 1.22 2000/01/20 04:42:50 xiphmont Exp $
###############################################################################
# #
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
+ psy.h smallft.h window.h scales.h os.h mdct.h\
+ time0.h floor0.h res0.h mapping0.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\
spectrum.o codebook.o vorbisfile.o
all:
* *
********************************************************************
- function: single-block PCM analysis
- last mod: $Id: analysis.c,v 1.20 2000/01/05 03:10:53 xiphmont Exp $
+ function: single-block PCM analysis mode dispatch
+ last mod: $Id: analysis.c,v 1.21 2000/01/20 04:42:51 xiphmont Exp $
********************************************************************/
#include <string.h>
#include <math.h>
#include "vorbis/codec.h"
-
-#include "os.h"
-#include "lpc.h"
-#include "lsp.h"
-#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 */
+#include "registry.h"
+/* decides between modes, dispatches to the appropriate mapping. */
int vorbis_analysis(vorbis_block *vb,ogg_packet *op){
- int i;
- double *window=vb->vd->window[vb->W][vb->lW][vb->nW];
- psy_lookup *vp=&vb->vd->vp[vb->W];
- lpc_lookup *vl=&vb->vd->vl[vb->W];
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];
+ int type;
+ int mode=0;
- vb->gluebits=0;
- vb->time_envelope_bits=0;
- vb->spectral_envelope_bits=0;
- vb->spectral_residue_bits=0;
+ vb->glue_bits=0;
+ vb->time_bits=0;
+ vb->floor_bits=0;
+ vb->res_bits=0;
- /*lpc_lookup *vbal=&vb->vd->vbal[vb->W];
- double balance_v[vbal->m];
- double balance_amp;*/
-
- /* first things first. Make sure encode is ready*/
- _oggpack_reset(opb);
+ /* first things first. Make sure encode is ready */
+ _oggpack_reset(&vb->opb);
/* Encode the packet type */
- _oggpack_write(opb,0,1);
-
- /* Encode the block size */
- _oggpack_write(opb,vb->W,1);
- if(vb->W){
- _oggpack_write(opb,vb->lW,1);
- _oggpack_write(opb,vb->nW,1);
- }
-
- /* No envelope encoding yet */
- _oggpack_write(opb,0,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++){
- static int frameno=0;
- int j;
- double *floor=alloca(n/2*sizeof(double));
- double *curve=alloca(n/2*sizeof(double));
- double *lpc=vb->lpc[i];
- double *lsp=vb->lsp[i];
-
- memset(floor,0,sizeof(double)*n/2);
-
-#ifdef ANALYSIS
- {
- FILE *out;
- char buffer[80];
-
- sprintf(buffer,"Aspectrum%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<n/2;j++)
- fprintf(out,"%g\n",vb->pcm[i][j]);
- fclose(out);
-
- }
-#endif
-
- _vp_mask_floor(vp,vb->pcm[i],floor);
-
-#ifdef ANALYSIS
- {
- FILE *out;
- char buffer[80];
-
- sprintf(buffer,"Apremask%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<n/2;j++)
- fprintf(out,"%g\n",floor[j]);
- fclose(out);
- }
-#endif
-
- /* Convert our floor to a set of lpc coefficients */
- vb->amp[i]=sqrt(vorbis_curve_to_lpc(floor,lpc,vl));
+ _oggpack_write(&vb->opb,0,1);
- /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
- vorbis_lpc_to_lsp(lpc,lsp,vl->m);
+ /* currently lazy. Short block dispatches to 0, long to 1. */
- /* code the spectral envelope; mutates the lsp coeffs to reflect
- what was actually encoded */
- _vs_spectrum_encode(vb,vb->amp[i],lsp);
+ if(vb->W &&vi->modes>1)mode=1;
+ type=vi->mappingtypes[mode];
- /* 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...*/
- if(vb->amp[i])_vs_residue_train(vb,vb->pcm[i],curve,n/2);
- _vs_residue_quantize(vb->pcm[i],curve,vi,n/2);
-
-#ifdef ANALYSIS
- {
- FILE *out;
- char buffer[80];
-
- sprintf(buffer,"Alpc%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<vl->m;j++)
- fprintf(out,"%g\n",lpc[j]);
- fclose(out);
-
- sprintf(buffer,"Alsp%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<vl->m;j++)
- fprintf(out,"%g\n",lsp[j]);
- fclose(out);
-
- sprintf(buffer,"Amask%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<n/2;j++)
- fprintf(out,"%g\n",curve[j]);
- fclose(out);
-
- sprintf(buffer,"Ares%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<n/2;j++)
- fprintf(out,"%g\n",vb->pcm[i][j]);
- fclose(out);
- }
-#endif
-
- /* encode the residue */
- _vs_residue_encode(vb,vb->pcm[i]);
-
- }
- }
+ /* Encode frame mode and dispatch */
+ _oggpack_write(&vb->opb,mode,vd->modebits);
+ if(vorbis_map_analysis_P[type](vb,vi->modelist[mode],op))
+ return(-1);
/* set up the packet wrapper */
- op->packet=opb->buffer;
- op->bytes=_oggpack_bytes(opb);
+ op->packet=_oggpack_buffer(&vb->opb);
+ op->bytes=_oggpack_bytes(&vb->opb);
op->b_o_s=0;
op->e_o_s=vb->eofflag;
op->frameno=vb->frameno;
return(0);
}
-
-
-
-
-/* commented out, relocated balance stuff */
- /*{
- double *C=vb->pcm[0];
- double *D=vb->pcm[1];
-
- balance_amp=_vp_balance_compute(D,C,balance_v,vbal);
-
- {
- FILE *out;
- char buffer[80];
-
- sprintf(buffer,"com%d.m",frameno);
- out=fopen(buffer,"w+");
- for(i=0;i<n/2;i++){
- fprintf(out," 0. 0.\n");
- fprintf(out,"%g %g\n",C[i],D[i]);
- fprintf(out,"\n");
- }
- fclose(out);
-
- sprintf(buffer,"L%d.m",frameno);
- out=fopen(buffer,"w+");
- for(i=0;i<n/2;i++){
- fprintf(out,"%g\n",C[i]);
- }
- fclose(out);
- sprintf(buffer,"R%d.m",frameno);
- out=fopen(buffer,"w+");
- for(i=0;i<n/2;i++){
- fprintf(out,"%g\n",D[i]);
- }
- fclose(out);
-
- }
-
- _vp_balance_apply(D,C,balance_v,balance_amp,vbal,1);
-
- {
- FILE *out;
- char buffer[80];
-
- sprintf(buffer,"bal%d.m",frameno);
- out=fopen(buffer,"w+");
- for(i=0;i<n/2;i++){
- fprintf(out," 0. 0.\n");
- fprintf(out,"%g %g\n",C[i],D[i]);
- fprintf(out,"\n");
- }
- fclose(out);
- sprintf(buffer,"C%d.m",frameno);
- out=fopen(buffer,"w+");
- for(i=0;i<n/2;i++){
- fprintf(out,"%g\n",C[i]);
- }
- fclose(out);
- sprintf(buffer,"D%d.m",frameno);
- out=fopen(buffer,"w+");
- for(i=0;i<n/2;i++){
- fprintf(out,"%g\n",D[i]);
- }
- fclose(out);
-
- }
- }*/
********************************************************************
function: PCM data vector blocking, windowing and dis/reassembly
- last mod: $Id: block.c,v 1.21 2000/01/05 03:10:55 xiphmont Exp $
+ last mod: $Id: block.c,v 1.22 2000/01/20 04:42:52 xiphmont Exp $
Handle windowing, overlap-add, etc of the PCM vectors. This is made
more amusing by Vorbis' current two allowed block sizes.
#include "psy.h"
#include "scales.h"
+static int ilog2(unsigned int v){
+ int ret=0;
+ while(v>1){
+ ret++;
+ v>>=1;
+ }
+ return(ret);
+}
+
/* pcm accumulator examples (not exhaustive):
<-------------- lW ---------------->
/* block abstraction setup *********************************************/
+#ifndef WORD_ALIGN
+#define WORD_ALIGN 8
+#endif
+
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=vi->blocksize[1];
- vb->pcm_channels=vi->channels;
- 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++)
- vb->pcm[i]=malloc(vb->pcm_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));
- }
+ vb->localalloc=64*1024;
+ vb->localstore=malloc(vb->localalloc);
if(v->analysisp)
_oggpack_writeinit(&vb->opb);
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);
+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);
}
- if(vb->lpc){
- for(i=0;i<vb->floor_channels;i++)
- free(vb->lpc[i]);
- free(vb->lpc);
- }
- if(vb->lsp){
- for(i=0;i<vb->floor_channels;i++)
- free(vb->lsp[i]);
- free(vb->lsp);
- }
- if(vb->amp)free(vb->amp);
+ return(vb->localstore+vb->localtop);
+}
+
+void _vorbis_block_ripcord(vorbis_block *vb){
+ vb->localtop=0;
+}
+
+int vorbis_block_clear(vorbis_block *vb){
if(vb->vd)
if(vb->vd->analysisp)
_oggpack_writeclear(&vb->opb);
+ if(vb->localstore)free(vb->localstore);
memset(vb,0,sizeof(vorbis_block));
return(0);
memset(v,0,sizeof(vorbis_dsp_state));
v->vi=vi;
- mdct_init(&v->vm[0],vi->blocksize[0]);
- mdct_init(&v->vm[1],vi->blocksize[1]);
+ v->modebits=ilog2(vi->modes);
+
+ mdct_init(&v->vm[0],vi->blocksizes[0]);
+ mdct_init(&v->vm[1],vi->blocksizes[1]);
- v->window[0][0][0]=_vorbis_window(vi->blocksize[0],
- vi->blocksize[0]/2,vi->blocksize[0]/2);
+ v->window[0][0][0]=_vorbis_window(vi->blocksizes[0],
+ vi->blocksizes[0]/2,vi->blocksizes[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(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);
+ 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 the storage vectors to a decent size greater than the
minimum */
v->W=0; /* current window size */
/* all vector indexes; multiples of samples_per_envelope_step */
- v->centerW=vi->blocksize[1]/2;
+ v->centerW=vi->blocksizes[1]/2;
v->pcm_current=v->centerW;
return(0);
/* the coder init is different for read/write */
v->analysisp=1;
- _vp_psy_init(&v->vp[0],vi,vi->blocksize[0]/2);
- _vp_psy_init(&v->vp[1],vi,vi->blocksize[1]/2);
-
- /* Yes, wasteful to have four lookups. This will get collapsed once
- things crystallize */
-
- lpc_init(&v->vl[0],vi->blocksize[0]/2,vi->floormap[0],vi->rate,
- vi->floororder[0]);
- lpc_init(&v->vl[1],vi->blocksize[1]/2,vi->floormap[1],vi->rate,
- vi->floororder[1]);
-
- /*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);*/
v->envelope_current=v->centerW/vi->envelopesa;
-
return(0);
}
_ve_envelope_clear(&v->ve);
mdct_clear(&v->vm[0]);
mdct_clear(&v->vm[1]);
- lpc_clear(&v->vl[0]);
- lpc_clear(&v->vl[1]);
- _vp_psy_clear(&v->vp[0]);
- _vp_psy_clear(&v->vp[1]);
- /*lpc_clear(&v->vbal[0]);
- lpc_clear(&v->vbal[1]);*/
memset(v,0,sizeof(vorbis_dsp_state));
}
}
[at least] a full block of zeroes at the end. */
int i;
- vorbis_analysis_buffer(v,v->vi->blocksize[1]*2);
+ vorbis_analysis_buffer(v,v->vi->blocksizes[1]*2);
v->eofflag=v->pcm_current;
- v->pcm_current+=v->vi->blocksize[1]*2;
+ v->pcm_current+=v->vi->blocksizes[1]*2;
for(i=0;i<vi->channels;i++)
memset(v->pcm[i]+v->eofflag,0,
(v->pcm_current-v->eofflag)*sizeof(double));
int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
int i;
vorbis_info *vi=v->vi;
- long beginW=v->centerW-vi->blocksize[v->W]/2,centerNext;
+ long beginW=v->centerW-vi->blocksizes[v->W]/2,centerNext;
/* check to see if we're done... */
if(v->eofflag==-1)return(0);
the next boundary so we can determine nW (the next window size)
which lets us compute the shape of the current block's window */
- if(vi->blocksize[0]<vi->blocksize[1]){
+ if(vi->blocksizes[0]<vi->blocksizes[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+vi->blocksize[1]/4-vi->blocksize[0]/4;
+ i=v->centerW+vi->blocksizes[1]/4-vi->blocksizes[0]/4;
else
/* short window. Search from centerW */
i=v->centerW;
long largebound;
if(v->W)
/* min boundary; nW large, next small */
- largebound=v->centerW+vi->blocksize[1]*3/4+vi->blocksize[0]/4;
+ largebound=v->centerW+vi->blocksizes[1]*3/4+vi->blocksizes[0]/4;
else
/* min boundary; nW large, next small */
- largebound=v->centerW+vi->blocksize[0]/2+vi->blocksize[1]/2;
+ largebound=v->centerW+vi->blocksizes[0]/2+vi->blocksizes[1]/2;
largebound/=vi->envelopesa;
if(i>=largebound)
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+vi->blocksize[v->W]/4+vi->blocksize[v->nW]/4;
+ centerNext=v->centerW+vi->blocksizes[v->W]/4+vi->blocksizes[v->nW]/4;
{
/* center of next block + next block maximum right side. Note
to actually be written (for the last multiplier), but we didn't
need that to determine its size */
- long blockbound=centerNext+vi->blocksize[v->nW]/2;
+ long blockbound=centerNext+vi->blocksizes[v->nW]/2;
if(v->pcm_current<blockbound)return(0); /* not enough data yet */
}
/* fill in the block. Note that for a short window, lW and nW are *short*
regardless of actual settings in the stream */
+ _vorbis_block_ripcord(vb);
if(v->W){
vb->lW=v->lW;
vb->W=v->W;
vb->vd=v;
vb->sequence=v->sequence;
vb->frameno=v->frameno;
+ vb->pcmend=vi->blocksizes[v->W];
- /* copy the vectors */
- vb->pcmend=vi->blocksize[v->W];
- for(i=0;i<vi->channels;i++)
- memcpy(vb->pcm[i],v->pcm[i]+beginW,vi->blocksize[v->W]*sizeof(double));
+ /* copy the vectors; this uses the local storage in vb */
+ {
+ vb->pcm=_vorbis_block_alloc(vb,sizeof(double *)*vi->channels);
+ for(i=0;i<vi->channels;i++){
+ vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(double));
+ memcpy(vb->pcm[i],v->pcm[i]+beginW,vi->blocksizes[v->W]*sizeof(double));
+ }
+ }
/* handle eof detection: eof==0 means that we've not yet received EOF
eof>0 marks the last 'real' sample in pcm[]
/* advance storage vectors and clean up */
{
- int new_centerNext=vi->blocksize[1]/2;
+ int new_centerNext=vi->blocksizes[1]/2;
int movementW=centerNext-new_centerNext;
int movementM=movementW/vi->envelopesa;
- /* the multipliers and pcm stay synced up because the blocksizes
+ /* the multipliers and pcm stay synced up because the blocksize
must be multiples of samples_per_envelope_step (minimum
multiple is 2) */
int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
_vds_shared_init(v,vi);
- /* Yes, wasteful to have four lookups. This will get collapsed once
- things crystallize */
- lpc_init(&v->vl[0],vi->blocksize[0]/2,vi->floormap[0],vi->rate,
- vi->floororder[0]);
- lpc_init(&v->vl[1],vi->blocksize[1]/2,vi->floormap[1],vi->rate,
- vi->floororder[1]);
- /*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-= vi->blocksize[v->W]/4+vi->blocksize[v->lW]/4;
+ v->centerW-= vi->blocksizes[v->W]/4+vi->blocksizes[v->lW]/4;
return(0);
}
/* Shift out any PCM/multipliers that we returned previously */
/* centerW is currently the center of the last block added */
- if(v->pcm_returned && v->centerW>vi->blocksize[1]/2){
+ if(v->pcm_returned && v->centerW>vi->blocksizes[1]/2){
/* don't shift too much; we need to have a minimum PCM buffer of
1/2 long block */
- int shiftPCM=v->centerW-vi->blocksize[1]/2;
+ int shiftPCM=v->centerW-vi->blocksizes[1]/2;
shiftPCM=(v->pcm_returned<shiftPCM?v->pcm_returned:shiftPCM);
v->pcm_current-=shiftPCM;
v->W=vb->W;
v->nW=-1;
- v->gluebits+=vb->gluebits;
- v->time_envelope_bits+=vb->time_envelope_bits;
- v->spectral_envelope_bits+=vb->spectral_envelope_bits;
- v->spectral_residue_bits+=vb->spectral_residue_bits;
+ v->glue_bits+=vb->glue_bits;
+ v->time_bits+=vb->time_bits;
+ v->floor_bits+=vb->floor_bits;
+ v->res_bits+=vb->res_bits;
v->sequence=vb->sequence;
{
- int sizeW=vi->blocksize[v->W];
- int centerW=v->centerW+vi->blocksize[v->lW]/4+sizeW/4;
+ int sizeW=vi->blocksizes[v->W];
+ int centerW=v->centerW+vi->blocksizes[v->lW]/4+sizeW/4;
int beginW=centerW-sizeW/2;
int endW=beginW+sizeW;
int beginSl;
/* Do we have enough PCM/mult storage for the block? */
if(endW>v->pcm_storage){
/* expand the storage */
- v->pcm_storage=endW+vi->blocksize[1];
+ v->pcm_storage=endW+vi->blocksizes[1];
for(i=0;i<vi->channels;i++)
v->pcm[i]=realloc(v->pcm[i],v->pcm_storage*sizeof(double));
switch(v->W){
case 0:
beginSl=0;
- endSl=vi->blocksize[0]/2;
+ endSl=vi->blocksizes[0]/2;
break;
case 1:
- beginSl=vi->blocksize[1]/4-vi->blocksize[v->lW]/4;
- endSl=beginSl+vi->blocksize[v->lW]/2;
+ beginSl=vi->blocksizes[1]/4-vi->blocksizes[v->lW]/4;
+ endSl=beginSl+vi->blocksizes[v->lW]/2;
break;
}
********************************************************************
function: basic codebook pack/unpack/code/decode operations
- last mod: $Id: bookinternal.h,v 1.2 2000/01/12 11:16:36 xiphmont Exp $
+ last mod: $Id: bookinternal.h,v 1.3 2000/01/20 04:42:54 xiphmont Exp $
********************************************************************/
*/
extern void vorbis_book_dup(codebook *dest,const codebook *source);
-extern void vorbis_book_free(codebook *b);
+extern void vorbis_book_clear(codebook *b);
extern int vorbis_book_pack(codebook *c,oggpack_buffer *b);
extern int vorbis_book_unpack(oggpack_buffer *b,codebook *c);
* *
********************************************************************
- function: pack/unpack/dup/clear the various floor backend setups
- last mod: $Id: infofloor.c,v 1.1 2000/01/19 08:57:56 xiphmont Exp $
+ function: floor backend 0 implementation
+ last mod: $Id: floor0.c,v 1.1 2000/01/20 04:42:55 xiphmont Exp $
********************************************************************/
#include <string.h>
#include "vorbis/codec.h"
#include "bitwise.h"
-#include "bookinternal.h"
+#include "registry.h"
+#include "floor0.h"
-/* calls for floor backend 0 *********************************************/
-static void *_vorbis_floor0_dup(void *source){
+extern _vi_info_floor *_vorbis_floor0_dup(_vi_info_floor *source){
vorbis_info_floor0 *d=malloc(sizeof(vorbis_info_floor0));
memcpy(d,source,sizeof(vorbis_info_floor0));
if(d->stages){
return(d);
}
-static void _vorbis_floor0_free(void *i){
+extern void _vorbis_floor0_free(_vi_info_floor *i){
vorbis_info_floor0 *d=(vorbis_info_floor0 *)i;
if(d){
if(d->books)free(d->books);
}
}
-static void _vorbis_floor0_pack(oggpack_buffer *opb,void *vi){
+extern void _vorbis_floor0_pack(oggpack_buffer *opb,_vi_info_floor *vi){
vorbis_info_floor0 *d=(vorbis_info_floor0 *)vi;
int i;
_oggpack_write(opb,d->order,8);
_oggpack_write(opb,d->books[i],8);
}
-/* type is read earlier (so that we know to call this type) */
-static void *_vorbis_floor0_unpack(oggpack_buffer *opb){
+extern _vi_info_floor *_vorbis_floor0_unpack(vorbis_info *vi,
+ oggpack_buffer *opb){
vorbis_info_floor0 d;
int i;
d.order=_oggpack_read(opb,8);
if(d.stages<1)return(NULL);
d.books=alloca(sizeof(int)*d.stages);
- for(i=0;i<d.stages;i++)
+ for(i=0;i<d.stages;i++){
d.books[i]=_oggpack_read(opb,8);
- if(d.books[d.stages-1]<0)return(NULL);
+ if(d.books[i]<0 || d.books[i]>=vi->books)return(NULL);
+ }
return(_vorbis_floor0_dup(&d));
}
-
-/* stuff em into arrays ************************************************/
-#define VI_FLOORB 1
-
-static void *(*vorbis_floor_dup_P[])(void *)={
- _vorbis_floor0_dup,
-};
-
-static void (*vorbis_floor_free_P[])(void *)={
- _vorbis_floor0_free,
-};
-
-static void (*vorbis_floor_pack_P[])(oggpack_buffer *,void *)={
- _vorbis_floor0_pack,
-};
-
-static void *(*vorbis_floor_unpack_P[])(oggpack_buffer *)={
- _vorbis_floor0_unpack,
-};
-
--- /dev/null
+/********************************************************************
+ * *
+ * 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-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: floor backend 0 implementation
+ last mod: $Id: floor0.h,v 1.1 2000/01/20 04:42:55 xiphmont Exp $
+
+ ********************************************************************/
+
+typedef struct vorbis_info_floor0{
+ int order;
+ long rate;
+ long barkmap;
+
+ int stages;
+ int *books;
+} vorbis_info_floor0;
+
+extern _vi_info_floor *_vorbis_floor0_dup(_vi_info_floor *source);
+extern void _vorbis_floor0_free(_vi_info_floor *vi);
+extern void _vorbis_floor0_pack(oggpack_buffer *opb,
+ _vi_info_floor *vi);
+extern _vi_info_floor *_vorbis_floor0_unpack(vorbis_info *vi,
+ oggpack_buffer *opb);
+
********************************************************************
function: maintain the info structure, info <-> header packets
- last mod: $Id: info.c,v 1.15 2000/01/19 08:57:55 xiphmont Exp $
+ last mod: $Id: info.c,v 1.16 2000/01/20 04:42:55 xiphmont Exp $
********************************************************************/
#include "vorbis/codec.h"
#include "bitwise.h"
#include "bookinternal.h"
-
-/* these modules were split out only to make this file more readable.
- I don't want to expose the symbols */
-#include "infomap.c"
+#include "registry.h"
+#include "psy.h"
/* helpers */
/* dup mode maps, blockflags and map types */
if(source->modes){
dest->blockflags=malloc(source->modes*sizeof(int));
- dest->maptypes=malloc(source->modes*sizeof(int));
- dest->maplist=calloc(source->modes,sizeof(void *));
+ dest->windowtypes=malloc(source->modes*sizeof(int));
+ dest->transformtypes=malloc(source->modes*sizeof(int));
+ dest->mappingtypes=malloc(source->modes*sizeof(int));
+ dest->modelist=calloc(source->modes,sizeof(void *));
memcpy(dest->blockflags,source->blockflags,sizeof(int)*dest->modes);
- memcpy(dest->maptypes,source->maptypes,sizeof(int)*dest->modes);
+ memcpy(dest->windowtypes,source->windowtypes,sizeof(int)*dest->modes);
+ memcpy(dest->transformtypes,source->transformtypes,sizeof(int)*dest->modes);
+ memcpy(dest->mappingtypes,source->mappingtypes,sizeof(int)*dest->modes);
for(i=0;i<source->modes;i++){
- void *dup;
- if(dest->maptypes[i]<0|| dest->maptypes[i]>=VI_MAPB)goto err_out;
- if(!(dup=vorbis_map_dup_P[dest->maptypes[i]](source->maplist[i])))
- goto err_out;
- dest->maplist[i]=dup;
+ if(dest->mappingtypes[i]<0|| dest->mappingtypes[i]>=VI_MAPB)goto err_out;
+ dest->modelist[i]=
+ vorbis_map_dup_P[dest->mappingtypes[i]](source,source->modelist[i]);
+ }
+ }
+
+ /* dup times */
+ if(source->times){
+ dest->timetypes=malloc(source->times*sizeof(int));
+ dest->timelist=calloc(source->times,sizeof(void *));
+ memcpy(dest->timetypes,source->timetypes,sizeof(int)*dest->times);
+ for(i=0;i<source->times;i++){
+ if(dest->timetypes[i]<0|| dest->timetypes[i]>=VI_TIMEB)goto err_out;
+ dest->timelist[i]=
+ vorbis_time_dup_P[dest->timetypes[i]](source->timelist[i]);
+ }
+ }
+
+ /* dup floors */
+ if(source->floors){
+ dest->floortypes=malloc(source->floors*sizeof(int));
+ dest->floorlist=calloc(source->floors,sizeof(void *));
+ memcpy(dest->floortypes,source->floortypes,sizeof(int)*dest->floors);
+ for(i=0;i<source->floors;i++){
+ if(dest->floortypes[i]<0|| dest->floortypes[i]>=VI_FLOORB)goto err_out;
+ dest->floorlist[i]=
+ vorbis_floor_dup_P[dest->floortypes[i]](source->floorlist[i]);
+ }
+ }
+
+ /* dup residues */
+ if(source->residues){
+ dest->residuetypes=malloc(source->residues*sizeof(int));
+ dest->residuelist=calloc(source->residues,sizeof(void *));
+ memcpy(dest->residuetypes,source->residuetypes,sizeof(int)*dest->residues);
+ for(i=0;i<source->residues;i++){
+ if(dest->residuetypes[i]<0|| dest->residuetypes[i]>=VI_RESB)
+ goto err_out;
+ dest->residuelist[i]=
+ vorbis_res_dup_P[dest->residuetypes[i]](source->residuelist[i]);
}
}
vorbis_book_dup(dest->booklist[i],source->booklist[i]);
}
}
+
+ /* dup psychoacoustics (if any) */
+ if(source->psys){
+ dest->psylist=calloc(source->psys,sizeof(void *));
+ for(i=0;i<source->psys;i++){
+ dest->psylist[i]=_vi_psy_dup(source->psylist[i]);
+ }
+ }
+
/* we do *not* dup local storage */
dest->header=NULL;
dest->header1=NULL;
free(vi->user_comments);
}
if(vi->vendor)free(vi->vendor);
+ if(vi->windowtypes)free(vi->windowtypes);
+ if(vi->transformtypes)free(vi->transformtypes);
if(vi->modes){
for(i=0;i<vi->modes;i++)
- if(vi->maptypes[i]>=0 && vi->maptypes[i]<VI_MAPB)
- vorbis_map_free_P[vi->maptypes[i]](vi->maplist[i]);
- free(vi->maplist);
- free(vi->maptypes);
+ if(vi->mappingtypes[i]>=0 && vi->mappingtypes[i]<VI_MAPB)
+ vorbis_map_free_P[vi->mappingtypes[i]](vi->modelist[i]);
+ free(vi->modelist);
+ free(vi->mappingtypes);
free(vi->blockflags);
}
+ if(vi->times){
+ for(i=0;i<vi->times;i++)
+ if(vi->timetypes[i]>=0 && vi->timetypes[i]<VI_TIMEB)
+ vorbis_time_free_P[vi->timetypes[i]](vi->timelist[i]);
+ free(vi->timelist);
+ free(vi->timetypes);
+ }
+ if(vi->floors){
+ for(i=0;i<vi->floors;i++)
+ if(vi->floortypes[i]>=0 && vi->floortypes[i]<VI_FLOORB)
+ vorbis_floor_free_P[vi->floortypes[i]](vi->floorlist[i]);
+ free(vi->floorlist);
+ free(vi->floortypes);
+ }
+ if(vi->residues){
+ for(i=0;i<vi->residues;i++)
+ if(vi->residuetypes[i]>=0 && vi->residuetypes[i]<VI_RESB)
+ vorbis_res_free_P[vi->residuetypes[i]](vi->residuelist[i]);
+ free(vi->residuelist);
+ free(vi->residuetypes);
+ }
if(vi->books){
for(i=0;i<vi->books;i++){
if(vi->booklist[i]){
}
free(vi->booklist);
}
+ if(vi->psys){
+ for(i=0;i<vi->psys;i++)
+ _vi_psy_free(vi->psylist[i]);
+ free(vi->psylist);
+ }
if(vi->header)free(vi->header);
if(vi->header1)free(vi->header1);
if(vi->rate<1)goto err_out;
if(vi->channels<1)goto err_out;
if(vi->blocksizes[0]<8)goto err_out;
- if(vi->blocksizes[1]<vi->blocksizes[0])
- goto err_out; /* doubles as EOF check */
+ if(vi->blocksizes[1]<vi->blocksizes[0])goto err_out;
+
+ if(_oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
return(0);
err_out:
vi->user_comments[i]=calloc(len+1,1);
_v_readstring(opb,vi->user_comments[i],len);
}
+ if(_oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
+
return(0);
err_out:
vorbis_info_clear(vi);
static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
int i;
- vi->modes=_oggpack_read(opb,16);
- vi->blockflags=malloc(vi->modes*sizeof(int));
- vi->maptypes=malloc(vi->modes*sizeof(int));
- vi->maplist=calloc(vi->modes,sizeof(void *));
+ /* time backend settings */
+ vi->times=_oggpack_read(opb,8);
+ vi->timetypes=malloc(vi->times*sizeof(int));
+ vi->timelist=calloc(vi->times,sizeof(void *));
+ for(i=0;i<vi->times;i++){
+ vi->timetypes[i]=_oggpack_read(opb,16);
+ if(vi->timetypes[i]<0 || vi->timetypes[i]>VI_TIMEB)goto err_out;
+ vi->timelist[i]=vorbis_time_unpack_P[vi->timetypes[i]](vi,opb);
+ if(!vi->timelist[i])goto err_out;
+ }
- for(i=0;i<vi->modes;i++){
- vi->blockflags[i]=_oggpack_read(opb,1);
- vi->maptypes[i]=_oggpack_read(opb,8);
- if(vi->maptypes[i]<0 || vi->maptypes[i]>VI_MAPB)goto err_out;
- vi->maplist[i]=vorbis_map_unpack_P[vi->maptypes[i]](opb);
- if(!vi->maplist[i])goto err_out;
+ /* floor backend settings */
+ vi->floors=_oggpack_read(opb,8);
+ vi->floortypes=malloc(vi->floors*sizeof(int));
+ vi->floorlist=calloc(vi->floors,sizeof(void *));
+ for(i=0;i<vi->floors;i++){
+ vi->floortypes[i]=_oggpack_read(opb,16);
+ if(vi->floortypes[i]<0 || vi->floortypes[i]>VI_FLOORB)goto err_out;
+ vi->floorlist[i]=vorbis_floor_unpack_P[vi->floortypes[i]](vi,opb);
+ if(!vi->floorlist[i])goto err_out;
}
+ /* residue backend settings */
+ vi->residues=_oggpack_read(opb,8);
+ vi->residuetypes=malloc(vi->residues*sizeof(int));
+ vi->residuelist=calloc(vi->residues,sizeof(void *));
+ for(i=0;i<vi->residues;i++){
+ vi->residuetypes[i]=_oggpack_read(opb,16);
+ if(vi->residuetypes[i]<0 || vi->residuetypes[i]>VI_RESB)goto err_out;
+ vi->residuelist[i]=vorbis_res_unpack_P[vi->residuetypes[i]](vi,opb);
+ if(!vi->residuelist[i])goto err_out;
+ }
+
+ /* codebooks */
vi->books=_oggpack_read(opb,16);
vi->booklist=calloc(vi->books,sizeof(codebook *));
for(i=0;i<vi->books;i++){
vi->booklist[i]=calloc(1,sizeof(codebook));
if(vorbis_book_unpack(opb,vi->booklist[i]))goto err_out;
}
+
+ /* modes/mappings; these are loaded last in order that the mappings
+ can range-check their time/floor/res/book settings */
+ vi->modes=_oggpack_read(opb,8);
+ vi->blockflags=malloc(vi->modes*sizeof(int));
+ vi->windowtypes=malloc(vi->modes*sizeof(int));
+ vi->transformtypes=malloc(vi->modes*sizeof(int));
+ vi->mappingtypes=malloc(vi->modes*sizeof(int));
+ vi->modelist=calloc(vi->modes,sizeof(void *));
+ for(i=0;i<vi->modes;i++){
+ vi->blockflags[i]=_oggpack_read(opb,1);
+ vi->windowtypes[i]=_oggpack_read(opb,16);
+ vi->transformtypes[i]=_oggpack_read(opb,16);
+ vi->mappingtypes[i]=_oggpack_read(opb,16);
+ if(vi->windowtypes[i]!=0)goto err_out;
+ if(vi->transformtypes[i]!=0)goto err_out;
+ if(vi->mappingtypes[i]<0 || vi->mappingtypes[i]>VI_MAPB)goto err_out;
+ vi->modelist[i]=vorbis_map_unpack_P[vi->mappingtypes[i]](vi,opb);
+ if(!vi->modelist[i])goto err_out;
+ }
+
+ if(_oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
+
return(0);
err_out:
vorbis_info_clear(vi);
_oggpack_write(opb,ilog2(vi->blocksizes[0]),4);
_oggpack_write(opb,ilog2(vi->blocksizes[1]),4);
-
+ _oggpack_write(opb,1,1);
+
return(0);
}
}
}
}
+ _oggpack_write(opb,1,1);
return(0);
}
_v_writestring(opb,"vorbis");
_oggpack_write(opb,0x82,8);
- _oggpack_write(opb,vi->modes,16);
- for(i=0;i<vi->modes;i++){
- _oggpack_write(opb,vi->blockflags[i],1);
- _oggpack_write(opb,vi->maptypes[i],8);
- if(vi->maptypes[i]<0 || vi->maptypes[i]>VI_MAPB)goto err_out;
- vorbis_map_pack_P[vi->maptypes[i]](opb,vi->maplist[i]);
+ /* times */
+ _oggpack_write(opb,vi->times,8);
+ for(i=0;i<vi->times;i++){
+ _oggpack_write(opb,vi->timetypes[i],16);
+ vorbis_time_pack_P[vi->timetypes[i]](opb,vi->timelist[i]);
+ }
+
+ /* floors */
+ _oggpack_write(opb,vi->floors,8);
+ for(i=0;i<vi->floors;i++){
+ _oggpack_write(opb,vi->floortypes[i],16);
+ vorbis_floor_pack_P[vi->floortypes[i]](opb,vi->floorlist[i]);
}
+ /* residues */
+ _oggpack_write(opb,vi->residues,8);
+ for(i=0;i<vi->residues;i++){
+ _oggpack_write(opb,vi->residuetypes[i],16);
+ vorbis_res_pack_P[vi->residuetypes[i]](opb,vi->residuelist[i]);
+ }
+
+ /* books */
_oggpack_write(opb,vi->books,16);
for(i=0;i<vi->books;i++)
if(vorbis_book_pack(vi->booklist[i],opb))goto err_out;
+
+ /* mode mappings */
+
+ _oggpack_write(opb,vi->modes,8);
+ for(i=0;i<vi->modes;i++){
+ _oggpack_write(opb,vi->blockflags[i],1);
+ _oggpack_write(opb,vi->windowtypes[i],16);
+ _oggpack_write(opb,vi->transformtypes[i],16);
+ _oggpack_write(opb,vi->mappingtypes[i],16);
+ vorbis_map_pack_P[vi->mappingtypes[i]](vi,opb,vi->modelist[i]);
+ }
+
+ _oggpack_write(opb,1,1);
+
return(0);
err_out:
return(-1);
+++ /dev/null
-/********************************************************************
- * *
- * 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-2000 *
- * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
- * http://www.xiph.org/ *
- * *
- ********************************************************************
-
- function: pack/unpack/dup/clear the various channel mapping setups
- last mod: $Id: infomap.c,v 1.1 2000/01/19 08:57:56 xiphmont Exp $
-
- ********************************************************************/
-
-#include <stdlib.h>
-#include <string.h>
-#include "vorbis/codec.h"
-#include "bitwise.h"
-#include "bookinternal.h"
-
-/* these modules were split out only to make this file more readable.
- I don't want to expose the symbols */
-#include "infotime.c"
-#include "infofloor.c"
-#include "infores.c"
-#include "infopsy.c"
-
-/* Handlers for mapping 0 *******************************************/
-static void *_vorbis_map0_dup(void *source){
- vorbis_info_mapping0 *d=malloc(sizeof(vorbis_info_mapping0));
- vorbis_info_mapping0 *s=(vorbis_info_mapping0 *)source;
- memcpy(d,s,sizeof(vorbis_info_mapping0));
-
- if(d->timetype<0 || d->timetype>=VI_TIMEB)goto err_out;
- if(d->floortype<0 || d->floortype>=VI_FLOORB)goto err_out;
- if(d->restype<0 || d->restype>=VI_RESB)goto err_out;
-
- d->time=vorbis_time_dup_P[d->timetype](s->time);
- d->floor=vorbis_floor_dup_P[d->floortype](s->floor);
- d->res=vorbis_res_dup_P[d->restype](s->res);
- d->psy=vorbis_psy_dup(s->psy);
-
- return(d);
-err_out:
- memset(d,0,sizeof(vorbis_info_mapping0));
- free(d);
- return(NULL);
-}
-
-static void _vorbis_map0_free(void *i){
- vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)i;
-
- if(d){
- if(d->timetype>=0 && d->timetype<VI_TIMEB)
- vorbis_time_free_P[d->timetype](d->time);
- if(d->floortype>=0 && d->floortype<VI_FLOORB)
- vorbis_floor_free_P[d->floortype](d->floor);
- if(d->restype>=0 && d->restype<VI_RESB)
- vorbis_res_free_P[d->restype](d->res);
- vorbis_psy_free(d->psy);
-
- memset(d,0,sizeof(vorbis_info_mapping0));
- free(d);
- }
-}
-
-static void _vorbis_map0_pack(oggpack_buffer *opb,void *i){
- vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)i;
- _oggpack_write(opb,d->timetype,8);
- _oggpack_write(opb,d->floortype,8);
- _oggpack_write(opb,d->restype,8);
-
- vorbis_time_pack_P[d->timetype](opb,d->time);
- vorbis_floor_pack_P[d->floortype](opb,d->floor);
- vorbis_res_pack_P[d->restype](opb,d->res);
-}
-
-static void *_vorbis_map0_unpack(oggpack_buffer *opb){
- vorbis_info_mapping0 d;
- memset(&d,0,sizeof(d));
-
- d.timetype=_oggpack_read(opb,8);
- d.floortype=_oggpack_read(opb,8);
- d.restype=_oggpack_read(opb,8);
-
- if(d.timetype<0 || d.timetype>=VI_TIMEB)goto err_out;
- if(d.floortype<0 || d.floortype>=VI_FLOORB)goto err_out;
- if(d.restype<0 || d.restype>=VI_RESB)goto err_out;
-
- d.time=vorbis_time_unpack_P[d.timetype](opb);
- d.floor=vorbis_floor_unpack_P[d.floortype](opb);
- d.res=vorbis_res_unpack_P[d.restype](opb);
- d.psy=NULL;
-
- return _vorbis_map0_dup(&d);
-
- err_out:
- /* the null check protects against type out of range */
- if(d.time)vorbis_time_free_P[d.timetype](d.time);
- if(d.floor)vorbis_floor_free_P[d.floortype](d.floor);
- if(d.res)vorbis_res_free_P[d.restype](d.res);
-
- return(NULL);
-}
-
-/* stuff em into arrays ************************************************/
-#define VI_MAPB 1
-
-static void *(*vorbis_map_dup_P[])(void *)={
- _vorbis_map0_dup,
-};
-
-static void (*vorbis_map_free_P[])(void *)={
- _vorbis_map0_free,
-};
-
-static void (*vorbis_map_pack_P[])(oggpack_buffer *,void *)={
- _vorbis_map0_pack,
-};
-
-static void *(*vorbis_map_unpack_P[])(oggpack_buffer *)={
- _vorbis_map0_unpack,
-};
-
+++ /dev/null
-/********************************************************************
- * *
- * 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-2000 *
- * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
- * http://www.xiph.org/ *
- * *
- ********************************************************************
-
- function: pack/unpack/dup/clear the various time info storage
- last mod: $Id: infotime.c,v 1.1 2000/01/19 08:57:56 xiphmont Exp $
-
- ********************************************************************/
-
-#include <stdlib.h>
-#include <string.h>
-#include "vorbis/codec.h"
-#include "bitwise.h"
-#include "bookinternal.h"
-
-/* hadlers for time backend 0 (dummy) *********************************/
-static void *_vorbis_time0_dup(void *source){
- return(calloc(1,sizeof(vorbis_info_time0)));
-}
-
-static void _vorbis_time0_free(void *i){
- if(i)free(i);
-}
-
-static void _vorbis_time0_pack(oggpack_buffer *opb,void *i){
-}
-
-static void *_vorbis_time0_unpack(oggpack_buffer *opb){
- return(_vorbis_time0_dup(NULL));
-}
-
-/* stuff em into arrays ************************************************/
-#define VI_TIMEB 1
-
-static void *(*vorbis_time_dup_P[])(void *)={
- &_vorbis_time0_dup,
-};
-
-static void (*vorbis_time_free_P[])(void *)={
- &_vorbis_time0_free,
-};
-
-static void (*vorbis_time_pack_P[])(oggpack_buffer *,void *)={
- &_vorbis_time0_pack,
-};
-
-static void *(*vorbis_time_unpack_P[])(oggpack_buffer *)={
- &_vorbis_time0_unpack,
-};
-
********************************************************************
function: LPC low level routines
- last mod: $Id: lpc.c,v 1.13 2000/01/04 09:05:01 xiphmont Exp $
+ last mod: $Id: lpc.c,v 1.14 2000/01/20 04:43:01 xiphmont Exp $
********************************************************************/
void vorbis_lpc_to_curve(double *curve,double *lpc,double amp,lpc_lookup *l){
double *lcurve=alloca(sizeof(double)*(l->ln*2));
int i;
- static int frameno=0;
_vlpc_de_helper(lcurve,lpc,amp,l);
#ifdef ANALYSIS
{
+ static int frameno=0;
int j;
FILE *out;
char buffer[80];
for(j=0;j<l->ln;j++)
fprintf(out,"%g\n",lcurve[j]);
fclose(out);
- }
+
#endif
if(amp==0)return;
for(i=0;i<l->n;i++)curve[i]=lcurve[l->linearmap[i]];
#ifdef ANALYSIS
- {
- int j;
- FILE *out;
- char buffer[80];
sprintf(buffer,"lpc%d.m",frameno-1);
out=fopen(buffer,"w+");
void vorbis_lpc_apply(double *residue,double *lpc,double amp,lpc_lookup *l){
double *lcurve=alloca(sizeof(double)*((l->ln+l->n)*2));
int i;
- static int frameno=0;
if(amp==0){
memset(residue,0,l->n*sizeof(double));
_vlpc_de_helper(lcurve,lpc,amp,l);
-#ifdef ANALYSIS
- {
- int j;
- FILE *out;
- char buffer[80];
-
- sprintf(buffer,"loglpc%d.m",frameno++);
- out=fopen(buffer,"w+");
- for(j=0;j<l->ln;j++)
- fprintf(out,"%g\n",lcurve[j]);
- fclose(out);
- }
-#endif
-
for(i=0;i<l->ln;i++)lcurve[i]/=l->barknorm[i];
for(i=0;i<l->n;i++)
if(residue[i]!=0)
--- /dev/null
+/********************************************************************
+ * *
+ * 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-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: channel mapping 0 implementation
+ last mod: $Id: mapping0.c,v 1.1 2000/01/20 04:43:02 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "vorbis/codec.h"
+#include "bitwise.h"
+#include "bookinternal.h"
+#include "registry.h"
+#include "mapping0.h"
+
+extern _vi_info_map *_vorbis_map0_dup(vi_info *vi,_vi_info_mapping *source){
+ vorbis_info_mapping0 *d=malloc(sizeof(vorbis_info_mapping0));
+ vorbis_info_mapping0 *s=(vorbis_info_mapping0 *)source;
+ memcpy(d,s,sizeof(vorbis_info_mapping0));
+
+ d->floorsubmap=malloc(sizeof(int)*vi->channels);
+ d->residuesubmap=malloc(sizeof(int)*vi->channels);
+ d->psysubmap=malloc(sizeof(int)*vi->channels);
+ memcpy(d->floorsubmap,s->floorsubmap,sizeof(int)*vi->channels);
+ memcpy(d->residuesubmap,s->residuesubmap,sizeof(int)*vi->channels);
+ memcpy(d->psysubmap,s->psysubmap,sizeof(int)*vi->channels);
+
+ return(d);
+}
+
+extern void _vorbis_map0_free(_vi_info_mapping *i){
+ vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)i;
+
+ if(d){
+ if(d->floorsubmap)free(d->floorsubmap);
+ if(d->residuesubmap)free(d->residuesubmap);
+ if(d->psysubmap)free(d->psysubmap);
+ memset(d,0,sizeof(vorbis_info_mapping0));
+ free(d);
+ }
+}
+
+extern void _vorbis_map0_pack(vorbis_info *vi,oggpack_buffer *opb,
+ _vi_info_map *i){
+ int i;
+ vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)i;
+
+ _oggpack_write(opb,d->timesubmap,8);
+
+ /* we abbreviate the channel submappings if they all map to the same
+ floor/res/psy */
+ for(i=1;i<vi->channels;i++)if(d->floorsubmap[i]!=d->floorsubmap[i-1])break;
+ if(i==vi->channels){
+ _oggpack_write(opb,0,1);
+ _oggpack_write(opb,d->floorsubmap[0],8);
+ }else{
+ _oggpack_write(opb,1,1);
+ for(i=0;i<vi->channels;i++)
+ _oggpack_write(opb,d->floorsubmap[i],8);
+ }
+
+ for(i=1;i<vi->channels;i++)
+ if(d->residuesubmap[i]!=d->residuesubmap[i-1])break;
+ if(i==vi->channels){
+ /* no channel submapping */
+ _oggpack_write(opb,0,1);
+ _oggpack_write(opb,d->residuesubmap[0],8);
+ }else{
+ /* channel submapping */
+ _oggpack_write(opb,1,1);
+ for(i=0;i<vi->channels;i++)
+ _oggpack_write(opb,d->residuesubmap[i],8);
+ }
+}
+
+/* also responsible for range checking */
+extern _vi_info_map *_vorbis_map0_unpack(vorbis_info *vi,oggpack_buffer *opb){
+ int i;
+ vorbis_info_mapping0 d=calloc(1,sizeof(vorbis_info_mapping0));
+ memset(d,0,sizeof(vorbis_info_mapping0));
+
+ d->timesubmap=_oggpack_read(opb,8);
+ if(d->timesubmap>=vi->times)goto err_out;
+
+ d->floorsubmap=malloc(sizeof(int)*vi->channels);
+ if(_oggpack_read(opb,1)){
+ /* channel submap */
+ for(i=0;i<vi->channels;i++)
+ d->floorsubmap[i]=_oggpack_read(opb,8);
+ }else{
+ int temp=_oggpack_read(opb,8);
+ for(i=0;i<vi->channels;i++)
+ d->floorsubmap[i]=temp;
+ }
+
+ d->residuesubmap=malloc(sizeof(int)*vi->channels);
+ if(_oggpack_read(opb,1)){
+ /* channel submap */
+ for(i=0;i<vi->channels;i++)
+ d->residuesubmap[i]=_oggpack_read(opb,8);
+ }else{
+ int temp=_oggpack_read(opb,8);
+ for(i=0;i<vi->channels;i++)
+ d->residuesubmap[i]=temp;
+ }
+
+ for(i=0;i<vi->channels;i++){
+ if(d->floorsubmap[i]<0 || d->floorsubmap[i]>=vi->floors)goto err_out;
+ if(d->residuesubmap[i]<0 || d->residuesubmap[i]>=vi->residuess)
+ goto err_out;
+ }
+
+ return d;
+
+ err_out:
+ _vorbis_map0_free(d);
+ return(NULL);
+}
+
+#include <stdio.h>
+#include "os.h"
+#include "lpc.h"
+#include "lsp.h"
+#include "envelope.h"
+#include "mdct.h"
+#include "psy.h"
+#include "bitwise.h"
+#include "spectrum.h"
+
+/* no time mapping implementation for now */
+int *_vorbis_map0_analysis(vorbis_block *vb,vorbis_info_map *i,
+ ogg_packet *opb){
+ int i;
+ vorbis_dsp_state *vd=vb->vd;
+ double *window=vd->window[vb->W][vb->lW][vb->nW];
+ oggpack_buffer *opb=&vb->opb;
+ vorbis_info_mapping0 *vi=i;
+ int n=vb->pcmend;
+
+ /* time domain pre-window: NONE IMPLEMENTED */
+
+ /* window the PCM data: takes PCM vector, vb; modifies PCM vector */
+
+ /* time-domain post-window: NONE IMPLEMENTED */
+
+ /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
+
+ /* perform psychoacoustics; takes PCM vector; returns transform floor
+ and resolution floor, modifies PCM vector */
+
+ /* perform floor encoding; takes transform floor, returns decoded floor*/
+
+ /* perform residue encoding with residue mapping */
+
+
+
+ psy_lookup *vp=&vb->vd->vp[vb->W];
+ lpc_lookup *vl=&vb->vd->vl[vb->W];
+
+
+ vb->gluebits=0;
+ vb->time_envelope_bits=0;
+ vb->spectral_envelope_bits=0;
+ vb->spectral_residue_bits=0;
+
+ /*lpc_lookup *vbal=&vb->vd->vbal[vb->W];
+ double balance_v[vbal->m];
+ double balance_amp;*/
+
+ /* 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);
+ if(vb->W){
+ _oggpack_write(opb,vb->lW,1);
+ _oggpack_write(opb,vb->nW,1);
+ }
+
+ /* No envelope encoding yet */
+ _oggpack_write(opb,0,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++){
+ static int frameno=0;
+ int j;
+ double *floor=alloca(n/2*sizeof(double));
+ double *curve=alloca(n/2*sizeof(double));
+ double *lpc=vb->lpc[i];
+ double *lsp=vb->lsp[i];
+
+ memset(floor,0,sizeof(double)*n/2);
+
+#ifdef ANALYSIS
+ {
+ FILE *out;
+ char buffer[80];
+
+ sprintf(buffer,"Aspectrum%d.m",vb->sequence);
+ out=fopen(buffer,"w+");
+ for(j=0;j<n/2;j++)
+ fprintf(out,"%g\n",vb->pcm[i][j]);
+ fclose(out);
+
+ }
+#endif
+
+ _vp_mask_floor(vp,vb->pcm[i],floor);
+
+#ifdef ANALYSIS
+ {
+ FILE *out;
+ char buffer[80];
+
+ sprintf(buffer,"Apremask%d.m",vb->sequence);
+ out=fopen(buffer,"w+");
+ for(j=0;j<n/2;j++)
+ fprintf(out,"%g\n",floor[j]);
+ fclose(out);
+ }
+#endif
+
+ /* 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...*/
+ if(vb->amp[i])_vs_residue_train(vb,vb->pcm[i],curve,n/2);
+ _vs_residue_quantize(vb->pcm[i],curve,vi,n/2);
+
+#ifdef ANALYSIS
+ {
+ FILE *out;
+ char buffer[80];
+
+ sprintf(buffer,"Alpc%d.m",vb->sequence);
+ out=fopen(buffer,"w+");
+ for(j=0;j<vl->m;j++)
+ fprintf(out,"%g\n",lpc[j]);
+ fclose(out);
+
+ sprintf(buffer,"Alsp%d.m",vb->sequence);
+ out=fopen(buffer,"w+");
+ for(j=0;j<vl->m;j++)
+ fprintf(out,"%g\n",lsp[j]);
+ fclose(out);
+
+ sprintf(buffer,"Amask%d.m",vb->sequence);
+ out=fopen(buffer,"w+");
+ for(j=0;j<n/2;j++)
+ fprintf(out,"%g\n",curve[j]);
+ fclose(out);
+
+ sprintf(buffer,"Ares%d.m",vb->sequence);
+ out=fopen(buffer,"w+");
+ for(j=0;j<n/2;j++)
+ fprintf(out,"%g\n",vb->pcm[i][j]);
+ fclose(out);
+ }
+#endif
+
+ /* 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;
+ op->packetno=vb->sequence; /* for sake of completeness */
+
+ return(0);
+}
+
+
+
+
+/* commented out, relocated balance stuff */
+ /*{
+ double *C=vb->pcm[0];
+ double *D=vb->pcm[1];
+
+ balance_amp=_vp_balance_compute(D,C,balance_v,vbal);
+
+ {
+ FILE *out;
+ char buffer[80];
+
+ sprintf(buffer,"com%d.m",frameno);
+ out=fopen(buffer,"w+");
+ for(i=0;i<n/2;i++){
+ fprintf(out," 0. 0.\n");
+ fprintf(out,"%g %g\n",C[i],D[i]);
+ fprintf(out,"\n");
+ }
+ fclose(out);
+
+ sprintf(buffer,"L%d.m",frameno);
+ out=fopen(buffer,"w+");
+ for(i=0;i<n/2;i++){
+ fprintf(out,"%g\n",C[i]);
+ }
+ fclose(out);
+ sprintf(buffer,"R%d.m",frameno);
+ out=fopen(buffer,"w+");
+ for(i=0;i<n/2;i++){
+ fprintf(out,"%g\n",D[i]);
+ }
+ fclose(out);
+
+ }
+
+ _vp_balance_apply(D,C,balance_v,balance_amp,vbal,1);
+
+ {
+ FILE *out;
+ char buffer[80];
+
+ sprintf(buffer,"bal%d.m",frameno);
+ out=fopen(buffer,"w+");
+ for(i=0;i<n/2;i++){
+ fprintf(out," 0. 0.\n");
+ fprintf(out,"%g %g\n",C[i],D[i]);
+ fprintf(out,"\n");
+ }
+ fclose(out);
+ sprintf(buffer,"C%d.m",frameno);
+ out=fopen(buffer,"w+");
+ for(i=0;i<n/2;i++){
+ fprintf(out,"%g\n",C[i]);
+ }
+ fclose(out);
+ sprintf(buffer,"D%d.m",frameno);
+ out=fopen(buffer,"w+");
+ for(i=0;i<n/2;i++){
+ fprintf(out,"%g\n",D[i]);
+ }
+ fclose(out);
+
+ }
+ }*/
+
+
+int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
+ double *window;
+ vorbis_dsp_state *vd=vb->vd;
+ vorbis_info *vi=vd->vi;
+ oggpack_buffer *opb=&vb->opb;
+ lpc_lookup *vl;
+ 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);
+ }
+
+ /* Decode the block size */
+ vb->W=_oggpack_read(opb,1);
+ if(vb->W){
+ vb->lW=_oggpack_read(opb,1);
+ vb->nW=_oggpack_read(opb,1);
+ }else{
+ vb->lW=0;
+ vb->nW=0;
+ }
+
+ window=vb->vd->window[vb->W][vb->lW][vb->nW];
+
+ /* other random setup */
+ vb->frameno=op->frameno;
+ vb->sequence=op->packetno-3; /* first block is third packet */
+
+ 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];
+
+ /* No envelope encoding yet */
+ _oggpack_read(opb,0,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);
+
+#ifdef ANALYSIS
+ {
+ int j;
+ FILE *out;
+ char buffer[80];
+
+ sprintf(buffer,"Sres%d.m",vb->sequence);
+ out=fopen(buffer,"w+");
+ for(j=0;j<n/2;j++)
+ fprintf(out,"%g\n",vb->pcm[i][j]);
+ fclose(out);
+ }
+#endif
+
+ /* LSP->LPC */
+ vorbis_lsp_to_lpc(lsp,lpc,vl->m);
+
+ /* apply envelope to residue */
+
+#ifdef ANALYSIS
+ {
+ int j;
+ FILE *out;
+ char buffer[80];
+ double curve[n/2];
+ vorbis_lpc_to_curve(curve,lpc,vb->amp[i],vl);
+
+
+ sprintf(buffer,"Smask%d.m",vb->sequence);
+ out=fopen(buffer,"w+");
+ for(j=0;j<n/2;j++)
+ fprintf(out,"%g\n",curve[j]);
+ fclose(out);
+
+ sprintf(buffer,"Slsp%d.m",vb->sequence);
+ out=fopen(buffer,"w+");
+ for(j=0;j<vl->m;j++)
+ fprintf(out,"%g\n",lsp[j]);
+ fclose(out);
+
+ sprintf(buffer,"Slpc%d.m",vb->sequence);
+ out=fopen(buffer,"w+");
+ for(j=0;j<vl->m;j++)
+ fprintf(out,"%g\n",lpc[j]);
+ fclose(out);
+ }
+#endif
+
+ vorbis_lpc_apply(vb->pcm[i],lpc,vb->amp[i],vl);
+
+#ifdef ANALYSIS
+ {
+ int j;
+ FILE *out;
+ char buffer[80];
+
+ sprintf(buffer,"Sspectrum%d.m",vb->sequence);
+ out=fopen(buffer,"w+");
+ for(j=0;j<n/2;j++)
+ fprintf(out,"%g\n",vb->pcm[i][j]);
+ fclose(out);
+ }
+#endif
+
+
+ /* MDCT->time */
+ mdct_backward(&vb->vd->vm[vb->W],vb->pcm[i],vb->pcm[i],window);
+
+ }
+ return(0);
+}
+
+
--- /dev/null
+/********************************************************************
+ * *
+ * 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-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: channel mapping 0 implementation
+ last mod: $Id: mapping0.h,v 1.1 2000/01/20 04:43:02 xiphmont Exp $
+
+ ********************************************************************/
+
+typedef struct vorbis_info_mapping0{
+ int timesubmap; /* list position of the time backend/settings
+ we're using */
+
+ int *floorsubmap; /* for each floor map, which channels */
+ int *residuesubmap; /* residue to use for each incoming channel */
+ int *psysubmap; /* psychoacoustics to use for each incoming channel */
+
+} vorbis_info_mapping0;
+
+extern _vi_info_map *_vorbis_map0_dup (vorbis_info *vi,
+ _vi_info_map *source);
+extern void _vorbis_map0_free (_vi_info_map *i);
+extern void _vorbis_map0_pack (vorbis_info *vi,
+ oggpack_buffer *opb,
+ _vi_info_map *i);
+extern _vi_info_map *_vorbis_map0_unpack (vorbis_info *vi,
+ oggpack_buffer *opb);
+extern int _vorbis_map0_analysis (vorbis_block *vb,
+ _vi_info_map *i,ogg_packet *);
+extern int _vorbis_map0_synthesis(vorbis_block *vb,
+ _vi_info_map *i,ogg_packet *);
+
* *
********************************************************************
- function: random psychoacoustics (not including preecho)
- last mod: $Id: psy.c,v 1.10 2000/01/05 03:11:01 xiphmont Exp $
+ function: psychoacoustics not including preecho
+ last mod: $Id: psy.c,v 1.11 2000/01/20 04:43:02 xiphmont Exp $
********************************************************************/
}
}
-void _vp_psy_init(psy_lookup *p,vorbis_info *vi,int n){
+void _vp_psy_init(psy_lookup *p,vorbis_info_psy *vi,int n,long rate){
long i;
memset(p,0,sizeof(psy_lookup));
p->maskthresh=malloc(n*sizeof(double));
/* set up the lookups for a given blocksize and sample rate */
/* Vorbis max sample rate is limited by 26 Bark (54kHz) */
- set_curve(vi->maskthresh, p->maskthresh, n,vi->rate);
+ set_curve(vi->maskthresh, p->maskthresh, n,rate);
for(i=0;i<n;i++)
- p->barknum[i]=toBARK(vi->rate/2.*i/n);
+ p->barknum[i]=toBARK(rate/2.*i/n);
#ifdef ANALYSIS
{
}
}
+/* for duplicating the info struct */
+
+void *_vi_psy_dup(void *i){
+ vorbis_info_psy *source=i;
+ if(source){
+ vorbis_info_psy *d=malloc(sizeof(vorbis_info_psy));
+ memcpy(d,source,sizeof(vorbis_info_psy));
+ return(d);
+ }else
+ return(NULL);
+}
+
+void _vi_psy_free(void *i){
+ if(i){
+ memset(i,0,sizeof(vorbis_info_psy));
+ free(i);
+ }
+}
+
********************************************************************
function: random psychoacoustics (not including preecho)
- last mod: $Id: psy.h,v 1.4 1999/12/30 07:26:48 xiphmont Exp $
+ last mod: $Id: psy.h,v 1.5 2000/01/20 04:43:03 xiphmont Exp $
********************************************************************/
#ifndef _V_PSY_H_
#define _V_PSY_H_
-extern void _vp_psy_init(psy_lookup *p,vorbis_info *vi,int n);
-extern void _vp_psy_clear(psy_lookup *p);
+typedef struct vorbis_info_psy{
+ double maskthresh[MAX_BARK];
+ double lrolldB;
+ double hrolldB;
+} vorbis_info_psy;
-extern void _vp_noise_floor(psy_lookup *p, double *f, double *m);
-extern void _vp_mask_floor(psy_lookup *p,double *f, double *m);
+typedef struct {
+ int n;
+ struct vorbis_info_psy *vi;
+ double *maskthresh;
+ double *barknum;
-extern double _vp_balance_compute(double *A, double *B, double *lpc,
- lpc_lookup *vb);
-extern void _vp_balance_apply(double *A, double *B, double *lpc, double amp,
- lpc_lookup *vb,int divp);
+} psy_lookup;
+extern void _vp_psy_init(psy_lookup *p,vorbis_info_psy *vi,int n,long rate);
+extern void _vp_psy_clear(psy_lookup *p);
+extern void *_vi_psy_dup(void *source);
+extern void _vi_psy_free(void *i);
+
+extern void _vp_noise_floor(psy_lookup *p, double *f, double *m);
+extern void _vp_mask_floor(psy_lookup *p,double *f, double *m);
+
#endif
+
+
--- /dev/null
+/********************************************************************
+ * *
+ * 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-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: registry for time, floor, res backends and channel mappings
+ last mod: $Id: registry.c,v 1.1 2000/01/20 04:43:04 xiphmont Exp $
+
+ ********************************************************************/
+
+#include "vorbis/codec.h"
+#include "time0.h"
+#include "floor0.h"
+#include "res0.h"
+#include "mapping0.h"
+#include "registry.h"
+
+/* time backend registry */
+void *(*vorbis_time_dup_P[])(void *)={
+ &_vorbis_time0_dup,
+};
+
+void (*vorbis_time_free_P[])(void *)={
+ &_vorbis_time0_free,
+};
+
+void (*vorbis_time_pack_P[])(oggpack_buffer *,void *)={
+ &_vorbis_time0_pack,
+};
+
+void *(*vorbis_time_unpack_P[])(oggpack_buffer *)={
+ &_vorbis_time0_unpack,
+};
+
+/* floor backend registry */
+void *(*vorbis_floor_dup_P[])(void *)={
+ &_vorbis_floor0_dup,
+};
+
+void (*vorbis_floor_free_P[])(void *)={
+ &_vorbis_floor0_free,
+};
+
+void (*vorbis_floor_pack_P[])(oggpack_buffer *,void *)={
+ &_vorbis_floor0_pack,
+};
+
+void *(*vorbis_floor_unpack_P[])(oggpack_buffer *)={
+ &_vorbis_floor0_unpack,
+};
+
+/* residue backend registry */
+void *(*vorbis_res_dup_P[])(void *)={
+ &_vorbis_res0_dup,
+};
+
+void (*vorbis_res_free_P[])(void *)={
+ &_vorbis_res0_free,
+};
+
+void (*vorbis_res_pack_P[])(oggpack_buffer *,void *)={
+ &_vorbis_res0_pack,
+};
+
+void *(*vorbis_res_unpack_P[])(oggpack_buffer *)={
+ &_vorbis_res0_unpack,
+};
+
+/* channel mapping registry */
+void *(*vorbis_map_dup_P[])(void *)={
+ &_vorbis_map0_dup,
+};
+
+void (*vorbis_map_free_P[])(void *)={
+ &_vorbis_map0_free,
+};
+
+void (*vorbis_map_pack_P[])(oggpack_buffer *,void *)={
+ &_vorbis_map0_pack,
+};
+
+void *(*vorbis_map_unpack_P[])(oggpack_buffer *)={
+ &_vorbis_map0_unpack,
+};
+
+void *(*vorbis_map_analysis_P[])(vorbis_block *vb,void *,ogg_packet *)={
+ &_vorbis_map0_analysis,
+};
+
+void *(*vorbis_map_synthesis_P[])(vorbis_block *vb,void *,ogg_packet *)={
+ &_vorbis_map0_synthesis,
+};
--- /dev/null
+/********************************************************************
+ * *
+ * 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-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: registry for time, floor, res backends and channel mappings
+ last mod: $Id: registry.h,v 1.1 2000/01/20 04:43:04 xiphmont Exp $
+
+ ********************************************************************/
+
+#ifndef _V_REG_H_
+#define _V_REG_H_
+
+typedef void _vi_info_time;
+typedef void _vi_info_floor;
+typedef void _vi_info_res;
+typedef void _vi_info_map;
+
+#define VI_TIMEB 1
+extern _vi_info_time *(*vorbis_time_dup_P[]) (_vi_info_time *);
+extern void (*vorbis_time_free_P[]) (_vi_info_time *);
+extern void (*vorbis_time_pack_P[]) (oggpack_buffer *,
+ _vi_info_time *);
+extern _vi_info_time *(*vorbis_time_unpack_P[]) (vorbis_info *,
+ oggpack_buffer *);
+
+#define VI_FLOORB 1
+extern _vi_info_floor *(*vorbis_floor_dup_P[]) (_vi_info_floor *);
+extern void (*vorbis_floor_free_P[]) (_vi_info_floor *);
+extern void (*vorbis_floor_pack_P[]) (oggpack_buffer *,
+ _vi_info_floor*);
+extern _vi_info_floor *(*vorbis_floor_unpack_P[])(vorbis_info *,
+ oggpack_buffer *);
+
+#define VI_RESB 1
+extern _vi_info_res *(*vorbis_res_dup_P[]) (_vi_info_res *);
+extern void (*vorbis_res_free_P[]) (_vi_info_res *);
+extern void (*vorbis_res_pack_P[]) (oggpack_buffer *,
+ _vi_info_res *);
+extern _vi_info_res *(*vorbis_res_unpack_P[]) (vorbis_info *,
+ oggpack_buffer *);
+
+#define VI_MAPB 1
+extern _vi_info_map *(*vorbis_map_dup_P[]) (vorbis_info *,
+ _vi_info_map *);
+extern void (*vorbis_map_free_P[]) (_vi_info_map *);
+extern void (*vorbis_map_pack_P[]) (vorbis_info *,
+ oggpack_buffer *,
+ _vi_info_map *);
+extern _vi_info_map *(*vorbis_map_unpack_P[]) (vorbis_info *,
+ oggpack_buffer *);
+
+extern int (*vorbis_map_analysis_P[]) (vorbis_block *vb,_vi_info_map *,
+ ogg_packet *);
+extern int (*vorbis_map_synthesis_P[])(vorbis_block *vb,_vi_info_map *,
+ ogg_packet *);
+
+#endif
* *
********************************************************************
- function: pack/unpack/dup/clear the various residue backend setups
- last mod: $Id: infores.c,v 1.1 2000/01/19 08:57:56 xiphmont Exp $
+ function: residue backend 0 implementation
+ last mod: $Id: res0.c,v 1.1 2000/01/20 04:43:04 xiphmont Exp $
********************************************************************/
#include <string.h>
#include "vorbis/codec.h"
#include "bitwise.h"
-#include "bookinternal.h"
-
-/* handlers for residue backend 0 ***********************************/
+#include "registry.h"
+#include "res0.h"
/* unfinished as of 20000118 */
-static void *_vorbis_res0_dup(void *source){
+extern _vi_info_res *_vorbis_res0_dup(_vi_info_res *source){
vorbis_info_res0 *d=malloc(sizeof(vorbis_info_res0));
memcpy(d,source,sizeof(vorbis_info_res0));
d->books=malloc(sizeof(int)*d->stages);
return(d);
}
-static void _vorbis_res0_free(void *i){
+extern void _vorbis_res0_free(_vi_info_res *i){
vorbis_info_res0 *d=(vorbis_info_res0 *)i;
if(d){
if(d->books)free(d->books);
}
/* not yet */
-static void _vorbis_res0_pack(oggpack_buffer *opb, void *vi){
+extern void _vorbis_res0_pack(oggpack_buffer *opb, _vi_info_res *vi){
}
-static void *_vorbis_res0_unpack(oggpack_buffer *opb){
- vorbis_info_floor0 d;
+extern _vi_info_res *_vorbis_res0_unpack(vorbis_info *vi,
+ oggpack_buffer *opb){
+ vorbis_info_res0 d;
memset(&d,0,sizeof(d));
return(_vorbis_res0_dup(&d));
}
-
-/* stuff em into arrays ************************************************/
-#define VI_RESB 1
-
-static void *(*vorbis_res_dup_P[])(void *)={
- _vorbis_res0_dup,
-};
-
-static void (*vorbis_res_free_P[])(void *)={
- _vorbis_res0_free,
-};
-
-static void (*vorbis_res_pack_P[])(oggpack_buffer *,void *)={
- _vorbis_res0_pack,
-};
-
-static void *(*vorbis_res_unpack_P[])(oggpack_buffer *)={
- _vorbis_res0_unpack,
-};
-
--- /dev/null
+/********************************************************************
+ * *
+ * 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-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: residue backend 0 implementation
+ last mod: $Id: res0.h,v 1.1 2000/01/20 04:43:04 xiphmont Exp $
+
+ ********************************************************************/
+
+typedef struct vorbis_info_res0{
+/* block-partitioned VQ coded straight residue */
+ long begin;
+ long end;
+
+ /* way unfinished, just so you know while poking around CVS ;-) */
+ int stages;
+ int *books;
+} vorbis_info_res0;
+
+extern _vi_info_res *_vorbis_res0_dup (_vi_info_res *source);
+extern void _vorbis_res0_free (_vi_info_res *i);
+extern void _vorbis_res0_pack (oggpack_buffer *opb,
+ _vi_info_res *vi);
+extern _vi_info_res *_vorbis_res0_unpack(vorbis_info *vi,
+ oggpack_buffer *opb);
********************************************************************
function: single-block PCM synthesis
- last mod: $Id: synthesis.c,v 1.12 2000/01/12 11:34:41 xiphmont Exp $
+ last mod: $Id: synthesis.c,v 1.13 2000/01/20 04:43:04 xiphmont Exp $
********************************************************************/
#include <stdio.h>
#include "vorbis/codec.h"
-
-#include "envelope.h"
-#include "mdct.h"
-#include "lpc.h"
-#include "lsp.h"
+#include "registry.h"
#include "bitwise.h"
-#include "spectrum.h"
int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
- double *window;
vorbis_dsp_state *vd=vb->vd;
vorbis_info *vi=vd->vi;
oggpack_buffer *opb=&vb->opb;
- lpc_lookup *vl;
- int spectral_order;
- int n,i;
+ int type;
+ int mode;
/* first things first. Make sure decode is ready */
+ _vorbis_block_ripcord(vb);
_oggpack_readinit(opb,op->packet,op->bytes);
/* Check the packet type */
return(-1);
}
- /* Decode the block size */
- vb->W=_oggpack_read(opb,1);
- if(vb->W){
- vb->lW=_oggpack_read(opb,1);
- vb->nW=_oggpack_read(opb,1);
- }else{
- vb->lW=0;
- vb->nW=0;
- }
-
- window=vb->vd->window[vb->W][vb->lW][vb->nW];
-
- /* other random setup */
- vb->frameno=op->frameno;
- vb->sequence=op->packetno-3; /* first block is third packet */
-
- 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];
-
- /* No envelope encoding yet */
- _oggpack_read(opb,0,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);
-
-#ifdef ANALYSIS
- {
- int j;
- FILE *out;
- char buffer[80];
-
- sprintf(buffer,"Sres%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<n/2;j++)
- fprintf(out,"%g\n",vb->pcm[i][j]);
- fclose(out);
- }
-#endif
+ /* read our mode */
+ mode=_oggpack_read(&vb->opb,vd->modebits);
+ type=vi->mappingtypes[mode]; /* unpack_header enforces range checking */
- /* LSP->LPC */
- vorbis_lsp_to_lpc(lsp,lpc,vl->m);
-
- /* apply envelope to residue */
-
-#ifdef ANALYSIS
- {
- int j;
- FILE *out;
- char buffer[80];
- double curve[n/2];
- vorbis_lpc_to_curve(curve,lpc,vb->amp[i],vl);
-
-
- sprintf(buffer,"Smask%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<n/2;j++)
- fprintf(out,"%g\n",curve[j]);
- fclose(out);
-
- sprintf(buffer,"Slsp%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<vl->m;j++)
- fprintf(out,"%g\n",lsp[j]);
- fclose(out);
-
- sprintf(buffer,"Slpc%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<vl->m;j++)
- fprintf(out,"%g\n",lpc[j]);
- fclose(out);
- }
-#endif
-
- vorbis_lpc_apply(vb->pcm[i],lpc,vb->amp[i],vl);
-
-#ifdef ANALYSIS
- {
- int j;
- FILE *out;
- char buffer[80];
-
- sprintf(buffer,"Sspectrum%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<n/2;j++)
- fprintf(out,"%g\n",vb->pcm[i][j]);
- fclose(out);
- }
-#endif
-
-
- /* MDCT->time */
- mdct_backward(&vb->vd->vm[vb->W],vb->pcm[i],vb->pcm[i],window);
-
- }
- return(0);
+ return(vorbis_map_synthesis_P[type](vb,vi->modelist[mode],op));
}
* *
********************************************************************
- function: dup/clear the psy setup
- last mod: $Id: infopsy.c,v 1.1 2000/01/19 08:57:56 xiphmont Exp $
+ function: time backend 0 (dummy)
+ last mod: $Id: time0.c,v 1.1 2000/01/20 04:43:05 xiphmont Exp $
********************************************************************/
#include <stdlib.h>
#include <string.h>
#include "vorbis/codec.h"
-#include "bitwise.h"
-#include "bookinternal.h"
+#include "registry.h"
+#include "time0.h"
-static vorbis_info_psy *vorbis_psy_dup(vorbis_info_psy *source){
- if(source){
- vorbis_info_psy *d=malloc(sizeof(vorbis_info_psy));
- memcpy(d,source,sizeof(vorbis_info_psy));
- return(d);
- }else
- return(NULL);
+extern _vi_info_time *_vorbis_time0_dup(_vi_info_time *source){
+ return(calloc(1,sizeof(vorbis_info_time0)));
}
-static void vorbis_psy_free(vorbis_info_psy *i){
- if(i){
- memset(i,0,sizeof(vorbis_info_psy));
- free(i);
- }
+extern void _vorbis_time0_free(_vi_info_time *i){
+ if(i)free(i);
}
+extern void _vorbis_time0_pack(oggpack_buffer *opb,_vi_info_time *i){
+}
+
+extern _vi_info_time *_vorbis_time0_unpack(vorbis_info *vi,
+ oggpack_buffer *opb){
+ return(_vorbis_time0_dup(NULL));
+}
--- /dev/null
+/********************************************************************
+ * *
+ * 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-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: time backend 0 (dummy)
+ last mod: $Id: time0.h,v 1.1 2000/01/20 04:43:05 xiphmont Exp $
+
+ ********************************************************************/
+
+typedef struct vorbis_info_time0{
+ long dummy;
+} vorbis_info_time0;
+
+extern _vi_info_time *_vorbis_time0_dup (_vi_info_time *source);
+extern void _vorbis_time0_free (_vi_info_time *i);
+extern void _vorbis_time0_pack (oggpack_buffer *opb,
+ _vi_info_time *i);
+extern _vi_info_time *_vorbis_time0_unpack(vorbis_info *vi,
+ oggpack_buffer *opb);