/* 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",
+ fprintf(stderr,"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",
+ fprintf(stderr,"pcm position out of tolerance: requested %ld, got %ld\n",
(long)pcmval,(long)ov_pcm_tell(ov));
exit(1);
}
if(timeval!=-1 && ov_time_tell(ov)>timeval){
- printf("time position out of tolerance: requested %f, got %f\n",
+ fprintf(stderr,"time position out of tolerance: requested %f, got %f\n",
timeval,ov_time_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);
+ fprintf(stderr,"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");
+ fprintf(stderr,"data position after seek doesn't match pcm position\n");
{
FILE *f=fopen("a.m","w");
#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
_setmode( _fileno( stdin ), _O_BINARY );
- _setmode( _fileno( stdout ), _O_BINARY );
#endif
/* 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");
+ if(ov_open_callbacks(stdin,&ov,NULL,-1,OV_CALLBACKS_NOCLOSE)<0){
+ fprintf(stderr,"Could not open input as an OggVorbis file.\n\n");
exit(1);
}
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"
+ fprintf(stderr,"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 */
- fflush(stdout);
pcmlength=ov_pcm_total(&ov,-1);
timelength=ov_time_total(&ov,-1);
bigassbuffer=malloc(pcmlength*2); /* w00t */
{
ogg_int64_t length=ov.end;
- printf("\rtesting raw seeking to random places in %ld bytes....\n",
+ fprintf(stderr,"\rtesting 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;
- printf("\r\t%d [raw position %ld]... ",i,(long)val);
- fflush(stdout);
+ fprintf(stderr,"\r\t%d [raw position %ld]... ",i,(long)val);
ret=ov_raw_seek(&ov,val);
if(ret<0){
- printf("seek failed: %d\n",ret);
+ fprintf(stderr,"seek failed: %d\n",ret);
exit(1);
}
}
}
- printf("\r");
+ fprintf(stderr,"\r");
{
- printf("testing pcm page seeking to random places in %ld samples....\n",
+ fprintf(stderr,"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;
- printf("\r\t%d [pcm position %ld]... ",i,(long)val);
- fflush(stdout);
+ fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val);
ret=ov_pcm_seek_page(&ov,val);
if(ret<0){
- printf("seek failed: %d\n",ret);
+ fprintf(stderr,"seek failed: %d\n",ret);
exit(1);
}
}
}
- printf("\r");
+ fprintf(stderr,"\r");
{
- printf("testing pcm exact seeking to random places in %ld samples....\n",
+ fprintf(stderr,"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;
- printf("\r\t%d [pcm position %ld]... ",i,(long)val);
- fflush(stdout);
+ fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val);
ret=ov_pcm_seek(&ov,val);
if(ret<0){
- printf("seek failed: %d\n",ret);
+ fprintf(stderr,"seek failed: %d\n",ret);
exit(1);
}
if(ov_pcm_tell(&ov)!=val){
- printf("Declared position didn't perfectly match request: %ld != %ld\n",
+ fprintf(stderr,"Declared position didn't perfectly match request: %ld != %ld\n",
(long)val,(long)ov_pcm_tell(&ov));
exit(1);
}
}
}
- printf("\r");
+ fprintf(stderr,"\r");
{
- printf("testing time page seeking to random places in %f seconds....\n",
+ fprintf(stderr,"testing time page seeking to random places in %f seconds....\n",
timelength);
for(i=0;i<1000;i++){
double val=(double)rand()/RAND_MAX*timelength;
- printf("\r\t%d [time position %f]... ",i,val);
- fflush(stdout);
+ fprintf(stderr,"\r\t%d [time position %f]... ",i,val);
ret=ov_time_seek_page(&ov,val);
if(ret<0){
- printf("seek failed: %d\n",ret);
+ fprintf(stderr,"seek failed: %d\n",ret);
exit(1);
}
}
}
- printf("\r");
+ fprintf(stderr,"\r");
{
- printf("testing time exact seeking to random places in %f seconds....\n",
+ fprintf(stderr,"testing time exact seeking to random places in %f seconds....\n",
timelength);
for(i=0;i<1000;i++){
double val=(double)rand()/RAND_MAX*timelength;
- printf("\r\t%d [time position %f]... ",i,val);
- fflush(stdout);
+ fprintf(stderr,"\r\t%d [time position %f]... ",i,val);
ret=ov_time_seek(&ov,val);
if(ret<0){
- printf("seek failed: %d\n",ret);
+ fprintf(stderr,"seek failed: %d\n",ret);
exit(1);
}
if(ov_time_tell(&ov)<val-1 || ov_time_tell(&ov)>val+1){
- printf("Declared position didn't perfectly match request: %f != %f\n",
+ fprintf(stderr,"Declared position didn't perfectly match request: %f != %f\n",
val,ov_time_tell(&ov));
exit(1);
}
}
}
- printf("\r \nOK.\n\n");
+ fprintf(stderr,"\r \nOK.\n\n");
}else{
- printf("Standard input was not seekable.\n");
+ fprintf(stderr,"Standard input was not seekable.\n");
}
ov_clear(&ov);
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
* *
********************************************************************
long (*tell_func) (void *datasource);
} ov_callbacks;
+/* a few sets of convenient callbacks, especially for use under
+ * Windows where ov_open_callbacks() should always be used instead of
+ * ov_open() to avoid problems with incompatable crt.o version linking
+ * issues. */
+
+static int _ov_header_fseek_wrap(FILE *f,ogg_int64_t off,int whence){
+ if(f==NULL)return(-1);
+ return fseek(f,off,whence);
+}
+
+static ov_callbacks OV_CALLBACKS_DEFAULT = {
+ (size_t (*)(void *, size_t, size_t, void *)) fread,
+ (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap,
+ (int (*)(void *)) fclose,
+ (long (*)(void *)) ftell
+};
+
+static ov_callbacks OV_CALLBACKS_NOCLOSE = {
+ (size_t (*)(void *, size_t, size_t, void *)) fread,
+ (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap,
+ (int (*)(void *)) NULL,
+ (long (*)(void *)) ftell
+};
+
+static ov_callbacks OV_CALLBACKS_STREAMONLY = {
+ (size_t (*)(void *, size_t, size_t, void *)) fread,
+ (int (*)(void *, ogg_int64_t, int)) NULL,
+ (int (*)(void *)) fclose,
+ (long (*)(void *)) NULL
+};
+
+static ov_callbacks OV_CALLBACKS_STREAMONLY_NOCLOSE = {
+ (size_t (*)(void *, size_t, size_t, void *)) fread,
+ (int (*)(void *, ogg_int64_t, int)) NULL,
+ (int (*)(void *)) NULL,
+ (long (*)(void *)) NULL
+};
+
#define NOTOPEN 0
#define PARTOPEN 1
#define OPENED 2
extern int ov_clear(OggVorbis_File *vf);
+extern int ov_fopen(char *path,OggVorbis_File *vf);
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);
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
* *
********************************************************************
static long _get_data(OggVorbis_File *vf){
errno=0;
+ if(!(vf->callbacks.read_func))return(-1);
if(vf->datasource){
char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
/* save a tiny smidge of verbosity to make the code more readable */
static int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
if(vf->datasource){
- if((vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
+ if(!(vf->callbacks.seek_func)||
+ (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
return OV_EREAD;
vf->offset=offset;
ogg_sync_reset(&vf->oy);
/* 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->callbacks.seek_func)(vf->datasource,0,SEEK_END);
- vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
+ if(vf->callbacks.seek_func){
+ (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
+ vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
+ }else{
+ vf->offset=vf->end=-1;
+ }
/* If seek_func is implemented, tell_func must also be implemented */
if(vf->end==-1) return(OV_EINVAL);
static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
long ibytes, ov_callbacks callbacks){
- int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
+ int offsettest=((f && callbacks.seek_func)?callbacks.seek_func(f,0,SEEK_CUR):-1);
int ret;
memset(vf,0,sizeof(*vf));
if(vf->serialnos)_ogg_free(vf->serialnos);
if(vf->offsets)_ogg_free(vf->offsets);
ogg_sync_clear(&vf->oy);
- if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
+ if(vf->datasource && vf->callbacks.close_func)
+ (vf->callbacks.close_func)(vf->datasource);
memset(vf,0,sizeof(*vf));
}
#ifdef DEBUG_LEAKS
return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
}
+
+int ov_fopen(char *path,OggVorbis_File *vf){
+ int ret;
+ FILE *f = fopen(path,"rb");
+ if(!f) return -1;
+
+ ret = ov_open(f,vf,NULL,0);
+ if(ret) fclose(f);
+ return ret;
+}
+
/* cheap hack for game usage where downsampling is desirable; there's
no need for SRC as we can just do it cheaply in libvorbis. */
vorbis_synthesis_restart(&vf->vd);
ret=_seek_helper(vf,pos);
- if(ret)return(ret);
+ if(ret)goto seek_error;
/* 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