[xiph-cvs] cvs commit: vorbis/vq bookutil.c distribution.c huffbuild.c latticehint.c
Monty
xiphmont at xiph.org
Sat May 26 23:44:09 PDT 2001
xiphmont 01/05/26 23:44:08
Modified: examples seeking_example.c
include/vorbis codec.h vorbisfile.h
lib Makefile.am analysis.c backends.h barkmel.c block.c
codebook.c codebook.h envelope.c floor0.c info.c
mapping0.c masking.h psy.c psy.h psytune.c
registry.c registry.h res0.c scales.h synthesis.c
vorbisenc.c vorbisfile.c
lib/modes mode_A.h mode_AA.h mode_B.h mode_C.h mode_D.h
mode_E.h
vq bookutil.c distribution.c huffbuild.c latticehint.c
Added: lib floor1.c
Log:
Floor 1
Res 1
Vorbisfile fixes/opts
now all on mainline
Revision Changes Path
1.8 +145 -12 vorbis/examples/seeking_example.c
Index: seeking_example.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/examples/seeking_example.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- seeking_example.c 2001/02/26 03:50:38 1.7
+++ seeking_example.c 2001/05/27 06:43:58 1.8
@@ -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,28 +21,161 @@
#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){
printf("Could not open input as an OggVorbis file.\n\n");
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);
- fflush(stdout);
+
+ /* 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");
+ printf("\r \nOK.\n\n");
+
+
}else{
printf("Standard input was not seekable.\n");
}
1.38 +2 -1 vorbis/include/vorbis/codec.h
Index: codec.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/include/vorbis/codec.h,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- codec.h 2001/02/26 03:50:39 1.37
+++ codec.h 2001/05/27 06:43:59 1.38
@@ -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_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 ***********************************/
1.14 +22 -12 vorbis/include/vorbis/vorbisfile.h
Index: vorbisfile.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/include/vorbis/vorbisfile.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- vorbisfile.h 2001/02/26 03:50:39 1.13
+++ vorbisfile.h 2001/05/27 06:43:59 1.14
@@ -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,27 +43,32 @@
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. */
+ void *datasource; /* Pointer to a FILE *, etc. */
int seekable;
- ogg_int64_t offset;
- ogg_int64_t end;
+ ogg_int64_t offset;
+ ogg_int64_t end;
ogg_sync_state oy;
/* If the FILE handle isn't seekable (eg, a pipe), only the current
stream appears */
int links;
- ogg_int64_t *offsets;
- ogg_int64_t *dataoffsets;
- long *serialnos;
- ogg_int64_t *pcmlengths;
- vorbis_info *vi;
- vorbis_comment *vc;
+ ogg_int64_t *offsets;
+ ogg_int64_t *dataoffsets;
+ long *serialnos;
+ ogg_int64_t *pcmlengths;
+ vorbis_info *vi;
+ vorbis_comment *vc;
/* Decoding working state local storage */
- ogg_int64_t pcm_offset;
- int decode_ready;
+ ogg_int64_t pcm_offset;
+ int ready_state;
long current_serialno;
int current_link;
@@ -83,6 +88,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);
1.12 +3 -2 vorbis/lib/Makefile.am
Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/Makefile.am,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- Makefile.am 2001/02/19 07:48:39 1.11
+++ Makefile.am 2001/05/27 06:43:59 1.12
@@ -8,8 +8,9 @@
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\
1.44 +30 -22 vorbis/lib/analysis.c
Index: analysis.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/analysis.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- analysis.c 2001/02/26 03:50:41 1.43
+++ analysis.c 2001/05/27 06:43:59 1.44
@@ -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,32 +75,40 @@
}
/* 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];
- sprintf(buffer,"%s_%d.m",base,i);
- of=fopen(buffer,"w");
-
- if(!of)perror("failed to open data dump file");
- for(j=0;j<n;j++){
- if(dB && v[j]==0)
- fprintf(of,"\n\n");
- else{
- if(bark)
- fprintf(of,"%g ",toBARK(22050.f*j/n));
- else
- fprintf(of,"%g ",(double)j);
-
- if(dB){
- fprintf(of,"%g\n",todB(fabs(v[j])));
- }else{
- fprintf(of,"%g\n",v[j]);
+ // if(i==5870){
+ sprintf(buffer,"%s_%d.m",base,i);
+ of=fopen(buffer,"w");
+
+ if(!of)perror("failed to open data dump file");
+
+ for(j=0;j<n;j++){
+ if(dB && v[j]==0)
+ fprintf(of,"\n\n");
+ else{
+ if(bark)
+ fprintf(of,"%g ",toBARK(22050.f*j/n));
+ else
+ fprintf(of,"%g ",(double)j);
+
+ if(dB){
+ fprintf(of,"%g\n",todB(v+j));
+ }else{
+ fprintf(of,"%g\n",v[j]);
+ }
}
}
- }
- fclose(of);
+ 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
}
+
1.7 +35 -2 vorbis/lib/backends.h
Index: backends.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/backends.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- backends.h 2001/02/26 03:50:41 1.6
+++ backends.h 2001/05/27 06:43:59 1.7
@@ -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 @@
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;
@@ -81,6 +83,37 @@
float greaterthan; /* encode-only config setting hacks for libvorbis */
} 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{
1.6 +8 -4 vorbis/lib/barkmel.c
Index: barkmel.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/barkmel.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- barkmel.c 2001/02/26 03:50:41 1.5
+++ barkmel.c 2001/05/27 06:43:59 1.6
@@ -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 @@
}
- 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);
}
1.48 +2 -2 vorbis/lib/block.c
Index: block.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/block.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -r1.47 -r1.48
--- block.c 2001/03/26 23:27:42 1.47
+++ block.c 2001/05/27 06:43:59 1.48
@@ -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 @@
/* 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++)
1.24 +39 -2 vorbis/lib/codebook.c
Index: codebook.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/codebook.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- codebook.c 2001/02/26 03:50:41 1.23
+++ codebook.c 2001/05/27 06:43:59 1.24
@@ -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 @@
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){
@@ -411,6 +411,43 @@
for(i=0,o=0;i<book->dim;i++,o+=step)
for (j=0;j<step;j++)
a[o+j]*=t[j][i];
+ break;
+ }
+ 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);
1.6 +3 -1 vorbis/lib/codebook.h
Index: codebook.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/codebook.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- codebook.h 2001/02/26 03:50:41 1.5
+++ codebook.h 2001/05/27 06:43:59 1.6
@@ -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 @@
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);
1.36 +3 -3 vorbis/lib/envelope.c
Index: envelope.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/envelope.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- envelope.c 2001/02/26 03:50:41 1.35
+++ envelope.c 2001/05/27 06:43:59 1.36
@@ -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 @@
B+=post[i]*post[i];
}
- A=todB(A);
- B=todB(B);
+ A=todB(&A);
+ B=todB(&B);
return(B-A);
}
1.40 +41 -20 vorbis/lib/floor0.c
Index: floor0.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/floor0.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- floor0.c 2001/02/26 03:50:41 1.39
+++ floor0.c 2001/05/27 06:43:59 1.40
@@ -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 *work=alloca(sizeof(float)*mapped);
int i,j,last=0;
int bark=0;
+ static int seq=0;
memset(work,0,sizeof(float)*mapped);
@@ -232,17 +233,30 @@
/* If we're over-ranged to avoid edge effects, fill in the end of spectrum gap */
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 @@
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 @@
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 @@
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 @@
{
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 @@
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 @@
_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);
+
+ _analysis_output("barklsp",seq-1,codedflr,look->n,1,1);
+ _analysis_output("lsp3",seq-1,codedflr,look->n,0,1);
+
+ /* generate residue output */
+ for(j=0;j<look->n;j++)
+ residue[j]=mdct[j]/codedflr[j];
+
return(val);
}
@@ -377,7 +398,7 @@
fclose(of);
#endif
- memset(flr,0,sizeof(float)*look->n);
+ memset(codedflr,0,sizeof(float)*look->n);
return(val);
}
1.40 +2 -2 vorbis/lib/info.c
Index: info.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/info.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- info.c 2001/02/26 03:50:41 1.39
+++ info.c 2001/05/27 06:44:00 1.40
@@ -11,7 +11,7 @@
********************************************************************
function: maintain the info structure, info <-> header packets
- last mod: $Id: info.c,v 1.39 2001/02/26 03:50:41 xiphmont Exp $
+ last mod: $Id: info.c,v 1.40 2001/05/27 06:44:00 xiphmont Exp $
********************************************************************/
@@ -408,7 +408,7 @@
}
static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){
- char temp[]="Xiphophorus libVorbis I 20010225";
+ char temp[]="Xiphophorus libVorbis I 20010501";
/* preamble */
oggpack_write(opb,0x03,8);
1.28 +45 -42 vorbis/lib/mapping0.c
Index: mapping0.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/mapping0.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- mapping0.c 2001/02/26 13:31:31 1.27
+++ mapping0.c 2001/05/27 06:44:00 1.28
@@ -11,7 +11,7 @@
********************************************************************
function: channel mapping 0 implementation
- last mod: $Id: mapping0.c,v 1.27 2001/02/26 13:31:31 xiphmont Exp $
+ last mod: $Id: mapping0.c,v 1.28 2001/05/27 06:44:00 xiphmont Exp $
********************************************************************/
@@ -197,6 +197,7 @@
#include "envelope.h"
#include "mdct.h"
#include "psy.h"
+#define VORBIS_IEEE_FLOAT32
#include "scales.h"
/* no time mapping implementation for now */
@@ -217,77 +218,80 @@
int *nonzero=alloca(sizeof(int)*vi->channels);
- float **floor=_vorbis_block_alloc(vb,vi->channels*sizeof(float *));
- float *additional=_vorbis_block_alloc(vb,n*sizeof(float));
+ float *work=_vorbis_block_alloc(vb,n*sizeof(float));
float newmax=vbi->ampmax;
for(i=0;i<vi->channels;i++){
- float *pcm=vb->pcm[i];
float scale=4.f/n;
int submap=info->chmuxlist[i];
float ret;
- _analysis_output("pcm",seq,pcm,n,0,0);
+ /* the following makes things clearer to *me* anyway */
+ float *pcm =vb->pcm[i];
+ float *mdct =pcm;
+ float *logmdct =pcm+n/2;
+ float *res =pcm;
+ float *codedflr=pcm+n/2;
+ float *fft =work;
+ float *logfft =work;
+ float *logmax =work;
+ float *logmask =work+n/2;
/* window the PCM data */
for(j=0;j<n;j++)
- additional[j]=pcm[j]*=window[j];
-
- _analysis_output("windowed",seq,pcm,n,0,0);
-
+ fft[j]=pcm[j]*=window[j];
+
/* transform the PCM data */
/* only MDCT right now.... */
mdct_forward(b->transform[vb->W][0],pcm,pcm);
+ for(j=0;j<n/2;j++)
+ logmdct[j]=todB(mdct+j);
/* FFT yields more accurate tonal estimation (not phase sensitive) */
- drft_forward(&look->fft_look,additional);
-
- additional[0]=fabs(additional[0]*scale);
- for(j=1;j<n-1;j+=2)
- additional[(j+1)>>1]=scale*FAST_HYPOT(additional[j],additional[j+1]);
-
- /* set up our masking data working vector, and stash unquantized
- data for later */
- /*memcpy(pcm+n/2,pcm,n*sizeof(float)/2);*/
- memcpy(additional+n/2,pcm,n*sizeof(float)/2);
-
- /* begin masking work */
- floor[i]=_vorbis_block_alloc(vb,n*sizeof(float)/2);
-
- _analysis_output("fft",seq,additional,n/2,0,1);
- _analysis_output("mdct",seq,additional+n/2,n/2,0,1);
- _analysis_output("lfft",seq,additional,n/2,0,0);
- _analysis_output("lmdct",seq,additional+n/2,n/2,0,0);
+ drft_forward(&look->fft_look,fft);
+ fft[0]*=scale;
+ fft[0]=todB(fft);
+ for(j=1;j<n-1;j+=2){
+ float temp=scale*FAST_HYPOT(fft[j],fft[j+1]);
+ logfft[(j+1)>>1]=todB(&temp);
+ }
+ _analysis_output("fft",seq,logfft,n/2,0,0);
+ _analysis_output("mdct",seq,logmdct,n/2,0,0);
+
/* perform psychoacoustics; do masking */
- ret=_vp_compute_mask(look->psy_look+submap,additional,additional+n/2,
- floor[i],NULL,vbi->ampmax);
+ ret=_vp_compute_mask(look->psy_look+submap,
+ logfft, /* -> logmax */
+ logmdct,
+ logmask,
+ vbi->ampmax);
if(ret>newmax)newmax=ret;
- _analysis_output("prefloor",seq,floor[i],n/2,0,0);
+ _analysis_output("mask",seq,logmask,n/2,0,0);
/* perform floor encoding */
nonzero[i]=look->floor_func[submap]->
- forward(vb,look->floor_look[submap],floor[i]);
-
- _analysis_output("floor",seq,floor[i],n/2,0,1);
-
- /* apply the floor, do optional noise levelling */
- _vp_apply_floor(look->psy_look+submap,pcm,floor[i]);
+ forward(vb,look->floor_look[submap],
+ mdct,
+ logmdct,
+ logmask,
+ logmax,
+ res,
+ codedflr);
- _analysis_output("res",seq++,pcm,n/2,0,0);
+ _analysis_output("codedflr",seq,codedflr,n/2,0,1);
+ _analysis_output("res",seq++,res,n/2,0,0);
#ifdef TRAIN_RES
if(nonzero[i]){
FILE *of;
char buffer[80];
- int i;
sprintf(buffer,"residue_%d.vqd",vb->mode);
of=fopen(buffer,"a");
- for(i=0;i<n/2;i++){
- fprintf(of,"%.2f, ",pcm[i]);
- if(fabs(pcm[i])>1000){
+ for(j=0;j<n/2;j++){
+ fprintf(of,"%.2f, ",res[j]);
+ if(fabs(res[j])>1000){
fprintf(stderr," %d ",seq-1);
}
}
@@ -297,7 +301,6 @@
#endif
}
- seq++;
vbi->ampmax=newmax;
/* perform residue encoding with residue mapping; this is
1.14 +2 -2 vorbis/lib/masking.h
Index: masking.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/masking.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- masking.h 2001/02/26 03:50:42 1.13
+++ masking.h 2001/05/27 06:44:00 1.14
@@ -11,7 +11,7 @@
********************************************************************
function: masking curve data for psychoacoustics
- last mod: $Id: masking.h,v 1.13 2001/02/26 03:50:42 xiphmont Exp $
+ last mod: $Id: masking.h,v 1.14 2001/05/27 06:44:00 xiphmont Exp $
********************************************************************/
@@ -22,7 +22,7 @@
float ATH_Bark_dB[]={
15, 15, 15, 15, 11, 10, 8, 7, 7, 7,
6, 2, 0, 0, -3, -5, -6, -6, -4.5f, 2.5f,
- 10, 15, 15, 15, 15, 15, 15};
+ 10, 15, 20, 30, 40, 50, 60};
/* The below masking curves are straight from the R. Ehmer
(J. Acoustical Society of America) papers ca 1958-59. I modified
1.45 +139 -128 vorbis/lib/psy.c
Index: psy.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/psy.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- psy.c 2001/03/21 07:44:46 1.44
+++ psy.c 2001/05/27 06:44:00 1.45
@@ -11,7 +11,7 @@
********************************************************************
function: psychoacoustics not including preecho
- last mod: $Id: psy.c,v 1.44 2001/03/21 07:44:46 msmith Exp $
+ last mod: $Id: psy.c,v 1.45 2001/05/27 06:44:00 xiphmont Exp $
********************************************************************/
@@ -178,7 +178,7 @@
}
void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,int n,long rate){
- long i,j;
+ long i,j,lo=0,hi=0;
long maxoc;
memset(p,0,sizeof(vorbis_look_psy));
@@ -192,21 +192,31 @@
p->ath=_ogg_malloc(n*sizeof(float));
p->octave=_ogg_malloc(n*sizeof(long));
- p->bark=_ogg_malloc(n*sizeof(float));
+ p->bark=_ogg_malloc(n*sizeof(unsigned long));
p->vi=vi;
p->n=n;
/* set up the lookups for a given blocksize and sample rate */
/* Vorbis max sample rate is currently limited by 26 Bark (54kHz) */
set_curve(ATH_Bark_dB, p->ath,n,rate);
- for(i=0;i<n;i++)
- p->bark[i]=toBARK(rate/(2*n)*i);
+ for(i=0;i<n;i++){
+ float bark=toBARK(rate/(2*n)*i);
+
+ for(;lo+vi->noisewindowlomin<i &&
+ toBARK(rate/(2*n)*lo)<=(bark-vi->noisewindowlo);lo++);
+
+ for(;hi<n && (hi<i+vi->noisewindowhimin ||
+ toBARK(rate/(2*n)*hi)<=(bark+vi->noisewindowhi));hi++);
+
+ p->bark[i]=((hi+1)<<16)+(lo+1);
+ }
+
for(i=0;i<n;i++)
p->octave[i]=toOC((i*.5f+.25f)*rate/n)*(1<<(p->shiftoc+1))+.5f;
p->tonecurves=_ogg_malloc(P_BANDS*sizeof(float **));
- p->noisemedian=_ogg_malloc(n*sizeof(float));
+ p->noisemedian=_ogg_malloc(n*sizeof(int));
p->noiseoffset=_ogg_malloc(n*sizeof(float));
p->peakatt=_ogg_malloc(P_BANDS*sizeof(float *));
for(i=0;i<P_BANDS;i++){
@@ -296,12 +306,13 @@
inthalfoc=(int)halfoc;
del=halfoc-inthalfoc;
- p->noisemedian[i]=
- p->vi->noisemedian[inthalfoc*2]*(1.-del) +
- p->vi->noisemedian[inthalfoc*2+2]*del;
+ p->noisemedian[i]=rint(
+ (p->vi->noisemedian[inthalfoc*2]*(1.-del) +
+ p->vi->noisemedian[inthalfoc*2+2]*del)*1024.f);
p->noiseoffset[i]=
p->vi->noisemedian[inthalfoc*2+1]*(1.-del) +
- p->vi->noisemedian[inthalfoc*2+3]*del;
+ p->vi->noisemedian[inthalfoc*2+3]*del -
+ 140.f;
}
/*_analysis_output("mediancurve",0,p->noisemedian,n,0,0);*/
}
@@ -331,21 +342,23 @@
/* octave/(8*eighth_octave_lines) x scale and dB y scale */
static void seed_curve(float *seed,
- float **curves,
- float amp,
- int oc,int n,int linesper,float dBoffset){
- int i;
- long seedptr;
- float *posts,*curve;
+ const float **curves,
+ float amp,
+ int oc, int n,
+ int linesper,float dBoffset){
+ int i,post1;
+ int seedptr;
+ const float *posts,*curve;
int choice=(int)((amp+dBoffset)*.1f);
choice=max(choice,0);
choice=min(choice,P_LEVELS-1);
posts=curves[choice];
curve=posts+2;
+ post1=(int)posts[1];
seedptr=oc+(posts[0]-16)*linesper-(linesper>>1);
- for(i=posts[0];i<posts[1];i++){
+ for(i=posts[0];i<post1;i++){
if(seedptr>0){
float lin=amp+curve[i];
if(seed[seedptr]<lin)seed[seedptr]=lin;
@@ -356,7 +369,7 @@
}
static void seed_peak(float *seed,
- float *att,
+ const float *att,
float amp,
int oc,
int linesper,
@@ -374,10 +387,10 @@
}
static void seed_loop(vorbis_look_psy *p,
- float ***curves,
- float **att,
- float *f,
- float *flr,
+ const float ***curves,
+ const float **att,
+ const float *f,
+ const float *flr,
float *minseed,
float *maxseed,
float specmax){
@@ -531,75 +544,103 @@
}
-/* quarter-dB bins */
-#define BIN(x) ((int)((x)*negFour))
-#define BINdB(x) ((x)*negQuarter)
-#define BINCOUNT (200*4)
+/* set to match vorbis_quantdblook.h */
+#define BINCOUNT 280
#define LASTBIN (BINCOUNT-1)
-static void bark_noise_median(long n,float *b,float *f,float *noise,
+static int psy_dBquant(const float *x){
+ int i= *x*2.f+279.5f;
+ if(i>279)return(279);
+ if(i<0)return(0);
+ return i;
+}
+
+
+static void bark_noise_median(int n,const long *b,const float *f,
+ float *noise,
float lowidth,float hiwidth,
int lomin,int himin,
- float *thresh,float *off){
- long i=0,lo=0,hi=0;
- float bi,threshi;
- long median=LASTBIN;
- float negFour = -4.0f;
- float negQuarter = -0.25f;
-
- /* these are really integral values, but we store them in floats to
- avoid excessive float/int conversions, which GCC and MSVC are
- farily poor at optimizing. */
-
- float radix[BINCOUNT];
- float countabove=0;
- float countbelow=0;
-
- memset(radix,0,sizeof(radix));
+ const int *thresh,const float *off,
+ int fixed){
+ int i=0,lo=-1,hi=-1,fixedc=0;
+ int median=LASTBIN>>1;
+
+ int barkradix[BINCOUNT];
+ int barkcountbelow=0;
+
+ int fixedradix[BINCOUNT];
+ int fixedcountbelow=0;
+
+ memset(barkradix,0,sizeof(barkradix));
+ memset(fixedradix,0,sizeof(fixedradix));
+
+ /* bootstrap the fixed window case seperately */
+ for(i=0;i<(fixed>>1);i++){
+ int bin=psy_dBquant(f+i);
+ fixedradix[bin]++;
+ fixedc++;
+ if(bin<=median)
+ fixedcountbelow++;
+ }
for(i=0;i<n;i++){
/* find new lo/hi */
- bi=b[i]+hiwidth;
- for(;hi<n && (hi<i+himin || b[hi]<=bi);hi++){
- int bin=BIN(f[hi]);
- if(bin>LASTBIN)bin=LASTBIN;
- if(bin<0)bin=0;
- radix[bin]++;
- if(bin<median)
- countabove++;
- else
- countbelow++;
- }
- bi=b[i]-lowidth;
- for(;lo<i && lo+lomin<i && b[lo]<=bi;lo++){
- int bin=BIN(f[lo]);
- if(bin>LASTBIN)bin=LASTBIN;
- if(bin<0)bin=0;
- radix[bin]--;
- if(bin<median)
- countabove--;
- else
- countbelow--;
+ int bi=b[i]>>16;
+ for(;hi<bi;hi++){
+ int bin=psy_dBquant(f+hi);
+ barkradix[bin]++;
+ if(bin<=median)
+ barkcountbelow++;
+ }
+ bi=b[i]&0xffff;
+ for(;lo<bi;lo++){
+ int bin=psy_dBquant(f+lo);
+ barkradix[bin]--;
+ if(bin<=median)
+ barkcountbelow--;
+ }
+
+ bi=i+(fixed>>1);
+ if(bi<n){
+ int bin=psy_dBquant(f+bi);
+ fixedradix[bin]++;
+ fixedc++;
+ if(bin<=median)
+ fixedcountbelow++;
+ }
+
+ bi-=fixed;
+ if(bi>=0){
+ int bin=psy_dBquant(f+bi);
+ fixedradix[bin]--;
+ fixedc--;
+ if(bin<=median)
+ fixedcountbelow--;
}
/* move the median if needed */
- if(countabove+countbelow){
- threshi = thresh[i]*(countabove+countbelow);
-
- while(threshi>countbelow && median>0){
- median--;
- countabove-=radix[median];
- countbelow+=radix[median];
+ {
+ int bark_th = (thresh[i]*(hi-lo)+512)/1024;
+ int fixed_th = (thresh[i]*(fixedc)+512)/1024;
+
+ while(bark_th>=barkcountbelow &&
+ fixed_th>=fixedcountbelow /* && median<LASTBIN by rep invariant */
+ ){
+ median++;
+ barkcountbelow+=barkradix[median];
+ fixedcountbelow+=fixedradix[median];
}
- while(threshi<(countbelow-radix[median]) &&
- median<LASTBIN){
- countabove+=radix[median];
- countbelow-=radix[median];
- median++;
+ while(bark_th<barkcountbelow ||
+ fixed_th<fixedcountbelow /* && median>=0 by rep invariant */
+ ){
+ barkcountbelow-=barkradix[median];
+ fixedcountbelow-=fixedradix[median];
+ median--;
}
}
- noise[i]=BINdB(median)+off[i];
+
+ noise[i]= (median+1)*.5f+off[i];
}
}
@@ -607,8 +648,7 @@
float _vp_compute_mask(vorbis_look_psy *p,
float *fft,
float *mdct,
- float *flr,
- float *decay,
+ float *mask,
float specmax){
int i,n=p->n;
float localmax=NEGINF;
@@ -618,37 +658,28 @@
float *maxseed=alloca(sizeof(float)*p->total_octave_lines);
for(i=0;i<p->total_octave_lines;i++)minseed[i]=maxseed[i]=NEGINF;
- /* go to dB scale. Also find the highest peak so we know the limits */
- for(i=0;i<n;i++){
- fft[i]=todB_nn(fft[i]);
+ /* Find the highest peak so we know the limits */
+ for(i=0;i<n;i++)
if(fft[i]>localmax)localmax=fft[i];
- }
if(specmax<localmax)specmax=localmax;
-
- for(i=0;i<n;i++){
- mdct[i]=todB(mdct[i]);
- }
-
- _analysis_output("mdct",seq,mdct,n,0,0);
- _analysis_output("fft",seq,fft,n,0,0);
-
/* noise masking */
if(p->vi->noisemaskp){
- bark_noise_median(n,p->bark,mdct,flr,
+ bark_noise_median(n,p->bark,mdct,mask,
p->vi->noisewindowlo,
p->vi->noisewindowhi,
p->vi->noisewindowlomin,
p->vi->noisewindowhimin,
p->noisemedian,
- p->noiseoffset);
+ p->noiseoffset,
+ p->vi->noisewindowfixed);
/* suppress any noise curve > specmax+p->vi->noisemaxsupp */
for(i=0;i<n;i++)
- if(flr[i]>specmax+p->vi->noisemaxsupp)
- flr[i]=specmax+p->vi->noisemaxsupp;
- _analysis_output("noise",seq,flr,n,0,0);
+ if(mask[i]>specmax+p->vi->noisemaxsupp)
+ mask[i]=specmax+p->vi->noisemaxsupp;
+ _analysis_output("noise",seq,mask,n,0,0);
}else{
- for(i=0;i<n;i++)flr[i]=NEGINF;
+ for(i=0;i<n;i++)mask[i]=NEGINF;
}
/* set the ATH (floating below localmax, not global max by a
@@ -659,52 +690,32 @@
for(i=0;i<n;i++){
float av=p->ath[i]+att;
- if(av>flr[i])flr[i]=av;
+ if(av>mask[i])mask[i]=av;
}
}
- _analysis_output("ath",seq,flr,n,0,0);
/* tone/peak masking */
/* XXX apply decay to the fft here */
- seed_loop(p,p->tonecurves,p->peakatt,fft,flr,minseed,maxseed,specmax);
- bound_loop(p,mdct,maxseed,flr,p->vi->bound_att_dB);
- _analysis_output("minseed",seq,minseed,p->total_octave_lines,0,0);
- _analysis_output("maxseed",seq,maxseed,p->total_octave_lines,0,0);
- max_seeds(p,minseed,maxseed,flr);
- _analysis_output("final",seq,flr,n,0,0);
+ seed_loop(p,
+ (const float ***)p->tonecurves,
+ (const float **)p->peakatt,fft,mask,minseed,maxseed,specmax);
+ bound_loop(p,mdct,maxseed,mask,p->vi->bound_att_dB);
+ max_seeds(p,minseed,maxseed,mask);
/* doing this here is clean, but we need to find a faster way to do
it than to just tack it on */
-
- for(i=0;i<n;i++)if(mdct[i]>=flr[i])break;
- if(i==n)for(i=0;i<n;i++)flr[i]=NEGINF;
-
+ for(i=0;i<n;i++)if(mdct[i]>=mask[i])break;
+ if(i==n)
+ for(i=0;i<n;i++)mask[i]=NEGINF;
+ else
+ for(i=0;i<n;i++)fft[i]=max(mdct[i],fft[i]);
seq++;
return(specmax);
-}
-
-
-/* this applies the floor and (optionally) tries to preserve noise
- energy in low resolution portions of the spectrum */
-/* f and flr are *linear* scale, not dB */
-void _vp_apply_floor(vorbis_look_psy *p,float *f, float *flr){
- float *work=alloca(p->n*sizeof(float));
- int j;
-
- /* subtract the floor */
- for(j=0;j<p->n;j++){
- if(flr[j]<=0)
- work[j]=0.f;
- else
- work[j]=f[j]/flr[j];
- }
-
- memcpy(f,work,p->n*sizeof(float));
}
float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd){
1.20 +5 -9 vorbis/lib/psy.h
Index: psy.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/psy.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- psy.h 2001/02/26 03:50:43 1.19
+++ psy.h 2001/05/27 06:44:00 1.20
@@ -11,7 +11,7 @@
********************************************************************
function: random psychoacoustics (not including preecho)
- last mod: $Id: psy.h,v 1.19 2001/02/26 03:50:43 xiphmont Exp $
+ last mod: $Id: psy.h,v 1.20 2001/05/27 06:44:00 xiphmont Exp $
********************************************************************/
@@ -52,14 +52,12 @@
float noisewindowhi;
int noisewindowlomin;
int noisewindowhimin;
+ int noisewindowfixed;
float noisemedian[P_BANDS*2];
float max_curve_dB;
float bound_att_dB;
- /* decay setup */
- float attack_coeff;
- float decay_coeff;
} vorbis_info_psy;
typedef struct {
@@ -68,12 +66,12 @@
float ***tonecurves;
float **peakatt;
- float *noisemedian;
+ int *noisemedian;
float *noiseoffset;
float *ath;
long *octave; /* in n.ocshift format */
- float *bark;
+ unsigned long *bark;
long firstoc;
long shiftoc;
@@ -92,10 +90,8 @@
extern float _vp_compute_mask(vorbis_look_psy *p,
float *fft,
float *mdct,
- float *floor,
- float *decay,
+ float *mask,
float prev_maxamp);
-extern void _vp_apply_floor(vorbis_look_psy *p,float *f,float *flr);
extern float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd);
#endif
1.15 +69 -103 vorbis/lib/psytune.c
Index: psytune.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/psytune.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- psytune.c 2001/02/26 03:50:43 1.14
+++ psytune.c 2001/05/27 06:44:00 1.15
@@ -12,7 +12,7 @@
function: simple utility that runs audio through the psychoacoustics
without encoding
- last mod: $Id: psytune.c,v 1.14 2001/02/26 03:50:43 xiphmont Exp $
+ last mod: $Id: psytune.c,v 1.15 2001/05/27 06:44:00 xiphmont Exp $
********************************************************************/
@@ -33,7 +33,7 @@
static vorbis_info_psy _psy_set0={
1,/*athp*/
- 0,/*decayp*/
+ 1,/*decayp*/
-100.f,
-140.f,
@@ -43,38 +43,30 @@
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
/* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
/* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
-
1,/* tonemaskp */
/* 0 10 20 30 40 50 60 70 80 90 100 */
{
{-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*63*/
{-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*88*/
{-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*125*/
- // {-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-100.}, /*175*/
- // {-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-100.}, /*250*/
- // {-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-100.}, /*350*/
- // {-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-100.}, /*500*/
- // {-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-100.}, /*700*/
-
- // {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*63*/
- // {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*88*/
- // {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*125*/
- {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*175*/
- {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*250*/
- {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*350*/
- {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*500*/
- {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*700*/
+
+ {-35.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*175*/
+ {-35.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*250*/
+ {-35.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*350*/
+ {-35.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*500*/
+ {-35.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*700*/
- {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1000*/
- {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1400*/
+ {-35.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1000*/
+ {-35.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1400*/
{-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2000*/
{-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2800*/
- {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*4000*/
- {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*5600*/
+ {-35.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*4000*/
+ {-35.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*5600*/
- {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*8000*/
- {-30.f,-30.f,-30.f,-40.f,-40.f,-45.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*11500*/
- {-30.f,-30.f,-30.f,-35.f,-35.f,-45.f,-50.f,-60.f,-70.f,-80.f,-90.f}, /*16000*/
+ {-30.f,-30.f,-33.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*8000*/
+ {-30.f,-30.f,-33.f,-35.f,-35.f,-45.f,-50.f,-60.f,-70.f,-90.f,-100.f}, /*11500*/
+ {-24.f,-24.f,-26.f,-32.f,-32.f,-42.f,-50.f,-60.f,-70.f,-90.f,-100.f}, /*16000*/
+
},
1,/* peakattp */
@@ -98,38 +90,37 @@
},
1,/*noisemaskp */
- -0.f, /* suppress any noise curve over maxspec+n */
+ -24.f, /* suppress any noise curve over maxspec+n */
.5f, /* low window */
.5f, /* high window */
25,
25,
- {.000f, /*63*/
- .000f, /*88*/
- .000f, /*125*/
- .000f, /*175*/
- .000f, /*250*/
- .000f, /*350*/
- .000f, /*500*/
- .200f, /*700*/
- .300f, /*1000*/
- .400f, /*1400*/
- .400f, /*2000*/
- .400f, /*2800*/
- .700f, /*4000*/
- .900f, /*5600*/
- .900f, /*8000*/
- .900f, /*11500*/
- .900f, /*16000*/
+ {.000f, 0.f, /*63*/
+ .000f, 0.f, /*88*/
+ .000f, 0.f, /*125*/
+ .000f, 0.f, /*175*/
+ .000f, 0.f, /*250*/
+ .000f, 0.f, /*350*/
+ .000f, 0.f, /*500*/
+ .200f, 0.f, /*700*/
+ .300f, 0.f, /*1000*/
+ .400f, 0.f, /*1400*/
+ .400f, 0.f, /*2000*/
+ .400f, 0.f, /*2800*/
+ .700f, 0.f, /*4000*/
+ .850f, 0.f, /*5600*/
+ .900f, 0.f, /*8000*/
+ .900f, 0.f, /*11500*/
+ .900f, 1.f, /*16000*/
},
- 105.f, /* even decade + 5 is important; saves an rint() later in a
+ 95.f, /* even decade + 5 is important; saves an rint() later in a
tight loop) */
-28.,
- -0.f, -.004f /* attack/decay control */
};
-static int noisy=0;
+static int noisy=1;
void analysis(char *base,int i,float *v,int n,int bark,int dB){
if(noisy){
int j;
@@ -148,7 +139,7 @@
fprintf(of,"%g ",(float)j);
if(dB){
- fprintf(of,"%g\n",todB(fabs(v[j])));
+ fprintf(of,"%g\n",todB(fabs(v+j)));
}else{
fprintf(of,"%g\n",v[j]);
}
@@ -158,41 +149,9 @@
}
}
-typedef struct {
- long n;
- int ln;
- int m;
- int *linearmap;
-
- void *vi;
- lpc_lookup lpclook;
- float *lsp_look;
-
-} vorbis_look_floor0;
-
-extern float _curve_to_lpc(float *curve,float *lpc,
- vorbis_look_floor0 *l);
-
long frameno=0;
-/* hacked from floor0.c */
-static void floorinit(vorbis_look_floor0 *look,int n,int m,int ln){
- int j;
- float scale;
- look->m=m;
- look->n=n;
- look->ln=ln;
- lpc_init(&look->lpclook,look->ln,look->m);
-
- scale=look->ln/toBARK(22050.f);
-
- look->linearmap=_ogg_malloc(look->n*sizeof(int));
- for(j=0;j<look->n;j++){
- int val=floor( toBARK(22050.f/n*j) *scale);
- if(val>look->ln)val=look->ln;
- look->linearmap[j]=val;
- }
-}
+/****************************************************************/
int main(int argc,char *argv[]){
int eos=0;
@@ -210,11 +169,10 @@
signed char *buffer,*buffer2;
mdct_lookup m_look;
drft_lookup f_look;
+ drft_lookup f_look2;
vorbis_look_psy p_look;
long i,j,k;
- vorbis_look_floor0 floorlook;
-
int ath=0;
int decayp=0;
@@ -260,8 +218,8 @@
window=_vorbis_window(0,framesize,framesize/2,framesize/2);
mdct_init(&m_look,framesize);
drft_init(&f_look,framesize);
+ drft_init(&f_look2,framesize/2);
_vp_psy_init(&p_look,&_psy_set0,framesize/2,44100);
- floorinit(&floorlook,framesize/2,order,map);
for(i=0;i<P_BANDS;i++)
for(j=0;j<P_LEVELS;j++)
@@ -329,35 +287,43 @@
}
analysis("mask",frameno,flr,framesize/2,0,0);
-
- for(j=0;j<framesize/2;j++)
- mask[j]=flr[j]+140.;
- amp=sqrt(_curve_to_lpc(mask,mask,&floorlook));
- vorbis_lpc_to_lsp(mask,mask,floorlook.m);
- vorbis_lsp_to_curve(flr,floorlook.linearmap,floorlook.n,floorlook.ln,
- mask,floorlook.m,amp,140.);
+ mask[framesize-1]=0.;
+ mask[0]=0.;
+ for(j=1;j<framesize-1;j+=2){
+ mask[j]=todB(pcm[i]+((j+1)>>1));
+ mask[j+1]=0;
+ }
- analysis("floor",frameno,flr,framesize/2,0,1);
+ analysis("lfft",frameno,mask,framesize,0,0);
+ drft_backward(&f_look,mask);
- _vp_apply_floor(&p_look,pcm[i],flr);
+ analysis("cep",frameno,mask,framesize,0,0);
+ analysis("logcep",frameno,mask,framesize,0,1);
+
- analysis("quant",frameno,pcm[i],framesize/2,0,0);
+ /*for(j=0;j<framesize/2;j++){
+ float val=fromdB(flr[j]);
+ int p=rint(pcm[i][j]/val);
+ pcm[i][j]=p*val;
+ }*/
+
+ /*for(j=0;j<framesize/2;j++){
+ float val=todB(pcm[i]+j);
+ if(val+6.<flr[j])
+ pcm[i][j]=0.;
+ }*/
- /* re-add floor */
for(j=0;j<framesize/2;j++){
- float val=rint(pcm[i][j]);
- tot++;
- if(val){
- nonz++;
- acc+=log(fabs(val)*2.f+1.f)/log(2);
- pcm[i][j]=val*flr[j];
- }else{
- pcm[i][j]=0.f;
- }
+ float val=rint(todB(pcm[i]+j)/6);
+ if(pcm[i][j]>0)
+ pcm[i][j]=fromdB(val*6);
+ else
+ pcm[i][j]=-fromdB(val*6);
}
-
+
+
analysis("final",frameno,pcm[i],framesize/2,0,1);
/* take it back to time */
1.7 +5 -1 vorbis/lib/registry.c
Index: registry.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/registry.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- registry.c 2001/02/26 03:50:43 1.6
+++ registry.c 2001/05/27 06:44:00 1.7
@@ -11,7 +11,7 @@
********************************************************************
function: registry for time, floor, res backends and channel mappings
- last mod: $Id: registry.c,v 1.6 2001/02/26 03:50:43 xiphmont Exp $
+ last mod: $Id: registry.c,v 1.7 2001/05/27 06:44:00 xiphmont Exp $
********************************************************************/
@@ -24,7 +24,9 @@
extern vorbis_func_time time0_exportbundle;
extern vorbis_func_floor floor0_exportbundle;
+extern vorbis_func_floor floor1_exportbundle;
extern vorbis_func_residue residue0_exportbundle;
+extern vorbis_func_residue residue1_exportbundle;
extern vorbis_func_mapping mapping0_exportbundle;
vorbis_func_time *_time_P[]={
@@ -33,10 +35,12 @@
vorbis_func_floor *_floor_P[]={
&floor0_exportbundle,
+ &floor1_exportbundle,
};
vorbis_func_residue *_residue_P[]={
&residue0_exportbundle,
+ &residue1_exportbundle,
};
vorbis_func_mapping *_mapping_P[]={
1.6 +3 -3 vorbis/lib/registry.h
Index: registry.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/registry.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- registry.h 2001/02/26 03:50:43 1.5
+++ registry.h 2001/05/27 06:44:00 1.6
@@ -11,7 +11,7 @@
********************************************************************
function: registry for time, floor, res backends and channel mappings
- last mod: $Id: registry.h,v 1.5 2001/02/26 03:50:43 xiphmont Exp $
+ last mod: $Id: registry.h,v 1.6 2001/05/27 06:44:00 xiphmont Exp $
********************************************************************/
@@ -23,8 +23,8 @@
#define VI_TRANSFORMB 1
#define VI_WINDOWB 1
#define VI_TIMEB 1
-#define VI_FLOORB 1
-#define VI_RESB 1
+#define VI_FLOORB 2
+#define VI_RESB 2
#define VI_MAPB 1
extern vorbis_func_time *_time_P[];
1.27 +146 -24 vorbis/lib/res0.c
Index: res0.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/res0.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- res0.c 2001/02/26 03:50:43 1.26
+++ res0.c 2001/05/27 06:44:01 1.27
@@ -7,11 +7,11 @@
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
-
+ * *
********************************************************************
- function: residue backend 0 implementation
- last mod: $Id: res0.c,v 1.26 2001/02/26 03:50:43 xiphmont Exp $
+ function: residue backend 0 and 1 implementation
+ last mod: $Id: res0.c,v 1.27 2001/05/27 06:44:01 xiphmont Exp $
********************************************************************/
@@ -170,8 +170,8 @@
/* does not guard against invalid settings; eg, a subn of 16 and a
subgroup request of 32. Max subn of 128 */
-static int _testhack(float *vec,int n,vorbis_look_residue0 *look,
- int auxparts,int auxpartnum){
+static int _interleaved_testhack(float *vec,int n,vorbis_look_residue0 *look,
+ int auxparts,int auxpartnum){
vorbis_info_residue0 *info=look->info;
int i,j=0;
float max,localmax=0.f;
@@ -191,9 +191,9 @@
while(1){
entropy[j]=localmax;
n>>=1;
+ if(!n)break;
j++;
- if(n<=0)break;
for(i=0;i<n;i++){
temp[i]+=temp[i+n];
}
@@ -211,6 +211,71 @@
return(i);
}
+static int _testhack(float *vec,int n,vorbis_look_residue0 *look,
+ int auxparts,int auxpartnum){
+ vorbis_info_residue0 *info=look->info;
+ int i,j=0;
+ float max,localmax=0.f;
+ float temp[128];
+ float entropy[8];
+
+ /* setup */
+ for(i=0;i<n;i++)temp[i]=fabs(vec[i]);
+
+ /* handle case subgrp==1 outside */
+ for(i=0;i<n;i++)
+ if(temp[i]>localmax)localmax=temp[i];
+ max=localmax;
+
+ for(i=0;i<n;i++)temp[i]=rint(temp[i]);
+
+ while(n){
+ entropy[j]=localmax;
+ n>>=1;
+ j++;
+ if(!n)break;
+ for(i=0;i<n;i++){
+ temp[i]=temp[i*2]+temp[i*2+1];
+ }
+ localmax=0.f;
+ for(i=0;i<n;i++)
+ if(temp[i]>localmax)localmax=temp[i];
+ }
+
+ for(i=0;i<auxparts-1;i++)
+ if(auxpartnum<info->blimit[i] &&
+ entropy[info->subgrp[i]]<=info->entmax[i] &&
+ max<=info->ampmax[i])
+ break;
+
+ return(i);
+}
+
+static int _interleaved_encodepart(oggpack_buffer *opb,float *vec, int n,
+ int stages, codebook **books,int mode,
+ int part){
+ int i,j=0,bits=0;
+ if(stages){
+ int dim=books[j]->dim;
+ int step=n/dim;
+ for(i=0;i<step;i++){
+ int entry=vorbis_book_besterror(books[j],vec+i,step,0);
+#ifdef TRAIN_RESENT
+ {
+ char buf[80];
+ FILE *f;
+ sprintf(buf,"res0_%da%d_%d.vqd",mode,j,part);
+ f=fopen(buf,"a");
+ fprintf(f,"%d\n",entry);
+ fclose(f);
+ }
+#endif
+ bits+=vorbis_book_encode(books[j],entry,opb);
+ }
+ }
+ return(bits);
+}
+
static int _encodepart(oggpack_buffer *opb,float *vec, int n,
int stages, codebook **books,int mode,int part){
int i,j=0,bits=0;
@@ -218,7 +283,7 @@
int dim=books[j]->dim;
int step=n/dim;
for(i=0;i<step;i++){
- int entry=vorbis_book_besterror(books[j],vec+i,step,0);
+ int entry=vorbis_book_besterror(books[j],vec+i*dim,1,0);
#ifdef TRAIN_RESENT
{
char buf[80];
@@ -235,14 +300,15 @@
return(bits);
}
-static int _decodepart(oggpack_buffer *opb,float *work,float *vec, int n,
- int stages, codebook **books){
+/* doesn;t yet deal with cascading */
+static int _interleaved_decodepart(oggpack_buffer *opb,float *work,
+ float *vec, int n,
+ int stages, codebook **books){
int i;
memset(work,0,sizeof(float)*n);
if(stages){
- int dim=books[0]->dim;
- int step=n/dim;
+ int step=n/books[0]->dim;
if(s_vorbis_book_decodevs(books[0],work,opb,step,0)==-1)
return(-1);
}
@@ -253,8 +319,29 @@
return(0);
}
-int res0_forward(vorbis_block *vb,vorbis_look_residue *vl,
- float **in,int ch){
+static int _decodepart(oggpack_buffer *opb,float *work,
+ float *vec, int n,
+ int stages, codebook **books){
+ int i;
+
+ memset(work,0,sizeof(float)*n);
+ if(stages){
+ if(s_vorbis_book_decodev(books[0],work,opb,n,0)==-1)
+ return(-1);
+ }
+
+ for(i=0;i<n;i++)
+ vec[i]*=work[i];
+
+ return(0);
+}
+
+static int _01forward(vorbis_block *vb,vorbis_look_residue *vl,
+ float **in,int ch,
+ int (*classify)(float *,int,vorbis_look_residue0 *,
+ int,int),
+ int (*encode)(oggpack_buffer *,float *,int,int,
+ codebook **,int,int)){
long i,j,k,l;
vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
vorbis_info_residue0 *info=look->info;
@@ -288,12 +375,13 @@
for(i=info->begin,l=0;i<info->end;i+=samples_per_partition,l++){
for(j=0;j<ch;j++)
- /* do the partition decision based on the number of 'bits'
- needed to encode the block */
+ /* do the partition decision based on the 'entropy'
+ int the block */
partword[j][l]=
- _testhack(in[j]+i,samples_per_partition,look,possible_partitions,l);
+ classify(in[j]+i,samples_per_partition,look,possible_partitions,l);
}
+
/* we code the partition words for each channel, then the residual
words for a partition per channel until we've written all the
residual words for that partition word. Then write the next
@@ -312,9 +400,9 @@
for(k=0;k<partitions_per_word;k++,l++,i+=samples_per_partition)
for(j=0;j<ch;j++){
/*resbits[partword[j][l]]+=*/
- resbitsT+=_encodepart(&vb->opb,in[j]+i,samples_per_partition,
- info->secondstages[partword[j][l]],
- look->partbooks[partword[j][l]],look->map,partword[j][l]);
+ resbitsT+=encode(&vb->opb,in[j]+i,samples_per_partition,
+ info->secondstages[partword[j][l]],
+ look->partbooks[partword[j][l]],look->map,partword[j][l]);
resvals[partword[j][l]]+=samples_per_partition;
}
@@ -332,7 +420,10 @@
}
/* a truncated packet here just means 'stop working'; it's not an error */
-int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,float **in,int ch){
+static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl,
+ float **in,int ch,
+ int (*decodepart)(oggpack_buffer *,float *,float *,
+ int,int,codebook **)){
long i,j,k,l,transend=vb->pcmend/2;
vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
vorbis_info_residue0 *info=look->info;
@@ -361,13 +452,13 @@
if(partword[j]==NULL)goto errout;
}
- /* now we decode interleaved residual values for the partitions */
+ /* now we decode residual values for the partitions */
for(k=0;k<partitions_per_word;k++,l++,i+=samples_per_partition)
for(j=0;j<ch;j++){
int part=partword[j][k];
- if(_decodepart(&vb->opb,work,in[j]+i,samples_per_partition,
- info->secondstages[part],
- look->partbooks[part])==-1)goto eopbreak;
+ if(decodepart(&vb->opb,work,in[j]+i,samples_per_partition,
+ info->secondstages[part],
+ look->partbooks[part])==-1)goto eopbreak;
}
}
@@ -385,6 +476,26 @@
return(0);
}
+/* residue 0 and 1 are just slight variants of one another. 0 is
+ interleaved, 1 is not */
+int res0_forward(vorbis_block *vb,vorbis_look_residue *vl,
+ float **in,int ch){
+ return(_01forward(vb,vl,in,ch,_interleaved_testhack,_interleaved_encodepart));
+}
+
+int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,float **in,int ch){
+ return(_01inverse(vb,vl,in,ch,_interleaved_decodepart));
+}
+
+int res1_forward(vorbis_block *vb,vorbis_look_residue *vl,
+ float **in,int ch){
+ return(_01forward(vb,vl,in,ch,_testhack,_encodepart));
+}
+
+int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,float **in,int ch){
+ return(_01inverse(vb,vl,in,ch,_decodepart));
+}
+
vorbis_func_residue residue0_exportbundle={
&res0_pack,
&res0_unpack,
@@ -394,4 +505,15 @@
&res0_free_look,
&res0_forward,
&res0_inverse
+};
+
+vorbis_func_residue residue1_exportbundle={
+ &res0_pack,
+ &res0_unpack,
+ &res0_look,
+ &res0_copy_info,
+ &res0_free_info,
+ &res0_free_look,
+ &res1_forward,
+ &res1_inverse
};
1.16 +86 -5 vorbis/lib/scales.h
Index: scales.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/scales.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- scales.h 2001/02/26 03:50:43 1.15
+++ scales.h 2001/05/27 06:44:01 1.16
@@ -11,7 +11,7 @@
********************************************************************
function: linear scale -> dB, Bark and Mel scales
- last mod: $Id: scales.h,v 1.15 2001/02/26 03:50:43 xiphmont Exp $
+ last mod: $Id: scales.h,v 1.16 2001/05/27 06:44:01 xiphmont Exp $
********************************************************************/
@@ -22,10 +22,91 @@
#include "os.h"
/* 20log10(x) */
-#define DYNAMIC_RANGE_dB 200.f
-#define todB(x) ((x)==0?-400.f:log((x)*(x))*4.34294480f)
-#define todB_nn(x) ((x)==0.f?-400.f:log(x)*8.6858896f)
-#define fromdB(x) (exp((x)*.11512925f))
+#ifdef VORBIS_IEEE_FLOAT32
+static float todB_LOOKUP[256]={
+ -140.277330f, -139.633636f, -139.034372f, -138.473797f,
+ -137.450747f, -136.535597f, -135.707743f, -134.951972f,
+ -134.256730f, -133.613036f, -133.013772f, -132.453198f,
+ -131.430147f, -130.514997f, -129.687144f, -128.931372f,
+ -128.236130f, -127.592437f, -126.993172f, -126.432598f,
+ -125.409547f, -124.494397f, -123.666544f, -122.910772f,
+ -122.215530f, -121.571837f, -120.972572f, -120.411998f,
+ -119.388947f, -118.473797f, -117.645944f, -116.890173f,
+ -116.194930f, -115.551237f, -114.951972f, -114.391398f,
+ -113.368347f, -112.453198f, -111.625344f, -110.869573f,
+ -110.174331f, -109.530637f, -108.931372f, -108.370798f,
+ -107.347748f, -106.432598f, -105.604744f, -104.848973f,
+ -104.153731f, -103.510037f, -102.910773f, -102.350198f,
+ -101.327148f, -100.411998f, -99.584144f, -98.828373f,
+ -98.133131f, -97.489437f, -96.890173f, -96.329598f,
+ -95.306548f, -94.391398f, -93.563544f, -92.807773f,
+ -92.112531f, -91.468837f, -90.869573f, -90.308998f,
+ -89.285948f, -88.370798f, -87.542944f, -86.787173f,
+ -86.091931f, -85.448237f, -84.848973f, -84.288398f,
+ -83.265348f, -82.350198f, -81.522344f, -80.766573f,
+ -80.071331f, -79.427637f, -78.828373f, -78.267799f,
+ -77.244748f, -76.329598f, -75.501745f, -74.745973f,
+ -74.050731f, -73.407038f, -72.807773f, -72.247199f,
+ -71.224148f, -70.308998f, -69.481145f, -68.725373f,
+ -68.030131f, -67.386438f, -66.787173f, -66.226599f,
+ -65.203548f, -64.288399f, -63.460545f, -62.704774f,
+ -62.009531f, -61.365838f, -60.766573f, -60.205999f,
+ -59.182948f, -58.267799f, -57.439945f, -56.684174f,
+ -55.988932f, -55.345238f, -54.745973f, -54.185399f,
+ -53.162349f, -52.247199f, -51.419345f, -50.663574f,
+ -49.968332f, -49.324638f, -48.725374f, -48.164799f,
+ -47.141749f, -46.226599f, -45.398745f, -44.642974f,
+ -43.947732f, -43.304038f, -42.704774f, -42.144199f,
+ -41.121149f, -40.205999f, -39.378145f, -38.622374f,
+ -37.927132f, -37.283438f, -36.684174f, -36.123599f,
+ -35.100549f, -34.185399f, -33.357545f, -32.601774f,
+ -31.906532f, -31.262838f, -30.663574f, -30.102999f,
+ -29.079949f, -28.164799f, -27.336945f, -26.581174f,
+ -25.885932f, -25.242238f, -24.642974f, -24.082400f,
+ -23.059349f, -22.144199f, -21.316346f, -20.560574f,
+ -19.865332f, -19.221639f, -18.622374f, -18.061800f,
+ -17.038749f, -16.123599f, -15.295746f, -14.539974f,
+ -13.844732f, -13.201039f, -12.601774f, -12.041200f,
+ -11.018149f, -10.103000f, -9.275146f, -8.519375f,
+ -7.824132f, -7.180439f, -6.581174f, -6.020600f,
+ -4.997549f, -4.082400f, -3.254546f, -2.498775f,
+ -1.803533f, -1.159839f, -0.560574f, 0.000000f,
+ 1.023050f, 1.938200f, 2.766054f, 3.521825f,
+ 4.217067f, 4.860761f, 5.460025f, 6.020600f,
+ 7.043650f, 7.958800f, 8.786654f, 9.542425f,
+ 10.237667f, 10.881361f, 11.480625f, 12.041200f,
+ 13.064250f, 13.979400f, 14.807254f, 15.563025f,
+ 16.258267f, 16.901961f, 17.501225f, 18.061800f,
+ 19.084850f, 20.000000f, 20.827854f, 21.583625f,
+ 22.278867f, 22.922561f, 23.521825f, 24.082400f,
+ 25.105450f, 26.020600f, 26.848453f, 27.604225f,
+ 28.299467f, 28.943161f, 29.542425f, 30.102999f,
+ 31.126050f, 32.041200f, 32.869053f, 33.624825f,
+ 34.320067f, 34.963760f, 35.563025f, 36.123599f,
+ 37.146650f, 38.061800f, 38.889653f, 39.645424f,
+ 40.340667f, 40.984360f, 41.583625f, 42.144199f,
+ 43.167250f, 44.082399f, 44.910253f, 45.666024f,
+ 46.361266f, 47.004960f, 47.604225f, 48.164799f,
+ 49.187850f, 50.102999f, 50.930853f, 51.686624f
+};
+
+static float todB(const float *x){
+ ogg_int32_t *i=(ogg_int32_t *)x;
+ ogg_int32_t temp=((*i&0x7fffffff)-0x33cfffff)>>20;
+ if(temp<0)return -400.f;
+ return(todB_LOOKUP[temp]);
+}
+
+#define todB_nn(x) todB(x)
+
+#else
+
+#define todB(x) (*(x)==0?-400.f:log(*(x)**(x))*4.34294480f)
+#define todB_nn(x) (*(x)==0.f?-400.f:log(*(x))*8.6858896f)
+
+#endif
+
+#define fromdB(x) (exp((x)*.11512925f))
/* The bark scale equations are approximations, since the original
table was somewhat hand rolled. The below are chosen to have the
1.22 +29 -1 vorbis/lib/synthesis.c
Index: synthesis.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/synthesis.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- synthesis.c 2001/02/26 03:50:43 1.21
+++ synthesis.c 2001/05/27 06:44:01 1.22
@@ -11,7 +11,7 @@
********************************************************************
function: single-block PCM synthesis
- last mod: $Id: synthesis.c,v 1.21 2001/02/26 03:50:43 xiphmont Exp $
+ last mod: $Id: synthesis.c,v 1.22 2001/05/27 06:44:01 xiphmont Exp $
********************************************************************/
@@ -70,6 +70,34 @@
type=ci->map_type[ci->mode_param[mode]->mapping];
return(_mapping_P[type]->inverse(vb,b->mode[mode]));
+}
+
+long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
+ codec_setup_info *ci=vi->codec_setup;
+ oggpack_buffer opb;
+ int type,mode,i;
+
+ 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(OV_ENOTAUDIO);
+ }
+
+ {
+ int modebits=0;
+ int v=ci->modes;
+ while(v>1){
+ modebits++;
+ v>>=1;
+ }
+
+ /* read our mode and pre/post windowsize */
+ mode=oggpack_read(&opb,modebits);
+ }
+ if(mode==-1)return(OV_EBADPACKET);
+ return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
}
1.7 +3 -2 vorbis/lib/vorbisenc.c
Index: vorbisenc.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/vorbisenc.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- vorbisenc.c 2001/02/26 03:50:43 1.6
+++ vorbisenc.c 2001/05/27 06:44:01 1.7
@@ -11,7 +11,7 @@
********************************************************************
function: simple programmatic interface for encoder mode setup
- last mod: $Id: vorbisenc.c,v 1.6 2001/02/26 03:50:43 xiphmont Exp $
+ last mod: $Id: vorbisenc.c,v 1.7 2001/05/27 06:44:01 xiphmont Exp $
********************************************************************/
@@ -139,7 +139,8 @@
/* adjust for sample rate */
for(i=0;i<ci->floors;i++)
- ((vorbis_info_floor0 *)(ci->floor_param[i]))->rate=rate;
+ if(ci->floor_type[i]==0)
+ ((vorbis_info_floor0 *)(ci->floor_param[i]))->rate=rate;
/* adjust for channels; all our mappings use submap zero now */
/* yeah, OK, _ogg_calloc did this for us. But it's a reminder/placeholder */
1.45 +463 -215 vorbis/lib/vorbisfile.c
Index: vorbisfile.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/vorbisfile.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- vorbisfile.c 2001/03/27 07:04:51 1.44
+++ vorbisfile.c 2001/05/27 06:44:01 1.45
@@ -7,11 +7,11 @@
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
-
+ * *
********************************************************************
function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.c,v 1.44 2001/03/27 07:04:51 xiphmont Exp $
+ last mod: $Id: vorbisfile.c,v 1.45 2001/05/27 06:44:01 xiphmont Exp $
********************************************************************/
@@ -57,7 +57,8 @@
* grokking near the end of the file */
/* read a little more data from the file/pipe into the ogg_sync framer */
-#define CHUNKSIZE 4096
+#define CHUNKSIZE 8500 /* a shade over 8k; anyone using pages well
+ over 8k gets what they deserve */
static long _get_data(OggVorbis_File *vf){
errno=0;
if(vf->datasource){
@@ -233,6 +234,7 @@
if(serialno)*serialno=ogg_page_serialno(og_ptr);
ogg_stream_init(&vf->os,ogg_page_serialno(og_ptr));
+ vf->ready_state=STREAMSET;
/* extract the initial header from the first page and verify that the
Ogg bitstream is in fact Vorbis data */
@@ -279,24 +281,19 @@
able to open and use damaged bitstreams as well as we can. Just
watch out for missing information for links in the OggVorbis_File
struct */
-static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first_i,
- vorbis_comment *first_c,
- long dataoffset){
+static void _prefetch_all_headers(OggVorbis_File *vf, long dataoffset){
ogg_page og;
int i,ret;
- vf->vi=_ogg_calloc(vf->links,sizeof(vorbis_info));
- vf->vc=_ogg_calloc(vf->links,sizeof(vorbis_info));
+ vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(vorbis_info));
+ vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(vorbis_info));
vf->dataoffsets=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
vf->pcmlengths=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
vf->serialnos=_ogg_malloc(vf->links*sizeof(long));
for(i=0;i<vf->links;i++){
- if(first_i && first_c && i==0){
- /* we already grabbed the initial header earlier. This just
- saves the waste of grabbing it again */
- memcpy(vf->vi+i,first_i,sizeof(vorbis_info));
- memcpy(vf->vc+i,first_c,sizeof(vorbis_comment));
+ if(i==0){
+ /* we already grabbed the initial header earlier. Just set the offset */
vf->dataoffsets[i]=dataoffset;
}else{
@@ -320,7 +317,7 @@
while(1){
ret=_get_prev_page(vf,&og);
if(ret<0){
- /* this should not be possible, actually */
+ /* this should not be possible */
vorbis_info_clear(vf->vi+i);
vorbis_comment_clear(vf->vc+i);
break;
@@ -330,39 +327,32 @@
vf->pcmlengths[i]=ogg_page_granulepos(&og);
break;
}
+ vf->offset=ret;
}
}
}
}
static void _make_decode_ready(OggVorbis_File *vf){
- if(vf->decode_ready)return;
+ if(vf->ready_state!=STREAMSET)return;
if(vf->seekable){
vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
}else{
vorbis_synthesis_init(&vf->vd,vf->vi);
}
vorbis_block_init(&vf->vd,&vf->vb);
- vf->decode_ready=1;
+ vf->ready_state=INITSET;
return;
}
-static int _open_seekable(OggVorbis_File *vf){
- vorbis_info initial_i;
- vorbis_comment initial_c;
- long serialno,end;
- int ret;
- long dataoffset;
+static int _open_seekable2(OggVorbis_File *vf){
+ long serialno=vf->current_serialno,end;
+ long dataoffset=vf->offset;
ogg_page og;
-
- /* is this even vorbis...? */
- ret=_fetch_headers(vf,&initial_i,&initial_c,&serialno,NULL);
- dataoffset=vf->offset;
- ogg_stream_clear(&vf->os);
- if(ret<0)return(ret);
-
+
+ /* we're partially open and have a first link header state in
+ storage in vf */
/* we can seek, so set out learning all about this file */
- vf->seekable=1;
(vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
@@ -370,7 +360,7 @@
Most OggVorbis files will contain a single logical bitstream */
end=_get_prev_page(vf,&og);
if(end<0){
- ogg_stream_clear(&vf->os);
+ ov_clear(vf);
return(end);
}
@@ -380,7 +370,7 @@
/* Chained bitstream. Bisect-search each logical bitstream
section. Do so based on serial number only */
if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0){
- ogg_stream_clear(&vf->os);
+ ov_clear(vf);
return(OV_EREAD);
}
@@ -388,30 +378,15 @@
/* Only one logical bitstream */
if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0)){
- ogg_stream_clear(&vf->os);
+ ov_clear(vf);
return(OV_EREAD);
}
}
- _prefetch_all_headers(vf,&initial_i,&initial_c,dataoffset);
+ /* the initial header memory is referenced by vf after; don't free it */
+ _prefetch_all_headers(vf,dataoffset);
return(ov_raw_seek(vf,0));
-
-}
-
-static int _open_nonseekable(OggVorbis_File *vf){
- int ret;
- /* we cannot seek. Set up a 'single' (current) logical bitstream entry */
- vf->links=1;
- vf->vi=_ogg_calloc(vf->links,sizeof(vorbis_info));
- vf->vc=_ogg_calloc(vf->links,sizeof(vorbis_info));
-
- /* Try to fetch the headers, maintaining all the storage */
- if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0)
- return(ret);
- _make_decode_ready(vf);
-
- return 0;
}
/* clear out the current logical bitstream decoder */
@@ -419,7 +394,7 @@
ogg_stream_clear(&vf->os);
vorbis_dsp_clear(&vf->vd);
vorbis_block_clear(&vf->vb);
- vf->decode_ready=0;
+ vf->ready_state=OPENED;
vf->bittrack=0.f;
vf->samptrack=0.f;
@@ -445,11 +420,11 @@
/* process a packet if we can. If the machine isn't loaded,
neither is a page */
- if(vf->decode_ready){
+ if(vf->ready_state==INITSET){
ogg_packet op;
int result=ogg_stream_packetout(&vf->os,&op);
ogg_int64_t granulepos;
-
+
if(result==-1)return(OV_HOLE); /* hole in the data. */
if(result>0){
/* got a packet. process it */
@@ -499,18 +474,26 @@
}
}
}
-
- if(!readp)return(0);
- if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof. leave unitialized */
- /* bitrate tracking; add the header's bytes here, the body bytes
- are done by packet above */
- vf->bittrack+=og.header_len*8;
-
- /* has our decoding just traversed a bitstream boundary? */
- if(vf->decode_ready){
- if(vf->current_serialno!=ogg_page_serialno(&og)){
- _decode_clear(vf);
+ if(vf->ready_state>=STREAMSET){
+ if(!readp)return(0);
+ if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof.
+ leave unitialized */
+
+ /* bitrate tracking; add the header's bytes here, the body bytes
+ are done by packet above */
+ vf->bittrack+=og.header_len*8;
+
+ /* has our decoding just traversed a bitstream boundary? */
+ if(vf->ready_state==INITSET){
+ if(vf->current_serialno!=ogg_page_serialno(&og)){
+ _decode_clear(vf);
+
+ if(!vf->seekable){
+ vorbis_info_clear(vf->vi);
+ vorbis_comment_clear(vf->vc);
+ }
+ }
}
}
@@ -526,33 +509,37 @@
we're now nominally at the header of the next bitstream
*/
- if(!vf->decode_ready){
+ if(vf->ready_state!=INITSET){
int link;
- if(vf->seekable){
- vf->current_serialno=ogg_page_serialno(&og);
-
- /* match the serialno to bitstream section. We use this rather than
- offset positions to avoid problems near logical bitstream
- boundaries */
- for(link=0;link<vf->links;link++)
- if(vf->serialnos[link]==vf->current_serialno)break;
- if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
- stream. error out,
- leave machine
- uninitialized */
-
- vf->current_link=link;
-
- ogg_stream_init(&vf->os,vf->current_serialno);
- ogg_stream_reset(&vf->os);
-
- }else{
- /* we're streaming */
- /* fetch the three header packets, build the info struct */
-
- _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
- vf->current_link++;
- link=0;
+
+ if(vf->ready_state<STREAMSET){
+ if(vf->seekable){
+ vf->current_serialno=ogg_page_serialno(&og);
+
+ /* match the serialno to bitstream section. We use this rather than
+ offset positions to avoid problems near logical bitstream
+ boundaries */
+ for(link=0;link<vf->links;link++)
+ if(vf->serialnos[link]==vf->current_serialno)break;
+ if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
+ stream. error out,
+ leave machine
+ uninitialized */
+
+ vf->current_link=link;
+
+ ogg_stream_init(&vf->os,vf->current_serialno);
+ ogg_stream_reset(&vf->os);
+ vf->ready_state=STREAMSET;
+
+ }else{
+ /* we're streaming */
+ /* fetch the three header packets, build the info struct */
+
+ _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
+ vf->current_link++;
+ link=0;
+ }
}
_make_decode_ready(vf);
@@ -561,9 +548,65 @@
}
}
-/**********************************************************************
- * The helpers are over; it's all toplevel interface from here on out */
-
+static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
+ if(f==NULL)return(-1);
+ return fseek(f,(int)off,whence);
+}
+
+static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
+ long ibytes, ov_callbacks callbacks){
+ long offset=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
+ int ret;
+
+ memset(vf,0,sizeof(OggVorbis_File));
+ vf->datasource=f;
+ vf->callbacks = callbacks;
+
+ /* init the framing state */
+ ogg_sync_init(&vf->oy);
+
+ /* perhaps some data was previously read into a buffer for testing
+ against other stream types. Allow initialization from this
+ previously read data (as we may be reading from a non-seekable
+ stream) */
+ if(initial){
+ char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
+ memcpy(buffer,initial,ibytes);
+ ogg_sync_wrote(&vf->oy,ibytes);
+ }
+
+ /* can we seek? Stevens suggests the seek test was portable */
+ if(offset!=-1)vf->seekable=1;
+
+ /* No seeking yet; Set up a 'single' (current) logical bitstream
+ entry for partial open */
+ vf->links=1;
+ vf->vi=_ogg_calloc(vf->links,sizeof(vorbis_info));
+ vf->vc=_ogg_calloc(vf->links,sizeof(vorbis_info));
+
+ /* Try to fetch the headers, maintaining all the storage */
+ if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
+ vf->datasource=NULL;
+ ov_clear(vf);
+ }else
+ vf->ready_state=PARTOPEN;
+ return(ret);
+}
+
+static int _ov_open2(OggVorbis_File *vf){
+ vf->ready_state=OPENED;
+ if(vf->seekable){
+ int ret=_open_seekable2(vf);
+ if(ret){
+ vf->datasource=NULL;
+ ov_clear(vf);
+ }
+ return(ret);
+ }
+ return 0;
+}
+
+
/* clear out the OggVorbis_File struct */
int ov_clear(OggVorbis_File *vf){
if(vf){
@@ -594,11 +637,6 @@
return(0);
}
-static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
- if(f==NULL)return(-1);
- return fseek(f,(int)off,whence);
-}
-
/* inspects the OggVorbis file and finds/documents all the logical
bitstreams contained in it. Tries to be tolerant of logical
bitstream sections that are truncated/woogie.
@@ -607,6 +645,13 @@
0) OK
*/
+int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
+ ov_callbacks callbacks){
+ int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
+ if(ret)return ret;
+ return _ov_open2(vf);
+}
+
int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
ov_callbacks callbacks = {
(size_t (*)(void *, size_t, size_t, void *)) fread,
@@ -618,42 +663,32 @@
return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
}
+/* Only partially open the vorbis file; test for Vorbisness, and load
+ the headers for the first chain. Do not seek (although test for
+ seekability). Use ov_test_open to finish opening the file, else
+ ov_clear to close/free it. Same return codes as open. */
-int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
+int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
ov_callbacks callbacks)
{
- long offset=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
- int ret;
-
- memset(vf,0,sizeof(OggVorbis_File));
- vf->datasource=f;
- vf->callbacks = callbacks;
-
- /* init the framing state */
- ogg_sync_init(&vf->oy);
+ return _ov_open1(f,vf,initial,ibytes,callbacks);
+}
- /* perhaps some data was previously read into a buffer for testing
- against other stream types. Allow initialization from this
- previously read data (as we may be reading from a non-seekable
- stream) */
- if(initial){
- char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
- memcpy(buffer,initial,ibytes);
- ogg_sync_wrote(&vf->oy,ibytes);
- }
+int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
+ ov_callbacks callbacks = {
+ (size_t (*)(void *, size_t, size_t, void *)) fread,
+ (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
+ (int (*)(void *)) fclose,
+ (long (*)(void *)) ftell
+ };
- /* can we seek? Stevens suggests the seek test was portable */
- if(offset!=-1){
- ret=_open_seekable(vf);
- }else{
- ret=_open_nonseekable(vf);
- }
- if(ret){
- vf->datasource=NULL;
- ov_clear(vf);
- }
- return(ret);
+ return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
}
+
+int ov_test_open(OggVorbis_File *vf){
+ if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
+ return _ov_open2(vf);
+}
/* How many logical bitstreams in this physical bitstream? */
long ov_streams(OggVorbis_File *vf){
@@ -675,6 +710,7 @@
vorbis_info structs */
long ov_bitrate(OggVorbis_File *vf,int i){
+ if(vf->ready_state<OPENED)return(OV_EINVAL);
if(i>=vf->links)return(OV_EINVAL);
if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
if(i<0){
@@ -706,10 +742,13 @@
}
/* returns the actual bitrate since last call. returns -1 if no
- additional data to offer since last call (or at beginning of stream) */
+ additional data to offer since last call (or at beginning of stream),
+ EINVAL if stream is only partially open
+*/
long ov_bitrate_instant(OggVorbis_File *vf){
int link=(vf->seekable?vf->current_link:0);
long ret;
+ if(vf->ready_state<OPENED)return(OV_EINVAL);
if(vf->samptrack==0)return(OV_FALSE);
ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
vf->bittrack=0.f;
@@ -730,9 +769,11 @@
/* returns: total raw (compressed) length of content if i==-1
raw (compressed) length of that logical bitstream for i==0 to n
- -1 if the stream is not seekable (we can't know the length)
+ OV_EINVAL if the stream is not seekable (we can't know the length)
+ or if stream is only partially open
*/
ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
+ if(vf->ready_state<OPENED)return(OV_EINVAL);
if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
if(i<0){
long acc=0;
@@ -745,11 +786,13 @@
}
}
-/* returns: total PCM length (samples) of content if i==-1
- PCM length (samples) of that logical bitstream for i==0 to n
- -1 if the stream is not seekable (we can't know the length)
+/* returns: total PCM length (samples) of content if i==-1 PCM length
+ (samples) of that logical bitstream for i==0 to n
+ OV_EINVAL if the stream is not seekable (we can't know the
+ length) or only partially open
*/
ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
+ if(vf->ready_state<OPENED)return(OV_EINVAL);
if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
if(i<0){
ogg_int64_t acc=0;
@@ -764,9 +807,11 @@
/* returns: total seconds of content if i==-1
seconds in that logical bitstream for i==0 to n
- -1 if the stream is not seekable (we can't know the length)
+ OV_EINVAL if the stream is not seekable (we can't know the
+ length) or only partially open
*/
double ov_time_total(OggVorbis_File *vf,int i){
+ if(vf->ready_state<OPENED)return(OV_EINVAL);
if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
if(i<0){
double acc=0;
@@ -780,69 +825,132 @@
}
/* seek to an offset relative to the *compressed* data. This also
- immediately sucks in and decodes pages to update the PCM cursor. It
- will cross a logical bitstream boundary, but only if it can't get
- any packets out of the tail of the bitstream we seek to (so no
- surprises).
+ scans packets to update the PCM cursor. It will cross a logical
+ bitstream boundary, but only if it can't get any packets out of the
+ tail of the bitstream we seek to (so no surprises).
returns zero on success, nonzero on failure */
int ov_raw_seek(OggVorbis_File *vf,long pos){
- int flag=0;
- if(!vf->seekable)return(OV_ENOSEEK); /* don't dump machine if we can't seek */
+ ogg_stream_state work_os;
+
+ if(vf->ready_state<OPENED)return(OV_EINVAL);
+ if(!vf->seekable)
+ return(OV_ENOSEEK); /* don't dump machine if we can't seek */
+
if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
/* clear out decoding machine state */
vf->pcm_offset=-1;
_decode_clear(vf);
- /* seek */
_seek_helper(vf,pos);
- /* we need to make sure the pcm_offset is set. We use the
- _fetch_packet helper to process one packet with readp set, then
- call it until it returns '0' with readp not set (the last packet
- from a page has the 'granulepos' field set, and that's how the
- helper updates the offset */
-
- while(!flag){
- switch(_process_packet(vf,1)){
- case 0:case OV_EOF:
- /* oh, eof. There are no packets remaining. Set the pcm offset to
- the end of file */
- vf->pcm_offset=ov_pcm_total(vf,-1);
- return(0);
- case OV_HOLE:
- break;
- case OV_EBADLINK:
- goto seek_error;
- default:
- /* all OK */
- flag=1;
- break;
- }
- }
-
- while(1){
- /* don't have to check each time through for the updated granule;
- it's always the last complete packet on a page */
- switch(_process_packet(vf,0)){
- case 0:case OV_EOF:
- /* the offset is set unless it's a bogus bitstream with no
- offset information but that's not our fault. We still run
- gracefully, we're just missing the offset */
- return(0);
- case OV_EBADLINK:
- goto seek_error;
- default:
- /* continue processing packets */
- break;
+ /* we need to make sure the pcm_offset is set, but we don't want to
+ advance the raw cursor past good packets just to get to the first
+ with a granulepos. That's not equivalent behavior to beginning
+ decoding as immediately after the seek position as possible.
+
+ So, a hack. We use two stream states; a local scratch state and
+ a the shared vf->os stream state. We use the local state to
+ scan, and the shared state as a buffer for later decode.
+
+ Unfortuantely, on the last page we still advance to last packet
+ because the granulepos on the last page is not necessarily on a
+ packet boundary, and we need to make sure the granpos is
+ correct.
+ */
+
+ {
+ ogg_page og;
+ ogg_packet op;
+ int lastblock=0;
+ int accblock=0;
+ int thisblock;
+ int eosflag;
+
+ memset(&work_os,0,sizeof(work_os));/* so that it's safe to clear
+ it later even if we don't
+ init it */
+
+ while(1){
+ if(vf->ready_state==STREAMSET){
+ /* snarf/scan a packet if we can */
+ int result=ogg_stream_packetout(&work_os,&op);
+
+ if(result>0){
+
+ if(vf->vi[vf->current_link].codec_setup)
+ thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
+ if(eosflag)
+ ogg_stream_packetout(&vf->os,NULL);
+ else
+ if(lastblock)accblock+=(lastblock+thisblock)>>2;
+
+ if(op.granulepos!=-1){
+ int i,link=vf->current_link;
+ ogg_int64_t granulepos=op.granulepos;
+
+ for(i=0;i<link;i++)
+ granulepos+=vf->pcmlengths[i];
+ vf->pcm_offset=granulepos-accblock;
+ break;
+ }
+ lastblock=thisblock;
+ continue;
+ }
+ }
+
+ if(!lastblock){
+ if(_get_next_page(vf,&og,-1)<0){
+ vf->pcm_offset=ov_pcm_total(vf,-1);
+ break;
+ }
+ }else{
+ /* huh? Bogus stream with packets but no granulepos */
+ vf->pcm_offset=-1;
+ break;
+ }
+
+ /* has our decoding just traversed a bitstream boundary? */
+ if(vf->ready_state==STREAMSET)
+ if(vf->current_serialno!=ogg_page_serialno(&og)){
+ _decode_clear(vf); /* clear out stream state */
+ ogg_stream_clear(&work_os);
+ }
+
+ if(vf->ready_state<STREAMSET){
+ int link;
+
+ vf->current_serialno=ogg_page_serialno(&og);
+ for(link=0;link<vf->links;link++)
+ if(vf->serialnos[link]==vf->current_serialno)break;
+ if(link==vf->links)goto seek_error; /* sign of a bogus stream.
+ error out, leave
+ machine uninitialized */
+ vf->current_link=link;
+
+ ogg_stream_init(&vf->os,vf->current_serialno);
+ ogg_stream_reset(&vf->os);
+ ogg_stream_init(&work_os,vf->current_serialno);
+ ogg_stream_reset(&work_os);
+ vf->ready_state=STREAMSET;
+
+ }
+
+ ogg_stream_pagein(&vf->os,&og);
+ ogg_stream_pagein(&work_os,&og);
+ eosflag=ogg_page_eos(&og);
}
}
-
+
+ ogg_stream_clear(&work_os);
+ return(0);
+
seek_error:
/* dump the machine so we're in a known state */
vf->pcm_offset=-1;
+ ogg_stream_clear(&work_os);
_decode_clear(vf);
return OV_EBADLINK;
}
@@ -858,9 +966,10 @@
long ret;
ogg_int64_t total=ov_pcm_total(vf,-1);
+ if(vf->ready_state<OPENED)return(OV_EINVAL);
if(!vf->seekable)return(OV_ENOSEEK);
if(pos<0 || pos>total)return(OV_EINVAL);
-
+
/* which bitstream section does this pcm offset occur in? */
for(link=vf->links-1;link>=0;link--){
total-=vf->pcmlengths[link];
@@ -872,46 +981,117 @@
missing pages or incorrect frame number information in the
bitstream could make our task impossible. Account for that (it
would be an error condition) */
+
+ /* new search algorithm by HB (Nicholas Vinen) */
{
ogg_int64_t target=pos-total;
long end=vf->offsets[link+1];
long begin=vf->offsets[link];
+ ogg_int64_t endtime = vf->pcmlengths[link];
+ ogg_int64_t begintime = 0;
long best=begin;
-
+
ogg_page og;
while(begin<end){
long bisect;
-
+
if(end-begin<CHUNKSIZE){
bisect=begin;
}else{
- bisect=(end+begin)/2;
+ /* take a (pretty decent) guess. */
+ bisect=begin +
+ (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
+ if(bisect<=begin)
+ bisect=begin+1;
}
-
_seek_helper(vf,bisect);
- ret=_get_next_page(vf,&og,end-bisect);
- switch(ret){
- case OV_FALSE: case OV_EOF:
- end=bisect;
- break;
- case OV_EREAD:
- goto seek_error;
- default:
- {
+
+ while(begin<end){
+ ret=_get_next_page(vf,&og,end-bisect);
+ if(ret==OV_EREAD) goto seek_error;
+ if(ret<0){
+ if(bisect<=begin+1)
+ end=begin; /* found it */
+ else{
+ if(bisect==0)goto seek_error;
+ bisect-=CHUNKSIZE;
+ if(bisect<=begin)bisect=begin+1;
+ _seek_helper(vf,bisect);
+ }
+ }else{
ogg_int64_t granulepos=ogg_page_granulepos(&og);
if(granulepos<target){
best=ret; /* raw offset of packet with granulepos */
- begin=vf->offset; /* raw offset of next packet */
+ begin=vf->offset; /* raw offset of next page */
+ begintime=granulepos;
+
+ if(target-begin>44100)break;
+ bisect=begin; /* *not* begin + 1 */
}else{
- end=bisect;
+ if(bisect<=begin+1)
+ end=begin; /* found it */
+ else{
+ if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
+ end=ret;
+ bisect-=CHUNKSIZE; /* an endless loop otherwise. */
+ if(bisect<=begin)bisect=begin+1;
+ _seek_helper(vf,bisect);
+ }else{
+ end=ret;
+ endtime=granulepos;
+ break;
+ }
+ }
}
}
}
}
- /* found our page. seek to it (call raw_seek). */
-
- if((ret=ov_raw_seek(vf,best)))goto seek_error;
+ /* found our page. seek to it, update pcm offset. Easier case than
+ raw_seek, don't keep packets preceeding granulepos. */
+ {
+ ogg_page og;
+ ogg_packet op;
+ /* clear out decoding machine state */
+ _decode_clear(vf);
+ /* seek */
+ _seek_helper(vf,best);
+
+ if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
+ vf->current_serialno=ogg_page_serialno(&og);
+ vf->current_link=link;
+
+ ogg_stream_init(&vf->os,vf->current_serialno);
+ ogg_stream_reset(&vf->os);
+ vf->ready_state=STREAMSET;
+ ogg_stream_pagein(&vf->os,&og);
+
+ /* pull out all but last packet; the one with granulepos */
+ while(1){
+ ret=ogg_stream_packetpeek(&vf->os,&op);
+ if(ret==0){
+ /* !!! the packet finishing this page originated on a
+ preceeding page. Keep fetching previous pages until we
+ get one with a granulepos or without the 'continued' flag
+ set. Then just use raw_seek for simplicity. */
+ while(1){
+ ret=_get_prev_page(vf,&og);
+ if(ret<0)goto seek_error;
+ if(ogg_page_granulepos(&og)>-1 ||
+ !ogg_page_continued(&og)){
+ return ov_raw_seek(vf,ret);
+ }
+ vf->offset=ret;
+ }
+ }
+ if(ret<0)goto seek_error;
+ if(op.granulepos!=-1 && !op.e_o_s){
+ vf->pcm_offset=op.granulepos+total;
+ break;
+ }else
+ ret=ogg_stream_packetout(&vf->os,NULL);
+ }
+ }
}
/* verify result */
@@ -932,11 +1112,71 @@
returns zero on success, nonzero on failure */
int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
+ int thisblock,lastblock=0,blockacc=0;
int ret=ov_pcm_seek_page(vf,pos);
if(ret<0)return(ret);
-
+
+ /* discard leading packets we don't need for the lapping of the
+ position we want; don't decode them */
+#if 0
+ while(1){
+ ogg_packet op;
+ ogg_page og;
+
+ int ret=ogg_stream_packetpeek(&vf->os,&op);
+ if(ret>0){
+ thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
+
+ if(blockacc+
+ ((lastblock+thisblock)>>2)+
+ (thisblock>>1)+vf->pcm_offset>pos)break;
+
+ ogg_stream_packetout(&vf->os,NULL);
+ /* end of logical stream case is hard, especially with exact
+ length positioning. */
+
+ if(op.granulepos>-1){
+ int i;
+ /* always believe the stream markers */
+ vf->pcm_offset=op.granulepos;
+ for(i=0;i<vf->current_link;i++)
+ vf->pcm_offset+=vf->pcmlengths[i];
+ blockacc=0;
+ }else
+ if(lastblock)blockacc+=(lastblock+thisblock)>>2;
+
+ lastblock=thisblock;
+ }else{
+ if(ret<0 && ret!=OV_HOLE)break;
+
+ /* suck in a new page */
+ if(_get_next_page(vf,&og,-1)<0)break;
+ if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
+
+ if(vf->ready_state<STREAMSET){
+ int link;
+
+ vf->current_serialno=ogg_page_serialno(&og);
+ for(link=0;link<vf->links;link++)
+ if(vf->serialnos[link]==vf->current_serialno)break;
+ if(link==vf->links)return(OV_EBADLINK);
+ vf->current_link=link;
+
+ ogg_stream_init(&vf->os,vf->current_serialno);
+ ogg_stream_reset(&vf->os);
+ vf->ready_state=STREAMSET;
+ lastblock=0;
+ }
+ ogg_stream_pagein(&vf->os,&og);
+ }
+ }
+
+ if(lastblock)vf->pcm_offset+=blockacc;
+#endif
+
/* discard samples until we reach the desired position. Crossing a
logical bitstream boundary with abandon is OK. */
+ _make_decode_ready(vf);
while(vf->pcm_offset<pos){
float **pcm;
long target=pos-vf->pcm_offset;
@@ -947,7 +1187,7 @@
vf->pcm_offset+=samples;
if(samples<target)
- if(_process_packet(vf,1)==0)
+ if(_process_packet(vf,1)<=0)
vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
}
return 0;
@@ -962,6 +1202,7 @@
ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
double time_total=ov_time_total(vf,-1);
+ if(vf->ready_state<OPENED)return(OV_EINVAL);
if(!vf->seekable)return(OV_ENOSEEK);
if(seconds<0 || seconds>time_total)return(OV_EINVAL);
@@ -988,6 +1229,7 @@
ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
double time_total=ov_time_total(vf,-1);
+ if(vf->ready_state<OPENED)return(OV_EINVAL);
if(!vf->seekable)return(OV_ENOSEEK);
if(seconds<0 || seconds>time_total)return(OV_EINVAL);
@@ -1008,11 +1250,13 @@
/* tell the current stream offset cursor. Note that seek followed by
tell will likely not give the set offset due to caching */
ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
+ if(vf->ready_state<OPENED)return(OV_EINVAL);
return(vf->offset);
}
/* return PCM offset (sample) of next PCM sample to be read */
ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
+ if(vf->ready_state<OPENED)return(OV_EINVAL);
return(vf->pcm_offset);
}
@@ -1024,6 +1268,7 @@
ogg_int64_t pcm_total=0;
double time_total=0.f;
+ if(vf->ready_state<OPENED)return(OV_EINVAL);
if(vf->seekable){
pcm_total=ov_pcm_total(vf,-1);
time_total=ov_time_total(vf,-1);
@@ -1050,20 +1295,17 @@
vorbis_info *ov_info(OggVorbis_File *vf,int link){
if(vf->seekable){
if(link<0)
- if(vf->decode_ready)
+ if(vf->ready_state>=STREAMSET)
return vf->vi+vf->current_link;
else
- return NULL;
+ return vf->vi;
else
if(link>=vf->links)
return NULL;
else
return vf->vi+link;
}else{
- if(vf->decode_ready)
- return vf->vi;
- else
- return NULL;
+ return vf->vi;
}
}
@@ -1071,20 +1313,17 @@
vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
if(vf->seekable){
if(link<0)
- if(vf->decode_ready)
+ if(vf->ready_state>=STREAMSET)
return vf->vc+vf->current_link;
else
- return NULL;
+ return vf->vc;
else
if(link>=vf->links)
return NULL;
else
return vf->vc+link;
}else{
- if(vf->decode_ready)
- return vf->vc;
- else
- return NULL;
+ return vf->vc;
}
}
@@ -1117,7 +1356,7 @@
word) word size for output. currently 1 (byte) or
2 (16 bit short)
- return values: <0) error/hole in data (OV_HOLE)
+ return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
0) EOF
n) number of bytes of PCM actually returned. The
below works on a packet-by-packet basis, so the
@@ -1131,8 +1370,17 @@
int i,j;
int host_endian = host_is_big_endian();
+ if(vf->ready_state<OPENED)return(OV_EINVAL);
+ if(vf->ready_state==OPENED)return(OV_EOF); /* stream is always
+ initialized after
+ other calls (after
+ open)... unless there
+ was no page at the end
+ to initialize state
+ with. */
+
while(1){
- if(vf->decode_ready){
+ if(vf->ready_state>=STREAMSET){
float **pcm;
long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
if(samples){
1.2 +1107 -0 vorbis/lib/floor1.c
1.15 +3 -4 vorbis/lib/modes/mode_A.h
Index: mode_A.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/modes/mode_A.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- mode_A.h 2001/02/26 03:51:10 1.14
+++ mode_A.h 2001/05/27 06:44:05 1.15
@@ -11,7 +11,7 @@
********************************************************************
function: predefined encoding modes
- last mod: $Id: mode_A.h,v 1.14 2001/02/26 03:51:10 xiphmont Exp $
+ last mod: $Id: mode_A.h,v 1.15 2001/05/27 06:44:05 xiphmont Exp $
********************************************************************/
@@ -109,6 +109,7 @@
.5f, /* high window */
5,
5,
+ 10,
{.000f, 0.f,/*63*/
.000f, 0.f,/*88*/
.000f, 0.f,/*125*/
@@ -132,7 +133,6 @@
tight loop) */
-22.,
- -0., -.004 /* attack/decay control */
};
static vorbis_info_psy _psy_set_A={
@@ -199,6 +199,7 @@
.5f, /* high window */
25,
25,
+ 50,
{.000f, 0.f, /*63*/
.000f, 0.f, /*88*/
.000f, 0.f, /*125*/
@@ -221,8 +222,6 @@
95.f, /* even decade + 5 is important; saves an rint() later in a
tight loop) */
-28.,
-
- -0.f, -.004f, /* attack/decay control */
};
1.11 +3 -5 vorbis/lib/modes/mode_AA.h
Index: mode_AA.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/modes/mode_AA.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- mode_AA.h 2001/02/26 03:51:10 1.10
+++ mode_AA.h 2001/05/27 06:44:05 1.11
@@ -11,7 +11,7 @@
********************************************************************
function: predefined encoding modes
- last mod: $Id: mode_AA.h,v 1.10 2001/02/26 03:51:10 xiphmont Exp $
+ last mod: $Id: mode_AA.h,v 1.11 2001/05/27 06:44:05 xiphmont Exp $
********************************************************************/
@@ -109,6 +109,7 @@
.5f, /* high window */
5,
5,
+ 10,
{.000f, 0.f,/*63*/
.000f, 0.f,/*88*/
.000f, 0.f,/*125*/
@@ -131,8 +132,6 @@
95.f, /* even decade + 5 is important; saves an rint() later in a
tight loop) */
-22.,
-
- -0., -.004 /* attack/decay control */
};
static vorbis_info_psy _psy_set_AA={
@@ -199,6 +198,7 @@
.7f, /* high window */
25,
25,
+ 50,
{.000f, 0.f, /*63*/
.000f, 0.f, /*88*/
.000f, 0.f, /*125*/
@@ -221,8 +221,6 @@
95.f, /* even decade + 5 is important; saves an rint() later in a
tight loop) */
-22.,
-
- -0.f, -.004f, /* attack/decay control */
};
1.14 +3 -5 vorbis/lib/modes/mode_B.h
Index: mode_B.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/modes/mode_B.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- mode_B.h 2001/02/26 03:51:10 1.13
+++ mode_B.h 2001/05/27 06:44:05 1.14
@@ -11,7 +11,7 @@
********************************************************************
function: predefined encoding modes
- last mod: $Id: mode_B.h,v 1.13 2001/02/26 03:51:10 xiphmont Exp $
+ last mod: $Id: mode_B.h,v 1.14 2001/05/27 06:44:05 xiphmont Exp $
********************************************************************/
@@ -109,6 +109,7 @@
.5f, /* high window */
5,
5,
+ 10,
{.000f, 0.f,/*63*/
.000f, 0.f,/*88*/
.000f, 0.f,/*125*/
@@ -131,8 +132,6 @@
95.f, /* even decade + 5 is important; saves an rint() later in a
tight loop) */
-26.,
-
- -0., -.004 /* attack/decay control */
};
static vorbis_info_psy _psy_set_B={
@@ -199,6 +198,7 @@
.5f, /* high window */
25,
25,
+ 40,
{.000f, 0.f, /*63*/
.000f, 0.f, /*88*/
.000f, 0.f, /*125*/
@@ -221,8 +221,6 @@
105.f, /* even decade + 5 is important; saves an rint() later in a
tight loop) */
-30.,
-
- -0.f, -.004f, /* attack/decay control */
};
1.13 +3 -5 vorbis/lib/modes/mode_C.h
Index: mode_C.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/modes/mode_C.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- mode_C.h 2001/02/26 03:51:10 1.12
+++ mode_C.h 2001/05/27 06:44:05 1.13
@@ -11,7 +11,7 @@
********************************************************************
function: predefined encoding modes
- last mod: $Id: mode_C.h,v 1.12 2001/02/26 03:51:10 xiphmont Exp $
+ last mod: $Id: mode_C.h,v 1.13 2001/05/27 06:44:05 xiphmont Exp $
********************************************************************/
@@ -109,6 +109,7 @@
.5f, /* high window */
5,
5,
+ 10,
{.000f, 0.f,/*63*/
.000f, 0.f,/*88*/
.000f, 0.f,/*125*/
@@ -131,8 +132,6 @@
105.f, /* even decade + 5 is important; saves an rint() later in a
tight loop) */
-26.,
-
- -0., -.004 /* attack/decay control */
};
static vorbis_info_psy _psy_set_C={
@@ -199,6 +198,7 @@
.5f, /* high window */
25,
25,
+ 40,
{.000f, 0.f, /*63*/
.000f, 0.f, /*88*/
.000f, 0.f, /*125*/
@@ -221,8 +221,6 @@
105.f, /* even decade + 5 is important; saves an rint() later in a
tight loop) */
-32.,
-
- -0.f, -.004f, /* attack/decay control */
};
1.14 +3 -5 vorbis/lib/modes/mode_D.h
Index: mode_D.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/modes/mode_D.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- mode_D.h 2001/02/26 03:51:10 1.13
+++ mode_D.h 2001/05/27 06:44:05 1.14
@@ -11,7 +11,7 @@
********************************************************************
function: predefined encoding modes
- last mod: $Id: mode_D.h,v 1.13 2001/02/26 03:51:10 xiphmont Exp $
+ last mod: $Id: mode_D.h,v 1.14 2001/05/27 06:44:05 xiphmont Exp $
********************************************************************/
@@ -107,6 +107,7 @@
.5f, /* high window */
5,
5,
+ 10,
{.000f, 0.f,/*63*/
.000f, 0.f,/*88*/
.000f, 0.f,/*125*/
@@ -129,8 +130,6 @@
105.f, /* even decade + 5 is important; saves an rint() later in a
tight loop) */
-28.,
-
- -0., -.004 /* attack/decay control */
};
static vorbis_info_psy _psy_set_D={
@@ -197,6 +196,7 @@
.5f, /* high window */
25,
25,
+ 40,
{.000f, 0.f, /*63*/
.000f, 0.f, /*88*/
.000f, 0.f, /*125*/
@@ -219,8 +219,6 @@
105.f, /* even decade + 5 is important; saves an rint() later in a
tight loop) */
-32.,
-
- -0.f, -.004f, /* attack/decay control */
};
1.13 +3 -5 vorbis/lib/modes/mode_E.h
Index: mode_E.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/modes/mode_E.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- mode_E.h 2001/02/26 03:51:10 1.12
+++ mode_E.h 2001/05/27 06:44:05 1.13
@@ -11,7 +11,7 @@
********************************************************************
function: predefined encoding modes
- last mod: $Id: mode_E.h,v 1.12 2001/02/26 03:51:10 xiphmont Exp $
+ last mod: $Id: mode_E.h,v 1.13 2001/05/27 06:44:05 xiphmont Exp $
********************************************************************/
@@ -107,13 +107,12 @@
.5f, /* high window */
5,
5,
+ 10,
{0.f},
105.f, /* even decade + 5 is important; saves an rint() later in a
tight loop) */
-28.,
-
- -0., -.004 /* attack/decay control */
};
static vorbis_info_psy _psy_set_E={
@@ -180,13 +179,12 @@
.5f, /* high window */
25,
25,
+ 40,
{0.f},
105.f, /* even decade + 5 is important; saves an rint() later in a
tight loop) */
-32.,
-
- -0.f, -.004f, /* attack/decay control */
};
1.24 +3 -3 vorbis/vq/bookutil.c
Index: bookutil.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/vq/bookutil.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- bookutil.c 2001/02/26 03:51:12 1.23
+++ bookutil.c 2001/05/27 06:44:07 1.24
@@ -11,7 +11,7 @@
********************************************************************
function: utility functions for loading .vqh and .vqd files
- last mod: $Id: bookutil.c,v 1.23 2001/02/26 03:51:12 xiphmont Exp $
+ last mod: $Id: bookutil.c,v 1.24 2001/05/27 06:44:07 xiphmont Exp $
********************************************************************/
@@ -191,7 +191,7 @@
}
/* find the codebook struct */
- find_seek_to(in,"static static_codebook _vq_book_");
+ find_seek_to(in,"static static_codebook _");
/* get the major important values */
line=get_line(in);
@@ -379,7 +379,7 @@
}
/* load the lengthlist */
- find_seek_to(in,"static long _vq_lengthlist");
+ find_seek_to(in,"_lengthlist");
reset_next_value();
c->lengthlist=_ogg_malloc(sizeof(long)*c->entries);
for(i=0;i<c->entries;i++)
1.5 +3 -3 vorbis/vq/distribution.c
Index: distribution.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/vq/distribution.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- distribution.c 2001/02/26 03:51:12 1.4
+++ distribution.c 2001/05/27 06:44:07 1.5
@@ -11,7 +11,7 @@
********************************************************************
function: utility for finding the distribution in a data set
- last mod: $Id: distribution.c,v 1.4 2001/02/26 03:51:12 xiphmont Exp $
+ last mod: $Id: distribution.c,v 1.5 2001/05/27 06:44:07 xiphmont Exp $
********************************************************************/
@@ -155,7 +155,7 @@
flag=1;
}
- while(sscanf(line,"%f",&code)==1){
+ while(line && sscanf(line,"%f",&code)==1){
line=strchr(line,',');
if(line)line++;
if(code<min)min=code;
@@ -187,7 +187,7 @@
lines--;
if(!(lines&0xff))spinnit("counting distribution. lines so far...",lines);
- while(sscanf(line,"%f",&code)==1){
+ while(line && sscanf(line,"%f",&code)==1){
line=strchr(line,',');
if(line)line++;
1.9 +53 -34 vorbis/vq/huffbuild.c
Index: huffbuild.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/vq/huffbuild.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- huffbuild.c 2001/02/26 03:51:12 1.8
+++ huffbuild.c 2001/05/27 06:44:07 1.9
@@ -7,11 +7,11 @@
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
-
+ * *
********************************************************************
function: hufftree builder
- last mod: $Id: huffbuild.c,v 1.8 2001/02/26 03:51:12 xiphmont Exp $
+ last mod: $Id: huffbuild.c,v 1.9 2001/05/27 06:44:07 xiphmont Exp $
********************************************************************/
@@ -50,7 +50,7 @@
static void usage(){
fprintf(stderr,
"usage:\n"
- "huffbuild <input>.vqd <begin,n,group> [noguard]\n"
+ "huffbuild <input>.vqd <begin,n,group>|<lorange-hirange> [noguard]\n"
" where begin,n,group is first scalar, \n"
" number of scalars of each in line,\n"
" number of scalars in a group\n"
@@ -65,6 +65,7 @@
int i,j,k,begin,n,subn,guard=1;
FILE *file;
int maxval=0;
+ int loval=0;
if(argc<3)usage();
if(argc==4)guard=0;
@@ -76,19 +77,28 @@
{
char *pos=strchr(argv[2],',');
- begin=atoi(argv[2]);
- if(!pos)
- usage();
- else
- n=atoi(pos+1);
- pos=strchr(pos+1,',');
- if(!pos)
- usage();
- else
- subn=atoi(pos+1);
- if(n/subn*subn != n){
- fprintf(stderr,"n must be divisible by group\n");
- exit(1);
+ char *dpos=strchr(argv[2],'-');
+ if(dpos){
+ loval=atoi(argv[2]);
+ maxval=atoi(dpos+1);
+ subn=1;
+ subn=1;
+ begin=0;
+ }else{
+ begin=atoi(argv[2]);
+ if(!pos)
+ usage();
+ else
+ n=atoi(pos+1);
+ pos=strchr(pos+1,',');
+ if(!pos)
+ usage();
+ else
+ subn=atoi(pos+1);
+ if(n/subn*subn != n){
+ fprintf(stderr,"n must be divisible by group\n");
+ exit(1);
+ }
}
}
@@ -96,35 +106,44 @@
file=fopen(infile,"r");
if(!file){
fprintf(stderr,"Could not open file %s\n",infile);
- exit(1);
+ if(!maxval)
+ exit(1);
+ else
+ fprintf(stderr," making untrained books.\n");
+
}
- i=0;
- while(1){
- long v;
- if(get_next_ivalue(file,&v))break;
- if(v>maxval)maxval=v;
- if(!(i++&0xff))spinnit("loading... ",i);
+ if(!maxval){
+ i=0;
+ while(1){
+ long v;
+ if(get_next_ivalue(file,&v))break;
+ if(v>maxval)maxval=v;
+
+ if(!(i++&0xff))spinnit("loading... ",i);
+ }
+ rewind(file);
+ maxval++;
}
- rewind(file);
- maxval++;
{
long vals=pow(maxval,subn);
long *hist=_ogg_malloc(vals*sizeof(long));
long *lengths=_ogg_malloc(vals*sizeof(long));
- for(j=0;j<vals;j++)hist[j]=guard;
+ for(j=loval;j<vals;j++)hist[j]=guard;
- reset_next_value();
- i/=subn;
- while(!feof(file)){
- long val=getval(file,begin,n,subn,maxval);
- if(val==-1)break;
- hist[val]++;
- if(!(i--&0xff))spinnit("loading... ",i*subn);
+ if(file){
+ reset_next_value();
+ i/=subn;
+ while(!feof(file)){
+ long val=getval(file,begin,n,subn,maxval);
+ if(val==-1 || val>=maxval)break;
+ hist[val]++;
+ if(!(i--&0xff))spinnit("loading... ",i*subn);
+ }
+ fclose(file);
}
- fclose(file);
/* we have the probabilities, build the tree */
fprintf(stderr,"Building tree for %ld entries\n",vals);
1.9 +2 -2 vorbis/vq/latticehint.c
Index: latticehint.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/vq/latticehint.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- latticehint.c 2001/02/26 03:51:12 1.8
+++ latticehint.c 2001/05/27 06:44:07 1.9
@@ -11,7 +11,7 @@
********************************************************************
function: utility main for building thresh/pigeonhole encode hints
- last mod: $Id: latticehint.c,v 1.8 2001/02/26 03:51:12 xiphmont Exp $
+ last mod: $Id: latticehint.c,v 1.9 2001/05/27 06:44:07 xiphmont Exp $
********************************************************************/
@@ -186,7 +186,7 @@
if(dB){
if(fabs(v1)<.01)v1=(v1+v2)*.5;
if(fabs(v2)<.01)v2=(v1+v2)*.5;
- t->quantthresh[i]=fromdB((todB(v1)+todB(v2))*.5);
+ t->quantthresh[i]=fromdB((todB(&v1)+todB(&v2))*.5);
if(v1<0 || v2<0)t->quantthresh[i]*=-1;
}else{
--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list