prebuffer small sounds to reduce buffering threads. This differs

from preloading; this loads the file directly, before decompression,
so it can load much longer sounds, which avoids any disk access
so no buffering thread is needed.
This commit is contained in:
Glenn Maynard
2007-02-21 11:14:17 +00:00
parent 00f9745c75
commit cfaa20c6fc
4 changed files with 50 additions and 23 deletions
+10 -6
View File
@@ -183,10 +183,12 @@ bool RageSound::Load( RString sSoundFilePath, bool bPrecache, const RageSoundLoa
/* If this sound is already preloaded and held by SOUNDMAN, just make a copy /* If this sound is already preloaded and held by SOUNDMAN, just make a copy
* of that. Since RageSoundReader_Preload is refcounted, this is cheap. */ * of that. Since RageSoundReader_Preload is refcounted, this is cheap. */
RageSoundReader *pSound = SOUNDMAN->GetLoadedSound( sSoundFilePath ); RageSoundReader *pSound = SOUNDMAN->GetLoadedSound( sSoundFilePath );
bool bNeedBuffer = true;
if( pSound == NULL ) if( pSound == NULL )
{ {
RString error; RString error;
pSound = RageSoundReader_FileReader::OpenFile( sSoundFilePath, error ); bool bPrebuffer;
pSound = RageSoundReader_FileReader::OpenFile( sSoundFilePath, error, &bPrebuffer );
if( pSound == NULL ) if( pSound == NULL )
{ {
LOG->Warn( "RageSound::Load: error opening sound \"%s\": %s", LOG->Warn( "RageSound::Load: error opening sound \"%s\": %s",
@@ -194,11 +196,16 @@ bool RageSound::Load( RString sSoundFilePath, bool bPrecache, const RageSoundLoa
pSound = new RageSoundReader_Silence; pSound = new RageSoundReader_Silence;
} }
/* If the sound is prebuffered into memory, we don't need to buffer reads. */
if( bPrebuffer )
bNeedBuffer = false;
} }
else else
{ {
/* The sound we were given from SOUNDMAN is already preloaded. */ /* The sound we were given from SOUNDMAN is already preloaded. */
bPrecache = false; bPrecache = false;
bNeedBuffer = false;
} }
LoadSoundReader( pSound ); LoadSoundReader( pSound );
@@ -211,15 +218,12 @@ bool RageSound::Load( RString sSoundFilePath, bool bPrecache, const RageSoundLoa
{ {
/* We've preloaded the sound. Pass it to SOUNDMAN, for reuse. */ /* We've preloaded the sound. Pass it to SOUNDMAN, for reuse. */
SOUNDMAN->AddLoadedSound( sSoundFilePath, (RageSoundReader_Preload *) m_pSource ); SOUNDMAN->AddLoadedSound( sSoundFilePath, (RageSoundReader_Preload *) m_pSource );
} bNeedBuffer = false;
else
{
bPrecache = false;
} }
} }
m_pSource = new RageSoundReader_Extend( m_pSource ); m_pSource = new RageSoundReader_Extend( m_pSource );
if( !bPrecache ) if( bNeedBuffer )
m_pSource = new RageSoundReader_ThreadedBuffer( m_pSource ); m_pSource = new RageSoundReader_ThreadedBuffer( m_pSource );
m_pSource = new RageSoundReader_PostBuffering( m_pSource ); m_pSource = new RageSoundReader_PostBuffering( m_pSource );
+2 -1
View File
@@ -76,7 +76,8 @@ int RageSoundReader_Chain::LoadSound( RString sPath )
} }
RString sError; RString sError;
RageSoundReader *pReader = RageSoundReader_FileReader::OpenFile( sPath, sError ); bool bPrebuffer;
RageSoundReader *pReader = RageSoundReader_FileReader::OpenFile( sPath, sError, &bPrebuffer );
if( pReader == NULL ) if( pReader == NULL )
{ {
LOG->Warn( "RageSoundReader_Chain: error opening sound \"%s\": %s", LOG->Warn( "RageSoundReader_Chain: error opening sound \"%s\": %s",
+34 -13
View File
@@ -83,28 +83,49 @@ RageSoundReader_FileReader *RageSoundReader_FileReader::TryOpenFile( RageFileBas
return NULL; return NULL;
} }
RageSoundReader_FileReader *RageSoundReader_FileReader::OpenFile( RString filename, RString &error ) #include "RageFileDriverMemory.h"
RageSoundReader_FileReader *RageSoundReader_FileReader::OpenFile( RString filename, RString &error, bool *pPrebuffer )
{ {
RageFile *pFile = new RageFile; RageFileBasic *pFile = NULL;
if( !pFile->Open(filename) )
{ {
error = pFile->GetError(); RageFile *pFileOpen = new RageFile;
delete pFile; if( !pFileOpen->Open(filename) )
return NULL; {
error = pFile->GetError();
delete pFileOpen;
return NULL;
}
pFile = pFileOpen;
} }
return OpenFile( pFile, error ); if( pPrebuffer )
} {
if( pFile->GetFileSize() < 1024*50 )
{
RageSoundReader_FileReader *RageSoundReader_FileReader::OpenFile( RageFileBasic *pFile, RString &error ) RageFileObjMem *pMem = new RageFileObjMem;
{ bool bRet = FileCopy( *pFile, *pMem, error, NULL );
delete pFile;
pFile = pMem;
if( !bRet )
{
delete pFile;
return NULL;
}
pFile->Seek( 0 );
*pPrebuffer = true;
}
else
{
*pPrebuffer = false;
}
}
set<RString> FileTypes; set<RString> FileTypes;
FileTypes.insert("ogg"); FileTypes.insert("ogg");
FileTypes.insert("mp3"); FileTypes.insert("mp3");
FileTypes.insert("wav"); FileTypes.insert("wav");
RString format = GetExtension( pFile->GetDisplayPath() ); RString format = GetExtension( filename );
format.MakeLower(); format.MakeLower();
error = ""; error = "";
+4 -3
View File
@@ -31,9 +31,10 @@ public:
virtual float GetStreamToSourceRatio() const { return 1.0f; } virtual float GetStreamToSourceRatio() const { return 1.0f; }
virtual RString GetError() const { return m_sError; } virtual RString GetError() const { return m_sError; }
/* Takes ownership of pFile (even on failure). */ /* Open a file. If pPrebuffer is non-NULL, and the file is sufficiently small,
static RageSoundReader_FileReader *OpenFile( RageFileBasic *pFile, RString &error ); * the (possibly compressed) data will be loaded entirely into memory, and pPrebuffer
static RageSoundReader_FileReader *OpenFile( RString filename, RString &error ); * will be set to true. */
static RageSoundReader_FileReader *OpenFile( RString filename, RString &error, bool *pPrebuffer = NULL );
protected: protected:
void SetError( RString sError ) const { m_sError = sError; } void SetError( RString sError ) const { m_sError = sError; }