This commit is contained in:
Glenn Maynard
2006-11-25 22:46:47 +00:00
parent ba1b184f48
commit b52c8f9966
2 changed files with 62 additions and 57 deletions
+40 -37
View File
@@ -4,7 +4,7 @@
#include "global.h" #include "global.h"
#include "RageSoundReader_Preload.h" #include "RageSoundReader_Preload.h"
#define samplesize (2 * channels) /* 16-bit */ #define samplesize (2 * m_iChannels) /* 16-bit */
/* If a sound is smaller than this, we'll load it entirely into memory. */ /* If a sound is smaller than this, we'll load it entirely into memory. */
const unsigned max_prebuf_size = 1024*256; const unsigned max_prebuf_size = 1024*256;
@@ -24,57 +24,60 @@ bool RageSoundReader_Preload::PreloadSound( SoundReader *&pSound )
return true; return true;
} }
int RageSoundReader_Preload::total_samples() const int RageSoundReader_Preload::GetTotalSamples() const
{ {
return buf.get().size() / samplesize; return m_Buffer.get().size() / samplesize;
} }
bool RageSoundReader_Preload::Open(SoundReader *source) bool RageSoundReader_Preload::Open( SoundReader *pSource )
{ {
ASSERT(source); ASSERT( pSource );
samplerate = source->GetSampleRate(); m_iSampleRate = pSource->GetSampleRate();
channels = source->GetNumChannels(); m_iChannels = pSource->GetNumChannels();
/* Check the length, and see if we think it'll fit in the buffer. */ /* Check the length, and see if we think it'll fit in the buffer. */
int len = source->GetLength_Fast(); int iLen = pSource->GetLength_Fast();
if(len != -1) if( iLen != -1 )
{ {
float secs = len / 1000.f; float fSecs = iLen / 1000.f;
unsigned pcmsize = unsigned(secs * samplerate * samplesize); /* seconds -> bytes */ unsigned iPCMSize = unsigned( fSecs * m_iSampleRate * samplesize ); /* seconds -> bytes */
if(pcmsize > max_prebuf_size) if( iPCMSize > max_prebuf_size )
return false; /* Don't bother trying to preload it. */ return false; /* Don't bother trying to preload it. */
buf.get_owned().reserve(pcmsize); m_Buffer.get_owned().reserve( iPCMSize );
} }
while(1) { while(1)
{
char buffer[1024]; char buffer[1024];
int cnt = source->Read(buffer, sizeof(buffer)); int iCnt = pSource->Read(buffer, sizeof(buffer));
if(cnt < 0) { if( iCnt < 0 )
{
/* XXX untested */ /* XXX untested */
SetError(source->GetError()); SetError(pSource->GetError());
return false; return false;
} }
if(!cnt) break; /* eof */ if( !iCnt )
break; /* eof */
/* Add the buffer. */ /* Add the buffer. */
buf.get_owned().append(buffer, buffer+cnt); m_Buffer.get_owned().append( buffer, buffer+iCnt );
if(buf.get_owned().size() > max_prebuf_size) if( m_Buffer.get_owned().size() > max_prebuf_size )
return false; /* too big */ return false; /* too big */
} }
position = 0; m_iPosition = 0;
delete source; delete pSource;
return true; return true;
} }
int RageSoundReader_Preload::GetLength() const int RageSoundReader_Preload::GetLength() const
{ {
return int(float(total_samples()) * 1000.f / samplerate); return int(float(GetTotalSamples()) * 1000.f / m_iSampleRate);
} }
int RageSoundReader_Preload::GetLength_Fast() const int RageSoundReader_Preload::GetLength_Fast() const
@@ -84,32 +87,32 @@ int RageSoundReader_Preload::GetLength_Fast() const
int RageSoundReader_Preload::SetPosition_Accurate(int ms) int RageSoundReader_Preload::SetPosition_Accurate(int ms)
{ {
const int sample = int((ms / 1000.0f) * samplerate); const int sample = int((ms / 1000.0f) * m_iSampleRate);
position = sample * samplesize; m_iPosition = sample * samplesize;
if(position >= int(buf.get().size())) if( m_iPosition >= int(m_Buffer.get().size()) )
{ {
position = buf.get().size(); m_iPosition = m_Buffer.get().size();
return 0; return 0;
} }
return position; return m_iPosition;
} }
int RageSoundReader_Preload::SetPosition_Fast(int ms) int RageSoundReader_Preload::SetPosition_Fast( int iMS )
{ {
return SetPosition_Accurate(ms); return SetPosition_Accurate( iMS );
} }
int RageSoundReader_Preload::Read(char *buffer, unsigned len) int RageSoundReader_Preload::Read( char *pBuffer, unsigned iLen )
{ {
const unsigned bytes_avail = buf.get().size() - position; const unsigned bytes_avail = m_Buffer.get().size() - m_iPosition;
len = min(len, bytes_avail); iLen = min( iLen, bytes_avail );
memcpy(buffer, buf.get().data()+position, len); memcpy( pBuffer, m_Buffer.get().data()+m_iPosition, iLen );
position += len; m_iPosition += iLen;
return len; return iLen;
} }
RageSoundReader_Preload *RageSoundReader_Preload::Copy() const RageSoundReader_Preload *RageSoundReader_Preload::Copy() const
@@ -119,7 +122,7 @@ RageSoundReader_Preload *RageSoundReader_Preload::Copy() const
int RageSoundReader_Preload::GetReferenceCount() const int RageSoundReader_Preload::GetReferenceCount() const
{ {
return buf.GetReferenceCount(); return m_Buffer.GetReferenceCount();
} }
rc_string::rc_string() rc_string::rc_string()
+22 -20
View File
@@ -9,9 +9,6 @@
* refcounted. Without this, Copy() is very slow. */ * refcounted. Without this, Copy() is very slow. */
class rc_string class rc_string
{ {
mutable string *buf;
mutable int *cnt;
public: public:
rc_string(); rc_string();
rc_string(const rc_string &rhs); rc_string(const rc_string &rhs);
@@ -19,32 +16,25 @@ public:
string &get_owned(); string &get_owned();
const string &get() const; const string &get() const;
int GetReferenceCount() const { return *cnt; } int GetReferenceCount() const { return *cnt; }
private:
mutable string *buf;
mutable int *cnt;
}; };
class RageSoundReader_Preload: public SoundReader class RageSoundReader_Preload: public SoundReader
{ {
rc_string buf;
/* Bytes: */
int position;
int total_samples() const;
int samplerate;
unsigned channels;
float OffsetFix;
public: public:
/* Return true if the sound has been preloaded, in which case source will /* Return true if the sound has been preloaded, in which case source will
* be deleted. Otherwise, return false. */ * be deleted. Otherwise, return false. */
bool Open(SoundReader *source); bool Open( SoundReader *pSource );
int GetLength() const; int GetLength() const;
int GetLength_Fast() const; int GetLength_Fast() const;
int SetPosition_Accurate(int ms); int SetPosition_Accurate( int iMS );
int SetPosition_Fast(int ms); int SetPosition_Fast( int iMS );
int Read(char *buf, unsigned len); int Read( char *pBuffer, unsigned iLength );
int GetSampleRate() const { return samplerate; } int GetSampleRate() const { return m_iSampleRate; }
unsigned GetNumChannels() const { return channels; } unsigned GetNumChannels() const { return m_iChannels; }
bool IsStreamingFromDisk() const { return false; } bool IsStreamingFromDisk() const { return false; }
/* Return the total number of copies of this sound. (If 1 is returned, /* Return the total number of copies of this sound. (If 1 is returned,
@@ -56,6 +46,18 @@ public:
/* Attempt to preload a sound. pSound must be rewound. */ /* Attempt to preload a sound. pSound must be rewound. */
static bool PreloadSound( SoundReader *&pSound ); static bool PreloadSound( SoundReader *&pSound );
private:
rc_string m_Buffer;
/* Bytes: */
int m_iPosition;
int GetTotalSamples() const;
int m_iSampleRate;
unsigned m_iChannels;
float OffsetFix;
}; };
#endif #endif