change SetPosition_Accurate and SetPosition_Fast to take and return frames

This commit is contained in:
Glenn Maynard
2006-12-09 06:35:09 +00:00
parent a272414497
commit ca67a9cb7c
17 changed files with 91 additions and 90 deletions
+7 -12
View File
@@ -153,8 +153,8 @@ class RageSoundReader_Silence: public RageSoundReader
public: public:
int GetLength() const { return 0; } int GetLength() const { return 0; }
int GetLength_Fast() const { return 0; } int GetLength_Fast() const { return 0; }
int SetPosition_Accurate(int ms) { return 0; } int SetPosition_Accurate( int iFrame ) { return 0; }
int SetPosition_Fast(int ms) { return 0; } int SetPosition_Fast( int iFrame ) { return 0; }
int Read(char *buf, unsigned len) { return 0; } int Read(char *buf, unsigned len) { return 0; }
RageSoundReader *Copy() const { return new RageSoundReader_Silence; } RageSoundReader *Copy() const { return new RageSoundReader_Silence; }
int GetSampleRate() const { return 44100; } int GetSampleRate() const { return 44100; }
@@ -720,16 +720,11 @@ bool RageSound::SetPositionFrames( int iFrames )
return false; return false;
} }
/* The position we're going to seek the input stream to. We have
* to do this in floating point to avoid overflow. */
int ms = int( float(iFrames) * 1000.f / samplerate() );
ms = max( ms, 0 );
int iRet; int iRet;
if( m_Param.m_bAccurateSync ) if( m_Param.m_bAccurateSync )
iRet = m_pSource->SetPosition_Accurate(ms); iRet = m_pSource->SetPosition_Accurate( iFrames );
else else
iRet = m_pSource->SetPosition_Fast(ms); iRet = m_pSource->SetPosition_Fast( iFrames );
if( iRet == -1 ) if( iRet == -1 )
{ {
@@ -746,12 +741,12 @@ bool RageSound::SetPositionFrames( int iFrames )
m_iStoppedSourceFrame = iFrames; m_iStoppedSourceFrame = iFrames;
} }
if( iRet == 0 && ms != 0 ) if( iRet == 0 && iFrames != 0 )
{ {
/* We were told to seek somewhere, and we got 0 instead, which means /* We were told to seek somewhere, and we got 0 instead, which means
* we passed EOF. This could be a truncated file or invalid data. */ * we passed EOF. This could be a truncated file or invalid data. */
LOG->Warn( "SetPositionFrames: %i ms is beyond EOF in %s", LOG->Warn( "SetPositionFrames: %i samples is beyond EOF in %s",
ms, GetLoadedFilePath().c_str() ); iFrames, GetLoadedFilePath().c_str() );
return false; /* failed */ return false; /* failed */
} }
+2 -2
View File
@@ -8,8 +8,8 @@ class RageSoundReader
public: public:
virtual int GetLength() const = 0; /* ms */ virtual int GetLength() const = 0; /* ms */
virtual int GetLength_Fast() const { return GetLength(); } /* ms */ virtual int GetLength_Fast() const { return GetLength(); } /* ms */
virtual int SetPosition_Accurate( int ms ) = 0; virtual int SetPosition_Accurate( int iSample ) = 0;
virtual int SetPosition_Fast( int ms ) { return SetPosition_Accurate(ms); } virtual int SetPosition_Fast( int iSample ) { return SetPosition_Accurate(iSample); }
virtual int Read(char *buf, unsigned len) = 0; virtual int Read(char *buf, unsigned len) = 0;
virtual ~RageSoundReader() { } virtual ~RageSoundReader() { }
virtual RageSoundReader *Copy() const = 0; virtual RageSoundReader *Copy() const = 0;
+8 -6
View File
@@ -151,30 +151,32 @@ void RageSoundReader_Chain::Finish()
sort( m_aSounds.begin(), m_aSounds.end() ); sort( m_aSounds.begin(), m_aSounds.end() );
} }
int RageSoundReader_Chain::SetPosition_Accurate( int ms ) int RageSoundReader_Chain::SetPosition_Accurate( int iFrame )
{ {
/* Clear m_apActiveSounds. */ /* Clear m_apActiveSounds. */
while( !m_apActiveSounds.empty() ) while( !m_apActiveSounds.empty() )
ReleaseSound( 0 ); ReleaseSound( 0 );
m_iCurrentFrame = int( int64_t(ms) * m_iActualSampleRate / 1000 ); m_iCurrentFrame = iFrame;
/* Run through all sounds in the chain, and activate all sounds which have data /* Run through all sounds in the chain, and activate all sounds which have data
* at ms. */ * at ms. */
for( unsigned i = 0; i < m_aSounds.size(); ++i ) for( unsigned i = 0; i < m_aSounds.size(); ++i )
{ {
Sound &sound = m_aSounds[i]; Sound &sound = m_aSounds[i];
int iOffsetFrame = sound.GetOffsetFrame( GetSampleRate() );
/* If this sound is in the future, skip it. */ /* If this sound is in the future, skip it. */
if( sound.iOffsetMS > ms ) if( iOffsetFrame > iFrame )
continue; continue;
/* Find the RageSoundReader. */ /* Find the RageSoundReader. */
int n = ActivateSound( sound ); int n = ActivateSound( sound );
RageSoundReader *pSound = m_apActiveSounds[n].pSound; RageSoundReader *pSound = m_apActiveSounds[n].pSound;
int iOffsetMS = ms - sound.iOffsetMS; int iOffsetFrames = iFrame - iOffsetFrame;
if( pSound->SetPosition_Accurate(iOffsetMS) == 0 ) if( pSound->SetPosition_Accurate(iOffsetFrames) == 0 )
{ {
/* We're past the end of this sound. */ /* We're past the end of this sound. */
ReleaseSound( n ); ReleaseSound( n );
@@ -189,7 +191,7 @@ int RageSoundReader_Chain::SetPosition_Accurate( int ms )
if( m_apActiveSounds.empty() && m_iNextSound == m_aSounds.size() ) if( m_apActiveSounds.empty() && m_iNextSound == m_aSounds.size() )
return 0; return 0;
return ms; return iFrame;
} }
unsigned RageSoundReader_Chain::ActivateSound( const Sound &s ) unsigned RageSoundReader_Chain::ActivateSound( const Sound &s )
+2 -2
View File
@@ -28,10 +28,10 @@ public:
int GetLength() const; int GetLength() const;
int GetLength_Fast() const; int GetLength_Fast() const;
int SetPosition_Accurate( int ms ); int SetPosition_Accurate( int iFrame );
/* It rarely makes sense to set an approximate time for a chained sound, since any /* It rarely makes sense to set an approximate time for a chained sound, since any
* error in overlap will become obvious. */ * error in overlap will become obvious. */
int SetPosition_Fast( int ms ) { return SetPosition_Accurate( ms ); } int SetPosition_Fast( int iFrame ) { return SetPosition_Accurate( iFrame ); }
int Read( char *buf, unsigned len ); int Read( char *buf, unsigned len );
int GetSampleRate() const { return m_iActualSampleRate; } int GetSampleRate() const { return m_iActualSampleRate; }
unsigned GetNumChannels() const { return m_iChannels; } unsigned GetNumChannels() const { return m_iChannels; }
+2 -2
View File
@@ -15,8 +15,8 @@ public:
virtual int GetLength() const { return m_pSource->GetLength(); } virtual int GetLength() const { return m_pSource->GetLength(); }
virtual int GetLength_Fast() const { return m_pSource->GetLength_Fast(); } virtual int GetLength_Fast() const { return m_pSource->GetLength_Fast(); }
virtual int SetPosition_Accurate( int ms ) { return m_pSource->SetPosition_Accurate( ms ); } virtual int SetPosition_Accurate( int iFrame ) { return m_pSource->SetPosition_Accurate( iFrame ); }
virtual int SetPosition_Fast( int ms ) { return m_pSource->SetPosition_Fast( ms ); } virtual int SetPosition_Fast( int iFrame ) { return m_pSource->SetPosition_Fast( iFrame ); }
virtual int Read( char *pBuf, unsigned iLen ) { return m_pSource->Read( pBuf, iLen ); } virtual int Read( char *pBuf, unsigned iLen ) { return m_pSource->Read( pBuf, iLen ); }
virtual int GetSampleRate() const { return m_pSource->GetSampleRate(); } virtual int GetSampleRate() const { return m_pSource->GetSampleRate(); }
virtual unsigned GetNumChannels() const { return m_pSource->GetNumChannels(); } virtual unsigned GetNumChannels() const { return m_pSource->GetNumChannels(); }
+18 -17
View File
@@ -801,7 +801,7 @@ bool RageSoundReader_MP3::MADLIB_rewind()
*/ */
/* Returns actual position on success, 0 if past EOF, -1 on error. */ /* Returns actual position on success, 0 if past EOF, -1 on error. */
int RageSoundReader_MP3::SetPosition_toc( int ms, bool Xing ) int RageSoundReader_MP3::SetPosition_toc( int iFrame, bool Xing )
{ {
int percent; int percent;
@@ -814,6 +814,7 @@ int RageSoundReader_MP3::SetPosition_toc( int ms, bool Xing )
/* We can speed up the seek using the XING tag. First, figure /* We can speed up the seek using the XING tag. First, figure
* out what percentage the requested position falls in. */ * out what percentage the requested position falls in. */
int ms = int( (iFrame * 1000LL) / SampleRate );
percent = ms * 100 / mad->length; percent = ms * 100 / mad->length;
if(percent >= 0) if(percent >= 0)
@@ -836,7 +837,7 @@ int RageSoundReader_MP3::SetPosition_toc( int ms, bool Xing )
while( percent >= 0 && mad->toc[percent] == -1 ) while( percent >= 0 && mad->toc[percent] == -1 )
percent--; percent--;
if( percent == -1 ) if( percent == -1 )
return ms; /* don't have any info */ return iFrame; /* don't have any info */
bytepos = mad->toc[percent]; bytepos = mad->toc[percent];
} }
@@ -859,13 +860,13 @@ int RageSoundReader_MP3::SetPosition_toc( int ms, bool Xing )
} }
} }
return ms; return iFrame;
} }
int RageSoundReader_MP3::SetPosition_hard( int ms ) int RageSoundReader_MP3::SetPosition_hard( int iFrame )
{ {
mad_timer_t desired; mad_timer_t desired;
mad_timer_set( &desired, 0, ms, 1000 ); mad_timer_set( &desired, 0, iFrame, mad->Frame.header.samplerate );
/* This seek doesn't change the accuracy of our timer. */ /* This seek doesn't change the accuracy of our timer. */
@@ -905,7 +906,7 @@ int RageSoundReader_MP3::SetPosition_hard( int ms )
* we're currently always using AUDIO_S16SYS. */ * we're currently always using AUDIO_S16SYS. */
mad->outpos = samples * 2 * this->Channels; mad->outpos = samples * 2 * this->Channels;
mad->outleft -= samples * 2 * this->Channels; mad->outleft -= samples * 2 * this->Channels;
return ms; return iFrame;
} }
/* Otherwise, if the desired time will be in the *next* decode, then synth /* Otherwise, if the desired time will be in the *next* decode, then synth
@@ -928,13 +929,13 @@ int RageSoundReader_MP3::SetPosition_hard( int ms )
} }
/* Do a seek based on the bitrate. */ /* Do a seek based on the bitrate. */
int RageSoundReader_MP3::SetPosition_estimate( int ms ) int RageSoundReader_MP3::SetPosition_estimate( int iFrame )
{ {
/* This doesn't leave us accurate. */ /* This doesn't leave us accurate. */
mad->timer_accurate = 0; mad->timer_accurate = 0;
mad_timer_t seekamt; mad_timer_t seekamt;
mad_timer_set( &seekamt, 0, ms, 1000 ); mad_timer_set( &seekamt, 0, iFrame, mad->Frame.header.samplerate );
{ {
/* We're going to skip ahead two samples below, so seek earlier than /* We're going to skip ahead two samples below, so seek earlier than
* we were asked to. */ * we were asked to. */
@@ -963,27 +964,27 @@ int RageSoundReader_MP3::SetPosition_estimate( int ms )
mad->outleft = 0; mad->outleft = 0;
/* Find out where we really seeked to. */ /* Find out where we really seeked to. */
ms = (get_this_frame_byte(mad) - mad->header_bytes) / (mad->bitrate / 8 / 1000); int ms = (get_this_frame_byte(mad) - mad->header_bytes) / (mad->bitrate / 8 / 1000);
mad_timer_set(&mad->Timer, 0, ms, 1000); mad_timer_set(&mad->Timer, 0, ms, 1000);
return ms; return iFrame;
} }
int RageSoundReader_MP3::SetPosition_Accurate( int ms ) int RageSoundReader_MP3::SetPosition_Accurate( int iFrame )
{ {
/* Seek using our own internal (accurate) TOC. */ /* Seek using our own internal (accurate) TOC. */
int ret = SetPosition_toc( ms, false ); int ret = SetPosition_toc( iFrame, false );
if( ret <= 0 ) if( ret <= 0 )
return ret; /* it set the error */ return ret; /* it set the error */
/* Align exactly. */ /* Align exactly. */
return SetPosition_hard( ms ); return SetPosition_hard( iFrame );
} }
int RageSoundReader_MP3::SetPosition_Fast( int ms ) int RageSoundReader_MP3::SetPosition_Fast( int iFrame )
{ {
/* Rewinding is always fast and accurate, and SetPosition_estimate is bad at 0. */ /* Rewinding is always fast and accurate, and SetPosition_estimate is bad at 0. */
if( !ms ) if( !iFrame )
{ {
MADLIB_rewind(); MADLIB_rewind();
return 0; /* ok */ return 0; /* ok */
@@ -991,11 +992,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 ); return SetPosition_toc( iFrame, true );
/* 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. */
return SetPosition_estimate( ms ); return SetPosition_estimate( iFrame );
} }
int RageSoundReader_MP3::GetNextSourceFrame() const int RageSoundReader_MP3::GetNextSourceFrame() const
+5 -5
View File
@@ -15,8 +15,8 @@ public:
void Close(); void Close();
int GetLength() const { return GetLengthConst(false); } int GetLength() const { return GetLengthConst(false); }
int GetLength_Fast() const { return GetLengthConst(true); } int GetLength_Fast() const { return GetLengthConst(true); }
int SetPosition_Accurate(int ms); int SetPosition_Accurate( int iSample );
int SetPosition_Fast(int ms); int SetPosition_Fast( int iSample );
int Read(char *buf, unsigned len); int Read(char *buf, unsigned len);
int GetSampleRate() const { return SampleRate; } int GetSampleRate() const { return SampleRate; }
int GetNextSourceFrame() const; int GetNextSourceFrame() const;
@@ -36,9 +36,9 @@ private:
bool MADLIB_rewind(); bool MADLIB_rewind();
int SetPosition_toc( int ms, bool Xing ); int SetPosition_toc( int iSample, bool Xing );
int SetPosition_hard( int ms ); int SetPosition_hard( int iSample );
int SetPosition_estimate( int ms ); int SetPosition_estimate( int iSample );
int fill_buffer(); int fill_buffer();
int do_mad_frame_decode( bool headers_only=false ); int do_mad_frame_decode( bool headers_only=false );
+5 -6
View File
@@ -95,10 +95,9 @@ int RageSoundReader_Preload::GetLength_Fast() const
return GetLength(); return GetLength();
} }
int RageSoundReader_Preload::SetPosition_Accurate(int ms) int RageSoundReader_Preload::SetPosition_Accurate( int iFrame )
{ {
const int sample = int((ms / 1000.0f) * m_iSampleRate); m_iPosition = iFrame * samplesize;
m_iPosition = sample * samplesize;
m_iPosition = lrintf(m_iPosition / m_fRate); m_iPosition = lrintf(m_iPosition / m_fRate);
if( m_iPosition >= int(m_Buffer->size()) ) if( m_iPosition >= int(m_Buffer->size()) )
@@ -107,12 +106,12 @@ int RageSoundReader_Preload::SetPosition_Accurate(int ms)
return 0; return 0;
} }
return ms; return iFrame;
} }
int RageSoundReader_Preload::SetPosition_Fast( int iMS ) int RageSoundReader_Preload::SetPosition_Fast( int iFrame )
{ {
return SetPosition_Accurate( iMS ); return SetPosition_Accurate( iFrame );
} }
int RageSoundReader_Preload::GetNextSourceFrame() const int RageSoundReader_Preload::GetNextSourceFrame() const
+2 -2
View File
@@ -15,8 +15,8 @@ public:
bool Open( RageSoundReader *pSource ); bool Open( RageSoundReader *pSource );
int GetLength() const; int GetLength() const;
int GetLength_Fast() const; int GetLength_Fast() const;
int SetPosition_Accurate( int iMS ); int SetPosition_Accurate( int iFrame );
int SetPosition_Fast( int iMS ); int SetPosition_Fast( int iFrame );
int Read( char *pBuffer, unsigned iLength ); int Read( char *pBuffer, unsigned iLength );
int GetSampleRate() const { return m_iSampleRate; } int GetSampleRate() const { return m_iSampleRate; }
unsigned GetNumChannels() const { return m_iChannels; } unsigned GetNumChannels() const { return m_iChannels; }
@@ -674,16 +674,23 @@ int RageSoundReader_Resample_Good::GetLength_Fast() const
return m_pSource->GetLength_Fast(); return m_pSource->GetLength_Fast();
} }
int RageSoundReader_Resample_Good::SetPosition_Accurate( int iMS ) /* iFrame is in the destination rate. Seek the source in its own sample rate. */
int RageSoundReader_Resample_Good::SetPosition_Accurate( int iFrame )
{ {
Reset(); Reset();
return m_pSource->SetPosition_Accurate( iMS ); iFrame = (int) SCALE( iFrame, 0, (int64_t) m_iSampleRate, 0, (int64_t) m_pSource->GetSampleRate() );
iFrame = m_pSource->SetPosition_Accurate( iFrame );
iFrame = (int) SCALE( iFrame, 0, (int64_t) m_pSource->GetSampleRate(), 0, (int64_t) m_iSampleRate );
return iFrame;
} }
int RageSoundReader_Resample_Good::SetPosition_Fast( int iMS ) int RageSoundReader_Resample_Good::SetPosition_Fast( int iFrame )
{ {
Reset(); Reset();
return m_pSource->SetPosition_Fast( iMS ); iFrame = (int) SCALE( iFrame, 0, (int64_t) m_iSampleRate, 0, (int64_t) m_pSource->GetSampleRate() );
iFrame = m_pSource->SetPosition_Fast( iFrame );
iFrame = (int) SCALE( iFrame, 0, (int64_t) m_pSource->GetSampleRate(), 0, (int64_t) m_iSampleRate );
return iFrame;
} }
int RageSoundReader_Resample_Good::Read( char *pBuf_, unsigned iLen ) int RageSoundReader_Resample_Good::Read( char *pBuf_, unsigned iLen )
@@ -16,8 +16,8 @@ public:
RageSoundReader_Resample_Good( const RageSoundReader_Resample_Good &cpy ); RageSoundReader_Resample_Good( const RageSoundReader_Resample_Good &cpy );
int GetLength() const; int GetLength() const;
int GetLength_Fast() const; int GetLength_Fast() const;
int SetPosition_Accurate( int iMS ); int SetPosition_Accurate( int iFrame );
int SetPosition_Fast( int iMS ); int SetPosition_Fast( int iFrame );
int Read( char *pBuf, unsigned iLen ); int Read( char *pBuf, unsigned iLen );
virtual ~RageSoundReader_Resample_Good(); virtual ~RageSoundReader_Resample_Good();
RageSoundReader_Resample_Good *Copy() const; RageSoundReader_Resample_Good *Copy() const;
@@ -282,24 +282,24 @@ int RageSoundReader_SpeedChange::Read( char *buf, unsigned iLen )
/* We prefer to be able to seek precisely, so seeking to a position produces data /* We prefer to be able to seek precisely, so seeking to a position produces data
* equal to what you'd get if you read data up to that point. This filter can't do * equal to what you'd get if you read data up to that point. This filter can't do
* that, because the exact selection of slices is dependent on the previous selection. */ * that, because the exact selection of slices is dependent on the previous selection. */
int RageSoundReader_SpeedChange::SetPosition_Accurate( int iMS ) int RageSoundReader_SpeedChange::SetPosition_Accurate( int iFrame )
{ {
Reset(); Reset();
int64_t iScaled = (int64_t(iMS) * GetWindowSizeFrames()) / m_iDeltaFrames; int64_t iScaled = (int64_t(iFrame) * GetWindowSizeFrames()) / m_iDeltaFrames;
iMS = (int) iScaled; iFrame = (int) iScaled;
return RageSoundReader_Filter::SetPosition_Accurate( iMS ); return RageSoundReader_Filter::SetPosition_Accurate( iFrame );
} }
int RageSoundReader_SpeedChange::SetPosition_Fast( int iMS ) int RageSoundReader_SpeedChange::SetPosition_Fast( int iFrame )
{ {
Reset(); Reset();
int64_t iScaled = (int64_t(iMS) * GetWindowSizeFrames()) / m_iDeltaFrames; int64_t iScaled = (int64_t(iFrame) * GetWindowSizeFrames()) / m_iDeltaFrames;
iMS = (int) iScaled; iFrame = (int) iScaled;
return RageSoundReader_Filter::SetPosition_Fast( iMS ); return RageSoundReader_Filter::SetPosition_Fast( iFrame );
} }
bool RageSoundReader_SpeedChange::SetProperty( const RString &sProperty, float fValue ) bool RageSoundReader_SpeedChange::SetProperty( const RString &sProperty, float fValue )
+2 -2
View File
@@ -10,8 +10,8 @@ class RageSoundReader_SpeedChange: public RageSoundReader_Filter
public: public:
RageSoundReader_SpeedChange( RageSoundReader *pSource ); RageSoundReader_SpeedChange( RageSoundReader *pSource );
virtual int SetPosition_Accurate( int ms ); virtual int SetPosition_Accurate( int iFrame );
virtual int SetPosition_Fast( int ms ); virtual int SetPosition_Fast( int iFrame );
virtual int Read( char *buf, unsigned len ); virtual int Read( char *buf, unsigned len );
virtual RageSoundReader_SpeedChange *Copy() const { return new RageSoundReader_SpeedChange(*this); } virtual RageSoundReader_SpeedChange *Copy() const { return new RageSoundReader_SpeedChange(*this); }
virtual bool SetProperty( const RString &sProperty, float fValue ); virtual bool SetProperty( const RString &sProperty, float fValue );
+3 -3
View File
@@ -142,11 +142,11 @@ int RageSoundReader_Vorbisfile::GetLength_Fast() const
return GetLength(); return GetLength();
} }
int RageSoundReader_Vorbisfile::SetPosition(int ms, bool accurate) int RageSoundReader_Vorbisfile::SetPosition( int iFrame, bool accurate )
{ {
eof = false; eof = false;
const ogg_int64_t sample = ogg_int64_t(ms) * GetSampleRate() / 1000; const ogg_int64_t sample = ogg_int64_t(iFrame);
int ret = ov_pcm_seek( vf, sample ); int ret = ov_pcm_seek( vf, sample );
if(ret < 0) if(ret < 0)
@@ -162,7 +162,7 @@ int RageSoundReader_Vorbisfile::SetPosition(int ms, bool accurate)
} }
read_offset = (int) ov_pcm_tell(vf); read_offset = (int) ov_pcm_tell(vf);
return ms; return iFrame;
} }
int RageSoundReader_Vorbisfile::Read(char *buf, unsigned len) int RageSoundReader_Vorbisfile::Read(char *buf, unsigned len)
+3 -3
View File
@@ -16,8 +16,8 @@ public:
int GetLength() const; int GetLength() const;
int GetLength_Fast() const; int GetLength_Fast() const;
int SetPosition_Accurate(int ms) { return SetPosition( ms, true ); } int SetPosition_Accurate( int iFrame ) { return SetPosition( iFrame, true ); }
int SetPosition_Fast(int ms) { return SetPosition( ms, false ); } int SetPosition_Fast( int iFrame ) { return SetPosition( iFrame, false ); }
int Read(char *buf, unsigned len); int Read(char *buf, unsigned len);
int GetSampleRate() const; int GetSampleRate() const;
unsigned GetNumChannels() const { return channels; } unsigned GetNumChannels() const { return channels; }
@@ -29,7 +29,7 @@ public:
private: private:
OggVorbis_File *vf; OggVorbis_File *vf;
bool eof; bool eof;
int SetPosition( int ms, bool accurate ); int SetPosition( int iFrame, bool accurate );
bool FillBuf(); bool FillBuf();
RString filename; RString filename;
int read_offset; int read_offset;
+8 -11
View File
@@ -45,7 +45,7 @@ struct WavReader
virtual int Read( char *buf, unsigned len ) = 0; virtual int Read( char *buf, unsigned len ) = 0;
virtual int GetLength() const = 0; virtual int GetLength() const = 0;
virtual bool Init() = 0; virtual bool Init() = 0;
virtual int SetPosition( int iMS ) = 0; virtual int SetPosition( int iFrame ) = 0;
virtual int GetNextSourceFrame() const = 0; virtual int GetNextSourceFrame() const = 0;
RString GetError() const { return m_sError; } RString GetError() const { return m_sError; }
@@ -102,11 +102,9 @@ struct WavReaderPCM: public WavReader
return (int) iMS; return (int) iMS;
} }
int SetPosition( int iMS ) int SetPosition( int iFrame )
{ {
const int iBytesPerSec = m_WavData.m_iSampleRate * m_WavData.m_iChannels * m_WavData.m_iBitsPerSample / 8; int iByte = (int) (int64_t(iFrame) * m_WavData.m_iChannels * m_WavData.m_iBitsPerSample / 8);
int iByte = (int) ((int64_t(iMS) * iBytesPerSec) / 1000);
iByte = Quantize( iByte, m_WavData.m_iChannels * m_WavData.m_iBitsPerSample / 8 );
if( iByte > m_WavData.m_iDataChunkSize ) if( iByte > m_WavData.m_iDataChunkSize )
{ {
m_File.Seek( m_WavData.m_iDataChunkSize+m_WavData.m_iDataChunkPos ); m_File.Seek( m_WavData.m_iDataChunkSize+m_WavData.m_iDataChunkPos );
@@ -114,7 +112,7 @@ struct WavReaderPCM: public WavReader
} }
m_File.Seek( iByte+m_WavData.m_iDataChunkPos ); m_File.Seek( iByte+m_WavData.m_iDataChunkPos );
return int((int64_t(iByte) * 1000) / iBytesPerSec); return iFrame;
} }
// XXX: untested // XXX: untested
@@ -330,9 +328,8 @@ public:
return iMS; return iMS;
} }
int SetPosition( int iMS ) int SetPosition( int iFrame )
{ {
const int iFrame = int((int64_t(iMS) * m_WavData.m_iSampleRate) / 1000);
const int iBlock = iFrame / m_iFramesPerBlock; const int iBlock = iFrame / m_iFramesPerBlock;
m_iBufferUsed = m_iBufferAvail = 0; m_iBufferUsed = m_iBufferAvail = 0;
@@ -359,7 +356,7 @@ public:
return 0; return 0;
} }
return iMS; return iFrame;
} }
// XXX: untested // XXX: untested
@@ -517,10 +514,10 @@ int RageSoundReader_WAV::GetLength() const
return m_pImpl->GetLength(); return m_pImpl->GetLength();
} }
int RageSoundReader_WAV::SetPosition( int ms ) int RageSoundReader_WAV::SetPosition( int iFrame )
{ {
ASSERT( m_pImpl != NULL ); ASSERT( m_pImpl != NULL );
return m_pImpl->SetPosition( ms ); return m_pImpl->SetPosition( iFrame );
} }
int RageSoundReader_WAV::GetNextSourceFrame() const int RageSoundReader_WAV::GetNextSourceFrame() const
+3 -3
View File
@@ -14,8 +14,8 @@ public:
void Close(); void Close();
int GetLength() const; int GetLength() const;
int GetLength_Fast() const { return GetLength(); } int GetLength_Fast() const { return GetLength(); }
int SetPosition_Accurate( int ms ) { return SetPosition(ms); } int SetPosition_Accurate( int iFrame ) { return SetPosition(iFrame); }
int SetPosition_Fast( int ms ) { return SetPosition(ms); } int SetPosition_Fast( int iFrame ) { return SetPosition(iFrame); }
int Read( char *buf, unsigned len ); int Read( char *buf, unsigned len );
int GetSampleRate() const { return m_WavData.m_iSampleRate; } int GetSampleRate() const { return m_WavData.m_iSampleRate; }
unsigned GetNumChannels() const { return m_WavData.m_iChannels; } unsigned GetNumChannels() const { return m_WavData.m_iChannels; }
@@ -38,7 +38,7 @@ private:
WavReader *m_pImpl; WavReader *m_pImpl;
int SetPosition( int ms ); int SetPosition( int iFrame );
}; };
#endif #endif