change SetPosition_Accurate and SetPosition_Fast to take and return frames
This commit is contained in:
@@ -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 */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 )
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|||||||
@@ -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(); }
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 )
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user