О немО себе[code]/maps/
[code] | 4D | Modules | Sound | soundsys.cpp
kMaps
4D
  Core
  Modules
    GUI
    Sound
      lib
      Sound___Win32_Debug
      dlls
      VTune
      NVS
      Ogg
      VS
      vorbis
        soundbuffer.h
        soundsource.cpp
        alu.h
        alut.h
        stdafx.h
        soundbuffer.cpp
        al.h
        remsnd.cpp
        soundsys.h
        stdafx.cpp
        alctypes.h
        alinit.h
        soundsource.h
        alc.h
        alinit.cpp
        soundsys.cpp
        remsnd.h
        altypes.h
    AI
    Quest
    TokaPH
    Terrain
  PlugIns
  auto_registrator_cc.c
  array-speed.php
  time.php
  auto_registrator.c
  ed_line.c
  SparseTileLayer.js
  codeZ.php
  ed_line.cc.c
 
#include "StdAfx.h"
#include "remSnd.h"
#include "soundsource.h"
#include "soundsys.h"
#include "alinit.h"
#include "SoundBuffer.h"

using namespace Sound;


class  
tSectionLocker
{
 
CRITICAL_SECTION Locker;
 
int            LockCount;
public:
 
tSectionLocker()
 { 
InitializeCriticalSection(&Locker);LockCount=0;}
~
tSectionLocker()
 { 
DeleteCriticalSection    (&Locker); }
 
void Lock()  { EnterCriticalSection(&Locker);LockCount++;if(LockCount>1){ASSERT(FALSE);}}
 
void Unlock(){ LockCount--;LeaveCriticalSection(&Locker);}
};


class 
/*DLLTYPE*/ tDynamicLocker
{
  
tSectionLocker     SLocker;
public:
  
tDynamicLocker(tSectionLocker     &SL){ SLocker=&SL;SL.Lock();}
 ~
tDynamicLocker()                     { if(SLocker)SLocker->Unlock();}
};
tSectionLocker  SOUND_LOCKER;
#define SLOCK  tDynamicLocker NearLock(SOUND_LOCKER);

bVector3f WorldScale;

bool IsGlobalGainChanged    =false;
bool IsGlobalListenerChanged=true;
bool IsTypeGainChanged      =false;
float OverallGain           =1.0f;
float AllGain               =1.0f;

DWORD SoundChannelsUsed=0;



DWORD SYS_SOUND=0;

PSoundSys MySoundSys;
SmartVector<PSoundSounds;
MakeProfile(SoundProf,"Sound");

HANDLE SoundThread;
HANDLE SoundEvent,SoundAskE;

void Touch()
{
    
SetEvent(SoundEvent);
};

PSound t_ResultSound=NULL;
bVector3f PosVector;
float *tmpPos=NULL;
DWORD t_PlayParams=0;
float fData;

//requests
void WINAPI t_CreateSound(DWORD Data)
{
   
t_ResultSound=MySoundSys->Load((LPCSTR)Data);
   
SetEvent(SoundAskE);
}

void WINAPI t_PlaySound(DWORD Data)
{
    ((
PSound)Data)->Play(t_PlayParams);
    
t_PlayParams=0;
}

void WINAPI t_GainSound(DWORD Data)
{
    ((
PSound)Data)->SetGain(fData);//>Play(t_PlayParams);
    
t_PlayParams=0;
}


void WINAPI t_PlayStop(DWORD Data)
{
    ((
PSound)Data)->Stop();
    
t_PlayParams=0;
}

void WINAPI t_PlaySetPos(DWORD Data)
{
    ((
PSound)Data)->SetPosition(PosVector);;
}

float tmpListenerPos1[9];
float tmpListenerPos2[9];
void WINAPI t_PlaySetLPos(DWORD Data)
{
    
alListenerfv(AL_POSITION,    tmpListenerPos1);
}

void WINAPI t_PlaySetLOri(DWORD Data)
{
    
alListenerfv(AL_ORIENTATIONtmpListenerPos2);
}

struct SounQstr
{
    
PAPCFUNC ptr;
    
DWORD param;
};

SounQstr SoundQ[0xFF];
int     CutCountQ=0;

int QueueSound(PAPCFUNC ptr,HANDLE SoundTH,DWORD Param)
{
    
SLOCK
     SoundQ
[CutCountQ].ptr  =ptr;
     
SoundQ[CutCountQ].param=Param;
     
CutCountQ++;
     
Touch();
     return 
0;
};

void UnquerySound()
{
    for(
int i=0;i<CutCountQ;++i)
        if(
SoundQ[i].ptr)
            
SoundQ[i].ptr(SoundQ[i].param);
    
CutCountQ=0;
}

PSound RequestToLoad(LPCSTR Str)
{
    
t_ResultSound=NULL;
    
ResetEvent(SoundAskE);
    
int ret=QueueSound(t_CreateSoundSoundThread, (DWORD)Str); 
    
ret=WaitForSingleObject(SoundAskE,1000);
    return 
t_ResultSound;
}

void RequestToPlay(PSound Snd,DWORD Params)
{
    
t_PlayParams=Params;
    if(!
Snd) return;
    
QueueSound(t_PlaySoundSoundThread, (DWORD)Snd); 
}

void RequestToGain(PSound Snd,float Params)
{
    
fData=Params;
    if(!
Snd) return;
    
QueueSound(t_GainSoundSoundThread, (DWORD)Snd); 
}

void RequestToStop(PSound Snd)
{
    if(!
Snd) return;
    
QueueSound(t_PlayStopSoundThread, (DWORD)Snd); 
}

void RequestToSetPos(PSound Snd,const float *Pos)
{
    
PosVector=Pos;
    if(!
Snd) return;
    
QueueSound(t_PlaySetPosSoundThread, (DWORD)Snd); 
}

void RequestToSetListenerPos(float *Pos)
{
    
tmpPos=Pos;
    
QueueSound(t_PlaySetLPosSoundThread, (DWORD)Pos); 
}

void RequestToSetListenerOri(float *Pos)
{
    
tmpPos=Pos;
    
QueueSound(t_PlaySetLOriSoundThread, (DWORD)Pos); 
}


//CALLBACK

int _CreateSound(LPCSTR FileName)
{
 if(!
FileName) return 0;
 if(
FileName[0]=='$')
 {
     if(
strcmp(FileName,"$channelsused")==0)
         return 
SoundChannelsUsed;
 }
 
PSound Sound=RequestToLoad(FileName);
 if(!
Sound) return 0;
 
Sounds.push_back(Sound);
 return 
Sounds.size();
}
void _PlaySound(int SID,DWORD Params)
{
    if(
SID==0)return;
    if(
SID>Sounds.size()){ASSERT(FALSE);}
    
RequestToPlay(Sounds[SID-1],Params);
}
void _GainSound(int SID,float Gain)
{
    if(
SID==0)return;
    if(
SID>Sounds.size()){ASSERT(FALSE);}
    
RequestToGain(Sounds[SID-1],Gain);
}

void _StopSound(int SID)
{
   if(
SID==0)return;
   if(
SID>Sounds.size()){ASSERT(FALSE);}
   
RequestToStop(Sounds[SID-1]);
}
void _KillSound(int SID)
{
   if(
SID>Sounds.size()){ASSERT(FALSE);}
   
_StopSound(SID);
   
delete Sounds[SID-1];
}
DWORD _DupSound(int SID)
{
   
PSound Sound=MySoundSys->Duplicate(Sounds[SID-1]);
   if(!
Sound) return 0;
   
Sounds.push_back(Sound);
   return 
Sounds.size();
}


bVector3f GetWorldScale()
{
    return 
WorldScale;
}

void _SetPosSound(int SID,bVector3f &Pos)
{
    if(
SID==0)return;
    if(
SID>Sounds.size()){ASSERT(FALSE);}
    
bVector3f SC=GetWorldScale();
    
Pos[0]*=SC[0];
    
Pos[1]*=SC[1];
    
Pos[2]*=SC[2];
    
RequestToSetPos(Sounds[SID-1],Pos);
}


bVector3f OldLPos;
void _SetListenerPos(bVector3f &_Pos)
{    
    if((
OldLPos-_Pos).Length()<0.01f) return;
    
OldLPos=_Pos;
    
bVector3f SC=GetWorldScale();
    
_Pos[0]*=SC[0];
    
_Pos[1]*=SC[1];
    
_Pos[2]*=SC[2];
    
ALfloat Pos[3] = { _Pos[0], _Pos[1], _Pos[2] };
    
ListenerPos=_Pos;
    
memcpy(tmpListenerPos1,Pos,sizeof(Pos));
    
RequestToSetListenerPos(_Pos);

    
IsGlobalListenerChanged=true;
}

bVector3f OldLUp;
bVector3f OldLAt;

void _SetListenerOri(bVector3f &_At,bVector3f &_Up)
{    
    if((
OldLUp-_Up).Length()<0.01f &&  (OldLAt-_At).Length()<0.01f)return ;
    
OldLUp=_Up;
    
OldLAt=_At;
    
//Print2Console(SYS_SOUND,"LORIL%f,%f,%f-%f,%f,%f",_At[0], _At[1], _At[2], _Up[0], _Up[1], _Up[2]);
     
ALfloat Pos[6] = { _At[0], _At[1], _At[2], _Up[0], _Up[1], _Up[2]};
     
memcpy(tmpListenerPos2,Pos,sizeof(Pos));
     
RequestToSetListenerOri(Pos);
}

void _SetScale(bVector3f &SC)
{
    
WorldScale=SC;
    
IsGlobalListenerChanged=true;
    
Touch();
};

void _SetGainOA(const float Gain)
{
     
IsGlobalGainChanged=true;
     
OverallGain=Gain;
     
Touch();
}

void _SetGain(const float Gain)
{
     
IsGlobalGainChanged=true;
     
AllGain=Gain;
     
Touch();
}


float GainPackByTypes[0xFF];

float     GetGainFor(const int Type)
{
    if(
Type<|| Type>0xFF) return 0;
    else
    return 
GainPackByTypes[Type];
}

void _SetGain(int SID,float Gain)
{
  if(
SID<|| SID>0xFF) return;
  
GainPackByTypes[SID]=Gain;
  if(
SID==0)
  {
     
IsGlobalGainChanged=true;
     
OverallGain=Gain;
  }
  else
  if(
SID==1)
  {
     
IsGlobalGainChanged=true;
     
AllGain=Gain;
  }
  
Touch();

}

void SetGainForAll()
{
    for(
int i=0;i<0xFF;++iGainPackByTypes[i]=1.0f;
}

struct THSstruct
{
    
DWORD TimeStart,TimeToDo,TimeEnd;
    
CGainPack Gains;
    
bool  Valid;
};


THSstruct THGs[0xFF];
int NumTHG=0;

void _ClearTHG()
{
    
SLOCK
    NumTHG
=0;
    
Touch();
};

void _SetTHG(DWORD TimeToDo,CGainPack Gains)
{
    
SLOCK
    THGs
[NumTHG].TimeStart=Time::Get();
    
THGs[NumTHG].TimeToDo=TimeToDo;
    
THGs[NumTHG].TimeEnd =THGs[NumTHG].TimeStart+TimeToDo;
    
THGs[NumTHG].Gains   =*Gains;    
    
THGs[NumTHG].Valid   =true;
    
NumTHG++; 
    
Touch();
}




//SOUND SYS

SoundSys::SoundSys(void):BaseObject(REFC_CORE,REFB_MODULE,"SOUND")
{
     
MySoundSys=this;
//     SetName("Sound[OpenAL]");
}

SoundSys::~SoundSys(void)
{
}


void CRTHT(void *P)
{((
SoundSys*)P)->ThreadFunc();}

void StartThread(SoundSys *trg)
{
  
SoundThread=CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)CRTHT,trg,0,0);
}

bool  SoundSys::Start()
{
    if(!
SYS_SOUND)
     
RegisterNewConsoleClass(SYS_SOUND,"SOUND",-1);
    
Print2Console(SYS_SOUND,"OpenAL sound system ready");
    
Sound::Set::SetCreateCallBack     (_CreateSound);
    
Sound::Set::SetPlayCallBack       (_PlaySound);
    
Sound::Set::SetGainCallBack       (_GainSound);
    
Sound::Set::SetStopCallBack       (_StopSound);
    
Sound::Set::SetKillCallBack       (_KillSound);
    
Sound::Set::SetPosCallBack        (_SetPosSound);
    
Sound::Set::SetDupCallBack        (_DupSound);

    
Sound::Set::SetListenPosCallBack  (_SetListenerPos);
    
Sound::Set::SetListenOriCallBack  (_SetListenerOri);
    
Sound::Set::SetOverallGainCallBack(_SetGainOA);
    
Sound::Set::SetWorldScaleCallBack (_SetScale);
    
Sound::Set::SetClearTHCallBack    (_ClearTHG);
    
Sound::Set::SetTHGainCallBack     (_SetTHG);
    
Sound::Set::SetGainForCallBack    (_SetGain);


    
SetGainForAll();
    
WorldScale.Set(0.01f,0.01f,0.01f);
    
Stoped=1;
    
SoundEvent=CreateEvent(0,FALSE,TRUE,NULL);
    
SoundAskE =CreateEvent(0,FALSE,TRUE,NULL);
    
ResetEvent(SoundAskE);
    
StartThread(this);
    
int ret=WaitForSingleObjectSoundAskE,10000);
    
ResetEvent(SoundAskE);
    return 
true;
    
//return suss;
}

void  SoundSys::SetPlaySlotsNum(int num)
{
    
PlaySlots.SetSize(num);
    for(
int i=0;i<num;i++)
    {
        
PlaySlots[i]=new CSoundPlayChanel();
        
PlaySlots[i]->CreateSource();
    }
}

void  SoundSys::Stop ()
{
    
ResetEvent(SoundAskE);
    
Stoped=1;
    
Touch();
    
WaitForSingleObjectSoundAskE,3000);
}

DWORD  SoundSys::Tick (float Time)
{
    
//do not anything
    
return 0;
}

void  SoundSys::ThreadFunc()
{
    
//SleepEx(100,false);
    
Stoped=0;
    if(
SoundThread!=GetCurrentThread())
        
Print2Console(SYS_SOUND,"Thread id not equal: %X : %X",SoundThread,GetCurrentThread());
    
bool sussInitializeOpenAL();
    if(
suss)
    {
        
SetPlaySlotsNum(32);
    }
    else
    {
        
Stoped=1;
    }
    
alListenerf(AL_GAIN    ,    1.0f);
    
bool FS=true;
    while(!
Stoped)
    {
        if(
FS)
        {
            
SetEvent(SoundAskE);
            
FS=0;
        }
        
//SleepEx(10,true);

        
FetchALError();
        
int ret=WaitForSingleObject(SoundEvent,200);//
        
ResetEvent(SoundEvent);
        {
                
                try
                {
                    if(
IsGlobalGainChanged)
                     
alListenerf(AL_GAIN    ,    OverallGain*AllGain);
                    
IsGlobalGainChanged=false;
                    {
                        
SLOCK;
                    try
                    {
                    
UnquerySound();
                    }
                    catch(...){
Print2Console(SYS_SOUND,"sound query error");}
                    }
                    
                    if(
NumTHG)
                    {
                        
int NumValid=0;
                        
DWORD ThisTime=Time::Get();
                        for(
int i=0;i<NumTHG;++i)
                            if(
THGs[i].Valid)
                            {
                                if(
THGs[i].TimeEnd<ThisTime)THGs[i].Valid=false;
                                else
                                {
                                  
NumValid++;
                                  
CGainPackGP=&THGs[i].Gains;
                                  
//SND_GAIN_OVERALL
                                  
if(THGs[i].TimeToDo==0)THGs[i].TimeToDo=1;
                                  if(
GP->IsValid(SND_GAIN_OVERALL))
                                  {
                                      
_SetGainOA(GP->GetGain(SND_GAIN_OVERALL)*(
                                       ((float)(
ThisTime-THGs[i].TimeStart))/((float)THGs[i].TimeToDo)));
                                  }
                                  if(
GP->IsValid(SND_GAIN_ALL))
                                  {
                                      
_SetGain(GP->GetGain(SND_GAIN_ALL)*(
                                       ((float)(
ThisTime-THGs[i].TimeStart))/((float)THGs[i].TimeToDo)));
                                  }
                                  
//else
                                  
{
                                    
int GID=-1;
                                    while((
GID=GP->GetGainID(GID+1))!=-1)
                                    {
                                     
_SetGain(GID,GP->GetGain(GID)*(
                                       ((float)(
ThisTime-THGs[i].TimeStart))/((float)THGs[i].TimeToDo)));
                                     
RecalcSoundGainFor(GID);
                                    }
                                  }
                                }
                            }
                        if(
NumValid==0)NumTHG=0;
                    }

                    if(    !
Onces.size() && !Dymanic.size()) continue;

      
//update ones
                
{
                   
SoundA::iterator end3=Onces.end();
                   for(
SoundA::iterator it2=Onces.begin();it2!=end3;++it2)
                      if(*
it2)
                      {
                          if(!(*
it2)->IsPlaying())
                          {
                              (*
it2)->Stop();
                              
delete *it2;
                              *
it2=NULL;
                          }
                      }
                }

      
//update chanels
                
_SPLAYPACK::iterator it;
                
_SPLAYPACK::iterator end=PlaySlots.end();
                
DWORD NumAwait=32;
                
int nChanel=0;
                
int ChanelsUsed=0;
                for(
it=PlaySlots.begin();it!=end;++it,++nChanel)
                {
                    
CSoundPlayChanel *ThisPlay=*it;
                  if(!(*
it)->IsFree())
                  {
                    (*
it)->Tick();
                    
ChanelsUsed++;
                  }
                  else
                  if(
NumAwait)
                  {
                      
NumAwait=0;
                      
//bool Haved=false;
                      
{
                        
SoundA::iterator end=Dymanic.end();
                        for(
SoundA::iterator it=Dymanic.begin();it!=end;++it)
                        if(*
it)if((*it)->NeedPlayButUncapable())
                        {
                            (*
it)->PlayOn(ThisPlay);
                            
NumAwait++;
                            break;
                        }
                      }
                      if(!
NumAwait)
                      {
                        
SoundA::iterator end3=Onces.end();
                        for(
SoundA::iterator it=Onces.begin();it!=end3;++it)
                         if(*
it)if((*it)->NeedPlayButUncapable())
                         {
                             (*
it)->PlayOn(ThisPlay);
                             
NumAwait++;
                         }
                      }

                  } 
                }
                
IsGlobalListenerChanged=false;
                
SoundChannelsUsed=ChanelsUsed;

                }
                catch(...)
                {
                    
Print2Console(SYS_SOUND,"sound proceed error");
                }
        }
    }
    
DestroyOpenAL();
    
SetEvent(SoundAskE);
    
CloseHandle(SoundEvent);
    
Stoped=2;
}

void SoundSys::RecalcSoundGainFor(const DWORD GP)
{
    
_SPLAYPACK::iterator it;
    
_SPLAYPACK::iterator end=PlaySlots.end();
    for(
it=PlaySlots.begin();it!=end;++it)
    {
        
CSoundPlayChanel *ThisPlay=*it;
        if(!(*
it)->IsFree())
        {
            (*
it)->TouchGain(GP);
        }
    }
}

CSound MyDummy;

PSound SoundSys::Load(const GString Name)
{
    
PSound S=new CSound();
    if(!
S->Load(Name))
    {
        
Error2Console(SYS_SOUND,"Fail to load %s",Name.c_str());
        
delete S;
        return &
MyDummy;
    }
    
//if(S->ContainStream())
    
Dymanic.push_back(S);
    
//else
    //Static.push_back(S);
    
return S;
}

bVector3f OldlPos;

void   SoundSys::SetMyPosition   (bVector3f Pos)
{
    
bVector3f TPos=Pos;
    
Pos*=SOUND_WORLD_SCALE;
    if((
OldlPos-TPos).Length()>1Print2Console(SYS_SOUND,"Sound listener set to %f,%f,%f",Pos[0],Pos[1],Pos[2]);

    
alListenerfv(AL_POSITION,(ALfloat*)&Pos);
}

void   SoundSys::SetMyOrientation(bVector3f Or)
{
    
alListenerfv(AL_ORIENTATION,(ALfloat*)&Or);
}

PSound SoundSys::Duplicate(PSound Src)
{
    if(!
Src)return false;

    
PSound RS=new CSound();
    if(
RS->DuplicateFrom(Src))
        return 
RS;
    
delete RS;
    return 
NULL;
}

void   SoundSys::CheckDeath(PSound Sound)
{
    
bool F=false;
    
SoundA::iterator end=Dymanic.end();
    for(
SoundA::iterator it=Dymanic.begin();it!=end;++it)
        if((*
it)==Sound){ F=true;*it=NULL;break;}
    if(!
F)
    {
        
SoundA::iterator end2=Static.end();
        for(
SoundA::iterator it=Static.begin();it!=end2;++it)
         if((*
it)==Sound){ F=true;*it=NULL;break;}
    }
       
SoundA::iterator end3=Onces.end();
    for(
SoundA::iterator it2=Onces.begin();it2!=end3;++it2)
     if((*
it2)==Sound){ F=true;*it2=NULL;break;}
}

void   SoundSys::AddOnes   (PSound One)
{
    
Onces.push_back(One);
}

bool   SoundSys::GetPlaySlot(CSoundSource *Source)
{
    
_SPLAYPACK::iterator it;
    
_SPLAYPACK::iterator end=PlaySlots.end();
    
float minimallevel=0.001f;
    
int   minimalslot =-1;
    
int i=0;
    for(
it=PlaySlots.begin();it!=end;++it,++i)
    {
        if((*
it)->IsFree())
        {
            (*
it)->Use(Source);
            return 
true;
        }else if((*
it)->PriLevel()<minimallevel){minimallevel=(*it)->PriLevel();minimalslot=i;}
    }
    if(
Source->PriLevel()>minimallevel)
    {
      
PlaySlots[minimalslot]->Use(Source);
      return 
true;
    }
    return 
false;
}

//------------------------------------------------------

// SOUND


CSound::CSound()
{
  
State=0;
}
CSound::~CSound()
{
  
Source.UnBind();
}

bool CSound::NeedPlayButUncapable()
{
  return 
Source.NeedPlayButUncapable();
}

void CSound::Play(DWORD Params)
{
    if(
Source.Empty())return;
    if(
Params)
    {
        if(
Params SND_PLAY_ONCE)
         
MySoundSys->AddOnes(this);
    }
    if(
Source.HaveDriver() || MySoundSys->GetPlaySlot(&Source))
     
Source.Play();
    else
    {
        
Source.DoAlterLoop();
    }
}

void CSound::PlayOn(CSoundPlayChanel *Src)
{
     
Src->Use(&Source);
     
Source.Play();
}
bool CSound::DuplicateFrom(CSound *Src){ return Source.DuplicateFrom(&Src->Source);}
void CSound::Stop(){Source.Stop();}
void CSound::SetPosition(bVector3f Pos){Source.Move(Pos);}
BYTE CSound::GetState(){return State;}
bool CSound::Load(const GString &Name)
{
    
Source.SetName(Name);
    
CSoundSourceShader *Shader=NULL;
    
bool found=GetSoundShaderManager()->GetShader(Name,Shader);
    
bool ret=false;
    if(
found && Shader)
     
retSource.Assign(Shader);
    if(
ret) return true;
    else
    return 
Source.AddBuffer(GetBufferFor(Name,0));
}



//bool CSound::IsStreamed(){return false;}//MySound->IsStreamed();}
void CSound::Update(){Source.Tick();}

//bool CSound::DuplicateTo(PSound Dest)
//{
//    if(!((remSnd*)Dest->_MySound)->CreateSourse(MySound->GetSoundShader()))        return false;
    //((remSnd*)Dest->_MySound)->AssingBuffer(MySound->GetBufferID());
    //return true;
//}

bool CSound::IsPlaying()   {return Source.IsPlaying();}
void CSound::SetGain  (float Gain)   {Source.SetGain(Gain);}

//PSoundSys MySoundSys;

PBlopBaseObject GetSoundSystem()
{
    return 
MySoundSys;
}

PBlopBaseObject GetSound()
{
    
MySoundSys=new SoundSys();
    return 
MySoundSys;
}

PLoadObjectList DLLTYPE GetStoredClasses()
{
    
ONCE_PLUGIN
    MAKE_PLUGIN 
(GetSound,"SOUND",0,true);
    
END_PLUGIN
}


                                                



//9035774305  Марина








//SYSTEM






[CODE]/4D/Modules/Sound/soundsys.cpp

Знаете как меня эти белорусы называют?
ДОХЛИК НЕМИРУШИЙ!
kashey