Blame examples/seeking_example.c

Packit 06404a
/********************************************************************
Packit 06404a
 *                                                                  *
Packit 06404a
 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
Packit 06404a
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
Packit 06404a
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
Packit 06404a
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
Packit 06404a
 *                                                                  *
Packit 06404a
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
Packit 06404a
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
Packit 06404a
 *                                                                  *
Packit 06404a
 ********************************************************************
Packit 06404a
Packit 06404a
 function: illustrate seeking, and test it too
Packit 06404a
 last mod: $Id: seeking_example.c 19164 2014-06-18 06:33:58Z xiphmont $
Packit 06404a
Packit 06404a
 ********************************************************************/
Packit 06404a
Packit 06404a
#include <stdlib.h>
Packit 06404a
#include <stdio.h>
Packit 06404a
#include "vorbis/codec.h"
Packit 06404a
#include "vorbis/vorbisfile.h"
Packit 06404a
Packit 06404a
#ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */
Packit 06404a
# include <io.h>
Packit 06404a
# include <fcntl.h>
Packit 06404a
#endif
Packit 06404a
Packit 06404a
void _verify(OggVorbis_File *ov,
Packit 06404a
             ogg_int64_t val,ogg_int64_t pcmval,double timeval,
Packit 06404a
             ogg_int64_t pcmlength,
Packit 06404a
             char *bigassbuffer){
Packit 06404a
  off_t i;
Packit 06404a
  int j;
Packit 06404a
  long bread;
Packit 06404a
  char buffer[4096];
Packit 06404a
  int dummy;
Packit 06404a
  ogg_int64_t pos;
Packit 06404a
  int hs = ov_halfrate_p(ov);
Packit 06404a
Packit 06404a
  /* verify the raw position, the pcm position and position decode */
Packit 06404a
  if(val!=-1 && ov_raw_tell(ov)
Packit 06404a
    fprintf(stderr,"raw position out of tolerance: requested %ld, got %ld\n",
Packit 06404a
           (long)val,(long)ov_raw_tell(ov));
Packit 06404a
    exit(1);
Packit 06404a
  }
Packit 06404a
  if(pcmval!=-1 && ov_pcm_tell(ov)>pcmval){
Packit 06404a
    fprintf(stderr,"pcm position out of tolerance: requested %ld, got %ld\n",
Packit 06404a
           (long)pcmval,(long)ov_pcm_tell(ov));
Packit 06404a
    exit(1);
Packit 06404a
  }
Packit 06404a
  if(timeval!=-1 && ov_time_tell(ov)>timeval){
Packit 06404a
    fprintf(stderr,"time position out of tolerance: requested %f, got %f\n",
Packit 06404a
           timeval,ov_time_tell(ov));
Packit 06404a
    exit(1);
Packit 06404a
  }
Packit 06404a
  pos=ov_pcm_tell(ov);
Packit 06404a
  if(pos<0 || pos>pcmlength){
Packit 06404a
    fprintf(stderr,"pcm position out of bounds: got %ld\n",(long)pos);
Packit 06404a
    exit(1);
Packit 06404a
  }
Packit 06404a
  bread=ov_read(ov,buffer,4096,1,1,1,&dummy);
Packit 06404a
  for(j=0;j
Packit 06404a
    if(buffer[j]!=bigassbuffer[j+((pos>>hs)*2)]){
Packit 06404a
      fprintf(stderr,"data after seek doesn't match declared pcm position %ld\n",(long)pos);
Packit 06404a
Packit 06404a
      for(i=0;i<(pcmlength>>hs)*2-bread;i++){
Packit 06404a
        for(j=0;j
Packit 06404a
          if(buffer[j] != bigassbuffer[i+j])break;
Packit 06404a
        if(j==bread){
Packit 06404a
          fprintf(stderr,"data after seek appears to match position %ld\n",(long)((i/2)<
Packit 06404a
        }
Packit 06404a
      }
Packit 06404a
      {
Packit 06404a
        FILE *f=fopen("a.m","w");
Packit 06404a
        for(j=0;j
Packit 06404a
        fclose(f);
Packit 06404a
        f=fopen("b.m","w");
Packit 06404a
        for(j=-4096;j
Packit 06404a
          if(j+((pos*2)>>hs)>=0 && (j+((pos*2)>>hs))<(pcmlength>>hs)*2)
Packit 06404a
             fprintf(f,"%d %d\n",j,(int)bigassbuffer[j+((pos*2)>>hs)]);
Packit 06404a
        fclose(f);
Packit 06404a
      }
Packit 06404a
Packit 06404a
      exit(1);
Packit 06404a
    }
Packit 06404a
  }
Packit 06404a
}
Packit 06404a
Packit 06404a
int main(){
Packit 06404a
  OggVorbis_File ov;
Packit 06404a
  int i,ret;
Packit 06404a
  ogg_int64_t pcmlength;
Packit 06404a
  double timelength;
Packit 06404a
  char *bigassbuffer;
Packit 06404a
  int dummy;
Packit 06404a
  int hs=0;
Packit 06404a
Packit 06404a
#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
Packit 06404a
  _setmode( _fileno( stdin ), _O_BINARY );
Packit 06404a
#endif
Packit 06404a
Packit 06404a
Packit 06404a
  /* open the file/pipe on stdin */
Packit 06404a
  if(ov_open_callbacks(stdin,&ov,NULL,-1,OV_CALLBACKS_NOCLOSE)<0){
Packit 06404a
    fprintf(stderr,"Could not open input as an OggVorbis file.\n\n");
Packit 06404a
    exit(1);
Packit 06404a
  }
Packit 06404a
Packit 06404a
#if 0 /*enable this code to test seeking with halfrate decode */
Packit 06404a
  if(ov_halfrate(&ov,1)){
Packit 06404a
    fprintf(stderr,"Sorry; unable to set half-rate decode.\n\n");
Packit 06404a
    exit(1);
Packit 06404a
  }else
Packit 06404a
    hs=1;
Packit 06404a
#endif
Packit 06404a
Packit 06404a
  if(ov_seekable(&ov)){
Packit 06404a
Packit 06404a
    /* to simplify our own lives, we want to assume the whole file is
Packit 06404a
       stereo.  Verify this to avoid potentially mystifying users
Packit 06404a
       (pissing them off is OK, just don't confuse them) */
Packit 06404a
    for(i=0;i
Packit 06404a
      vorbis_info *vi=ov_info(&ov,i);
Packit 06404a
      if(vi->channels!=2){
Packit 06404a
        fprintf(stderr,"Sorry; right now seeking_test can only use Vorbis files\n"
Packit 06404a
               "that are entirely stereo.\n\n");
Packit 06404a
        exit(1);
Packit 06404a
      }
Packit 06404a
    }
Packit 06404a
Packit 06404a
    /* because we want to do sample-level verification that the seek
Packit 06404a
       does what it claimed, decode the entire file into memory */
Packit 06404a
    pcmlength=ov_pcm_total(&ov,-1);
Packit 06404a
    timelength=ov_time_total(&ov,-1);
Packit 06404a
    bigassbuffer=malloc((pcmlength>>hs)*2); /* w00t */
Packit 06404a
    i=0;
Packit 06404a
    while(i<(pcmlength>>hs)*2){
Packit 06404a
      int ret=ov_read(&ov,bigassbuffer+i,((pcmlength>>hs)*2)-i,1,1,1,&dummy);
Packit 06404a
      if(ret<0){
Packit 06404a
        fprintf(stderr,"Error reading file.\n");
Packit 06404a
        exit(1);
Packit 06404a
      }
Packit 06404a
      if(ret){
Packit 06404a
        i+=ret;
Packit 06404a
      }else{
Packit 06404a
        pcmlength=(i/2)<
Packit 06404a
      }
Packit 06404a
      fprintf(stderr,"\rloading.... [%ld left]              ",
Packit 06404a
              (long)((pcmlength>>hs)*2-i));
Packit 06404a
    }
Packit 06404a
Packit 06404a
    {
Packit 06404a
      ogg_int64_t length=ov.end;
Packit 06404a
      fprintf(stderr,"\rtesting raw seeking to random places in %ld bytes....\n",
Packit 06404a
             (long)length);
Packit 06404a
Packit 06404a
      for(i=0;i<1000;i++){
Packit 06404a
        ogg_int64_t val=(double)rand()/RAND_MAX*length;
Packit 06404a
        fprintf(stderr,"\r\t%d [raw position %ld]...     ",i,(long)val);
Packit 06404a
        ret=ov_raw_seek(&ov,val);
Packit 06404a
        if(ret<0){
Packit 06404a
          fprintf(stderr,"seek failed: %d\n",ret);
Packit 06404a
          exit(1);
Packit 06404a
        }
Packit 06404a
Packit 06404a
        _verify(&ov,val,-1,-1.,pcmlength,bigassbuffer);
Packit 06404a
Packit 06404a
      }
Packit 06404a
    }
Packit 06404a
Packit 06404a
    fprintf(stderr,"\r");
Packit 06404a
    {
Packit 06404a
      fprintf(stderr,"testing pcm page seeking to random places in %ld samples....\n",
Packit 06404a
             (long)pcmlength);
Packit 06404a
Packit 06404a
      for(i=0;i<1000;i++){
Packit 06404a
        ogg_int64_t val= i==0?(ogg_int64_t)0:(double)rand()/RAND_MAX*pcmlength;
Packit 06404a
        fprintf(stderr,"\r\t%d [pcm position %ld]...     ",i,(long)val);
Packit 06404a
        ret=ov_pcm_seek_page(&ov,val);
Packit 06404a
        if(ret<0){
Packit 06404a
          fprintf(stderr,"seek failed: %d\n",ret);
Packit 06404a
          exit(1);
Packit 06404a
        }
Packit 06404a
Packit 06404a
        _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);
Packit 06404a
Packit 06404a
      }
Packit 06404a
    }
Packit 06404a
Packit 06404a
    fprintf(stderr,"\r");
Packit 06404a
    {
Packit 06404a
      fprintf(stderr,"testing pcm exact seeking to random places in %f seconds....\n",
Packit 06404a
             timelength);
Packit 06404a
      for(i=0;i<1000;i++){
Packit 06404a
        ogg_int64_t val= i==0?(ogg_int64_t)0:(double)rand()/RAND_MAX*pcmlength;
Packit 06404a
        fprintf(stderr,"\r\t%d [pcm position %ld]...     ",i,(long)val);
Packit 06404a
        ret=ov_pcm_seek(&ov,val);
Packit 06404a
        if(ret<0){
Packit 06404a
          fprintf(stderr,"seek failed: %d\n",ret);
Packit 06404a
          exit(1);
Packit 06404a
        }
Packit 06404a
        if(ov_pcm_tell(&ov)!=((val>>hs)<
Packit 06404a
          fprintf(stderr,"Declared position didn't perfectly match request: %ld != %ld\n",
Packit 06404a
                 (long)val,(long)ov_pcm_tell(&ov);;
Packit 06404a
          exit(1);
Packit 06404a
        }
Packit 06404a
Packit 06404a
        _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);
Packit 06404a
Packit 06404a
      }
Packit 06404a
    }
Packit 06404a
Packit 06404a
    fprintf(stderr,"\r");
Packit 06404a
    {
Packit 06404a
      fprintf(stderr,"testing time page seeking to random places in %f seconds....\n",
Packit 06404a
             timelength);
Packit 06404a
    
Packit 06404a
      for(i=0;i<1000;i++){
Packit 06404a
        double val=(double)rand()/RAND_MAX*timelength;
Packit 06404a
        fprintf(stderr,"\r\t%d [time position %f]...     ",i,val);
Packit 06404a
        ret=ov_time_seek_page(&ov,val);
Packit 06404a
        if(ret<0){
Packit 06404a
          fprintf(stderr,"seek failed: %d\n",ret);
Packit 06404a
          exit(1);
Packit 06404a
        }
Packit 06404a
Packit 06404a
        _verify(&ov,-1,-1,val,pcmlength,bigassbuffer);
Packit 06404a
Packit 06404a
      }
Packit 06404a
    }
Packit 06404a
Packit 06404a
    fprintf(stderr,"\r");
Packit 06404a
    {
Packit 06404a
      fprintf(stderr,"testing time exact seeking to random places in %f seconds....\n",
Packit 06404a
             timelength);
Packit 06404a
    
Packit 06404a
      for(i=0;i<1000;i++){
Packit 06404a
        double val=(double)rand()/RAND_MAX*timelength;
Packit 06404a
        fprintf(stderr,"\r\t%d [time position %f]...     ",i,val);
Packit 06404a
        ret=ov_time_seek(&ov,val);
Packit 06404a
        if(ret<0){
Packit 06404a
          fprintf(stderr,"seek failed: %d\n",ret);
Packit 06404a
          exit(1);
Packit 06404a
        }
Packit 06404a
        if(ov_time_tell(&ov)<val-1 || ov_time_tell(&ov)>val+1){
Packit 06404a
          fprintf(stderr,"Declared position didn't perfectly match request: %f != %f\n",
Packit 06404a
                 val,ov_time_tell(&ov);;
Packit 06404a
          exit(1);
Packit 06404a
        }
Packit 06404a
Packit 06404a
        _verify(&ov,-1,-1,val,pcmlength,bigassbuffer);
Packit 06404a
Packit 06404a
      }
Packit 06404a
    }
Packit 06404a
    
Packit 06404a
    fprintf(stderr,"\r                                           \nOK.\n\n");
Packit 06404a
Packit 06404a
Packit 06404a
  }else{
Packit 06404a
    fprintf(stderr,"Standard input was not seekable.\n");
Packit 06404a
  }
Packit 06404a
Packit 06404a
  ov_clear(&ov);
Packit 06404a
  return 0;
Packit 06404a
}
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a