|
|
@ -40,11 +40,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
|
|
#include "plStatusLog/plStatusLog.h" |
|
|
|
#include "plStatusLog/plStatusLog.h" |
|
|
|
#include "hsTimer.h" |
|
|
|
#include "hsTimer.h" |
|
|
|
|
|
|
|
|
|
|
|
static bool s_running; |
|
|
|
|
|
|
|
static LISTDECL(plSoundBuffer, link) s_loading; |
|
|
|
|
|
|
|
static CCritSect s_critsect; |
|
|
|
|
|
|
|
static CEvent s_event(kEventAutoReset); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void GetFullPath( const char filename[], char *destStr ) |
|
|
|
static void GetFullPath( const char filename[], char *destStr ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
char path[ kFolderIterator_MaxPath ]; |
|
|
|
char path[ kFolderIterator_MaxPath ]; |
|
|
@ -79,73 +74,74 @@ static plAudioFileReader *CreateReader( hsBool fullpath, const char filename[], |
|
|
|
return reader; |
|
|
|
return reader; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// our loading thread
|
|
|
|
hsError plSoundPreloader::Run() |
|
|
|
static void LoadCallback(void *) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
LISTDECL(plSoundBuffer, link) templist; |
|
|
|
hsTArray<plSoundBuffer*> templist; |
|
|
|
while(s_running) |
|
|
|
|
|
|
|
{ |
|
|
|
while (fRunning) |
|
|
|
s_critsect.Enter();
|
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
while(plSoundBuffer *buffer = s_loading.Head()) |
|
|
|
fCritSect.Lock(); |
|
|
|
|
|
|
|
for (int i = fBuffers.GetCount(); i > 0; i--) |
|
|
|
{ |
|
|
|
{ |
|
|
|
templist.Link(buffer); |
|
|
|
templist.Append(fBuffers.Pop()); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
s_critsect.Leave(); |
|
|
|
fCritSect.Unlock(); |
|
|
|
|
|
|
|
|
|
|
|
if(!templist.Head()) |
|
|
|
if (templist.GetCount() == 0) |
|
|
|
{ |
|
|
|
{ |
|
|
|
s_event.Wait(kEventWaitForever); |
|
|
|
fEvent.Wait(); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
plAudioFileReader *reader = nil; |
|
|
|
plAudioFileReader *reader = nil; |
|
|
|
while(plSoundBuffer *buffer = templist.Head()) |
|
|
|
for (int i = templist.GetCount(); i > 0; i--) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if(buffer->GetData()) |
|
|
|
plSoundBuffer* buf = templist.Pop(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (buf->GetData()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
reader = CreateReader(true, buffer->GetFileName(), buffer->GetAudioReaderType(), buffer->GetReaderSelect());
|
|
|
|
reader = CreateReader(true, buf->GetFileName(), buf->GetAudioReaderType(), buf->GetReaderSelect());
|
|
|
|
|
|
|
|
|
|
|
|
if( reader ) |
|
|
|
if( reader ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
unsigned readLen = buffer->GetAsyncLoadLength() ? buffer->GetAsyncLoadLength() : buffer->GetDataLength();
|
|
|
|
unsigned readLen = buf->GetAsyncLoadLength() ? buf->GetAsyncLoadLength() : buf->GetDataLength();
|
|
|
|
reader->Read( readLen, buffer->GetData() ); |
|
|
|
reader->Read( readLen, buf->GetData() ); |
|
|
|
buffer->SetAudioReader(reader); // give sound buffer reader, since we may need it later
|
|
|
|
buf->SetAudioReader(reader); // give sound buffer reader, since we may need it later
|
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
buffer->SetError(); |
|
|
|
{ |
|
|
|
|
|
|
|
buf->SetError(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
templist.Unlink(buffer); |
|
|
|
buf->SetLoaded(true); |
|
|
|
buffer->SetLoaded(true); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// we need to be sure that all buffers are removed from our load list when shutting this thread down or we will hang,
|
|
|
|
// we need to be sure that all buffers are removed from our load list when shutting this thread down or we will hang,
|
|
|
|
// since the sound buffer will wait to be destroyed until it is marked as loaded
|
|
|
|
// since the sound buffer will wait to be destroyed until it is marked as loaded
|
|
|
|
s_critsect.Enter(); |
|
|
|
fCritSect.Lock(); |
|
|
|
|
|
|
|
for (int i = fBuffers.GetCount(); i > 0; i--) |
|
|
|
{ |
|
|
|
{ |
|
|
|
while(plSoundBuffer *buffer = s_loading.Head()) |
|
|
|
plSoundBuffer* buf = fBuffers.Pop(); |
|
|
|
{ |
|
|
|
buf->SetLoaded(true); |
|
|
|
buffer->SetLoaded(true); |
|
|
|
|
|
|
|
s_loading.Unlink(buffer); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
s_critsect.Leave(); |
|
|
|
fCritSect.Unlock(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return hsOK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static plSoundPreloader gLoaderThread; |
|
|
|
|
|
|
|
|
|
|
|
void plSoundBuffer::Init() |
|
|
|
void plSoundBuffer::Init() |
|
|
|
{ |
|
|
|
{ |
|
|
|
s_running = true; |
|
|
|
gLoaderThread.Start(); |
|
|
|
_beginthread(LoadCallback, 0, 0); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void plSoundBuffer::Shutdown() |
|
|
|
void plSoundBuffer::Shutdown() |
|
|
|
{ |
|
|
|
{ |
|
|
|
s_running = false; |
|
|
|
gLoaderThread.Stop(); |
|
|
|
s_event.Signal(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//// Constructor/Destructor //////////////////////////////////////////////////
|
|
|
|
//// Constructor/Destructor //////////////////////////////////////////////////
|
|
|
@ -175,7 +171,6 @@ plSoundBuffer::~plSoundBuffer() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ASSERT(!link.IsLinked()); |
|
|
|
|
|
|
|
delete [] fFileName; |
|
|
|
delete [] fFileName; |
|
|
|
UnLoad(); |
|
|
|
UnLoad(); |
|
|
|
} |
|
|
|
} |
|
|
@ -342,7 +337,7 @@ void plSoundBuffer::IGetFullPath( char *destStr ) |
|
|
|
// While a file is loading(fLoading == true, and fLoaded == false) a buffer, no paremeters of the buffer should be modified.
|
|
|
|
// While a file is loading(fLoading == true, and fLoaded == false) a buffer, no paremeters of the buffer should be modified.
|
|
|
|
plSoundBuffer::ELoadReturnVal plSoundBuffer::AsyncLoad(plAudioFileReader::StreamType type, unsigned length /* = 0 */ ) |
|
|
|
plSoundBuffer::ELoadReturnVal plSoundBuffer::AsyncLoad(plAudioFileReader::StreamType type, unsigned length /* = 0 */ ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if(!s_running) |
|
|
|
if(!gLoaderThread.IsRunning()) |
|
|
|
return kError; // we cannot load the data since the load thread is no longer running
|
|
|
|
return kError; // we cannot load the data since the load thread is no longer running
|
|
|
|
if(!fLoading && !fLoaded) |
|
|
|
if(!fLoading && !fLoaded) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -354,13 +349,9 @@ plSoundBuffer::ELoadReturnVal plSoundBuffer::AsyncLoad(plAudioFileReader::Stream |
|
|
|
if( fData == nil ) |
|
|
|
if( fData == nil ) |
|
|
|
return kError; |
|
|
|
return kError; |
|
|
|
} |
|
|
|
} |
|
|
|
s_critsect.Enter(); |
|
|
|
|
|
|
|
{ |
|
|
|
gLoaderThread.AddBuffer(this); |
|
|
|
fLoading = true; |
|
|
|
fLoading = true; |
|
|
|
s_loading.Link(this); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
s_critsect.Leave(); |
|
|
|
|
|
|
|
s_event.Signal(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
if(fLoaded)
|
|
|
|
if(fLoaded)
|
|
|
|
{
|
|
|
|
{
|
|
|
|