RageSoundReader::Read(buf, unsigned bytes) -> (buf, int frames);
return value in frames, not bytes
This commit is contained in:
@@ -156,7 +156,7 @@ public:
|
|||||||
int GetLength_Fast() const { return 0; }
|
int GetLength_Fast() const { return 0; }
|
||||||
int SetPosition_Accurate( int iFrame ) { return 0; }
|
int SetPosition_Accurate( int iFrame ) { return 0; }
|
||||||
int SetPosition_Fast( int iFrame ) { return 0; }
|
int SetPosition_Fast( int iFrame ) { return 0; }
|
||||||
int Read(char *buf, unsigned len) { return 0; }
|
int Read( char *buf, int iFrames ) { 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; }
|
||||||
bool IsStreamingFromDisk() const { return false; }
|
bool IsStreamingFromDisk() const { return false; }
|
||||||
@@ -288,8 +288,7 @@ int RageSound::GetData( char *pBuffer, int iFrames )
|
|||||||
|
|
||||||
fRate = m_pSource->GetStreamToSourceRatio();
|
fRate = m_pSource->GetStreamToSourceRatio();
|
||||||
int iNewSourceFrame = m_pSource->GetNextSourceFrame();
|
int iNewSourceFrame = m_pSource->GetNextSourceFrame();
|
||||||
int iReadSize = iFrames * sizeof(int16_t) * m_pSource->GetNumChannels();
|
iGotFrames = m_pSource->Read( pBuffer, iFrames );
|
||||||
iGotFrames = m_pSource->Read( pBuffer, iReadSize );
|
|
||||||
if( iGotFrames == -1 )
|
if( iGotFrames == -1 )
|
||||||
{
|
{
|
||||||
Fail( m_pSource->GetError() );
|
Fail( m_pSource->GetError() );
|
||||||
@@ -297,7 +296,6 @@ int RageSound::GetData( char *pBuffer, int iFrames )
|
|||||||
/* Pretend we got EOF. */
|
/* Pretend we got EOF. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
iGotFrames /= sizeof(int16_t) * m_pSource->GetNumChannels();
|
|
||||||
|
|
||||||
/* If we didn't get any data, don't update iSourceFrame, so we just keep
|
/* If we didn't get any data, don't update iSourceFrame, so we just keep
|
||||||
* extrapolating if we're in M_CONTINUE. */
|
* extrapolating if we're in M_CONTINUE. */
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public:
|
|||||||
virtual int GetLength_Fast() const { return GetLength(); } /* ms */
|
virtual int GetLength_Fast() const { return GetLength(); } /* ms */
|
||||||
virtual int SetPosition_Accurate( int iSample ) = 0;
|
virtual int SetPosition_Accurate( int iSample ) = 0;
|
||||||
virtual int SetPosition_Fast( int iSample ) { return SetPosition_Accurate(iSample); }
|
virtual int SetPosition_Fast( int iSample ) { return SetPosition_Accurate(iSample); }
|
||||||
virtual int Read(char *buf, unsigned len) = 0;
|
virtual int Read( char *pBuf, int iFrames ) = 0;
|
||||||
virtual ~RageSoundReader() { }
|
virtual ~RageSoundReader() { }
|
||||||
virtual RageSoundReader *Copy() const = 0;
|
virtual RageSoundReader *Copy() const = 0;
|
||||||
virtual int GetSampleRate() const = 0;
|
virtual int GetSampleRate() const = 0;
|
||||||
|
|||||||
@@ -345,10 +345,10 @@ int RageSoundReader_Chain::ReadBlock( int16_t *pBuffer, int iFrames )
|
|||||||
/* We have only one source, and it matches our target. Don't mix; read
|
/* We have only one source, and it matches our target. Don't mix; read
|
||||||
* directly from the source into the destination. This is to optimize
|
* directly from the source into the destination. This is to optimize
|
||||||
* the common case of having one BGM track and no autoplay sounds. */
|
* the common case of having one BGM track and no autoplay sounds. */
|
||||||
int iBytes = m_apActiveSounds.front()->pSound->Read( (char *) pBuffer, iFrames * sizeof(int16_t) * m_iChannels );
|
iFrames = m_apActiveSounds.front()->pSound->Read( (char *) pBuffer, iFrames );
|
||||||
if( iBytes == 0 )
|
if( iFrames == 0 )
|
||||||
ReleaseSound( m_apActiveSounds.front() );
|
ReleaseSound( m_apActiveSounds.front() );
|
||||||
return iBytes / (sizeof(int16_t) * m_iChannels);
|
return iFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_apActiveSounds.empty() )
|
if( m_apActiveSounds.empty() )
|
||||||
@@ -369,20 +369,17 @@ int RageSoundReader_Chain::ReadBlock( int16_t *pBuffer, int iFrames )
|
|||||||
RageSoundReader *pSound = m_apActiveSounds[i]->pSound;
|
RageSoundReader *pSound = m_apActiveSounds[i]->pSound;
|
||||||
ASSERT( pSound->GetNumChannels() == m_iChannels ); // guaranteed by ActivateSound and Finish
|
ASSERT( pSound->GetNumChannels() == m_iChannels ); // guaranteed by ActivateSound and Finish
|
||||||
int iSamples = min( iFrames * pSound->GetNumChannels(), ARRAYLEN(Buffer) );
|
int iSamples = min( iFrames * pSound->GetNumChannels(), ARRAYLEN(Buffer) );
|
||||||
int iBytesRead = pSound->Read( (char *) Buffer, iSamples*sizeof(int16_t) );
|
int iFramesRead = pSound->Read( (char *) Buffer, iSamples/pSound->GetNumChannels() );
|
||||||
if( iBytesRead == -1 || iBytesRead == 0 )
|
if( iFramesRead == -1 || iFramesRead == 0 )
|
||||||
{
|
{
|
||||||
/* The sound is at EOF. Release it. */
|
/* The sound is at EOF. Release it. */
|
||||||
ReleaseSound( m_apActiveSounds[i] );
|
ReleaseSound( m_apActiveSounds[i] );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iSamplesRead = iBytesRead / sizeof(int16_t);
|
|
||||||
int iFramesRead = iSamplesRead / pSound->GetNumChannels();
|
|
||||||
|
|
||||||
iMaxFramesRead = max( iMaxFramesRead, iFramesRead );
|
iMaxFramesRead = max( iMaxFramesRead, iFramesRead );
|
||||||
|
|
||||||
mix.write( Buffer, iSamplesRead );
|
mix.write( Buffer, iFramesRead * sizeof(int16_t) * pSound->GetNumChannels() );
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,20 +389,19 @@ int RageSoundReader_Chain::ReadBlock( int16_t *pBuffer, int iFrames )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int RageSoundReader_Chain::Read( char *pBuffer, unsigned iLength )
|
int RageSoundReader_Chain::Read( char *pBuffer, int iFrames )
|
||||||
{
|
{
|
||||||
int iNumFramesToRead = iLength / (sizeof(int16_t) * m_iChannels);
|
|
||||||
int iTotalFramesRead = 0;
|
int iTotalFramesRead = 0;
|
||||||
|
|
||||||
/* If we have no sources, and no more sounds to play, EOF. */
|
/* If we have no sources, and no more sounds to play, EOF. */
|
||||||
while( iNumFramesToRead > 0 && (!m_apActiveSounds.empty() || m_iNextSound < m_aSounds.size()) )
|
while( iFrames > 0 && (!m_apActiveSounds.empty() || m_iNextSound < m_aSounds.size()) )
|
||||||
{
|
{
|
||||||
int iFramesRead = ReadBlock( (int16_t *) pBuffer, iNumFramesToRead );
|
int iFramesRead = ReadBlock( (int16_t *) pBuffer, iFrames );
|
||||||
if( iFramesRead == -1 )
|
if( iFramesRead == -1 )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
m_iCurrentFrame += iFramesRead;
|
m_iCurrentFrame += iFramesRead;
|
||||||
iNumFramesToRead -= iFramesRead;
|
iFrames -= iFramesRead;
|
||||||
iTotalFramesRead += iFramesRead;
|
iTotalFramesRead += iFramesRead;
|
||||||
pBuffer += iFramesRead * sizeof(int16_t) * m_iChannels;
|
pBuffer += iFramesRead * sizeof(int16_t) * m_iChannels;
|
||||||
|
|
||||||
@@ -417,7 +413,7 @@ int RageSoundReader_Chain::Read( char *pBuffer, unsigned iLength )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return iTotalFramesRead * sizeof(int16_t) * m_iChannels;
|
return iTotalFramesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RageSoundReader_Chain::GetLength() const
|
int RageSoundReader_Chain::GetLength() const
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public:
|
|||||||
/* 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 iFrame ) { return SetPosition_Accurate( iFrame ); }
|
int SetPosition_Fast( int iFrame ) { return SetPosition_Accurate( iFrame ); }
|
||||||
int Read( char *buf, unsigned len );
|
int Read( char *pBuf, int iFrames );
|
||||||
int GetSampleRate() const { return m_iActualSampleRate; }
|
int GetSampleRate() const { return m_iActualSampleRate; }
|
||||||
unsigned GetNumChannels() const { return m_iChannels; }
|
unsigned GetNumChannels() const { return m_iChannels; }
|
||||||
bool IsStreamingFromDisk() const;
|
bool IsStreamingFromDisk() const;
|
||||||
|
|||||||
@@ -107,9 +107,9 @@ bool RageSoundReader_Split::SetProperty( const RString &sProperty, float fValue
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RageSoundReader_Split::Read( char *pBuf, unsigned iBytes )
|
int RageSoundReader_Split::Read( char *pBuf, int iFrames )
|
||||||
{
|
{
|
||||||
m_iRequestFrames = iBytes / (sizeof(int16_t) * m_iNumOutputChannels);
|
m_iRequestFrames = iFrames;
|
||||||
if( !m_pImpl->ReadBuffer() )
|
if( !m_pImpl->ReadBuffer() )
|
||||||
{
|
{
|
||||||
this->SetError( m_pImpl->m_pSource->GetError() );
|
this->SetError( m_pImpl->m_pSource->GetError() );
|
||||||
@@ -126,7 +126,7 @@ int RageSoundReader_Split::Read( char *pBuf, unsigned iBytes )
|
|||||||
iBytesAvailable -= iSkipBytes;
|
iBytesAvailable -= iSkipBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iFramesWanted = iBytes / (sizeof(int16_t) * m_iNumOutputChannels);
|
int iFramesWanted = iFrames;
|
||||||
int iFramesAvailable = iBytesAvailable / (sizeof(int16_t) * m_pImpl->m_pSource->GetNumChannels());
|
int iFramesAvailable = iBytesAvailable / (sizeof(int16_t) * m_pImpl->m_pSource->GetNumChannels());
|
||||||
iFramesAvailable = min( iFramesAvailable, iFramesWanted );
|
iFramesAvailable = min( iFramesAvailable, iFramesWanted );
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ int RageSoundReader_Split::Read( char *pBuf, unsigned iBytes )
|
|||||||
* memory can be freed. */
|
* memory can be freed. */
|
||||||
m_iRequestFrames = 0;
|
m_iRequestFrames = 0;
|
||||||
m_pImpl->ReadBuffer();
|
m_pImpl->ReadBuffer();
|
||||||
return iFramesAvailable * (sizeof(int16_t) * m_iNumOutputChannels);
|
return iFramesAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RageSoundSplitterImpl::ReadBuffer()
|
bool RageSoundSplitterImpl::ReadBuffer()
|
||||||
@@ -186,13 +186,14 @@ bool RageSoundSplitterImpl::ReadBuffer()
|
|||||||
int iBytesToRead = iFramesToRead * sizeof(int16_t) * m_pSource->GetNumChannels();
|
int iBytesToRead = iFramesToRead * sizeof(int16_t) * m_pSource->GetNumChannels();
|
||||||
int iOldSizeBytes = m_sBuffer.size();
|
int iOldSizeBytes = m_sBuffer.size();
|
||||||
m_sBuffer.resize( iOldSizeBytes + iBytesToRead );
|
m_sBuffer.resize( iOldSizeBytes + iBytesToRead );
|
||||||
int iGotBytes = m_pSource->Read( &m_sBuffer[0] + iOldSizeBytes, iBytesToRead );
|
int iGotFrames = m_pSource->Read( &m_sBuffer[0] + iOldSizeBytes, iFramesToRead );
|
||||||
if( iGotBytes == -1 )
|
if( iGotFrames == -1 )
|
||||||
{
|
{
|
||||||
m_sBuffer.resize( iOldSizeBytes );
|
m_sBuffer.resize( iOldSizeBytes );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iGotBytes = iGotFrames * sizeof(int16_t) * m_pSource->GetNumChannels();
|
||||||
m_sBuffer.resize( iOldSizeBytes + iGotBytes );
|
m_sBuffer.resize( iOldSizeBytes + iGotBytes );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public:
|
|||||||
virtual int GetLength_Fast() const;
|
virtual int GetLength_Fast() const;
|
||||||
virtual int SetPosition_Accurate( int iFrame );
|
virtual int SetPosition_Accurate( int iFrame );
|
||||||
virtual int SetPosition_Fast( int iFrame );
|
virtual int SetPosition_Fast( int iFrame );
|
||||||
virtual int Read( char *pBuf, unsigned iBytes );
|
virtual int Read( char *pBuf, int iFrames );
|
||||||
virtual int GetSampleRate() const;
|
virtual int GetSampleRate() const;
|
||||||
virtual unsigned GetNumChannels() const;
|
virtual unsigned GetNumChannels() const;
|
||||||
virtual bool IsStreamingFromDisk() const;
|
virtual bool IsStreamingFromDisk() const;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public:
|
|||||||
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 iFrame ) { return m_pSource->SetPosition_Accurate( iFrame ); }
|
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 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, int iFrames ) { return m_pSource->Read( pBuf, iFrames ); }
|
||||||
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(); }
|
||||||
virtual bool IsStreamingFromDisk() const { return m_pSource->IsStreamingFromDisk(); }
|
virtual bool IsStreamingFromDisk() const { return m_pSource->IsStreamingFromDisk(); }
|
||||||
|
|||||||
@@ -741,12 +741,12 @@ static void mono_to_stereo( char *dst, const char *src, unsigned len )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int RageSoundReader_MP3::Read( char *buf, unsigned len )
|
int RageSoundReader_MP3::Read( char *buf, int iFrames )
|
||||||
{
|
{
|
||||||
|
uint32_t iFramesWritten = 0;
|
||||||
uint32_t bw = 0;
|
uint32_t bw = 0;
|
||||||
|
|
||||||
ASSERT( (len % (sizeof(int16_t)*2)) == 0 );
|
unsigned len = iFrames * sizeof(int16_t) * GetNumChannels();
|
||||||
|
|
||||||
while( bw < len )
|
while( bw < len )
|
||||||
{
|
{
|
||||||
if( mad->outleft > 0 )
|
if( mad->outleft > 0 )
|
||||||
@@ -763,6 +763,7 @@ int RageSoundReader_MP3::Read( char *buf, unsigned len )
|
|||||||
memcpy( buf + bw, mad->outbuf + mad->outpos, cpysize );
|
memcpy( buf + bw, mad->outbuf + mad->outpos, cpysize );
|
||||||
|
|
||||||
bw += cpysize * Ratio;
|
bw += cpysize * Ratio;
|
||||||
|
iFramesWritten += (cpysize * Ratio) / (sizeof(int16_t) * GetNumChannels());
|
||||||
mad->outpos += cpysize;
|
mad->outpos += cpysize;
|
||||||
mad->outleft -= cpysize;
|
mad->outleft -= cpysize;
|
||||||
continue;
|
continue;
|
||||||
@@ -771,14 +772,14 @@ int RageSoundReader_MP3::Read( char *buf, unsigned len )
|
|||||||
/* Decode more from the MP3 stream. */
|
/* Decode more from the MP3 stream. */
|
||||||
int ret = do_mad_frame_decode();
|
int ret = do_mad_frame_decode();
|
||||||
if( ret == 0 )
|
if( ret == 0 )
|
||||||
return bw;
|
return iFramesWritten;
|
||||||
if( ret == -1 )
|
if( ret == -1 )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
synth_output();
|
synth_output();
|
||||||
}
|
}
|
||||||
|
|
||||||
return bw;
|
return iFramesWritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RageSoundReader_MP3::MADLIB_rewind()
|
bool RageSoundReader_MP3::MADLIB_rewind()
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public:
|
|||||||
int GetLength_Fast() const { return GetLengthConst(true); }
|
int GetLength_Fast() const { return GetLengthConst(true); }
|
||||||
int SetPosition_Accurate( int iSample );
|
int SetPosition_Accurate( int iSample );
|
||||||
int SetPosition_Fast( int iSample );
|
int SetPosition_Fast( int iSample );
|
||||||
int Read(char *buf, unsigned len);
|
int Read( char *pBuf, int iFrames );
|
||||||
int GetSampleRate() const { return SampleRate; }
|
int GetSampleRate() const { return SampleRate; }
|
||||||
int GetNextSourceFrame() const;
|
int GetNextSourceFrame() const;
|
||||||
|
|
||||||
|
|||||||
@@ -9,31 +9,28 @@ RageSoundReader_Pan::RageSoundReader_Pan( RageSoundReader *pSource ):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int RageSoundReader_Pan::Read( char *pBuf, unsigned iLen )
|
int RageSoundReader_Pan::Read( char *pBuf, int iFrames )
|
||||||
{
|
{
|
||||||
/* If the source is mono, it'll be converted to stereo; read half as many frames,
|
/* If the source is mono, it'll be converted to stereo; read half as many frames,
|
||||||
* so we have space. */
|
* so we have space. */
|
||||||
if( m_pSource->GetNumChannels() == 1 )
|
if( m_pSource->GetNumChannels() == 1 )
|
||||||
iLen /= 2;
|
iFrames /= 2;
|
||||||
|
|
||||||
int iRet = m_pSource->Read( pBuf, iLen );
|
iFrames = m_pSource->Read( pBuf, iFrames );
|
||||||
int iSamples = iRet / sizeof(uint16_t);
|
int iSamples = iFrames * m_pSource->GetNumChannels();
|
||||||
|
|
||||||
int16_t *pSampleBuf = (int16_t *) pBuf;
|
int16_t *pSampleBuf = (int16_t *) pBuf;
|
||||||
if( m_pSource->GetNumChannels() == 1 )
|
if( m_pSource->GetNumChannels() == 1 )
|
||||||
{
|
{
|
||||||
RageSoundUtil::ConvertMonoToStereoInPlace( pSampleBuf, iSamples );
|
RageSoundUtil::ConvertMonoToStereoInPlace( pSampleBuf, iSamples );
|
||||||
iRet *= 2;
|
|
||||||
iSamples *= 2;
|
iSamples *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iFrames = iSamples / GetNumChannels();
|
|
||||||
|
|
||||||
/* This block goes from iStreamFrame to iStreamFrame+iGotFrames. */
|
/* This block goes from iStreamFrame to iStreamFrame+iGotFrames. */
|
||||||
if( GetNumChannels() == 2 && m_fPan != 0.0 )
|
if( GetNumChannels() == 2 && m_fPan != 0.0 )
|
||||||
RageSoundUtil::Pan( pSampleBuf, iFrames, m_fPan );
|
RageSoundUtil::Pan( pSampleBuf, iFrames, m_fPan );
|
||||||
|
|
||||||
return iRet;
|
return iFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned RageSoundReader_Pan::GetNumChannels() const
|
unsigned RageSoundReader_Pan::GetNumChannels() const
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public:
|
|||||||
RageSoundReader_Pan( RageSoundReader *pSource );
|
RageSoundReader_Pan( RageSoundReader *pSource );
|
||||||
RageSoundReader_Pan *Copy() const { return new RageSoundReader_Pan(*this); }
|
RageSoundReader_Pan *Copy() const { return new RageSoundReader_Pan(*this); }
|
||||||
virtual unsigned GetNumChannels() const;
|
virtual unsigned GetNumChannels() const;
|
||||||
virtual int Read( char *pBuf, unsigned iLen );
|
virtual int Read( char *pBuf, int iFrames );
|
||||||
virtual bool SetProperty( const RString &sProperty, float fValue );
|
virtual bool SetProperty( const RString &sProperty, float fValue );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ RageSoundReader_PitchChange::RageSoundReader_PitchChange( const RageSoundReader_
|
|||||||
m_fPitchRatio = cpy.m_fPitchRatio;
|
m_fPitchRatio = cpy.m_fPitchRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RageSoundReader_PitchChange::Read( char *pBuf, unsigned iLen )
|
int RageSoundReader_PitchChange::Read( char *pBuf, int iFrames )
|
||||||
{
|
{
|
||||||
/* Changing the ratios will tell the speed changer to change ratios, but it
|
/* Changing the ratios will tell the speed changer to change ratios, but it
|
||||||
* can't change immediately; it'll change on the next slice. The resampler
|
* can't change immediately; it'll change on the next slice. The resampler
|
||||||
@@ -44,7 +44,7 @@ int RageSoundReader_PitchChange::Read( char *pBuf, unsigned iLen )
|
|||||||
if( m_pSpeedChange->NextReadWillStep() )
|
if( m_pSpeedChange->NextReadWillStep() )
|
||||||
m_pResample->SetRate( m_fPitchRatio );
|
m_pResample->SetRate( m_fPitchRatio );
|
||||||
|
|
||||||
return RageSoundReader_Filter::Read( pBuf, iLen );
|
return RageSoundReader_Filter::Read( pBuf, iFrames );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RageSoundReader_PitchChange::SetProperty( const RString &sProperty, float fValue )
|
bool RageSoundReader_PitchChange::SetProperty( const RString &sProperty, float fValue )
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public:
|
|||||||
RageSoundReader_PitchChange( RageSoundReader *pSource );
|
RageSoundReader_PitchChange( RageSoundReader *pSource );
|
||||||
RageSoundReader_PitchChange( const RageSoundReader_PitchChange &cpy );
|
RageSoundReader_PitchChange( const RageSoundReader_PitchChange &cpy );
|
||||||
|
|
||||||
virtual int Read( char *pBuf, unsigned iLen );
|
virtual int Read( char *pBuf, int iFrames );
|
||||||
virtual bool SetProperty( const RString &sProperty, float fValue );
|
virtual bool SetProperty( const RString &sProperty, float fValue );
|
||||||
|
|
||||||
void SetSpeedRatio( float fRatio ) { m_fSpeedRatio = fRatio; }
|
void SetSpeedRatio( float fRatio ) { m_fSpeedRatio = fRatio; }
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ bool RageSoundReader_Preload::Open( RageSoundReader *pSource )
|
|||||||
return false; /* Don't bother trying to preload it. */
|
return false; /* Don't bother trying to preload it. */
|
||||||
|
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
int iCnt = pSource->Read(buffer, sizeof(buffer));
|
int iBytesPerFrame = m_iChannels * sizeof(int16_t);
|
||||||
|
int iCnt = pSource->Read( buffer, sizeof(buffer) / iBytesPerFrame );
|
||||||
|
|
||||||
if( iCnt < 0 )
|
if( iCnt < 0 )
|
||||||
{
|
{
|
||||||
@@ -74,7 +75,7 @@ bool RageSoundReader_Preload::Open( RageSoundReader *pSource )
|
|||||||
break; /* eof */
|
break; /* eof */
|
||||||
|
|
||||||
/* Add the buffer. */
|
/* Add the buffer. */
|
||||||
m_Buffer.Get()->append( buffer, buffer+iCnt );
|
m_Buffer.Get()->append( buffer, buffer+iCnt*iBytesPerFrame );
|
||||||
|
|
||||||
if( m_Buffer.Get()->size() > max_prebuf_size )
|
if( m_Buffer.Get()->size() > max_prebuf_size )
|
||||||
return false; /* too big */
|
return false; /* too big */
|
||||||
@@ -97,12 +98,12 @@ int RageSoundReader_Preload::GetLength_Fast() const
|
|||||||
|
|
||||||
int RageSoundReader_Preload::SetPosition_Accurate( int iFrame )
|
int RageSoundReader_Preload::SetPosition_Accurate( int iFrame )
|
||||||
{
|
{
|
||||||
m_iPosition = iFrame * samplesize;
|
m_iPosition = iFrame;
|
||||||
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() / samplesize) )
|
||||||
{
|
{
|
||||||
m_iPosition = m_Buffer->size();
|
m_iPosition = m_Buffer->size() / samplesize;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,18 +117,19 @@ int RageSoundReader_Preload::SetPosition_Fast( int iFrame )
|
|||||||
|
|
||||||
int RageSoundReader_Preload::GetNextSourceFrame() const
|
int RageSoundReader_Preload::GetNextSourceFrame() const
|
||||||
{
|
{
|
||||||
return lrintf(m_iPosition * m_fRate) / samplesize;
|
return lrintf(m_iPosition * m_fRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
int RageSoundReader_Preload::Read( char *pBuffer, unsigned iLen )
|
int RageSoundReader_Preload::Read( char *pBuffer, int iFrames )
|
||||||
{
|
{
|
||||||
const unsigned bytes_avail = m_Buffer->size() - m_iPosition;
|
const int iSizeFrames = m_Buffer->size() / samplesize;
|
||||||
|
const int iFramesAvail = iSizeFrames - m_iPosition;
|
||||||
|
|
||||||
iLen = min( iLen, bytes_avail );
|
iFrames = min( iFrames, iFramesAvail );
|
||||||
memcpy( pBuffer, m_Buffer->data()+m_iPosition, iLen );
|
memcpy( pBuffer, m_Buffer->data() + (m_iPosition * samplesize), iFrames * samplesize );
|
||||||
m_iPosition += iLen;
|
m_iPosition += iFrames;
|
||||||
|
|
||||||
return iLen;
|
return iFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
RageSoundReader_Preload *RageSoundReader_Preload::Copy() const
|
RageSoundReader_Preload *RageSoundReader_Preload::Copy() const
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public:
|
|||||||
int GetLength_Fast() const;
|
int GetLength_Fast() const;
|
||||||
int SetPosition_Accurate( int iFrame );
|
int SetPosition_Accurate( int iFrame );
|
||||||
int SetPosition_Fast( int iFrame );
|
int SetPosition_Fast( int iFrame );
|
||||||
int Read( char *pBuffer, unsigned iLength );
|
int Read( char *pBuffer, int 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; }
|
||||||
bool IsStreamingFromDisk() const { return false; }
|
bool IsStreamingFromDisk() const { return false; }
|
||||||
|
|||||||
@@ -693,12 +693,10 @@ int RageSoundReader_Resample_Good::SetPosition_Fast( int iFrame )
|
|||||||
return iFrame;
|
return iFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RageSoundReader_Resample_Good::Read( char *pBuf_, unsigned iLen )
|
int RageSoundReader_Resample_Good::Read( char *pBuf_, int iFrames )
|
||||||
{
|
{
|
||||||
int iChannels = m_apResamplers.size();
|
int iChannels = m_apResamplers.size();
|
||||||
int iBytesPerFrame = sizeof(int16_t) * iChannels;
|
|
||||||
|
|
||||||
int iFrames = iLen / iBytesPerFrame; /* bytes -> frames */
|
|
||||||
int16_t *pBuf = (int16_t *) pBuf_;
|
int16_t *pBuf = (int16_t *) pBuf_;
|
||||||
|
|
||||||
int iFramesRead = 0;
|
int iFramesRead = 0;
|
||||||
@@ -725,32 +723,27 @@ int RageSoundReader_Resample_Good::Read( char *pBuf_, unsigned iLen )
|
|||||||
iFramesRead += iGotFrames;
|
iFramesRead += iGotFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iFramesRead * iBytesPerFrame;
|
return iFramesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_pSource->Read( pBuf_, iLen );
|
return m_pSource->Read( pBuf_, iFrames );
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int iFramesNeeded = m_apResamplers[0]->NumInputsForOutputSamples(iFrames);
|
int iFramesNeeded = m_apResamplers[0]->NumInputsForOutputSamples(iFrames);
|
||||||
int iBytesNeeded = iFramesNeeded * sizeof(int16_t) * iChannels;
|
int16_t *pTmpBuf = (int16_t *) alloca( iFramesNeeded * sizeof(int16_t) * iChannels );
|
||||||
int16_t *pTmpBuf = (int16_t *) alloca( iBytesNeeded );
|
|
||||||
ASSERT( pTmpBuf );
|
ASSERT( pTmpBuf );
|
||||||
int iBytesIn = m_pSource->Read( (char *) pTmpBuf, iBytesNeeded );
|
int iFramesIn = m_pSource->Read( (char *) pTmpBuf, iFramesNeeded );
|
||||||
|
|
||||||
if( iBytesIn == -1 )
|
if( iFramesIn == -1 )
|
||||||
{
|
{
|
||||||
SetError( m_pSource->GetError() );
|
SetError( m_pSource->GetError() );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
iBytesNeeded -= iBytesIn;
|
const int iSamplesIn = iFramesIn * iChannels;
|
||||||
iFramesNeeded -= iBytesIn / (sizeof(int16_t) * iChannels);
|
|
||||||
|
|
||||||
const int iSamplesIn = iBytesIn / sizeof(int16_t);
|
float *pFloatBuf = (float *) alloca( iFramesIn * sizeof(float) );
|
||||||
const int iFramesIn = iSamplesIn / iChannels;
|
|
||||||
|
|
||||||
float *pFloatBuf = (float *) alloca( iSamplesIn * sizeof(float) );
|
|
||||||
float *pFloatOut = (float *) alloca( iFrames * sizeof(float) );
|
float *pFloatOut = (float *) alloca( iFrames * sizeof(float) );
|
||||||
for( int iChannel = 0; iChannel < iChannels; ++iChannel )
|
for( int iChannel = 0; iChannel < iChannels; ++iChannel )
|
||||||
{
|
{
|
||||||
@@ -775,7 +768,7 @@ int RageSoundReader_Resample_Good::Read( char *pBuf_, unsigned iLen )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return iFramesRead * iBytesPerFrame;
|
return iFramesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public:
|
|||||||
int GetLength_Fast() const;
|
int GetLength_Fast() const;
|
||||||
int SetPosition_Accurate( int iFrame );
|
int SetPosition_Accurate( int iFrame );
|
||||||
int SetPosition_Fast( int iFrame );
|
int SetPosition_Fast( int iFrame );
|
||||||
int Read( char *pBuf, unsigned iLen );
|
int Read( char *pBuf, int iFrames );
|
||||||
virtual ~RageSoundReader_Resample_Good();
|
virtual ~RageSoundReader_Resample_Good();
|
||||||
RageSoundReader_Resample_Good *Copy() const;
|
RageSoundReader_Resample_Good *Copy() const;
|
||||||
bool SetProperty( const RString &sProperty, float fValue );
|
bool SetProperty( const RString &sProperty, float fValue );
|
||||||
|
|||||||
@@ -94,14 +94,14 @@ void RageSoundReader_SpeedChange::FillData( int iMaxFrames )
|
|||||||
* we average out the short block. */
|
* we average out the short block. */
|
||||||
while( iMaxFrames > 0 )
|
while( iMaxFrames > 0 )
|
||||||
{
|
{
|
||||||
int iSamplesToRead = (iMaxFrames - m_iDataBufferAvailFrames)*m_Channels.size();
|
int iFramesToRead = iMaxFrames - m_iDataBufferAvailFrames;
|
||||||
int iBytesToRead = iSamplesToRead*sizeof(int16_t);
|
int iBytesToRead = iFramesToRead * m_Channels.size() * sizeof(int16_t);
|
||||||
if( iBytesToRead <= 0 )
|
if( iBytesToRead <= 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int16_t *pTempBuffer = (int16_t *) alloca( iBytesToRead );
|
int16_t *pTempBuffer = (int16_t *) alloca( iBytesToRead );
|
||||||
int iGotBytes = m_pSource->Read( (char *) pTempBuffer, iBytesToRead );
|
int iGotFrames = m_pSource->Read( (char *) pTempBuffer, iFramesToRead );
|
||||||
int iGotFrames = iGotBytes / (m_Channels.size()*sizeof(int16_t));
|
// if( iGotFrames == -1 ) XXX
|
||||||
if( !iGotFrames )
|
if( !iGotFrames )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -229,7 +229,7 @@ int RageSoundReader_SpeedChange::GetCursorAvail() const
|
|||||||
return iCursorAvail;
|
return iCursorAvail;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RageSoundReader_SpeedChange::Read( char *buf, unsigned iLen )
|
int RageSoundReader_SpeedChange::Read( char *buf, int iFrames )
|
||||||
{
|
{
|
||||||
int16_t *pBuf = (int16_t *) buf;
|
int16_t *pBuf = (int16_t *) buf;
|
||||||
|
|
||||||
@@ -242,7 +242,7 @@ int RageSoundReader_SpeedChange::Read( char *buf, unsigned iLen )
|
|||||||
{
|
{
|
||||||
/* Fast path: the buffer is empty, and we're not scaling the audio. Read directly
|
/* Fast path: the buffer is empty, and we're not scaling the audio. Read directly
|
||||||
* into the output buffer, to eliminate memory and copying overhead. */
|
* into the output buffer, to eliminate memory and copying overhead. */
|
||||||
return m_pSource->Read( (char *) pBuf, iLen );
|
return m_pSource->Read( (char *) pBuf, iFrames );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( iCursorAvail == 0 )
|
if( iCursorAvail == 0 )
|
||||||
@@ -254,11 +254,11 @@ int RageSoundReader_SpeedChange::Read( char *buf, unsigned iLen )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* copy GetWindowSizeFrames() from iCorrelatedPos */
|
/* copy GetWindowSizeFrames() from iCorrelatedPos */
|
||||||
int iFramesLen = iLen / (m_Channels.size()*sizeof(int16_t));
|
int iFramesLen = iFrames;
|
||||||
int iFramesAvail = min( iCursorAvail, iFramesLen );
|
int iFramesAvail = min( iCursorAvail, iFramesLen );
|
||||||
|
|
||||||
iLen -= iFramesAvail * sizeof(int16_t) * m_Channels.size();
|
iFrames -= iFramesAvail;
|
||||||
int iBytesRead = iFramesAvail * sizeof(int16_t) * m_Channels.size();
|
int iFramesRead = iFramesAvail;
|
||||||
|
|
||||||
int iWindowSizeFrames = GetWindowSizeFrames();
|
int iWindowSizeFrames = GetWindowSizeFrames();
|
||||||
while( iFramesAvail-- )
|
while( iFramesAvail-- )
|
||||||
@@ -274,8 +274,8 @@ int RageSoundReader_SpeedChange::Read( char *buf, unsigned iLen )
|
|||||||
++m_iPos;
|
++m_iPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( iBytesRead )
|
if( iFramesRead )
|
||||||
return iBytesRead;
|
return iFramesRead;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public:
|
|||||||
|
|
||||||
virtual int SetPosition_Accurate( int iFrame );
|
virtual int SetPosition_Accurate( int iFrame );
|
||||||
virtual int SetPosition_Fast( int iFrame );
|
virtual int SetPosition_Fast( int iFrame );
|
||||||
virtual int Read( char *buf, unsigned len );
|
virtual int Read( char *pBuf, int iFrames );
|
||||||
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 );
|
||||||
virtual int GetNextSourceFrame() const;
|
virtual int GetNextSourceFrame() const;
|
||||||
|
|||||||
@@ -165,11 +165,11 @@ int RageSoundReader_Vorbisfile::SetPosition( int iFrame, bool accurate )
|
|||||||
return iFrame;
|
return iFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RageSoundReader_Vorbisfile::Read(char *buf, unsigned len)
|
int RageSoundReader_Vorbisfile::Read( char *buf, int iFrames )
|
||||||
{
|
{
|
||||||
int bytes_read = 0;
|
int frames_read = 0;
|
||||||
|
|
||||||
while( len && !eof )
|
while( iFrames && !eof )
|
||||||
{
|
{
|
||||||
const int bytes_per_frame = sizeof(int16_t)*channels;
|
const int bytes_per_frame = sizeof(int16_t)*channels;
|
||||||
|
|
||||||
@@ -192,9 +192,10 @@ int RageSoundReader_Vorbisfile::Read(char *buf, unsigned len)
|
|||||||
* That way, corruptions in the file won't casue desyncs. */
|
* That way, corruptions in the file won't casue desyncs. */
|
||||||
|
|
||||||
/* In bytes: */
|
/* In bytes: */
|
||||||
int silence = (curofs - read_offset) * bytes_per_frame;
|
int iSilentFrames = curofs - read_offset;
|
||||||
|
iSilentFrames = min( iSilentFrames, (int) iFrames );
|
||||||
|
int silence = iSilentFrames * bytes_per_frame;
|
||||||
CHECKPOINT_M( ssprintf("p %i,%i: %i frames of silence needed", curofs, read_offset, silence) );
|
CHECKPOINT_M( ssprintf("p %i,%i: %i frames of silence needed", curofs, read_offset, silence) );
|
||||||
silence = min( silence, (int) len );
|
|
||||||
|
|
||||||
memset( buf, 0, silence );
|
memset( buf, 0, silence );
|
||||||
ret = silence;
|
ret = silence;
|
||||||
@@ -205,9 +206,9 @@ int RageSoundReader_Vorbisfile::Read(char *buf, unsigned len)
|
|||||||
{
|
{
|
||||||
int bstream;
|
int bstream;
|
||||||
#if defined(INTEGER_VORBIS)
|
#if defined(INTEGER_VORBIS)
|
||||||
ret = ov_read( vf, buf, len, &bstream );
|
ret = ov_read( vf, buf, iFrames * bytes_per_frame, &bstream );
|
||||||
#else // float vorbis decoder
|
#else // float vorbis decoder
|
||||||
ret = ov_read( vf, buf, len, (BYTE_ORDER == BIG_ENDIAN)?1:0, 2, 1, &bstream );
|
ret = ov_read( vf, buf, iFrames * bytes_per_frame, (BYTE_ORDER == BIG_ENDIAN)?1:0, 2, 1, &bstream );
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
vorbis_info *vi = ov_info( vf, -1 );
|
vorbis_info *vi = ov_info( vf, -1 );
|
||||||
@@ -234,14 +235,15 @@ int RageSoundReader_Vorbisfile::Read(char *buf, unsigned len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iFramesRead = ret / bytes_per_frame;
|
||||||
read_offset += ret / bytes_per_frame;
|
read_offset += ret / bytes_per_frame;
|
||||||
|
|
||||||
buf += ret;
|
buf += ret;
|
||||||
bytes_read += ret;
|
frames_read += iFramesRead;
|
||||||
len -= ret;
|
iFrames -= iFramesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes_read;
|
return frames_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RageSoundReader_Vorbisfile::GetSampleRate() const
|
int RageSoundReader_Vorbisfile::GetSampleRate() const
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public:
|
|||||||
int GetLength_Fast() const;
|
int GetLength_Fast() const;
|
||||||
int SetPosition_Accurate( int iFrame ) { return SetPosition( iFrame, true ); }
|
int SetPosition_Accurate( int iFrame ) { return SetPosition( iFrame, true ); }
|
||||||
int SetPosition_Fast( int iFrame ) { return SetPosition( iFrame, false ); }
|
int SetPosition_Fast( int iFrame ) { return SetPosition( iFrame, false ); }
|
||||||
int Read(char *buf, unsigned len);
|
int Read( char *pBuf, int iFrames );
|
||||||
int GetSampleRate() const;
|
int GetSampleRate() const;
|
||||||
unsigned GetNumChannels() const { return channels; }
|
unsigned GetNumChannels() const { return channels; }
|
||||||
int GetNextSourceFrame() const;
|
int GetNextSourceFrame() const;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ struct WavReader
|
|||||||
WavReader( RageFile &f, const RageSoundReader_WAV::WavData &data ):
|
WavReader( RageFile &f, const RageSoundReader_WAV::WavData &data ):
|
||||||
m_File(f), m_WavData(data) { }
|
m_File(f), m_WavData(data) { }
|
||||||
virtual ~WavReader() { }
|
virtual ~WavReader() { }
|
||||||
virtual int Read( char *buf, unsigned len ) = 0;
|
virtual int Read( char *pBuf, int iFrames ) = 0;
|
||||||
virtual int GetLength() const = 0;
|
virtual int GetLength() const = 0;
|
||||||
virtual bool Init() = 0;
|
virtual bool Init() = 0;
|
||||||
virtual int SetPosition( int iFrame ) = 0;
|
virtual int SetPosition( int iFrame ) = 0;
|
||||||
@@ -72,27 +72,28 @@ struct WavReaderPCM: public WavReader
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Read( char *buf, unsigned len )
|
int Read( char *buf, int iFrames )
|
||||||
{
|
{
|
||||||
|
int len = iFrames * m_WavData.m_iChannels * sizeof(int16_t);
|
||||||
if( m_WavData.m_iBitsPerSample == 8 )
|
if( m_WavData.m_iBitsPerSample == 8 )
|
||||||
len /= 2;
|
len /= 2;
|
||||||
|
|
||||||
const unsigned iBytesLeftInDataChunk = m_WavData.m_iDataChunkSize - (m_File.Tell() - m_WavData.m_iDataChunkPos);
|
const int iBytesLeftInDataChunk = m_WavData.m_iDataChunkSize - (m_File.Tell() - m_WavData.m_iDataChunkPos);
|
||||||
len = min( len, iBytesLeftInDataChunk );
|
len = min( len, iBytesLeftInDataChunk );
|
||||||
int iGot = m_File.Read( buf, len );
|
int iGot = m_File.Read( buf, len );
|
||||||
|
int iGotSamples = 0;
|
||||||
switch( m_WavData.m_iBitsPerSample )
|
switch( m_WavData.m_iBitsPerSample )
|
||||||
{
|
{
|
||||||
case 8:
|
case 8:
|
||||||
Convert8bitTo16bit( buf, iGot );
|
Convert8bitTo16bit( buf, iGot );
|
||||||
iGot *= 2;
|
iGotSamples = iGot;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
Convert16BitFromLittleEndian( (int16_t *) buf, iGot/2 );
|
Convert16BitFromLittleEndian( (int16_t *) buf, iGot/2 );
|
||||||
iGot &= ~1;
|
iGotSamples = iGot / 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return iGot;
|
return iGotSamples / m_WavData.m_iChannels;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetLength() const
|
int GetLength() const
|
||||||
@@ -286,10 +287,11 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Read( char *buf, unsigned len )
|
int Read( char *buf, int iFrames )
|
||||||
{
|
{
|
||||||
unsigned got = 0;
|
int iBytesPerFrame = m_WavData.m_iChannels * sizeof(int16_t);
|
||||||
while( got < len )
|
int iGotFrames = 0;
|
||||||
|
while( iGotFrames < (int) iFrames )
|
||||||
{
|
{
|
||||||
if( m_iBufferUsed == m_iBufferAvail )
|
if( m_iBufferUsed == m_iBufferAvail )
|
||||||
{
|
{
|
||||||
@@ -299,13 +301,16 @@ public:
|
|||||||
if( m_iBufferAvail == 0 )
|
if( m_iBufferAvail == 0 )
|
||||||
break; /* EOF */
|
break; /* EOF */
|
||||||
|
|
||||||
int iBytesToCopy = min( m_iBufferAvail-m_iBufferUsed, (int) (len-got) );
|
int iFramesToCopy = (m_iBufferAvail-m_iBufferUsed) / iBytesPerFrame;
|
||||||
memcpy( buf+got, m_pBuffer+m_iBufferUsed, iBytesToCopy );
|
iFramesToCopy = min( iFramesToCopy, (int) (iFrames-iGotFrames) );
|
||||||
|
int iBytesToCopy = iFramesToCopy * iBytesPerFrame;
|
||||||
|
memcpy( buf, m_pBuffer+m_iBufferUsed, iBytesToCopy );
|
||||||
m_iBufferUsed += iBytesToCopy;
|
m_iBufferUsed += iBytesToCopy;
|
||||||
got += iBytesToCopy;
|
iGotFrames += iFramesToCopy;
|
||||||
|
buf += iBytesToCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
return got;
|
return iGotFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetLength() const
|
int GetLength() const
|
||||||
@@ -526,10 +531,10 @@ int RageSoundReader_WAV::GetNextSourceFrame() const
|
|||||||
return m_pImpl->GetNextSourceFrame();
|
return m_pImpl->GetNextSourceFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
int RageSoundReader_WAV::Read( char *buf, unsigned len )
|
int RageSoundReader_WAV::Read( char *pBuf, int iFrames )
|
||||||
{
|
{
|
||||||
ASSERT( m_pImpl != NULL );
|
ASSERT( m_pImpl != NULL );
|
||||||
return m_pImpl->Read( buf, len );
|
return m_pImpl->Read( pBuf, iFrames );
|
||||||
}
|
}
|
||||||
|
|
||||||
RageSoundReader_WAV::RageSoundReader_WAV()
|
RageSoundReader_WAV::RageSoundReader_WAV()
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public:
|
|||||||
int GetLength_Fast() const { return GetLength(); }
|
int GetLength_Fast() const { return GetLength(); }
|
||||||
int SetPosition_Accurate( int iFrame ) { return SetPosition(iFrame); }
|
int SetPosition_Accurate( int iFrame ) { return SetPosition(iFrame); }
|
||||||
int SetPosition_Fast( int iFrame ) { return SetPosition(iFrame); }
|
int SetPosition_Fast( int iFrame ) { return SetPosition(iFrame); }
|
||||||
int Read( char *buf, unsigned len );
|
int Read( char *pBuf, int iFrames );
|
||||||
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; }
|
||||||
int GetNextSourceFrame() const;
|
int GetNextSourceFrame() const;
|
||||||
|
|||||||
Reference in New Issue
Block a user