mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2024-12-21 00:18:43 +00:00
Merge
--HG-- branch : sound_dev
This commit is contained in:
commit
a33f3e7e32
10 changed files with 124 additions and 35 deletions
|
@ -36,6 +36,12 @@ namespace NLMISC {
|
||||||
class CPThread : public IThread
|
class CPThread : public IThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum TThreadState
|
||||||
|
{
|
||||||
|
ThreadStateNone,
|
||||||
|
ThreadStateRunning,
|
||||||
|
ThreadStateFinished,
|
||||||
|
};
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
CPThread( IRunnable *runnable, uint32 stackSize);
|
CPThread( IRunnable *runnable, uint32 stackSize);
|
||||||
|
@ -59,10 +65,11 @@ public:
|
||||||
/// Internal use
|
/// Internal use
|
||||||
IRunnable *Runnable;
|
IRunnable *Runnable;
|
||||||
|
|
||||||
private:
|
TThreadState _State;
|
||||||
uint8 _State; // 0=not created, 1=started, 2=finished
|
|
||||||
uint32 _StackSize;
|
|
||||||
pthread_t _ThreadHandle;
|
pthread_t _ThreadHandle;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32 _StackSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace NLSOUND {
|
||||||
class CGroupController : public UGroupController
|
class CGroupController : public UGroupController
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
friend CGroupControllerRoot;
|
friend class CGroupControllerRoot;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CGroupController *m_Parent;
|
CGroupController *m_Parent;
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace NLSOUND {
|
||||||
class CStreamFileSound : public CStreamSound
|
class CStreamFileSound : public CStreamSound
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
friend CSourceMusicChannel;
|
friend class CSourceMusicChannel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CStreamFileSound();
|
CStreamFileSound();
|
||||||
|
|
|
@ -18,7 +18,11 @@
|
||||||
|
|
||||||
// STL includes
|
// STL includes
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <conio.h>
|
#ifdef NL_OS_WINDOWS
|
||||||
|
# include <conio.h>
|
||||||
|
#else
|
||||||
|
# include <curses.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// NeL includes
|
// NeL includes
|
||||||
#include <nel/misc/app_context.h>
|
#include <nel/misc/app_context.h>
|
||||||
|
@ -110,9 +114,16 @@ static void runSample()
|
||||||
printf("Press ANY other key to exit\n");
|
printf("Press ANY other key to exit\n");
|
||||||
for (; ; )
|
for (; ; )
|
||||||
{
|
{
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
if (_kbhit())
|
if (_kbhit())
|
||||||
{
|
{
|
||||||
switch (_getch())
|
switch (_getch())
|
||||||
|
#else
|
||||||
|
char ch;
|
||||||
|
if (read(0, &ch, 1))
|
||||||
|
{
|
||||||
|
switch (ch)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
case '+':
|
case '+':
|
||||||
s_GroupController->setUserGain(s_GroupController->getUserGain() + 0.1f);
|
s_GroupController->setUserGain(s_GroupController->getUserGain() + 0.1f);
|
||||||
|
|
|
@ -18,7 +18,11 @@
|
||||||
|
|
||||||
// STL includes
|
// STL includes
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <conio.h>
|
#ifdef NL_OS_WINDOWS
|
||||||
|
# include <conio.h>
|
||||||
|
#else
|
||||||
|
# include <curses.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// NeL includes
|
// NeL includes
|
||||||
#include <nel/misc/app_context.h>
|
#include <nel/misc/app_context.h>
|
||||||
|
@ -138,9 +142,16 @@ static void runSample()
|
||||||
printf("Press ANY other key to exit\n");
|
printf("Press ANY other key to exit\n");
|
||||||
while (!s_AudioDecoder->isMusicEnded())
|
while (!s_AudioDecoder->isMusicEnded())
|
||||||
{
|
{
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
if (_kbhit())
|
if (_kbhit())
|
||||||
{
|
{
|
||||||
switch (_getch())
|
switch (_getch())
|
||||||
|
#else
|
||||||
|
char ch;
|
||||||
|
if (read(0, &ch, 1))
|
||||||
|
{
|
||||||
|
switch (ch)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
case '+':
|
case '+':
|
||||||
s_GroupController->setUserGain(s_GroupController->getUserGain() + 0.1f);
|
s_GroupController->setUserGain(s_GroupController->getUserGain() + 0.1f);
|
||||||
|
@ -172,7 +183,13 @@ static void runSample()
|
||||||
|
|
||||||
printf("End of song\n");
|
printf("End of song\n");
|
||||||
printf("Press ANY key to exit\n");
|
printf("Press ANY key to exit\n");
|
||||||
while (!_kbhit()) { s_AudioMixer->update(); nlSleep(10); } _getch();
|
#ifdef NL_OS_WINDOWS
|
||||||
|
while (!_kbhit())
|
||||||
|
#else
|
||||||
|
char ch;
|
||||||
|
while (!read(0, &ch, 1))
|
||||||
|
#endif
|
||||||
|
{ s_AudioMixer->update(); nlSleep(10); }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,17 @@ static void *ProxyFunc( void *arg )
|
||||||
// Run the code of the thread
|
// Run the code of the thread
|
||||||
parent->Runnable->run();
|
parent->Runnable->run();
|
||||||
|
|
||||||
|
{
|
||||||
|
pthread_t thread_self = pthread_self();
|
||||||
|
// Make sure the parent still cares
|
||||||
|
// If this thread was replaced with a new thread (which should not happen),
|
||||||
|
// and the IThread object has been deleted, this will likely crash.
|
||||||
|
if (parent->_ThreadHandle == thread_self)
|
||||||
|
parent->_State = CPThread::ThreadStateFinished;
|
||||||
|
else
|
||||||
|
throw EThread("Thread ended after being detached, this should not happen");
|
||||||
|
}
|
||||||
|
|
||||||
// Allow some clean
|
// Allow some clean
|
||||||
// pthread_exit(0);
|
// pthread_exit(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -96,7 +107,7 @@ static void *ProxyFunc( void *arg )
|
||||||
*/
|
*/
|
||||||
CPThread::CPThread(IRunnable *runnable, uint32 stackSize)
|
CPThread::CPThread(IRunnable *runnable, uint32 stackSize)
|
||||||
: Runnable(runnable),
|
: Runnable(runnable),
|
||||||
_State(0),
|
_State(ThreadStateNone),
|
||||||
_StackSize(stackSize)
|
_StackSize(stackSize)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -106,10 +117,9 @@ CPThread::CPThread(IRunnable *runnable, uint32 stackSize)
|
||||||
*/
|
*/
|
||||||
CPThread::~CPThread()
|
CPThread::~CPThread()
|
||||||
{
|
{
|
||||||
if(_State == 1)
|
|
||||||
terminate(); // force the end of the thread if not already ended
|
terminate(); // force the end of the thread if not already ended
|
||||||
|
|
||||||
if(_State > 0)
|
if (_State != ThreadStateNone)
|
||||||
pthread_detach(_ThreadHandle); // free allocated resources only if it was created
|
pthread_detach(_ThreadHandle); // free allocated resources only if it was created
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,26 +129,51 @@ CPThread::~CPThread()
|
||||||
void CPThread::start()
|
void CPThread::start()
|
||||||
{
|
{
|
||||||
pthread_attr_t tattr;
|
pthread_attr_t tattr;
|
||||||
pthread_t tid;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (_StackSize != 0)
|
||||||
|
{
|
||||||
/* initialized with default attributes */
|
/* initialized with default attributes */
|
||||||
ret = pthread_attr_init(&tattr);
|
ret = pthread_attr_init(&tattr);
|
||||||
|
|
||||||
/* setting the size of the stack also */
|
/* setting the size of the stack also */
|
||||||
ret = pthread_attr_setstacksize(&tattr, _StackSize);
|
ret = pthread_attr_setstacksize(&tattr, _StackSize);
|
||||||
|
}
|
||||||
|
|
||||||
if(pthread_create(&_ThreadHandle, _StackSize != 0 ? &tattr : 0, ProxyFunc, this) != 0)
|
bool detach_old_thread = false;
|
||||||
|
pthread_t old_thread_handle;
|
||||||
|
if (_State != ThreadStateNone)
|
||||||
|
{
|
||||||
|
if (_State == ThreadStateRunning)
|
||||||
|
{
|
||||||
|
// I don't know if this behaviour is allowed, but neither thread implementations
|
||||||
|
// check the start function, and both simply let the existing running thread for what it is...
|
||||||
|
// From now on, this is not allowed.
|
||||||
|
throw EThread("Starting a thread that is already started, existing thread will continue running, this should not happen");
|
||||||
|
}
|
||||||
|
detach_old_thread = true;
|
||||||
|
old_thread_handle = _ThreadHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthread_create(&_ThreadHandle, _StackSize != 0 ? &tattr : NULL, ProxyFunc, this) != 0)
|
||||||
{
|
{
|
||||||
throw EThread("Cannot start new thread");
|
throw EThread("Cannot start new thread");
|
||||||
}
|
}
|
||||||
_State = 1;
|
_State = ThreadStateRunning;
|
||||||
|
|
||||||
|
if (detach_old_thread)
|
||||||
|
{
|
||||||
|
// Docs don't say anything about what happens when pthread_create is called with existing handle referenced.
|
||||||
|
if (old_thread_handle == _ThreadHandle)
|
||||||
|
throw EThread("Thread handle did not change, this should not happen");
|
||||||
|
// Don't care about old thread, free resources when it terminates.
|
||||||
|
pthread_detach(old_thread_handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPThread::isRunning()
|
bool CPThread::isRunning()
|
||||||
{
|
{
|
||||||
// TODO : need a real implementation here that check thread status
|
return _State == ThreadStateRunning;
|
||||||
return _State == 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -146,11 +181,11 @@ bool CPThread::isRunning()
|
||||||
*/
|
*/
|
||||||
void CPThread::terminate()
|
void CPThread::terminate()
|
||||||
{
|
{
|
||||||
if(_State == 1)
|
if (_State == ThreadStateRunning)
|
||||||
{
|
{
|
||||||
// cancel only if started
|
// cancel only if started
|
||||||
pthread_cancel(_ThreadHandle);
|
pthread_cancel(_ThreadHandle);
|
||||||
_State = 2; // set to finished
|
_State = ThreadStateFinished; // set to finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,13 +194,24 @@ void CPThread::terminate()
|
||||||
*/
|
*/
|
||||||
void CPThread::wait ()
|
void CPThread::wait ()
|
||||||
{
|
{
|
||||||
if(_State == 1)
|
if (_State == ThreadStateRunning)
|
||||||
{
|
{
|
||||||
if(pthread_join(_ThreadHandle, 0) != 0)
|
int error = pthread_join(_ThreadHandle, 0);
|
||||||
|
switch (error)
|
||||||
{
|
{
|
||||||
throw EThread( "Cannot join with thread" );
|
case 0:
|
||||||
|
break;
|
||||||
|
case EINVAL:
|
||||||
|
throw EThread("Thread is not joinable");
|
||||||
|
case ESRCH:
|
||||||
|
throw EThread("No thread found with this id");
|
||||||
|
case EDEADLK:
|
||||||
|
throw EThread("Deadlock detected or calling thread waits for itself");
|
||||||
|
default:
|
||||||
|
throw EThread("Unknown thread join error");
|
||||||
}
|
}
|
||||||
_State = 2; // set to finished
|
if(_State != ThreadStateFinished)
|
||||||
|
throw EThread("Thread did not finish, this should not happen");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,27 +255,29 @@ uint64 CPThread::getCPUMask()
|
||||||
|
|
||||||
void CPThread::setPriority(TThreadPriority priority)
|
void CPThread::setPriority(TThreadPriority priority)
|
||||||
{
|
{
|
||||||
// TODO: Verify and test this
|
// TODO: Test this
|
||||||
|
sched_param sp;
|
||||||
switch (priority)
|
switch (priority)
|
||||||
{
|
{
|
||||||
case ThreadPriorityHigh:
|
case ThreadPriorityHigh:
|
||||||
{
|
{
|
||||||
int minPrio = sched_get_priority_min(SCHED_FIFO);
|
int minPrio = sched_get_priority_min(SCHED_FIFO);
|
||||||
int maxPrio = sched_get_priority_max(SCHED_FIFO);
|
int maxPrio = sched_get_priority_max(SCHED_FIFO);
|
||||||
int prio = ((maxPrio - minPrio) / 4) + minPrio;
|
sp.sched_priority = ((maxPrio - minPrio) / 4) + minPrio;
|
||||||
pthread_setschedparam(_ThreadHandle, SCHED_FIFO, prio);
|
pthread_setschedparam(_ThreadHandle, SCHED_FIFO, &sp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ThreadPriorityHighest:
|
case ThreadPriorityHighest:
|
||||||
{
|
{
|
||||||
int minPrio = sched_get_priority_min(SCHED_FIFO);
|
int minPrio = sched_get_priority_min(SCHED_FIFO);
|
||||||
int maxPrio = sched_get_priority_max(SCHED_FIFO);
|
int maxPrio = sched_get_priority_max(SCHED_FIFO);
|
||||||
int prio = ((maxPrio - minPrio) / 2) + minPrio;
|
sp.sched_priority = ((maxPrio - minPrio) / 2) + minPrio;
|
||||||
pthread_setschedparam(_ThreadHandle, SCHED_FIFO, prio);
|
pthread_setschedparam(_ThreadHandle, SCHED_FIFO, &sp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
pthread_setschedparam(_ThreadHandle, SCHED_OTHER, 0);
|
sp.sched_priority = 0;
|
||||||
|
pthread_setschedparam(_ThreadHandle, SCHED_OTHER, &sp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -190,6 +190,9 @@ CWinThread::~CWinThread ()
|
||||||
|
|
||||||
void CWinThread::start ()
|
void CWinThread::start ()
|
||||||
{
|
{
|
||||||
|
if (isRunning())
|
||||||
|
throw EThread("Starting a thread that is already started, existing thread will continue running, this should not happen");
|
||||||
|
|
||||||
// ThreadHandle = (void *) ::CreateThread (NULL, _StackSize, ProxyFunc, this, 0, (DWORD *)&ThreadId);
|
// ThreadHandle = (void *) ::CreateThread (NULL, _StackSize, ProxyFunc, this, 0, (DWORD *)&ThreadId);
|
||||||
ThreadHandle = (void *) ::CreateThread (NULL, 0, ProxyFunc, this, 0, (DWORD *)&ThreadId);
|
ThreadHandle = (void *) ::CreateThread (NULL, 0, ProxyFunc, this, 0, (DWORD *)&ThreadId);
|
||||||
// nldebug("NLMISC: thread %x started for runnable '%x'", typeid( Runnable ).name());
|
// nldebug("NLMISC: thread %x started for runnable '%x'", typeid( Runnable ).name());
|
||||||
|
|
|
@ -102,7 +102,7 @@ static ov_callbacks OV_CALLBACKS_NLMISC_STREAM = {
|
||||||
};
|
};
|
||||||
|
|
||||||
CAudioDecoderVorbis::CAudioDecoderVorbis(NLMISC::IStream *stream, bool loop)
|
CAudioDecoderVorbis::CAudioDecoderVorbis(NLMISC::IStream *stream, bool loop)
|
||||||
: _Stream(stream), _Loop(loop), _StreamSize(0), _IsMusicEnded(false)
|
: _Stream(stream), _Loop(loop), _IsMusicEnded(false), _StreamSize(0)
|
||||||
{
|
{
|
||||||
_StreamOffset = stream->getPos();
|
_StreamOffset = stream->getPos();
|
||||||
stream->seek(0, NLMISC::IStream::end);
|
stream->seek(0, NLMISC::IStream::end);
|
||||||
|
|
|
@ -3,6 +3,8 @@ FILE(GLOB HEADERS ../../../include/nel/sound/driver/*.h)
|
||||||
|
|
||||||
NL_TARGET_LIB(nelsnd_lowlevel ${HEADERS} ${SRC})
|
NL_TARGET_LIB(nelsnd_lowlevel ${HEADERS} ${SRC})
|
||||||
|
|
||||||
|
TARGET_LINK_LIBRARIES(nelsnd_lowlevel nelmisc)
|
||||||
|
|
||||||
SET_TARGET_PROPERTIES(nelsnd_lowlevel PROPERTIES LINK_INTERFACE_LIBRARIES "")
|
SET_TARGET_PROPERTIES(nelsnd_lowlevel PROPERTIES LINK_INTERFACE_LIBRARIES "")
|
||||||
NL_DEFAULT_PROPS(nelsnd_lowlevel "NeL, Library: Sound Lowlevel")
|
NL_DEFAULT_PROPS(nelsnd_lowlevel "NeL, Library: Sound Lowlevel")
|
||||||
NL_ADD_RUNTIME_FLAGS(nelsnd_lowlevel)
|
NL_ADD_RUNTIME_FLAGS(nelsnd_lowlevel)
|
||||||
|
|
|
@ -87,7 +87,8 @@ std::string CGroupController::getPath() // overridden by root
|
||||||
return returnPath;
|
return returnPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
nlerror("Group Controller not child of parent");
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGroupController::calculateFinalGain() // overridden by root
|
void CGroupController::calculateFinalGain() // overridden by root
|
||||||
|
|
Loading…
Reference in a new issue