Readded seeking_example.c to the build
authorMonty <xiphmont@xiph.org>
Fri, 13 Oct 2000 19:48:03 +0000 (19:48 +0000)
committerMonty <xiphmont@xiph.org>
Fri, 13 Oct 2000 19:48:03 +0000 (19:48 +0000)
Added page-granularity seeking for a seek that's faster than
ov_pcm_seek or ov_time_seek, but not quite as accurate.  See the
comments in vorbisfile.c for ov_pcm_seek_page.

Monty

svn path=/trunk/vorbis/; revision=733

examples/Makefile.am
include/vorbis/vorbisfile.h
lib/vorbisfile.c

index ee645eb9b32bd4a0412e9324ee9840ab93ad8bbf..7dfb6a276b865e029e6396739e8245a382f30fb7 100644 (file)
@@ -5,7 +5,7 @@ AUTOMAKE_OPTIONS = foreign
 INCLUDES = -I$(top_srcdir)/include
 
 noinst_PROGRAMS = decoder_example encoder_example chaining_example\
-               vorbisfile_example
+               vorbisfile_example seeking_example
 
 LDADD = $(top_srcdir)/lib/.libs/libvorbis.a
 
@@ -15,6 +15,8 @@ chaining_example_SOURCES = chaining_example.c
 chaining_example_LDADD = $(top_srcdir)/lib/.libs/libvorbisfile.a $(top_srcdir)/lib/.libs/libvorbis.a
 vorbisfile_example_SOURCES = vorbisfile_example.c
 vorbisfile_example_LDADD = $(top_srcdir)/lib/.libs/libvorbisfile.a $(top_srcdir)/lib/.libs/libvorbis.a
+seeking_example_SOURCES = seeking_example.c
+seeking_example_LDADD = $(top_srcdir)/lib/.libs/libvorbisfile.a $(top_srcdir)/lib/.libs/libvorbis.a
 
 debug:
        $(MAKE) all CFLAGS="@DEBUG@"
index 001689b445d114244ea15a6e065831d9768b4606..18de2280b0accdc978b3350b8153a475819f2d6c 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.h,v 1.8 2000/10/12 03:12:41 xiphmont Exp $
+ last mod: $Id: vorbisfile.h,v 1.9 2000/10/13 19:48:02 xiphmont Exp $
 
  ********************************************************************/
 
@@ -97,7 +97,9 @@ extern double ov_time_total(OggVorbis_File *vf,int i);
 
 extern int ov_raw_seek(OggVorbis_File *vf,long pos);
 extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos);
+extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos);
 extern int ov_time_seek(OggVorbis_File *vf,double pos);
+extern int ov_time_seek_page(OggVorbis_File *vf,double pos);
 
 extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf);
 extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf);
index a1f8119f41302843f43155c0bd0c7e682095d0ae..08015960ae28452948a52c5c0a6d3cfc7393642d 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.c,v 1.29 2000/10/12 03:12:54 xiphmont Exp $
+ last mod: $Id: vorbisfile.c,v 1.30 2000/10/13 19:48:03 xiphmont Exp $
 
  ********************************************************************/
 
@@ -813,11 +813,13 @@ int ov_raw_seek(OggVorbis_File *vf,long pos){
   return -1;
 }
 
-/* seek to a sample offset relative to the decompressed pcm stream 
-
-   returns zero on success, nonzero on failure */
+/* Page granularity seek (faster than sample granularity because we
+   don't do the last bit of decode to find a specific sample).
 
-int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
+   Seek to the last [granule marked] page preceeding the specified pos
+   location, such that decoding past the returned point will quickly
+   arrive at the requested position. */
+int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
   int link=-1;
   ogg_int64_t total=ov_pcm_total(vf,-1);
 
@@ -876,6 +878,20 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
   /* verify result */
   if(vf->pcm_offset>=pos)goto seek_error;
   if(pos>ov_pcm_total(vf,-1))goto seek_error;
+  return(0);
+
+ seek_error:
+  /* dump machine so we're in a known state */
+  vf->pcm_offset=-1;
+  _decode_clear(vf);
+  return -1;
+}
+
+/* seek to a sample offset relative to the decompressed pcm stream 
+   returns zero on success, nonzero on failure */
+
+int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
+  if(ov_pcm_seek_page(vf,pos))return(-1);
 
   /* discard samples until we reach the desired position. Crossing a
      logical bitstream boundary with abandon is OK. */
@@ -893,7 +909,33 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
        vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
   }
   return 0;
+}
+
+/* seek to a playback time relative to the decompressed pcm stream 
+   returns zero on success, nonzero on failure */
+int ov_time_seek(OggVorbis_File *vf,double seconds){
+  /* translate time to PCM position and call ov_pcm_seek */
+
+  int link=-1;
+  ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
+  double time_total=ov_time_total(vf,-1);
+
+  if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */  
+  if(seconds<0 || seconds>time_total)goto seek_error;
   
+  /* which bitstream section does this time offset occur in? */
+  for(link=vf->links-1;link>=0;link--){
+    pcm_total-=vf->pcmlengths[link];
+    time_total-=ov_time_total(vf,link);
+    if(seconds>=time_total)break;
+  }
+
+  /* enough information to convert time offset to pcm offset */
+  {
+    ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
+    return(ov_pcm_seek(vf,target));
+  }
+
  seek_error:
   /* dump machine so we're in a known state */
   vf->pcm_offset=-1;
@@ -901,9 +943,9 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
   return -1;
 }
 
-/* seek to a playback time relative to the decompressed pcm stream 
+/* page-granularity version of ov_time_seek 
    returns zero on success, nonzero on failure */
-int ov_time_seek(OggVorbis_File *vf,double seconds){
+int ov_time_seek_page(OggVorbis_File *vf,double seconds){
   /* translate time to PCM position and call ov_pcm_seek */
 
   int link=-1;
@@ -923,7 +965,7 @@ int ov_time_seek(OggVorbis_File *vf,double seconds){
   /* enough information to convert time offset to pcm offset */
   {
     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
-    return(ov_pcm_seek(vf,target));
+    return(ov_pcm_seek_page(vf,target));
   }
 
  seek_error: