Commit 939a038b authored by Monty's avatar Monty
Browse files

Floor 1
Res 1
Vorbisfile fixes/opts

now all on mainline

svn path=/trunk/vorbis/; revision=1458
parent d734a509
......@@ -11,7 +11,7 @@
********************************************************************
function: illustrate seeking, and test it too
last mod: $Id: seeking_example.c,v 1.7 2001/02/26 03:50:38 xiphmont Exp $
last mod: $Id: seeking_example.c,v 1.8 2001/05/27 06:43:58 xiphmont Exp $
********************************************************************/
......@@ -21,9 +21,47 @@
#include "vorbis/vorbisfile.h"
#include "../lib/misc.h"
void _verify(OggVorbis_File *ov,ogg_int64_t pos,
ogg_int64_t val,ogg_int64_t pcmval,
ogg_int64_t pcmlength,
char *bigassbuffer){
int j;
long bread;
char buffer[4096];
int dummy;
/* verify the raw position, the pcm position and position decode */
if(val!=-1 && ov_raw_tell(ov)<val){
printf("raw position out of tolerance: requested %ld, got %ld\n",
(long)val,(long)ov_raw_tell(ov));
exit(1);
}
if(pcmval!=-1 && ov_pcm_tell(ov)>pcmval){
printf("pcm position out of tolerance: requested %ld, got %ld\n",
(long)pcmval,(long)ov_pcm_tell(ov));
exit(1);
}
pos=ov_pcm_tell(ov);
if(pos<0 || pos>pcmlength){
printf("pcm position out of bounds: got %ld\n",(long)pos);
exit(1);
}
bread=ov_read(ov,buffer,4096,1,1,1,&dummy);
for(j=0;j<bread;j++){
if(buffer[j]!=bigassbuffer[j+pos*2]){
printf("data position after seek doesn't match pcm position\n");
exit(1);
}
}
}
int main(){
OggVorbis_File ov;
int i;
int i,ret;
ogg_int64_t pcmlength;
char *bigassbuffer;
int dummy;
/* open the file/pipe on stdin */
if(ov_open(stdin,&ov,NULL,-1)<0){
......@@ -31,18 +69,113 @@ int main(){
exit(1);
}
/* print details about each logical bitstream in the input */
if(ov_seekable(&ov)){
double length=ov_time_total(&ov,-1);
printf("testing seeking to random places in %g seconds....\n",length);
for(i=0;i<100;i++){
double val=(double)rand()/RAND_MAX*length;
ov_time_seek(&ov,val);
printf("\r\t%d [%gs]... ",i,val);
/* to simplify our own lives, we want to assume the whole file is
stereo. Verify this to avoid potentially mystifying users
(pissing them off is OK, just don't confuse them) */
for(i=0;i<ov.links;i++){
vorbis_info *vi=ov_info(&ov,i);
if(vi->channels!=2){
printf("Sorry; right now seeking_test can only use Vorbis files\n"
"that are entirely stereo.\n\n");
exit(1);
}
}
/* because we want to do sample-level verification that the seek
does what it claimed, decode the entire file into memory */
printf("loading....\n");
fflush(stdout);
pcmlength=ov_pcm_total(&ov,-1);
bigassbuffer=malloc(pcmlength*2); /* w00t */
i=0;
while(i<pcmlength*2){
int ret=ov_read(&ov,bigassbuffer+i,pcmlength*2-i,1,1,1,&dummy);
if(ret<0)continue;
if(ret){
i+=ret;
}else{
pcmlength=i/2;
}
}
/* Exercise all the real seeking cases; ov_raw_seek,
ov_pcm_seek_page and ov_pcm_seek. time seek is just a wrapper
on pcm_seek */
{
ogg_int64_t length=ov.end;
printf("testing raw seeking to random places in %ld bytes....\n",
(long)length);
for(i=0;i<1000;i++){
ogg_int64_t val=(double)rand()/RAND_MAX*length;
ogg_int64_t pos;
printf("\r\t%d [raw position %ld]... ",i,(long)val);
fflush(stdout);
ret=ov_raw_seek(&ov,val);
if(ret<0){
printf("seek failed: %d\n",ret);
exit(1);
}
_verify(&ov,pos,val,-1,pcmlength,bigassbuffer);
}
}
printf("\r");
{
ogg_int64_t length=ov.end;
printf("testing pcm page seeking to random places in %ld samples....\n",
(long)pcmlength);
for(i=0;i<1000;i++){
ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength;
ogg_int64_t pos;
printf("\r\t%d [pcm position %ld]... ",i,(long)val);
fflush(stdout);
ret=ov_pcm_seek_page(&ov,val);
if(ret<0){
printf("seek failed: %d\n",ret);
exit(1);
}
_verify(&ov,pos,-1,val,pcmlength,bigassbuffer);
}
}
printf("\r");
{
ogg_int64_t length=ov.end;
printf("testing pcm exact seeking to random places in %ld samples....\n",
(long)pcmlength);
for(i=0;i<1000;i++){
ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength;
ogg_int64_t pos;
printf("\r\t%d [pcm position %ld]... ",i,(long)val);
fflush(stdout);
ret=ov_pcm_seek(&ov,val);
if(ret<0){
printf("seek failed: %d\n",ret);
exit(1);
}
if(ov_pcm_tell(&ov)!=val){
printf("Decalred position didn't perfectly match request: %ld != %ld\n",
(long)val,(long)ov_pcm_tell(&ov));
exit(1);
}
_verify(&ov,pos,-1,val,pcmlength,bigassbuffer);
}
}
printf("\r \nOK.\n\n");
}else{
printf("Standard input was not seekable.\n");
}
......
......@@ -11,7 +11,7 @@
********************************************************************
function: libvorbis codec headers
last mod: $Id: codec.h,v 1.37 2001/02/26 03:50:39 xiphmont Exp $
last mod: $Id: codec.h,v 1.38 2001/05/27 06:43:59 xiphmont Exp $
********************************************************************/
......@@ -199,6 +199,7 @@ 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,float ***pcm);
extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples);
extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op);
/* Vorbis ERRORS and return codes ***********************************/
......
......@@ -11,7 +11,7 @@
********************************************************************
function: stdio-based convenience library for opening/seeking/decoding
last mod: $Id: vorbisfile.h,v 1.13 2001/02/26 03:50:39 xiphmont Exp $
last mod: $Id: vorbisfile.h,v 1.14 2001/05/27 06:43:59 xiphmont Exp $
********************************************************************/
......@@ -43,6 +43,11 @@ typedef struct {
long (*tell_func) (void *datasource);
} ov_callbacks;
#define NOTOPEN 0
#define PARTOPEN 1
#define OPENED 2
#define STREAMSET 3
#define INITSET 4
typedef struct OggVorbis_File {
void *datasource; /* Pointer to a FILE *, etc. */
......@@ -63,7 +68,7 @@ typedef struct OggVorbis_File {
/* Decoding working state local storage */
ogg_int64_t pcm_offset;
int decode_ready;
int ready_state;
long current_serialno;
int current_link;
......@@ -84,6 +89,11 @@ extern int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes);
extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf,
char *initial, long ibytes, ov_callbacks callbacks);
extern int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes);
extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf,
char *initial, long ibytes, ov_callbacks callbacks);
extern int ov_test_open(OggVorbis_File *vf);
extern long ov_bitrate(OggVorbis_File *vf,int i);
extern long ov_bitrate_instant(OggVorbis_File *vf);
extern long ov_streams(OggVorbis_File *vf);
......
......@@ -8,8 +8,9 @@ INCLUDES = -I$(top_srcdir)/include @OGG_CFLAGS@
lib_LTLIBRARIES = libvorbis.la libvorbisfile.la libvorbisenc.la
libvorbis_la_SOURCES = mdct.c smallft.c block.c envelope.c window.c lsp.c lpc.c\
analysis.c synthesis.c psy.c info.c time0.c floor0.c\
libvorbis_la_SOURCES = mdct.c smallft.c block.c envelope.c window.c lsp.c \
lpc.c analysis.c synthesis.c psy.c info.c time0.c \
floor1.c floor0.c\
res0.c mapping0.c registry.c codebook.c sharedbook.c\
lookup.c bitbuffer.c\
envelope.h lpc.h lsp.h codebook.h misc.h psy.h\
......
......@@ -11,7 +11,7 @@
********************************************************************
function: single-block PCM analysis mode dispatch
last mod: $Id: analysis.c,v 1.43 2001/02/26 03:50:41 xiphmont Exp $
last mod: $Id: analysis.c,v 1.44 2001/05/27 06:43:59 xiphmont Exp $
********************************************************************/
......@@ -75,11 +75,12 @@ int vorbis_analysis(vorbis_block *vb,ogg_packet *op){
}
/* there was no great place to put this.... */
void _analysis_output(char *base,int i,float *v,int n,int bark,int dB){
#ifdef ANALYSIS
void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB){
int j;
FILE *of;
char buffer[80];
// if(i==5870){
sprintf(buffer,"%s_%d.m",base,i);
of=fopen(buffer,"w");
......@@ -95,12 +96,19 @@ void _analysis_output(char *base,int i,float *v,int n,int bark,int dB){
fprintf(of,"%g ",(double)j);
if(dB){
fprintf(of,"%g\n",todB(fabs(v[j])));
fprintf(of,"%g\n",todB(v+j));
}else{
fprintf(of,"%g\n",v[j]);
}
}
}
fclose(of);
// }
}
void _analysis_output(char *base,int i,float *v,int n,int bark,int dB){
#ifdef ANALYSIS
_analysis_output_always(base,i,v,n,bark,dB);
#endif
}
......@@ -12,7 +12,7 @@
function: libvorbis backend and mapping structures; needed for
static mode headers
last mod: $Id: backends.h,v 1.6 2001/02/26 03:50:41 xiphmont Exp $
last mod: $Id: backends.h,v 1.7 2001/05/27 06:43:59 xiphmont Exp $
********************************************************************/
......@@ -61,7 +61,9 @@ typedef struct{
void (*free_info) (vorbis_info_floor *);
void (*free_look) (vorbis_look_floor *);
int (*forward) (struct vorbis_block *,vorbis_look_floor *,
float *);
const float *, const float *, /* in */
const float *, const float *, /* in */
float *, float *); /* out */
int (*inverse) (struct vorbis_block *,vorbis_look_floor *,
float *);
} vorbis_func_floor;
......@@ -82,6 +84,37 @@ typedef struct{
} vorbis_info_floor0;
#define VIF_POSIT 63
#define VIF_CLASS 16
#define VIF_PARTS 31
typedef struct{
int partitions; /* 0 to 31 */
int partitionclass[VIF_PARTS]; /* 0 to 15 */
int class_dim[VIF_CLASS]; /* 1 to 8 */
int class_subs[VIF_CLASS]; /* 0,1,2,3 (bits: 1<<n poss) */
int class_book[VIF_CLASS]; /* subs ^ dim entries */
int class_subbook[VIF_CLASS][8]; /* [VIF_CLASS][subs] */
int mult; /* 1 2 3 or 4 */
int postlist[VIF_POSIT+2]; /* first two implicit */
/* encode side analysis parameters */
float maxover;
float maxunder;
float maxerr;
int twofitminsize;
int twofitminused;
int twofitweight;
float twofitatten;
int unusedminsize;
int unusedmin_n;
} vorbis_info_floor1;
/* Residue backend generic *****************************************/
typedef struct{
void (*pack) (vorbis_info_residue *,oggpack_buffer *);
......
......@@ -11,7 +11,7 @@
********************************************************************
function: bark scale utility
last mod: $Id: barkmel.c,v 1.5 2001/02/26 03:50:41 xiphmont Exp $
last mod: $Id: barkmel.c,v 1.6 2001/05/27 06:43:59 xiphmont Exp $
********************************************************************/
......@@ -51,9 +51,13 @@ int main(){
}
for(i=0;i<28;i++){
fprintf(stderr,"bark=%d %gHz\n",
i,fromBARK(i));
{
float i;
int j;
for(i=0.,j=0;i<28;i+=2.107,j++){
fprintf(stderr,"(%d) bark=%f %gHz (%d of 128)\n",
j,i,fromBARK(i),(int)(fromBARK(i)/22050.*128.));
}
}
return(0);
}
......
......@@ -11,7 +11,7 @@
********************************************************************
function: PCM data vector blocking, windowing and dis/reassembly
last mod: $Id: block.c,v 1.47 2001/03/26 23:27:42 xiphmont Exp $
last mod: $Id: block.c,v 1.48 2001/05/27 06:43:59 xiphmont Exp $
Handle windowing, overlap-add, etc of the PCM vectors. This is made
more amusing by Vorbis' current two allowed block sizes.
......@@ -787,7 +787,7 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
/* pcm==NULL indicates we just want the pending samples, no more */
int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
vorbis_info *vi=v->vi;
if(v->pcm_returned<v->centerW){
if(v->pcm_returned>-1 && v->pcm_returned<v->centerW){
if(pcm){
int i;
for(i=0;i<vi->channels;i++)
......
......@@ -11,7 +11,7 @@
********************************************************************
function: basic codebook pack/unpack/code/decode operations
last mod: $Id: codebook.c,v 1.23 2001/02/26 03:50:41 xiphmont Exp $
last mod: $Id: codebook.c,v 1.24 2001/05/27 06:43:59 xiphmont Exp $
********************************************************************/
......@@ -40,7 +40,7 @@ int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
length random. Decide between the two now. */
for(i=1;i<c->entries;i++)
if(c->lengthlist[i]<c->lengthlist[i-1])break;
if(c->lengthlist[i-1]==0 || c->lengthlist[i]<c->lengthlist[i-1])break;
if(i==c->entries)ordered=1;
if(ordered){
......@@ -416,6 +416,43 @@ long s_vorbis_book_decodevs(codebook *book,float *a,oggpack_buffer *b,
return(0);
}
long s_vorbis_book_decodev(codebook *book,float *a,oggpack_buffer *b,
int partsize,int addmul){
int i,j,entry;
float *t;
switch(addmul){
case -1:
for(i=0;i<partsize;){
entry = vorbis_book_decode(book,b);
if(entry==-1)return(-1);
t = book->valuelist+entry*book->dim;
for (j=0;j<book->dim;)
a[i++]=t[j++];
}
break;
case 0:
for(i=0;i<partsize;){
entry = vorbis_book_decode(book,b);
if(entry==-1)return(-1);
t = book->valuelist+entry*book->dim;
for (j=0;j<book->dim;)
a[i++]+=t[j++];
}
break;
case 1:
for(i=0;i<partsize;){
entry = vorbis_book_decode(book,b);
if(entry==-1)return(-1);
t = book->valuelist+entry*book->dim;
for (j=0;j<book->dim;)
a[i++]*=t[j++];
}
break;
}
return(0);
}
#ifdef _V_SELFTEST
/* Simple enough; pack a few candidate codebooks, unpack them. Code a
......
......@@ -11,7 +11,7 @@
********************************************************************
function: basic shared codebook operations
last mod: $Id: codebook.h,v 1.5 2001/02/26 03:50:41 xiphmont Exp $
last mod: $Id: codebook.h,v 1.6 2001/05/27 06:43:59 xiphmont Exp $
********************************************************************/
......@@ -153,6 +153,8 @@ extern long vorbis_book_decodevs(codebook *book, float *a, oggpack_buffer *b,
int step,int stagetype);
extern long s_vorbis_book_decodevs(codebook *book, float *a, oggpack_buffer *b,
int step,int stagetype);
extern long s_vorbis_book_decodev(codebook *book, float *a, oggpack_buffer *b,
int partsize,int stagetype);
......
......@@ -11,7 +11,7 @@
********************************************************************
function: PCM data envelope analysis and manipulation
last mod: $Id: envelope.c,v 1.35 2001/02/26 03:50:41 xiphmont Exp $
last mod: $Id: envelope.c,v 1.36 2001/05/27 06:43:59 xiphmont Exp $
Preecho calculation.
......@@ -141,8 +141,8 @@ static float _ve_deltai(envelope_lookup *ve,float *pre,float *post){
B+=post[i]*post[i];
}
A=todB(A);
B=todB(B);
A=todB(&A);
B=todB(&B);
return(B-A);
}
......
......@@ -11,7 +11,7 @@
********************************************************************
function: floor backend 0 implementation
last mod: $Id: floor0.c,v 1.39 2001/02/26 03:50:41 xiphmont Exp $
last mod: $Id: floor0.c,v 1.40 2001/05/27 06:43:59 xiphmont Exp $
********************************************************************/
......@@ -197,6 +197,7 @@ float _curve_to_lpc(float *curve,float *lpc,
float *work=alloca(sizeof(float)*mapped);
int i,j,last=0;
int bark=0;
static int seq=0;
memset(work,0,sizeof(float)*mapped);
......@@ -233,16 +234,29 @@ float _curve_to_lpc(float *curve,float *lpc,
for(i=bark+1;i<mapped;i++)
work[i]=work[i-1];
/**********************/
for(i=0;i<l->n;i++)
curve[i]-=150;
_analysis_output("barkfloor",seq,work,bark,0,0);
_analysis_output("barkcurve",seq++,curve,l->n,1,0);
for(i=0;i<l->n;i++)
curve[i]+=150;
/**********************/
return vorbis_lpc_from_curve(work,lpc,&(l->lpclook));
}
/* generate the whole freq response curve of an LSP IIR filter */
/* didn't need in->out seperation, modifies the flr[] vector; takes in
a dB scale floor, puts out linear */
static int floor0_forward(vorbis_block *vb,vorbis_look_floor *i,
float *flr){
static int floor0_forward(vorbis_block *vb,vorbis_look_floor *in,
const float *mdct, const float *logmdct, /* in */
const float *logmask, const float *logmax, /* in */
float *residue, float *codedflr){ /* out */
long j;
vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
vorbis_look_floor0 *look=(vorbis_look_floor0 *)in;
vorbis_info_floor0 *info=look->vi;
float amp;
long bits=0;
......@@ -267,11 +281,11 @@ static int floor0_forward(vorbis_block *vb,vorbis_look_floor *i,
positive, so we offset it. */
for(j=0;j<look->n;j++)
flr[j]+=info->ampdB;
codedflr[j]=logmask[j]+info->ampdB;
/* use 'out' as temp storage */
/* Convert our floor to a set of lpc coefficients */
amp=sqrt(_curve_to_lpc(flr,flr,look));
amp=sqrt(_curve_to_lpc(codedflr,codedflr,look));
/* amp is in the range (0. to ampdB]. Encode that range using
ampbits bits */
......@@ -292,8 +306,8 @@ static int floor0_forward(vorbis_block *vb,vorbis_look_floor *i,
if(val){
/* LSP <-> LPC is orthogonal and LSP quantizes more stably */
_analysis_output("lpc",seq-1,flr,look->m,0,0);
if(vorbis_lpc_to_lsp(flr,flr,look->m))
_analysis_output("lpc",seq-1,codedflr,look->m,0,0);
if(vorbis_lpc_to_lsp(codedflr,codedflr,look->m))
val=0;
}
......@@ -309,15 +323,15 @@ static int floor0_forward(vorbis_block *vb,vorbis_look_floor *i,
codebook *b;
int booknum;
_analysis_output("lsp",seq-1,flr,look->m,0,0);
_analysis_output("lsp",seq-1,codedflr,look->m,0,0);
/* which codebook to use? We do it only by range right now. */
if(info->numbooks>1){
float last=0.;
for(j=0;j<look->m;j++){
float val=flr[j]-last;
float val=codedflr[j]-last;
if(val<info->lessthan || val>info->greaterthan)break;
last=flr[j];
last=codedflr[j];
}
if(j<look->m)
booknum=0;
......@@ -334,8 +348,8 @@ static int floor0_forward(vorbis_block *vb,vorbis_look_floor *i,
{
float last=0.f;
for(j=0;j<look->m;j++){
fprintf(of,"%.12g, ",flr[j]-last);
last=flr[j];
fprintf(of,"%.12g, ",codedflr[j]-last);
last=codedflr[j];
}
}
fprintf(of,"\n");
......@@ -351,7 +365,7 @@ static int floor0_forward(vorbis_block *vb,vorbis_look_floor *i,
nailed to the last quantized value of the previous block. */
for(j=0;j<look->m;j+=b->dim){
int entry=_f0_fit(b,flr,lspwork,j);
int entry=_f0_fit(b,codedflr,lspwork,j);
bits+=vorbis_book_encode(b,entry,&vb->opb);
#ifdef TRAIN_LSP
......@@ -367,9 +381,16 @@ static int floor0_forward(vorbis_block *vb,vorbis_look_floor *i,
_analysis_output("lsp2",seq-1,lspwork,look->m,0,0);
/* take the coefficients back to a spectral envelope curve */
vorbis_lsp_to_curve(flr,look->linearmap,look->n,look->ln,
vorbis_lsp_to_curve(codedflr,look->linearmap,look->n,look->ln,
lspwork,look->m,amp,info->ampdB);
_analysis_output("lsp3",seq-1,flr,look->n,0,1);