From c699ae8ab64481a7a251061fc2912916de4803de Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Sun, 26 Jun 2011 16:14:47 -0700 Subject: [PATCH 1/3] Use hsThread for SoundBuffer preloading. --- .../PubUtilLib/plAudioCore/plSoundBuffer.cpp | 117 ++++++++---------- .../PubUtilLib/plAudioCore/plSoundBuffer.h | 38 +++++- 2 files changed, 89 insertions(+), 66 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp b/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp index 9c9bf9da..d2a0304b 100644 --- a/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp +++ b/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp @@ -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 ]; @@ -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) - { - s_critsect.Enter(); - { - while(plSoundBuffer *buffer = s_loading.Head()) - { - templist.Link(buffer); - } - } - s_critsect.Leave(); - - if(!templist.Head()) - { - s_event.Wait(kEventWaitForever); - } - else - { + hsTArray templist; + + while (fRunning) + { + fCritSect.Lock(); + for (int i = fBuffers.GetCount(); i > 0; i--) + { + templist.Append(fBuffers.Pop()); + } + fCritSect.Unlock(); + + if (templist.GetCount() == 0) + { + fEvent.Wait(); + } + else + { plAudioFileReader *reader = nil; - while(plSoundBuffer *buffer = templist.Head()) - { - if(buffer->GetData()) - { - reader = CreateReader(true, buffer->GetFileName(), buffer->GetAudioReaderType(), buffer->GetReaderSelect()); + for (int i = templist.GetCount(); i > 0; i--) + { + plSoundBuffer* buf = templist.Pop(); + + if (buf->GetData()) + { + 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(); - } - - templist.Unlink(buffer); - buffer->SetLoaded(true); - } - } - } + { + buf->SetError(); + } + } + + 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(); - { - while(plSoundBuffer *buffer = s_loading.Head()) - { - buffer->SetLoaded(true); - s_loading.Unlink(buffer); - } - } - s_critsect.Leave(); + fCritSect.Lock(); + for (int i = fBuffers.GetCount(); i > 0; i--) + { + plSoundBuffer* buf = fBuffers.Pop(); + buf->SetLoaded(true); + } + 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 ////////////////////////////////////////////////// @@ -175,7 +171,6 @@ plSoundBuffer::~plSoundBuffer() } } - ASSERT(!link.IsLinked()); delete [] fFileName; 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. 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) { @@ -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) { diff --git a/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.h b/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.h index 2dfc90e6..b35f7534 100644 --- a/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.h +++ b/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.h @@ -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 //////////////////////////////////////////////////////// @@ -55,8 +55,6 @@ public: CLASSNAME_REGISTER( plSoundBuffer ); GETINTERFACE_ANY( plSoundBuffer, hsKeyedObject ); - LINK(plSoundBuffer) link; - enum Flags { kIsExternal = 0x0001, @@ -143,4 +141,38 @@ protected: plAudioFileReader *IGetReader( hsBool fullpath ); }; + +class plSoundPreloader : public hsThread +{ +protected: + hsTArray 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 From 93adfa9c7d245b24995c441e0608fa9907fb811b Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Tue, 28 Jun 2011 22:07:14 -0700 Subject: [PATCH 2/3] :%s/^I/ /ge --- .../PubUtilLib/plAudioCore/plSoundBuffer.cpp | 86 +++++++++---------- .../PubUtilLib/plAudioCore/plSoundBuffer.h | 42 ++++----- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp b/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp index d2a0304b..bc4f1948 100644 --- a/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp +++ b/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp @@ -76,30 +76,30 @@ static plAudioFileReader *CreateReader( hsBool fullpath, const char filename[], hsError plSoundPreloader::Run() { - hsTArray templist; - - while (fRunning) - { - fCritSect.Lock(); - for (int i = fBuffers.GetCount(); i > 0; i--) - { - templist.Append(fBuffers.Pop()); - } - fCritSect.Unlock(); - - if (templist.GetCount() == 0) - { - fEvent.Wait(); - } - else - { + hsTArray templist; + + while (fRunning) + { + fCritSect.Lock(); + for (int i = fBuffers.GetCount(); i > 0; i--) + { + templist.Append(fBuffers.Pop()); + } + fCritSect.Unlock(); + + if (templist.GetCount() == 0) + { + fEvent.Wait(); + } + else + { plAudioFileReader *reader = nil; - for (int i = templist.GetCount(); i > 0; i--) - { - plSoundBuffer* buf = templist.Pop(); + for (int i = templist.GetCount(); i > 0; i--) + { + plSoundBuffer* buf = templist.Pop(); - if (buf->GetData()) - { + if (buf->GetData()) + { reader = CreateReader(true, buf->GetFileName(), buf->GetAudioReaderType(), buf->GetReaderSelect()); if( reader ) @@ -109,39 +109,39 @@ hsError plSoundPreloader::Run() buf->SetAudioReader(reader); // give sound buffer reader, since we may need it later } else - { + { buf->SetError(); - } - } + } + } - buf->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 - fCritSect.Lock(); - for (int i = fBuffers.GetCount(); i > 0; i--) - { - plSoundBuffer* buf = fBuffers.Pop(); - buf->SetLoaded(true); - } - fCritSect.Unlock(); - - return hsOK; + fCritSect.Lock(); + for (int i = fBuffers.GetCount(); i > 0; i--) + { + plSoundBuffer* buf = fBuffers.Pop(); + buf->SetLoaded(true); + } + fCritSect.Unlock(); + + return hsOK; } static plSoundPreloader gLoaderThread; void plSoundBuffer::Init() { - gLoaderThread.Start(); + gLoaderThread.Start(); } void plSoundBuffer::Shutdown() { - gLoaderThread.Stop(); + gLoaderThread.Stop(); } //// Constructor/Destructor ////////////////////////////////////////////////// @@ -350,8 +350,8 @@ plSoundBuffer::ELoadReturnVal plSoundBuffer::AsyncLoad(plAudioFileReader::Stream return kError; } - gLoaderThread.AddBuffer(this); - fLoading = true; + gLoaderThread.AddBuffer(this); + fLoading = true; } if(fLoaded) { @@ -553,4 +553,4 @@ plAudioFileReader *plSoundBuffer::IGetReader( hsBool fullpath ) RoundDataPos( fDataLength ); return reader; -} \ No newline at end of file +} diff --git a/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.h b/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.h index b35f7534..c2579e2a 100644 --- a/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.h +++ b/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.h @@ -145,34 +145,34 @@ protected: class plSoundPreloader : public hsThread { protected: - hsTArray fBuffers; - hsEvent fEvent; - bool fRunning; - hsMutex fCritSect; + hsTArray fBuffers; + hsEvent fEvent; + bool fRunning; + hsMutex fCritSect; public: - virtual hsError Run(); + virtual hsError Run(); - virtual void Start() { - fRunning = true; - hsThread::Start(); - } + virtual void Start() { + fRunning = true; + hsThread::Start(); + } - virtual void Stop() { - fRunning = false; - fEvent.Signal(); - hsThread::Stop(); - } + virtual void Stop() { + fRunning = false; + fEvent.Signal(); + hsThread::Stop(); + } - bool IsRunning() const { return fRunning; } + bool IsRunning() const { return fRunning; } - void AddBuffer(plSoundBuffer* buffer) { - fCritSect.Lock(); - fBuffers.Push(buffer); - fCritSect.Unlock(); + void AddBuffer(plSoundBuffer* buffer) { + fCritSect.Lock(); + fBuffers.Push(buffer); + fCritSect.Unlock(); - fEvent.Signal(); - } + fEvent.Signal(); + } }; #endif //_plSoundBuffer_h From 88f594bc11aa437a42474f28154cec5feb61144a Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Sat, 23 Jul 2011 14:50:06 -0700 Subject: [PATCH 3/3] Tidy up some loops over the queue. --- Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp b/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp index bc4f1948..eb1d6ef7 100644 --- a/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp +++ b/Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp @@ -81,7 +81,7 @@ hsError plSoundPreloader::Run() while (fRunning) { fCritSect.Lock(); - for (int i = fBuffers.GetCount(); i > 0; i--) + while (fBuffers.GetCount()) { templist.Append(fBuffers.Pop()); } @@ -94,7 +94,7 @@ hsError plSoundPreloader::Run() else { plAudioFileReader *reader = nil; - for (int i = templist.GetCount(); i > 0; i--) + while (templist.GetCount()) { plSoundBuffer* buf = templist.Pop(); @@ -122,7 +122,7 @@ hsError plSoundPreloader::Run() // 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 fCritSect.Lock(); - for (int i = fBuffers.GetCount(); i > 0; i--) + while (fBuffers.GetCount()) { plSoundBuffer* buf = fBuffers.Pop(); buf->SetLoaded(true);