mirror of
https://github.com/tribes2/engine.git
synced 2026-01-20 03:34:48 +00:00
219 lines
4.7 KiB
C++
219 lines
4.7 KiB
C++
//-----------------------------------------------------------------------------
|
|
// V12 Engine
|
|
//
|
|
// Copyright (c) 2001 GarageGames.Com
|
|
// Portions Copyright (c) 2001 by Sierra Online, Inc.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "audio/audioThread.h"
|
|
|
|
// AudioResourceQueue: -----------------------------------------------------
|
|
AudioResourceQueue::AudioResourceQueue()
|
|
{
|
|
mHead = mTail = 0;
|
|
}
|
|
|
|
void AudioResourceQueue::enqueue(AudioResourceEntry * entry)
|
|
{
|
|
AssertFatal(entry, "AudioResourceQueue::enqueue: invalid entry");
|
|
entry->mNext = 0;
|
|
|
|
if(!mHead)
|
|
mHead = mTail = entry;
|
|
else
|
|
{
|
|
mTail->mNext = entry;
|
|
mTail = entry;
|
|
}
|
|
}
|
|
|
|
AudioResourceEntry * AudioResourceQueue::dequeue()
|
|
{
|
|
AudioResourceEntry * entry = mHead;
|
|
|
|
if(mHead == mTail)
|
|
mHead = mTail = 0;
|
|
else
|
|
mHead = mHead->mNext;
|
|
|
|
return(entry);
|
|
}
|
|
|
|
// AudioThread: ------------------------------------------------------------
|
|
AudioThread * gAudioThread = 0;
|
|
|
|
AudioThread::AudioThread() : Thread(0, 0, false)
|
|
{
|
|
mStopSemaphore = Semaphore::createSemaphore(0);
|
|
mWakeSemaphore = Semaphore::createSemaphore();
|
|
mMutex = Mutex::createMutex();
|
|
|
|
// Now that the semaphores are created, start up the thread
|
|
start();
|
|
}
|
|
|
|
AudioThread::~AudioThread()
|
|
{
|
|
Semaphore::destroySemaphore(mStopSemaphore);
|
|
Semaphore::destroySemaphore(mWakeSemaphore);
|
|
Mutex::destroyMutex(mMutex);
|
|
}
|
|
|
|
void AudioThread::wake()
|
|
{
|
|
if(!isAlive())
|
|
return;
|
|
|
|
Semaphore::releaseSemaphore(mWakeSemaphore);
|
|
}
|
|
|
|
void AudioThread::stop()
|
|
{
|
|
if(!isAlive())
|
|
return;
|
|
|
|
Semaphore::releaseSemaphore(mStopSemaphore);
|
|
wake();
|
|
join();
|
|
}
|
|
|
|
void AudioThread::run(S32)
|
|
{
|
|
while(1)
|
|
{
|
|
Semaphore::acquireSemaphore(mWakeSemaphore);
|
|
|
|
if(Semaphore::acquireSemaphore(mStopSemaphore, false))
|
|
return;
|
|
|
|
lock();
|
|
AudioResourceEntry * entry = mLoadingQueue.mHead;
|
|
|
|
if(!entry)
|
|
{
|
|
unlock();
|
|
continue;
|
|
}
|
|
|
|
// load it in
|
|
Stream * stream = ResourceManager->openStream(entry->mResourceObj);
|
|
stream->read(entry->mResourceObj->fileSize, entry->mData);
|
|
ResourceManager->closeStream(stream);
|
|
|
|
mLoadedQueue.enqueue(mLoadingQueue.dequeue());
|
|
unlock();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
void AudioThread::loadResource(ResourceObject * obj, AudioBuffer * buffer)
|
|
{
|
|
AssertFatal(!buffer->mLoading, "AudioThread::loadResource: buffer already loading");
|
|
AudioResourceEntry * entry = new AudioResourceEntry();
|
|
|
|
entry->mResourceObj = obj;
|
|
entry->mBuffer = buffer;
|
|
entry->mData = dMalloc(obj->fileSize);
|
|
dMemset(entry->mData, 0, obj->fileSize);
|
|
|
|
buffer->mLoading = true;
|
|
|
|
lock();
|
|
mLoadingQueue.enqueue(entry);
|
|
unlock();
|
|
|
|
Semaphore::acquireSemaphore(mWakeSemaphore, false);
|
|
Semaphore::releaseSemaphore(mWakeSemaphore);
|
|
}
|
|
|
|
void AudioThread::setBufferPlayHandle(AudioBuffer * buffer, AUDIOHANDLE handle)
|
|
{
|
|
lock();
|
|
|
|
// search the loading list
|
|
AudioResourceEntry * entry = mLoadingQueue.mHead;
|
|
bool found = false;
|
|
|
|
while(entry && !found)
|
|
{
|
|
if(entry->mBuffer == buffer)
|
|
{
|
|
entry->mPlayHandle = handle;
|
|
found = true;
|
|
}
|
|
entry = entry->mNext;
|
|
}
|
|
|
|
// search the loaded list
|
|
if(!found)
|
|
{
|
|
entry = mLoadedQueue.mHead;
|
|
|
|
while(entry && !found)
|
|
{
|
|
if(entry->mBuffer == buffer)
|
|
{
|
|
entry->mPlayHandle = handle;
|
|
found = true;
|
|
}
|
|
entry = entry->mNext;
|
|
}
|
|
}
|
|
|
|
unlock();
|
|
}
|
|
|
|
AudioResourceEntry * AudioThread::getLoadedList()
|
|
{
|
|
lock();
|
|
AudioResourceEntry * list = mLoadedQueue.mHead;
|
|
mLoadedQueue.mHead = mLoadedQueue.mTail = 0;
|
|
unlock();
|
|
|
|
return(list);
|
|
}
|
|
|
|
// static methods: --------------------------------------------------------
|
|
void AudioThread::create()
|
|
{
|
|
if(gAudioThread)
|
|
return;
|
|
|
|
gAudioThread = new AudioThread();
|
|
}
|
|
|
|
void AudioThread::destroy()
|
|
{
|
|
if(!gAudioThread)
|
|
return;
|
|
|
|
gAudioThread->stop();
|
|
delete gAudioThread;
|
|
gAudioThread = 0;
|
|
}
|
|
|
|
void AudioThread::process()
|
|
{
|
|
if(!gAudioThread)
|
|
return;
|
|
|
|
AudioResourceEntry * entry = gAudioThread->getLoadedList();
|
|
|
|
// sync all the loaded buffers and play those marked
|
|
while(entry)
|
|
{
|
|
entry->mBuffer->mLoading = false;
|
|
|
|
if(alBufferSyncData_EXT(entry->mBuffer->malBuffer, AL_FORMAT_WAVE_EXT, entry->mData,
|
|
entry->mResourceObj->fileSize, 0))
|
|
{
|
|
if(entry->mPlayHandle != NULL_AUDIOHANDLE)
|
|
alxPlay(entry->mPlayHandle);
|
|
}
|
|
|
|
AudioResourceEntry * next = entry->mNext;
|
|
delete entry;
|
|
entry = next;
|
|
}
|
|
}
|