Skip to content

Commit

Permalink
Merge pull request H-uru#52 from dpogue/soundbuffer
Browse files Browse the repository at this point in the history
Use hsThread for SoundBuffer preloading.
  • Loading branch information
Deledrius committed Jul 23, 2011
2 parents 4ce9d1d + 6b73fd0 commit f1ed8ea
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 53 deletions.
91 changes: 41 additions & 50 deletions Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp
Expand Up @@ -40,11 +40,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plStatusLog/plStatusLog.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 )
{
char path[ kFolderIterator_MaxPath ];
Expand Down Expand Up @@ -79,73 +74,74 @@ static plAudioFileReader *CreateReader( hsBool fullpath, const char filename[],
return reader;
}

// our loading thread
static void LoadCallback(void *)
hsError plSoundPreloader::Run()
{
LISTDECL(plSoundBuffer, link) templist;
while(s_running)
hsTArray<plSoundBuffer*> templist;

while (fRunning)
{
s_critsect.Enter();
fCritSect.Lock();
while (fBuffers.GetCount())
{
while(plSoundBuffer *buffer = s_loading.Head())
{
templist.Link(buffer);
}
templist.Append(fBuffers.Pop());
}
s_critsect.Leave();
if(!templist.Head())
fCritSect.Unlock();

if (templist.GetCount() == 0)
{
s_event.Wait(kEventWaitForever);
fEvent.Wait();
}
else
{
plAudioFileReader *reader = nil;
while(plSoundBuffer *buffer = templist.Head())
{
if(buffer->GetData())
while (templist.GetCount())
{
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 )
{
unsigned readLen = buffer->GetAsyncLoadLength() ? buffer->GetAsyncLoadLength() : buffer->GetDataLength();
reader->Read( readLen, buffer->GetData() );
buffer->SetAudioReader(reader); // give sound buffer reader, since we may need it later
unsigned readLen = buf->GetAsyncLoadLength() ? buf->GetAsyncLoadLength() : buf->GetDataLength();
reader->Read( readLen, buf->GetData() );
buf->SetAudioReader(reader); // give sound buffer reader, since we may need it later
}
else
buffer->SetError();
{
buf->SetError();
}
}

templist.Unlink(buffer);
buffer->SetLoaded(true);

buf->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,
// since the sound buffer will wait to be destroyed until it is marked as loaded
s_critsect.Enter();
fCritSect.Lock();
while (fBuffers.GetCount())
{
while(plSoundBuffer *buffer = s_loading.Head())
{
buffer->SetLoaded(true);
s_loading.Unlink(buffer);
}
plSoundBuffer* buf = fBuffers.Pop();
buf->SetLoaded(true);
}
s_critsect.Leave();
fCritSect.Unlock();

return hsOK;
}

static plSoundPreloader gLoaderThread;

void plSoundBuffer::Init()
{
s_running = true;
_beginthread(LoadCallback, 0, 0);
gLoaderThread.Start();
}

void plSoundBuffer::Shutdown()
{
s_running = false;
s_event.Signal();
gLoaderThread.Stop();
}

//// Constructor/Destructor //////////////////////////////////////////////////
Expand Down Expand Up @@ -175,7 +171,6 @@ plSoundBuffer::~plSoundBuffer()
}
}

ASSERT(!link.IsLinked());
delete [] fFileName;
UnLoad();
}
Expand Down Expand Up @@ -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.
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
if(!fLoading && !fLoaded)
{
Expand All @@ -354,13 +349,9 @@ plSoundBuffer::ELoadReturnVal plSoundBuffer::AsyncLoad(plAudioFileReader::Stream
if( fData == nil )
return kError;
}
s_critsect.Enter();
{
fLoading = true;
s_loading.Link(this);
}
s_critsect.Leave();
s_event.Signal();

gLoaderThread.AddBuffer(this);
fLoading = true;
}
if(fLoaded)
{
Expand Down Expand Up @@ -562,4 +553,4 @@ plAudioFileReader *plSoundBuffer::IGetReader( hsBool fullpath )
RoundDataPos( fDataLength );

return reader;
}
}
38 changes: 35 additions & 3 deletions Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.h
Expand Up @@ -39,7 +39,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "pnKeyedObject/hsKeyedObject.h"
#include "plAudioCore.h"
#include "plAudioFileReader.h"
#include "pnUtils/pnUtils.h"
#include "hsThread.h"

//// Class Definition ////////////////////////////////////////////////////////

Expand All @@ -55,8 +55,6 @@ class plSoundBuffer : public hsKeyedObject
CLASSNAME_REGISTER( plSoundBuffer );
GETINTERFACE_ANY( plSoundBuffer, hsKeyedObject );

LINK(plSoundBuffer) link;

enum Flags
{
kIsExternal = 0x0001,
Expand Down Expand Up @@ -143,4 +141,38 @@ class plSoundBuffer : public hsKeyedObject
plAudioFileReader *IGetReader( hsBool fullpath );
};


class plSoundPreloader : public hsThread
{
protected:
hsTArray<plSoundBuffer*> fBuffers;
hsEvent fEvent;
bool fRunning;
hsMutex fCritSect;

public:
virtual hsError Run();

virtual void Start() {
fRunning = true;
hsThread::Start();
}

virtual void Stop() {
fRunning = false;
fEvent.Signal();
hsThread::Stop();
}

bool IsRunning() const { return fRunning; }

void AddBuffer(plSoundBuffer* buffer) {
fCritSect.Lock();
fBuffers.Push(buffer);
fCritSect.Unlock();

fEvent.Signal();
}
};

#endif //_plSoundBuffer_h

0 comments on commit f1ed8ea

Please sign in to comment.