static GslLong dh_vorbis_coarse_seek (GslDataHandle *dhandle, GslLong voffset) { VorbisHandle *vhandle = (VorbisHandle*) dhandle; GslLong opos = vhandle->pcm_pos, pos = voffset / dhandle->setup.n_channels; if (voffset < 0) return vhandle->pcm_pos * dhandle->setup.n_channels; if (pos < vhandle->pcm_pos || pos >= vhandle->pcm_pos + vhandle->pcm_length + SEEK_BY_READ_AHEAD (vhandle)) { gint err = ov_pcm_seek_page (&vhandle->ofile, vhandle->soffset + pos); if (err) /* eek */ err = ov_pcm_seek_page (&vhandle->ofile, vhandle->soffset); else vhandle->pcm_pos = ov_pcm_tell (&vhandle->ofile) - vhandle->soffset; if (err || vhandle->pcm_pos < 0) /* urg, we're completely screwed */ vhandle->pcm_pos = 0; vhandle->pcm_length = 0; } if (0) g_printerr ("OggS-SEEK: at %llu want %llu got %llu (diff-requested %lld)\n", opos, pos, vhandle->pcm_pos, pos - opos); return vhandle->pcm_pos * dhandle->setup.n_channels; }
BOOL ovd_seek(HANDLE hov, LONGLONG samples) { LIBOV_STRUCT* lov = (LIBOV_STRUCT*)hov; if (!lov) return FALSE; return ov_pcm_seek_page(&lov->vf, samples) == 0; }
/** * Decompresses ogg vorbis data to raw PCM data. * * @param PCMData where to place the decompressed sound * @param bLooping whether to loop the wav by seeking to the start, or pad the buffer with zeroes * @param BufferSize number of bytes of PCM data to create. A value of 0 means decompress the entire sound. * * @return bool true if the end of the data was reached (for both single shot and looping sounds) */ bool FVorbisAudioInfo::ReadCompressedData( uint8* InDestination, bool bLooping, uint32 BufferSize ) { bool bLooped; uint32 TotalBytesRead; SCOPE_CYCLE_COUNTER( STAT_VorbisDecompressTime ); FScopeLock ScopeLock(&VorbisCriticalSection); bLooped = false; // Work out number of samples to read TotalBytesRead = 0; char* Destination = ( char* )InDestination; check( VFWrapper != NULL ); while( TotalBytesRead < BufferSize ) { long BytesRead = ov_read( &VFWrapper->vf, Destination, BufferSize - TotalBytesRead, 0, 2, 1, NULL ); if( !BytesRead ) { // We've reached the end bLooped = true; if( bLooping ) { int Result = ov_pcm_seek_page( &VFWrapper->vf, 0 ); if (Result < 0) { // indicates an error - fill remainder of buffer with zero FMemory::Memzero(Destination, BufferSize - TotalBytesRead); return true; } } else { int32 Count = ( BufferSize - TotalBytesRead ); FMemory::Memzero( Destination, Count ); BytesRead += BufferSize - TotalBytesRead; } } else if (BytesRead < 0) { // indicates an error - fill remainder of buffer with zero FMemory::Memzero(Destination, BufferSize - TotalBytesRead); return false; } TotalBytesRead += BytesRead; Destination += BytesRead; } return( bLooped ); }
int main(){ OggVorbis_File ov; int i,ret; ogg_int64_t pcmlength; char *bigassbuffer; int dummy; #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"); exit(1); } if(ov_seekable(&ov)){ /* 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 */ 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; } fprintf(stderr,"\rloading.... [%ld left] ", (long)(pcmlength*2-i)); } /* 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("\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; 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"); { 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("Declared position didn't perfectly match request: %ld != %ld\n", (long)val,(long)ov_pcm_tell(&ov)); exit(1); } _verify(&ov,pos,-1,val,pcmlength,bigassbuffer); } } printf("\r \nOK.\n\n"); }else{ printf("Standard input was not seekable.\n"); } ov_clear(&ov); return 0; }
int main(){ OggVorbis_File ov; int i,ret; ogg_int64_t pcmlength; double timelength; char *bigassbuffer; int dummy; int hs=0; #ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */ _setmode( _fileno( stdin ), _O_BINARY ); #endif /* open the file/pipe on stdin */ 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); } #if 0 /*enable this code to test seeking with halfrate decode */ if(ov_halfrate(&ov,1)){ fprintf(stderr,"Sorry; unable to set half-rate decode.\n\n"); exit(1); }else hs=1; #endif if(ov_seekable(&ov)){ /* 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){ 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 */ pcmlength=ov_pcm_total(&ov,-1); timelength=ov_time_total(&ov,-1); bigassbuffer=malloc((pcmlength>>hs)*2); /* w00t */ i=0; while(i<(pcmlength>>hs)*2){ int ret=ov_read(&ov,bigassbuffer+i,((pcmlength>>hs)*2)-i,1,1,1,&dummy); if(ret<0){ fprintf(stderr,"Error reading file.\n"); exit(1); } if(ret){ i+=ret; }else{ pcmlength=(i/2)<<hs; } fprintf(stderr,"\rloading.... [%ld left] ", (long)((pcmlength>>hs)*2-i)); } { ogg_int64_t length=ov.end; 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; fprintf(stderr,"\r\t%d [raw position %ld]... ",i,(long)val); ret=ov_raw_seek(&ov,val); if(ret<0){ fprintf(stderr,"seek failed: %d\n",ret); exit(1); } _verify(&ov,val,-1,-1.,pcmlength,bigassbuffer); } } fprintf(stderr,"\r"); { 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= i==0?(ogg_int64_t)0:(double)rand()/RAND_MAX*pcmlength; fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val); ret=ov_pcm_seek_page(&ov,val); if(ret<0){ fprintf(stderr,"seek failed: %d\n",ret); exit(1); } _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer); } } fprintf(stderr,"\r"); { fprintf(stderr,"testing pcm exact seeking to random places in %f seconds....\n", timelength); for(i=0;i<1000;i++){ ogg_int64_t val= i==0?(ogg_int64_t)0:(double)rand()/RAND_MAX*pcmlength; fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val); ret=ov_pcm_seek(&ov,val); if(ret<0){ fprintf(stderr,"seek failed: %d\n",ret); exit(1); } if(ov_pcm_tell(&ov)!=((val>>hs)<<hs)){ fprintf(stderr,"Declared position didn't perfectly match request: %ld != %ld\n", (long)val,(long)ov_pcm_tell(&ov)); exit(1); } _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer); } } fprintf(stderr,"\r"); { 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; fprintf(stderr,"\r\t%d [time position %f]... ",i,val); ret=ov_time_seek_page(&ov,val); if(ret<0){ fprintf(stderr,"seek failed: %d\n",ret); exit(1); } _verify(&ov,-1,-1,val,pcmlength,bigassbuffer); } } fprintf(stderr,"\r"); { 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; fprintf(stderr,"\r\t%d [time position %f]... ",i,val); ret=ov_time_seek(&ov,val); if(ret<0){ fprintf(stderr,"seek failed: %d\n",ret); exit(1); } if(ov_time_tell(&ov)<val-1 || ov_time_tell(&ov)>val+1){ fprintf(stderr,"Declared position didn't perfectly match request: %f != %f\n", val,ov_time_tell(&ov)); exit(1); } _verify(&ov,-1,-1,val,pcmlength,bigassbuffer); } } fprintf(stderr,"\r \nOK.\n\n"); }else{
static playbackstatus MV_GetNextVorbisBlock ( VoiceNode *voice ) { vorbis_data * vd = (vorbis_data *) voice->extra; int bytes = 0, bytesread = 0; int bitstream = 0, err = 0; voice->Playing = TRUE; bytesread = 0; do { bytes = ov_read(&vd->vf, vd->block + bytesread, sizeof(vd->block) - bytesread, 0, 2, 1, &bitstream); //fprintf(stderr, "ov_read = %d\n", bytes); if (bytes == OV_HOLE) continue; if (bytes == 0) { if (voice->LoopStart) { err = ov_pcm_seek_page(&vd->vf, 0); if (err != 0) { fprintf(stderr, "MV_GetNextVorbisBlock ov_pcm_seek_page_lap: err %d\n", err); } else { continue; } } else { break; } } else if (bytes < 0) { fprintf(stderr, "MV_GetNextVorbisBlock ov_read: err %d\n", bytes); voice->Playing = FALSE; return NoMoreData; } bytesread += bytes; } while (bytesread < sizeof(vd->block)); if (bytesread == 0) { voice->Playing = FALSE; return NoMoreData; } if (bitstream != vd->lastbitstream) { vorbis_info * vi = 0; vi = ov_info(&vd->vf, -1); if (!vi) { voice->Playing = FALSE; return NoMoreData; } if (vi->channels != 1 && vi->channels != 2) { voice->Playing = FALSE; return NoMoreData; } voice->channels = vi->channels; voice->SamplingRate = vi->rate; voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) / MV_MixRate; voice->FixedPointBufferSize = ( voice->RateScale * MixBufferSize ) - voice->RateScale; MV_SetVoiceMixMode( voice ); } vd->lastbitstream = bitstream; bytesread /= 2 * voice->channels; voice->position = 0; voice->sound = vd->block; voice->BlockLength = 0; voice->length = bytesread << 16; return( KeepPlaying ); }