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:
int GetLength() const { return 0; }
int GetLength_Fast() const { return 0; }
int SetPosition_Accurate(int ms) { return 0; }
int SetPosition_Fast(int ms) { return 0; }
int SetPosition_Accurate( int iFrame ) { return 0; }
int SetPosition_Fast( int iFrame ) { return 0; }
int Read(char *buf, unsigned len) { return 0; }
RageSoundReader *Copy() const { return new RageSoundReader_Silence; }
int GetSampleRate() const { return 44100; }
@@ -720,16 +720,11 @@ bool RageSound::SetPositionFrames( int iFrames )
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;
if( m_Param.m_bAccurateSync )
iRet = m_pSource->SetPosition_Accurate(ms);
iRet = m_pSource->SetPosition_Accurate( iFrames );
else
iRet = m_pSource->SetPosition_Fast(ms);
iRet = m_pSource->SetPosition_Fast( iFrames );
if( iRet == -1 )
{
@@ -746,12 +741,12 @@ bool RageSound::SetPositionFrames( int 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 passed EOF. This could be a truncated file or invalid data. */
LOG->Warn( "SetPositionFrames: %i ms is beyond EOF in %s",
ms, GetLoadedFilePath().c_str() );
LOG->Warn( "SetPositionFrames: %i samples is beyond EOF in %s",
iFrames, GetLoadedFilePath().c_str() );
return false; /* failed */
}
+2 -2
View File
@@ -8,8 +8,8 @@ class RageSoundReader
public:
virtual int GetLength() const = 0; /* ms */
virtual int GetLength_Fast() const { return GetLength(); } /* ms */
virtual int SetPosition_Accurate( int ms ) = 0;
virtual int SetPosition_Fast( int ms ) { return SetPosition_Accurate(ms); }
virtual int SetPosition_Accurate( int iSample ) = 0;
virtual int SetPosition_Fast( int iSample ) { return SetPosition_Accurate(iSample); }
virtual int Read(char *buf, unsigned len) = 0;
virtual ~RageSoundReader() { }
virtual RageSoundReader *Copy() const = 0;
+8 -6
View File
@@ -151,30 +151,32 @@ void RageSoundReader_Chain::Finish()
sort( m_aSounds.begin(), m_aSounds.end() );
}
int RageSoundReader_Chain::SetPosition_Accurate( int ms )
int RageSoundReader_Chain::SetPosition_Accurate( int iFrame )
{
/* Clear m_apActiveSounds. */
while( !m_apActiveSounds.empty() )
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
* at ms. */
for( unsigned i = 0; i < m_aSounds.size(); ++i )
{
Sound &sound = m_aSounds[i];
int iOffsetFrame = sound.GetOffsetFrame( GetSampleRate() );
/* If this sound is in the future, skip it. */
if( sound.iOffsetMS > ms )
if( iOffsetFrame > iFrame )
continue;
/* Find the RageSoundReader. */
int n = ActivateSound( sound );
RageSoundReader *pSound = m_apActiveSounds[n].pSound;
int iOffsetMS = ms - sound.iOffsetMS;
if( pSound->SetPosition_Accurate(iOffsetMS) == 0 )
int iOffsetFrames = iFrame - iOffsetFrame;
if( pSound->SetPosition_Accurate(iOffsetFrames) == 0 )
{
/* We're past the end of this sound. */
ReleaseSound( n );
@@ -189,7 +191,7 @@ int RageSoundReader_Chain::SetPosition_Accurate( int ms )
if( m_apActiveSounds.empty() && m_iNextSound == m_aSounds.size() )
return 0;
return ms;
return iFrame;
}
unsigned RageSoundReader_Chain::ActivateSound( const Sound &s )
+2 -2
View File
@@ -28,10 +28,10 @@ public:
int GetLength() 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
* 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 GetSampleRate() const { return m_iActualSampleRate; }
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_Fast() const { return m_pSource->GetLength_Fast(); }
virtual int SetPosition_Accurate( int ms ) { return m_pSource->SetPosition_Accurate( ms ); }
virtual int SetPosition_Fast( int ms ) { return m_pSource->SetPosition_Fast( ms ); }
virtual int SetPosition_Accurate( int iFrame ) { return m_pSource->SetPosition_Accurate( iFrame ); }
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 GetSampleRate() const { return m_pSource->GetSampleRate(); }
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. */
int RageSoundReader_MP3::SetPosition_toc( int ms, bool Xing )
int RageSoundReader_MP3::SetPosition_toc( int iFrame, bool Xing )
{
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
* out what percentage the requested position falls in. */
int ms = int( (iFrame * 1000LL) / SampleRate );
percent = ms * 100 / mad->length;
if(percent >= 0)
@@ -836,7 +837,7 @@ int RageSoundReader_MP3::SetPosition_toc( int ms, bool Xing )
while( percent >= 0 && mad->toc[percent] == -1 )
percent--;
if( percent == -1 )
return ms; /* don't have any info */
return iFrame; /* don't have any info */
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_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. */
@@ -905,7 +906,7 @@ int RageSoundReader_MP3::SetPosition_hard( int ms )
* we're currently always using AUDIO_S16SYS. */
mad->outpos = 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
@@ -928,13 +929,13 @@ int RageSoundReader_MP3::SetPosition_hard( int ms )
}
/* 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. */
mad->timer_accurate = 0;
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 were asked to. */
@@ -963,27 +964,27 @@ int RageSoundReader_MP3::SetPosition_estimate( int ms )
mad->outleft = 0;
/* 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);
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. */
int ret = SetPosition_toc( ms, false );
int ret = SetPosition_toc( iFrame, false );
if( ret <= 0 )
return ret; /* it set the error */
/* 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. */
if( !ms )
if( !iFrame )
{
MADLIB_rewind();
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. */
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
* do it if we have no Xing tag. */
return SetPosition_estimate( ms );
return SetPosition_estimate( iFrame );
}
int RageSoundReader_MP3::GetNextSourceFrame() const
+5 -5
View File
@@ -15,8 +15,8 @@ public:
void Close();
int GetLength() const { return GetLengthConst(false); }
int GetLength_Fast() const { return GetLengthConst(true); }
int SetPosition_Accurate(int ms);
int SetPosition_Fast(int ms);
int SetPosition_Accurate( int iSample );
int SetPosition_Fast( int iSample );
int Read(char *buf, unsigned len);
int GetSampleRate() const { return SampleRate; }
int GetNextSourceFrame() const;
@@ -36,9 +36,9 @@ private:
bool MADLIB_rewind();
int SetPosition_toc( int ms, bool Xing );
int SetPosition_hard( int ms );
int SetPosition_estimate( int ms );
int SetPosition_toc( int iSample, bool Xing );
int SetPosition_hard( int iSample );
int SetPosition_estimate( int iSample );
int fill_buffer();
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();
}
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 = sample * samplesize;
m_iPosition = iFrame * samplesize;
m_iPosition = lrintf(m_iPosition / m_fRate);
if( m_iPosition >= int(m_Buffer->size()) )
@@ -107,12 +106,12 @@ int RageSoundReader_Preload::SetPosition_Accurate(int ms)
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
+2 -2
View File
@@ -15,8 +15,8 @@ public:
bool Open( RageSoundReader *pSource );
int GetLength() const;
int GetLength_Fast() const;
int SetPosition_Accurate( int iMS );
int SetPosition_Fast( int iMS );
int SetPosition_Accurate( int iFrame );
int SetPosition_Fast( int iFrame );
int Read( char *pBuffer, unsigned iLength );
int GetSampleRate() const { return m_iSampleRate; }
unsigned GetNumChannels() const { return m_iChannels; }
@@ -674,16 +674,23 @@ int RageSoundReader_Resample_Good::GetLength_Fast() const
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();
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();
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 )
@@ -16,8 +16,8 @@ public:
RageSoundReader_Resample_Good( const RageSoundReader_Resample_Good &cpy );
int GetLength() const;
int GetLength_Fast() const;
int SetPosition_Accurate( int iMS );
int SetPosition_Fast( int iMS );
int SetPosition_Accurate( int iFrame );
int SetPosition_Fast( int iFrame );
int Read( char *pBuf, unsigned iLen );
virtual ~RageSoundReader_Resample_Good();
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
* 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. */
int RageSoundReader_SpeedChange::SetPosition_Accurate( int iMS )
int RageSoundReader_SpeedChange::SetPosition_Accurate( int iFrame )
{
Reset();
int64_t iScaled = (int64_t(iMS) * GetWindowSizeFrames()) / m_iDeltaFrames;
iMS = (int) iScaled;
int64_t iScaled = (int64_t(iFrame) * GetWindowSizeFrames()) / m_iDeltaFrames;
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();
int64_t iScaled = (int64_t(iMS) * GetWindowSizeFrames()) / m_iDeltaFrames;
iMS = (int) iScaled;
int64_t iScaled = (int64_t(iFrame) * GetWindowSizeFrames()) / m_iDeltaFrames;
iFrame = (int) iScaled;
return RageSoundReader_Filter::SetPosition_Fast( iMS );
return RageSoundReader_Filter::SetPosition_Fast( iFrame );
}
bool RageSoundReader_SpeedChange::SetProperty( const RString &sProperty, float fValue )
+2 -2
View File
@@ -10,8 +10,8 @@ class RageSoundReader_SpeedChange: public RageSoundReader_Filter
public:
RageSoundReader_SpeedChange( RageSoundReader *pSource );
virtual int SetPosition_Accurate( int ms );
virtual int SetPosition_Fast( int ms );
virtual int SetPosition_Accurate( int iFrame );
virtual int SetPosition_Fast( int iFrame );
virtual int Read( char *buf, unsigned len );
virtual RageSoundReader_SpeedChange *Copy() const { return new RageSoundReader_SpeedChange(*this); }
virtual bool SetProperty( const RString &sProperty, float fValue );
+3 -3
View File
@@ -142,11 +142,11 @@ int RageSoundReader_Vorbisfile::GetLength_Fast() const
return GetLength();
}
int RageSoundReader_Vorbisfile::SetPosition(int ms, bool accurate)
int RageSoundReader_Vorbisfile::SetPosition( int iFrame, bool accurate )
{
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 );
if(ret < 0)
@@ -162,7 +162,7 @@ int RageSoundReader_Vorbisfile::SetPosition(int ms, bool accurate)
}
read_offset = (int) ov_pcm_tell(vf);
return ms;
return iFrame;
}
int RageSoundReader_Vorbisfile::Read(char *buf, unsigned len)
+3 -3
View File
@@ -16,8 +16,8 @@ public:
int GetLength() const;
int GetLength_Fast() const;
int SetPosition_Accurate(int ms) { return SetPosition( ms, true ); }
int SetPosition_Fast(int ms) { return SetPosition( ms, false ); }
int SetPosition_Accurate( int iFrame ) { return SetPosition( iFrame, true ); }
int SetPosition_Fast( int iFrame ) { return SetPosition( iFrame, false ); }
int Read(char *buf, unsigned len);
int GetSampleRate() const;
unsigned GetNumChannels() const { return channels; }
@@ -29,7 +29,7 @@ public:
private:
OggVorbis_File *vf;
bool eof;
int SetPosition( int ms, bool accurate );
int SetPosition( int iFrame, bool accurate );
bool FillBuf();
RString filename;
int read_offset;
+8 -11
View File
@@ -45,7 +45,7 @@ struct WavReader
virtual int Read( char *buf, unsigned len ) = 0;
virtual int GetLength() const = 0;
virtual bool Init() = 0;
virtual int SetPosition( int iMS ) = 0;
virtual int SetPosition( int iFrame ) = 0;
virtual int GetNextSourceFrame() const = 0;
RString GetError() const { return m_sError; }
@@ -102,11 +102,9 @@ struct WavReaderPCM: public WavReader
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(iMS) * iBytesPerSec) / 1000);
iByte = Quantize( iByte, m_WavData.m_iChannels * m_WavData.m_iBitsPerSample / 8 );
int iByte = (int) (int64_t(iFrame) * m_WavData.m_iChannels * m_WavData.m_iBitsPerSample / 8);
if( iByte > m_WavData.m_iDataChunkSize )
{
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 );
return int((int64_t(iByte) * 1000) / iBytesPerSec);
return iFrame;
}
// XXX: untested
@@ -330,9 +328,8 @@ public:
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;
m_iBufferUsed = m_iBufferAvail = 0;
@@ -359,7 +356,7 @@ public:
return 0;
}
return iMS;
return iFrame;
}
// XXX: untested
@@ -517,10 +514,10 @@ int RageSoundReader_WAV::GetLength() const
return m_pImpl->GetLength();
}
int RageSoundReader_WAV::SetPosition( int ms )
int RageSoundReader_WAV::SetPosition( int iFrame )
{
ASSERT( m_pImpl != NULL );
return m_pImpl->SetPosition( ms );
return m_pImpl->SetPosition( iFrame );
}
int RageSoundReader_WAV::GetNextSourceFrame() const
+3 -3
View File
@@ -14,8 +14,8 @@ public:
void Close();
int GetLength() const;
int GetLength_Fast() const { return GetLength(); }
int SetPosition_Accurate( int ms ) { return SetPosition(ms); }
int SetPosition_Fast( int ms ) { return SetPosition(ms); }
int SetPosition_Accurate( int iFrame ) { return SetPosition(iFrame); }
int SetPosition_Fast( int iFrame ) { return SetPosition(iFrame); }
int Read( char *buf, unsigned len );
int GetSampleRate() const { return m_WavData.m_iSampleRate; }
unsigned GetNumChannels() const { return m_WavData.m_iChannels; }
@@ -38,7 +38,7 @@ private:
WavReader *m_pImpl;
int SetPosition( int ms );
int SetPosition( int iFrame );
};
#endif