Change EOF seek behavior: reading after a seek past EOF returns EOF.
Minor Vorbis seek fix.
This commit is contained in:
@@ -878,11 +878,18 @@ int RageSoundReader_MP3::SetPosition_toc( int ms, bool Xing )
|
|||||||
if(percent >= 0)
|
if(percent >= 0)
|
||||||
{
|
{
|
||||||
int bytepos = -1;
|
int bytepos = -1;
|
||||||
if( Xing && percent < 100 )
|
if( Xing )
|
||||||
|
{
|
||||||
|
if( percent < 100 )
|
||||||
|
{
|
||||||
|
int jump = mad->xingtag.toc[percent];
|
||||||
|
bytepos = mad->filesize * jump / 256;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bytepos = 2000000000; /* force EOF */
|
||||||
|
}
|
||||||
|
else if( percent < 200 )
|
||||||
{
|
{
|
||||||
int jump = mad->xingtag.toc[percent];
|
|
||||||
bytepos = mad->filesize * jump / 256;
|
|
||||||
} else if(percent < 200) {
|
|
||||||
/* Find the last entry <= percent that we actually have an entry for;
|
/* Find the last entry <= percent that we actually have an entry for;
|
||||||
* this will get us as close as possible. */
|
* this will get us as close as possible. */
|
||||||
while( percent >= 0 && mad->toc[percent] == -1 )
|
while( percent >= 0 && mad->toc[percent] == -1 )
|
||||||
@@ -1026,17 +1033,10 @@ int RageSoundReader_MP3::SetPosition_Accurate( int ms )
|
|||||||
/* Seek using our own internal (accurate) TOC. */
|
/* Seek using our own internal (accurate) TOC. */
|
||||||
int ret = SetPosition_toc( ms, false );
|
int ret = SetPosition_toc( ms, false );
|
||||||
if( ret <= 0 )
|
if( ret <= 0 )
|
||||||
{
|
|
||||||
MADLIB_rewind();
|
|
||||||
return ret; /* it set the error */
|
return ret; /* it set the error */
|
||||||
}
|
|
||||||
|
|
||||||
/* Align exactly. */
|
/* Align exactly. */
|
||||||
ret = SetPosition_hard( ms );
|
return SetPosition_hard( ms );
|
||||||
if( ret <= 0 )
|
|
||||||
MADLIB_rewind();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int RageSoundReader_MP3::SetPosition_Fast( int ms )
|
int RageSoundReader_MP3::SetPosition_Fast( int ms )
|
||||||
@@ -1050,19 +1050,11 @@ int RageSoundReader_MP3::SetPosition_Fast( int ms )
|
|||||||
|
|
||||||
/* We can do a fast jump in VBR with Xing with more accuracy than without Xing. */
|
/* We can do a fast jump in VBR with Xing with more accuracy than without Xing. */
|
||||||
if( mad->has_xing )
|
if( mad->has_xing )
|
||||||
{
|
return SetPosition_toc( ms, true );
|
||||||
int ret = SetPosition_toc( ms, true );
|
|
||||||
if( ret <= 0 )
|
|
||||||
MADLIB_rewind();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Guess. This is only remotely accurate when we're not VBR, but also
|
/* Guess. This is only remotely accurate when we're not VBR, but also
|
||||||
* do it if we have no Xing tag. */
|
* do it if we have no Xing tag. */
|
||||||
int ret = SetPosition_estimate( ms );
|
return SetPosition_estimate( ms );
|
||||||
if( ret <= 0 )
|
|
||||||
MADLIB_rewind();
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int RageSoundReader_MP3::GetLengthInternal( bool fast )
|
int RageSoundReader_MP3::GetLengthInternal( bool fast )
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ SoundReader_FileReader::OpenResult RageSoundReader_Vorbisfile::Open(CString file
|
|||||||
}
|
}
|
||||||
|
|
||||||
avail = 0;
|
avail = 0;
|
||||||
|
eof = false;
|
||||||
|
|
||||||
return OPEN_OK;
|
return OPEN_OK;
|
||||||
}
|
}
|
||||||
@@ -113,16 +114,19 @@ int RageSoundReader_Vorbisfile::GetLength_Fast() const
|
|||||||
int RageSoundReader_Vorbisfile::SetPosition(int ms, bool accurate)
|
int RageSoundReader_Vorbisfile::SetPosition(int ms, bool accurate)
|
||||||
{
|
{
|
||||||
avail = 0;
|
avail = 0;
|
||||||
|
eof = false;
|
||||||
|
|
||||||
#if defined(INTEGER_OGG)
|
const ogg_int64_t sample = ogg_int64_t(ms) * GetSampleRate() / 1000;
|
||||||
const int to = ms;
|
|
||||||
#else
|
|
||||||
const float to = ms/1000.0f;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int ret = ov_time_seek( vf, to );
|
int ret = ov_pcm_seek( vf, sample );
|
||||||
if(ret < 0)
|
if(ret < 0)
|
||||||
{
|
{
|
||||||
|
/* Returns OV_EINVAL on EOF. */
|
||||||
|
if( ret == OV_EINVAL )
|
||||||
|
{
|
||||||
|
eof = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
SetError( ov_ssprintf(ret, "ogg: SetPosition failed") );
|
SetError( ov_ssprintf(ret, "ogg: SetPosition failed") );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -132,6 +136,9 @@ int RageSoundReader_Vorbisfile::SetPosition(int ms, bool accurate)
|
|||||||
|
|
||||||
int RageSoundReader_Vorbisfile::Read(char *buf, unsigned len)
|
int RageSoundReader_Vorbisfile::Read(char *buf, unsigned len)
|
||||||
{
|
{
|
||||||
|
if( eof )
|
||||||
|
return 0;
|
||||||
|
|
||||||
int bytes_read = 0;
|
int bytes_read = 0;
|
||||||
while(len)
|
while(len)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class RageSoundReader_Vorbisfile: public SoundReader_FileReader {
|
|||||||
OggVorbis_File *vf;
|
OggVorbis_File *vf;
|
||||||
char buffer[4096*4];
|
char buffer[4096*4];
|
||||||
unsigned avail;
|
unsigned avail;
|
||||||
|
bool eof;
|
||||||
int SetPosition(int ms, bool accurate);
|
int SetPosition(int ms, bool accurate);
|
||||||
CString filename;
|
CString filename;
|
||||||
|
|
||||||
|
|||||||
@@ -188,6 +188,10 @@ int RageSoundReader_WAV::seek_sample_fmt_normal( Uint32 ms )
|
|||||||
int rc = fseek( this->rw, pos, SEEK_SET );
|
int rc = fseek( this->rw, pos, SEEK_SET );
|
||||||
BAIL_IF_MACRO(rc == -1, strerror(errno), -1);
|
BAIL_IF_MACRO(rc == -1, strerror(errno), -1);
|
||||||
|
|
||||||
|
/* If we seek past end of ifle, leave the cursor there, so subsequent reads will return EOF. */
|
||||||
|
if( pos >= (int) GetFileSizeInBytes( filename ) )
|
||||||
|
return 0;
|
||||||
|
|
||||||
return ms;
|
return ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,8 +347,13 @@ Uint32 RageSoundReader_WAV::read_sample_fmt_adpcm(char *buf, unsigned len)
|
|||||||
bw += this->fmt.adpcm_sample_frame_size;
|
bw += this->fmt.adpcm_sample_frame_size;
|
||||||
|
|
||||||
if( !first_sample_in_block && adpcm.samples_left_in_block )
|
if( !first_sample_in_block && adpcm.samples_left_in_block )
|
||||||
|
{
|
||||||
if (!decode_adpcm_sample_frame())
|
if (!decode_adpcm_sample_frame())
|
||||||
|
{
|
||||||
|
adpcm.samples_left_in_block = 0;
|
||||||
return bw;
|
return bw;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bw;
|
return bw;
|
||||||
@@ -364,15 +373,13 @@ int RageSoundReader_WAV::seek_sample_fmt_adpcm( Uint32 ms )
|
|||||||
|
|
||||||
/* The offset we need is in this block, so we need to decode to there. */
|
/* The offset we need is in this block, so we need to decode to there. */
|
||||||
rc = offset % bpb; /* bytes into this block we need to decode */
|
rc = offset % bpb; /* bytes into this block we need to decode */
|
||||||
|
adpcm.samples_left_in_block = 0;
|
||||||
|
|
||||||
if( rc == 0 )
|
if( rc == 0 )
|
||||||
{
|
|
||||||
adpcm.samples_left_in_block = 0;
|
|
||||||
return ms;
|
return ms;
|
||||||
}
|
|
||||||
|
|
||||||
if (!read_adpcm_block_headers(adpcm))
|
if (!read_adpcm_block_headers(adpcm))
|
||||||
{
|
{
|
||||||
fseek(this->rw, fmt.data_starting_offset, SEEK_SET);
|
|
||||||
adpcm.samples_left_in_block = 0;
|
adpcm.samples_left_in_block = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -387,7 +394,6 @@ int RageSoundReader_WAV::seek_sample_fmt_adpcm( Uint32 ms )
|
|||||||
|
|
||||||
if (!decode_adpcm_sample_frame())
|
if (!decode_adpcm_sample_frame())
|
||||||
{
|
{
|
||||||
fseek(this->rw, fmt.data_starting_offset, SEEK_SET);
|
|
||||||
adpcm.samples_left_in_block = 0;
|
adpcm.samples_left_in_block = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user