reman3/Rayman_X/cpa/tempgrp/SND/src/sound3d.c

3691 lines
109 KiB
C
Raw Blame History

/*
//////////////////////////////////////////////////////////////
// SOUND3D.C Version 2.0 //
//////////////////////////////////////////////////////////////
*/
#include "SNDinc.h"
#include "sndevent.h"
#include "ERM.h"
#include "sndext/errsnd.h"
#include "SND.h"
#ifdef DEBUG_SON
#include <stdio.h>
#endif
/*--external FANTOME event*/
SND_tduRefEvt SND_EVT_FANTOME={(unsigned long)EVT_FANTOME_PTR};
#ifndef NO_ACP_SOUND
#if defined(_DLL_COMPILATION_MODE)/* || defined(USE_DBG_MODULE)*/
#include "snddll.h"
#endif
#include "snddbg.h"
#include "sndthrd.h"
#include "sndres.h"
#include "sndplay.h"
#include "sndswtch.h"
#include "sndthrd.h"
#ifdef SND_SCRIPT_VERSION
#include "sndld_s.h"
#endif /*SND_SCRIPT_VERSION*/
#ifdef SND_HYBRID_VERSION
#include "sndld_hy.h"
#endif /*SND_HYBRID_VERSION*/
#include "sndini.h"
#include "sndrnd.h"
/*For debugging*/
char SND_g_DateVersion[]=__DATE__"-"__TIME__; /*date of last compilation/LIB generation*/
char SND_g_LabelVersion[]=
#include "SND/version.txt"
; /*version label (PUBLIC\SND\VESRION.TXT)*/
#ifdef SOUND_DEBUG
#include <stdio.h>
#endif /*SOUND_DEBUG*/
/*------------- internal variables---------------------------*/
/*------- associations (object <-> event) description*/
typedef struct ASSOCIATION_DESCRIPTION_ *pASSOCIATION_DESCRIPTION;
SNDLST2_M_DynamicUseListOf(pASSOCIATION_DESCRIPTION);
typedef struct ASSOCIATION_DESCRIPTION_{
SndBool bDynamic; /*Update association*/
long channel; /*sound channel*/
long indice; /*sound object id*/
long type; /*sound object type*/
SND_tduRefEvt evt; /*sound event*/
long prio; /*priority; no used*/
long voice; /*SndPlay voice id (if any)*/
tduRefRes res_hi; /*sound resource associated with sound event (if any)*/
SndBool bValid; /*FALSE when then association is no more valid*/
SndReal rDeTune; /*random Detuning parameter (0 when inactive)*/
long lHandle; /*SendRequestSound handle (returned code)(to manage Callback or GetPos)*/
RollOffParam stRollOff; /*rolloff parameter*/
SNDLST2_M_DynamicElementDeclaration(pASSOCIATION_DESCRIPTION)
} ASSOCIATION_DESCRIPTION;
typedef struct LISTE_ASSOCIATION_{
SNDLST2_M_DynamicAnchorDeclaration(pASSOCIATION_DESCRIPTION) pList;
} LISTE_ASSOCIATION;
#define NB_ASSOCIATION_MAX 65
static LISTE_ASSOCIATION association; /*description of active association*/
/*-------information about microphones*/
typedef struct MICRO_DESCRIPTION_ *pMICRO_DESCRIPTION;
SNDLST2_M_DynamicUseListOf(pMICRO_DESCRIPTION);
typedef struct MICRO_DESCRIPTION_{
long sndId;
SNDLST2_M_DynamicElementDeclaration(pMICRO_DESCRIPTION)
}MICRO_DESCRIPTION;
typedef struct LISTE_MICRO_{
SNDLST2_M_DynamicAnchorDeclaration(pMICRO_DESCRIPTION) pList;
}LISTE_MICRO;
static LISTE_MICRO micros_sound;/*list of the active microphones (used by SynchroSound)*/
static int g_iNbActiveMicros=0; /*number of created/actived microphone*/
/*-------volume lines*/
typedef struct tdstVolumeLine_ *ptdstVolumeLine;
SNDLST2_M_DynamicUseListOf(ptdstVolumeLine);
typedef struct tdstVolumeLine_{
long lVol; /*current volume for the volume line*/
SNDLST2_M_DynamicElementDeclaration(ptdstVolumeLine)
}tdstVolumeLine;
typedef struct LISTE_tdstVolumeLine_{
SNDLST2_M_DynamicAnchorDeclaration(ptdstVolumeLine) pList;
}LISTE_tdstVolumeLine;
static LISTE_tdstVolumeLine g_VolumeLines;
static int nb_volume_lines=0;
/*------ informations about sound object's volume (may be one volume for each object)*/
typedef struct tdstVolumeChanged_ *ptdstVolumeChanged;
SNDLST2_M_DynamicUseListOf(ptdstVolumeChanged);
typedef struct tdstVolumeChanged_{
long lVolume; /*current volume for this sound object type*/
long lIndice; /*sound object id*/
SNDLST2_M_DynamicElementDeclaration(ptdstVolumeChanged)
}tdstVolumeChanged;
static int nb_object_type=0;
typedef struct {
tdstAllRetObjectSound pfnRetObjectSound; /*callback function (to get location of this object)*/
tdstAllRetChannelSound pfnRetChannelSound; /*Channel callback function (to get location of the sound)*/
tdstVolumeLine* pstVolumeLine; /*volume line id associated with this type (if any)*/
td_pfn_vCopyString pfnInfoObject; /*info callback function (if any)*/
td_pfn_bRetRollOffFactor pfnRollOff; /*rolloff callback function (if any)*/
SND_tdstBlockEvent* pstLastEvent; /*last sound event played*/
long lVolume; /*current volume*/
SNDLST2_M_DynamicAnchorDeclaration(ptdstVolumeChanged) pListVolumeChanged;/*list of ACTIVE objects whose volume have been changed (other object used the type's volume)*/
} tdstTypeObjectInfos;
static tdstTypeObjectInfos *g_d_pstTypeObjectSoundInfos;
static tdstAllRetMicroSound g_st_pfnRetMicroSound={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
SndReal fn_rRetObjectSoundSndRealDefault(long indice);
unsigned char fn_ucRetObjectSoundREVERBDefault(long indice);
void fn_vRetObjectSoundExtraCoefDefault(long indice,SND_tduRefEvt evt,SndReal* pitch,SndReal* pan,SndReal* vol);
long fn_lRetObjectSoundSwitchDefault(long indice,long type_switch);
SndBool fn_bRetObjectSoundMicroLinkDefault(long indice,long micro);
void fn_vRetObjectSoundVectorIDefault(long indice, SndVector * vect);
void fn_vRetObjectSoundVectorJDefault(long indice, SndVector * vect);
void fn_vRetObjectSoundVectorKDefault(long indice, SndVector * vect);
static tdstAllRetObjectSound g_astTypeObjectSoundInfosDefault={
fn_rRetObjectSoundSndRealDefault,
fn_rRetObjectSoundSndRealDefault,
fn_rRetObjectSoundSndRealDefault,
fn_rRetObjectSoundSndRealDefault,
fn_rRetObjectSoundSndRealDefault,
fn_rRetObjectSoundSndRealDefault,
fn_ucRetObjectSoundREVERBDefault,
fn_vRetObjectSoundExtraCoefDefault,
fn_lRetObjectSoundSwitchDefault,
fn_bRetObjectSoundMicroLinkDefault,
fn_vRetObjectSoundVectorIDefault,
fn_vRetObjectSoundVectorJDefault,
fn_vRetObjectSoundVectorKDefault
};
SndReal fn_rRetChannelSoundSndReal0Default(long channel, long indice);
SndReal fn_rRetChannelSoundSndReal1Default(long channel, long indice);
SndBool fn_bRetChannelSoundActiveDefault(long channel, long indice);
SndBool fn_bRetChannelSoundAbsCoordDefault(long channel, long indice);
//Default callback for sound channel
static tdstAllRetChannelSound g_astChannelSoundInfosDefault = {
fn_rRetChannelSoundSndReal0Default,
fn_rRetChannelSoundSndReal0Default,
fn_rRetChannelSoundSndReal0Default,
fn_rRetChannelSoundSndReal0Default,
fn_rRetChannelSoundSndReal0Default,
fn_rRetChannelSoundSndReal0Default,
fn_bRetChannelSoundActiveDefault,
TRUE
};
/*--next value to be returned by SendRequestSound*/
static long HandleCallback=1;
/*--global initialization flag*/
static SndBool g_bInitDoneSound=FALSE;
/*--doppler activation: FALSE->no doppler effect*/
static SndBool g_bDopplerActive=TRUE;
/*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*/
/* Private functions */
/*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*/
/*save the current event for a specific type*/
void fnSetLastEventForSoundObjectType(long type,SND_tdstBlockEvent* evt)
{
if (type<nb_object_type && type>=0)
g_d_pstTypeObjectSoundInfos[type].pstLastEvent=evt;
}
SND_tdstBlockEvent* SND_fn_pstGetLastEventForObjectTypeSound(long type)
{
if (type<nb_object_type && type>=0)
return g_d_pstTypeObjectSoundInfos[type].pstLastEvent;
else
return NULL;
}
/*------------------------------------------------------------------------------*/
/* managemnent of ChangeVolume event */
/* Call to ChangevolumeType cancel any other previous call to ChangeVolueObject */
/* */
/* set volume for object to 127 = retire volume object from list */
/*------------------------------------------------------------------------------*/
void fn_vResetVolumeForObject(long indice,long type)
{
ptdstVolumeChanged pVol;
int i;
SndBool bFound=FALSE;
/*search for the correspondant object*/
SNDLST2_M_DynamicForEachElementOf(&g_d_pstTypeObjectSoundInfos[type].pListVolumeChanged,pVol,i)
{
if (pVol->lIndice==indice)
{
bFound=TRUE;
break;
}
}
if (bFound)
{
SNDLST2_M_DynamicIsolate(pVol);
SND_fn_vFreeSndEx(E_ucSndBlockMain,pVol);
}
}
/*Change volume for a sound type -> cancel all other objet volume (volume for sound type is more important)*/
void fn_vChangeVolumeForType(long type,long lNewVolume)
{
g_d_pstTypeObjectSoundInfos[type].lVolume=lNewVolume;
}
void fn_vResetVolumeForType(long type)
{
g_d_pstTypeObjectSoundInfos[type].lVolume=C_SOUNDVOL_MAXI;
}
/*Change volume for one object*/
void fn_vChangeVolumeForObject(long indice,long type,long lNewVolume)
{
ptdstVolumeChanged pVol;
int i;
SndBool bFound=FALSE;
if (lNewVolume==C_SOUNDVOL_MAXI)
{/*reset object*/
fn_vResetVolumeForObject(indice,type);
}
else
{
/*look if object is still in the list*/
SNDLST2_M_DynamicForEachElementOf(&g_d_pstTypeObjectSoundInfos[type].pListVolumeChanged,pVol,i)
{
if (pVol->lIndice==indice)
{
bFound=TRUE;
break;
}
}
if (!bFound)
{/*the object is not yet in the list*/
pVol=SND_fn_pvMallocSndEx(E_ucSndBlockMain,sizeof(tdstVolumeChanged));
SNDLST2_M_DynamicInitElement(pVol);
SNDLST2_M_DynamicAddTail(&g_d_pstTypeObjectSoundInfos[type].pListVolumeChanged,pVol);
pVol->lIndice=indice;
}
pVol->lVolume=lNewVolume;
}
}
long fn_lGetVolumeForType(long type)
{
return g_d_pstTypeObjectSoundInfos[type].lVolume;
}
long fn_lGetVolumeForObject(long indice,long type)
{
ptdstVolumeChanged pVol;
int i;
SndBool bFound=FALSE;
/*first look if there is a specific volume for this object*/
SNDLST2_M_DynamicForEachElementOf(&g_d_pstTypeObjectSoundInfos[type].pListVolumeChanged,pVol,i)
{
if (pVol->lIndice==indice)
{
bFound=TRUE;
break;
}
}
if (bFound)
return pVol->lVolume;
else
return C_SOUNDVOL_MAXI;
}
/*--------------------------------------------------------*/
/* GetMicroParam:get microphone dynamic parameters (location...)*/
/* Parametere:id=microphone id*/
/* par(OUT)=struct where the dynamis parameters will be copied*/
/* Retour:neant*/
/*------------------------------------------------------*/
void GetMicroParam(long id,MicroParam *par)
{
par->pos.x=g_st_pfnRetMicroSound.X(id);
par->pos.y=g_st_pfnRetMicroSound.Y(id);
par->pos.z=g_st_pfnRetMicroSound.Z(id);
par->vit.x=g_st_pfnRetMicroSound.VX(id);
par->vit.y=g_st_pfnRetMicroSound.VY(id);
par->vit.z=g_st_pfnRetMicroSound.VZ(id);
par->dirnor.x=g_st_pfnRetMicroSound.DNX(id);
par->dirnor.y=g_st_pfnRetMicroSound.DNY(id);
par->dirnor.z=g_st_pfnRetMicroSound.DNZ(id);
par->dirtan.x=g_st_pfnRetMicroSound.DTX(id);
par->dirtan.y=g_st_pfnRetMicroSound.DTY(id);
par->dirtan.z=g_st_pfnRetMicroSound.DTZ(id);
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/*vector orientation MUST NOT BE NULL !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
snd_assert((par->dirnor.x!=0)||(par->dirnor.y!=0)||(par->dirnor.z!=0));
snd_assert((par->dirtan.x!=0)||(par->dirtan.y!=0)||(par->dirtan.z!=0));
if ((par->dirnor.x==0)&&(par->dirnor.y==0)&&(par->dirnor.z==0))
{
par->dirnor.x=C_SNDREAL_1;
}
if ((par->dirtan.x==0)&&(par->dirtan.y==0)&&(par->dirtan.z==0))
{
par->dirtan.y=C_SNDREAL_1;
}
/*vector orientation MUST NOT BE NULL !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
}
/*----------------------------------------------------------------
get a free association
return the id of this free association
-----------------------------------------------------------------*/
ASSOCIATION_DESCRIPTION* pre_associe_sound(void)
{
pASSOCIATION_DESCRIPTION pAsso;
int i;
/*get the number of element in the list (i)*/
i=SNDLST2_M_DynamicGetNumberOfElements(&association.pList);
if (i>=NB_ASSOCIATION_MAX)
{
SND_M_DisplayErrorEx(E_uwSndTooManyEvents,"",SNDERR_DISPLAY_IF_WANTED);
return NULL;
}
pAsso=(pASSOCIATION_DESCRIPTION)SND_fn_pvMallocSndEx(E_ucSndBlockMain,sizeof(ASSOCIATION_DESCRIPTION));
SNDLST2_M_DynamicInitElement(pAsso);
return pAsso;
}
/*---------------------------------------------------------
delete a association
Parameteree:association id
----------------------------------------------------------*/
void erase_association(pASSOCIATION_DESCRIPTION asso)
{
#ifdef SUPERVISATER
dbgSND_fn_vKillEventToObject(asso->indice,(long)asso);
#endif
SNDLST2_M_DynamicIsolate(asso);
SND_fn_vFreeSndEx(E_ucSndBlockMain,asso);
}
/*
*=============================================================================
* associe_sound
*
* Description : Store informations about a association
*=============================================================================
* Input: asso : association used to sotre these informations
* channel : sound channel id
* indice : sound object id
* type : sound object type id
* voice : PlaySnd voice
* evt : sound event played
* res_hi : resource played by Playsnd
* rDetune : ranomd detuning parmeter
* lHandle : retunred code for SendRequestSound
*
* Output : None
*
*=============================================================================
* Creation date : Author :
*=============================================================================
* Modification date : 01/06/99 Author : Pascal Lalancette
* Modifications : Add Sound channel support
*=============================================================================
*/
void associe_sound(pASSOCIATION_DESCRIPTION asso, long channel,long indice,long type,long prio,long voice,SND_tduRefEvt evt,tduRefRes res_hi,SndReal rDeTune,long lHandle)
{
int i;
pASSOCIATION_DESCRIPTION pAsso,pAssoNext;
/*only one association for each vlue of "voice"*/
SNDLST2_M_DynamicForEachMovingElementOf(&association.pList,pAsso,pAssoNext,i)
{
if (!(pAsso->bValid) || (pAsso->voice==voice))
{
erase_association(pAsso);
}
}
/*try to group association for the same object/type*/
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{
if ((pAsso->indice==indice) && (pAsso->type==type))
break;
}
if (pAsso)
{
pAssoNext=SNDLST2_M_DynamicGetNextElement(pAsso);
SNDLST2_M_DynamicInsertBetween(asso,pAsso,pAssoNext);
}
else
{
SNDLST2_M_DynamicAddTail(&association.pList,asso);
}
asso->bDynamic=TRUE;
asso->channel=channel;
asso->indice=indice;
asso->type=type;
asso->prio=prio;
asso->voice=voice;
asso->evt=evt;
asso->res_hi=res_hi;
asso->bValid=TRUE;
asso->rDeTune=rDeTune;
asso->lHandle=lHandle;
#ifdef SUPERVISATER
dbgSND_fn_vAddEventToObject(indice,type,(long)asso,evt);
#endif
}
/*
*=============================================================================
* get_association_object
*
* Description : Get the first association found used by a object/event couple
*=============================================================================
* Input
* indice : sound object id
* type : sound object type id
* evt : sound event played
*
* Output
* asso : association pointer or NULL if not found
*
*=============================================================================
* Creation date : Author :
*=============================================================================
* Modification date : 01/06/99 Author : Pascal Lalancette
* Modifications : Changed name for get_association_object()
*=============================================================================
*/
pASSOCIATION_DESCRIPTION get_association_object(long indice,long type,void* evt)
{
pASSOCIATION_DESCRIPTION pAsso;
int i=0;
if (evt==NULL)
{
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{
if (pAsso->bValid
&& (pAsso->indice==indice)
&& (pAsso->type==type))
break;
}
}
else
{
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{
if (pAsso->bValid
&& (pAsso->indice==indice)
&& (pAsso->evt.pstPtr==evt)
&& (pAsso->type==type))
break;
}
}
return pAsso;
}
/*
*=============================================================================
* get_association_channel
*
* Description : Get the first association found used by a channel/event couple
*=============================================================================
* Input
* channel : sound channel id
* indice : sound object id
* type : sound object type id
* evt : sound event played
*
* Output
* asso : association pointer or NULL if not found
*
*=============================================================================
* Creation date : 01/06/99 Author : Pascal Lalancette
*=============================================================================
* Modification date : Author :
* Modifications :
*=============================================================================
*/
pASSOCIATION_DESCRIPTION get_association_channel(long channel, long indice,long type,void* evt)
{
pASSOCIATION_DESCRIPTION pAsso;
int i=0;
if (evt==NULL)
{
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{
if (pAsso->bValid
&& (pAsso->channel == channel)
&& (pAsso->indice == indice)
&& (pAsso->type == type))
break;
}
}
else
{
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{
if (pAsso->bValid
&& (pAsso->channel == channel)
&& (pAsso->indice == indice)
&& (pAsso->evt.pstPtr == evt)
&& (pAsso->type == type))
break;
}
}
return pAsso;
}
/*
*=============================================================================
* stop_all_son_objet
*
* Description : Stop any sounds assoicated with a object (except when flag
* Stopable is FALSE).Called by KillObjectSound or
* SendRequetsSound to Stop event
*=============================================================================
* Input
* indice : sound object id
* type : sound object type id
*
* Output
* None
*
*=============================================================================
* Creation date : Author :
*=============================================================================
* Modification date : 01/06/99 Author : Pascal Lalancette
* Modifications : Changed to support get_association_object()
*=============================================================================
*/
void stop_all_son_objet(long indice,long type)
{
pASSOCIATION_DESCRIPTION pAsso;
while ((pAsso=get_association_object(indice,type,NULL))!=NULL)
{
if (pAsso->evt.pstPtr->bStopable)
SND_fn_vStopSnd(pAsso->voice);
else
invalidate_ptrvalid_snd(pAsso->voice);
erase_association(pAsso);
}
}
/*
*=============================================================================
* stop_un_son_objet
*
* Description : Stop any instance of a specific event associated with a
* specific object (except is stopbale flag is FALSE).
* Called by KillObjectSound, or SendRequetsSound for Stop event
*=============================================================================
* Input
* indice : sound object id
* type : sound object type id
* evt : sound event played
*
* Output
* None
*
*=============================================================================
* Creation date : Author :
*=============================================================================
* Modification date : 01/06/99 Author : Pascal Lalancette
* Modifications : Changed to support get_association_object()
*=============================================================================
*/
void stop_un_son_objet(long indice,long type,SND_tduRefEvt evt)
{
pASSOCIATION_DESCRIPTION pAsso;
while ((pAsso=get_association_object(indice,type,evt.pstPtr))!=NULL)
{
if (pAsso->evt.pstPtr->bStopable)
SND_fn_vStopSnd(pAsso->voice);
else
invalidate_ptrvalid_snd(pAsso->voice);
erase_association(pAsso);
}
}
/*-----------------------------------------------------------------
Stop any sounds for a specific sound object type (whatever is Stopbale flag)
-----------------------------------------------------------------*/
void stop_son_type_all(long type)
{
pASSOCIATION_DESCRIPTION pAsso,pAssoNext;
int i=0;
SNDLST2_M_DynamicForEachMovingElementOf(&association.pList,pAsso,pAssoNext,i)
{
if ((pAsso->bValid) && (pAsso->type==type))
{
SND_fn_vStopSnd(pAsso->voice);
erase_association(pAsso);
}
}
}
/*-----------------------------------------------------------------
Stop any sound for any objects whatever is stopable flag
-----------------------------------------------------------------*/
void stop_son_all(void)
{
pASSOCIATION_DESCRIPTION pAsso,pAssoNext;
int i=0;
SNDLST2_M_DynamicForEachMovingElementOf(&association.pList,pAsso,pAssoNext,i)
{
if (pAsso->bValid)
SND_fn_vStopSnd(pAsso->voice);
erase_association(pAsso);
}
}
/*-----------------------------------------------------------------
Stop any sound except for a specific type
-----------------------------------------------------------------*/
void stop_son_type_but_all(long type)
{
pASSOCIATION_DESCRIPTION pAsso,pAssoNext;
int i=0;
SNDLST2_M_DynamicForEachMovingElementOf(&association.pList,pAsso,pAssoNext,i)
{
if ((pAsso->bValid) && (pAsso->type!=type)) /* this is the line with the difference*/
{
SND_fn_vStopSnd(pAsso->voice);
erase_association(pAsso);
}
}
}
void get_RollOff(long indice,long type,SoundParam* pstSoundParam)
{
RollOffParam* pstRollOff;
pstRollOff=&(SND_M_GetExtraParamFromSoundParam(pstSoundParam))->stRollOff;
pstSoundParam->iFlags&=~C_SOUNDPARAM_ROLLOFF;
/*raj du RollOff */
if (g_d_pstTypeObjectSoundInfos[type].pfnRollOff)
{/*si fonction de callback */
if ((*g_d_pstTypeObjectSoundInfos[type].pfnRollOff)(indice,pstRollOff))
{/*si focntion retourne TRUE*/
pstSoundParam->iFlags|=C_SOUNDPARAM_ROLLOFF;
}
}
}
void set_SwitchParam(long indice,long type,SoundParam* pstSoundParam)
{
SwitchParam* pstSwitch;
pstSwitch=&(SND_M_GetExtraParamFromSoundParam(pstSoundParam))->stSwitch;
pstSoundParam->iFlags|=C_SOUNDPARAM_SWITCH;
pstSwitch->lObjectType=type;
pstSwitch->lObjectId=indice;
}
/*-----------------------------------------------------
Check if microphone function are OK
-------------------------------------------------------*/
void check_micro_fct(void)
{
snd_assert(g_st_pfnRetMicroSound.X!=NULL);
snd_assert(g_st_pfnRetMicroSound.Y!=NULL);
snd_assert(g_st_pfnRetMicroSound.Z!=NULL);
snd_assert(g_st_pfnRetMicroSound.VX!=NULL);
snd_assert(g_st_pfnRetMicroSound.VY!=NULL);
snd_assert(g_st_pfnRetMicroSound.VZ!=NULL);
snd_assert(g_st_pfnRetMicroSound.DTX!=NULL);
snd_assert(g_st_pfnRetMicroSound.DTY!=NULL);
snd_assert(g_st_pfnRetMicroSound.DTZ!=NULL);
snd_assert(g_st_pfnRetMicroSound.DNX!=NULL);
snd_assert(g_st_pfnRetMicroSound.DNY!=NULL);
snd_assert(g_st_pfnRetMicroSound.DNZ!=NULL);
snd_assert(g_st_pfnRetMicroSound.Filtre!=NULL);
}
/*
*=============================================================================
* fn_bIsChannelActive,
*
* Description : Call the channel callback to see if its still active
*=============================================================================
*
*=============================================================================
* Creation date : 02/06/99 Author : Pascal Lalancette
*=============================================================================
* Modification date : Author :
* Modifications :
*=============================================================================
*/
SndBool fn_bIsChannelActive(long channel, long indice, long type)
{
return (g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.Active)(channel, indice);
}
/*
*=============================================================================
* fn_vComputeRelToAbsCoord,
*
* Description : Convert a relative vector to an absolute world coordiante vector
*
*=============================================================================
*
*=============================================================================
* Creation date : 02/06/99 Author : Pascal Lalancette
*=============================================================================
* Modification date : Author :
* Modifications :
*=============================================================================
*/
SndVector fn_vComputeRelToAbsCoord(SndVector abs, SndVector rel, SndVector i, SndVector j, SndVector k )
{
SndVector ret;
//Do rotation to translate in world coordinate
ret.x = SND_fn_rMulRealRealSnd(rel.x , i.x) + SND_fn_rMulRealRealSnd(rel.y , j. x) + SND_fn_rMulRealRealSnd(rel.z , k.x);
ret.y = SND_fn_rMulRealRealSnd(rel.x , i.y) + SND_fn_rMulRealRealSnd(rel.y , j. y) + SND_fn_rMulRealRealSnd(rel.z , k.y);
ret.z = SND_fn_rMulRealRealSnd(rel.x , i.z) + SND_fn_rMulRealRealSnd(rel.y , j. z) + SND_fn_rMulRealRealSnd(rel.z , k.z);
ret.x += abs.x;
ret.y += abs.y;
ret.z += abs.z;
return ret;
}
/*
*=============================================================================
* fill_pre_filled_param
*
* Description : Get geometrical parameters for a specific object. Called only
* once for each channel. pstPreFilledParam will be used many
* time for each event associated with this channel.
*
*=============================================================================
* Input
* channel : sound channel id
* indice : sound object id
* type : sound object type id
*
* Output
* pstPreFilledParam : Will contain the geometrical parameters
(X,Y,Z,VX,VY,VZ,REVERB)
*
*=============================================================================
* Creation date : Author :
*=============================================================================
* Modification date : 01/06/99 Author : Pascal Lalancette
* Modifications : Changed to support get_association_object()
*=============================================================================
*/
void fill_pre_filled_param(long channel, long indice,long type,SoundParam* pstPreFilledParam)
{
int i;
pMICRO_DESCRIPTION pMicro;
SndVector I,J,K;
SndVector ChannelPos, ObjectPos, ChannelVit, ObjectVit;
SndVector AbsPos, AbsVit;
pstPreFilledParam->iFlags=0;
/*geometrical parameters*/
if (channel == SND_C_CHANNEL_FANTOME)
{
if (indice!=SND_C_OBJET_FANTOME)
{
pstPreFilledParam->Pos.x=(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.X)(indice);
pstPreFilledParam->Pos.y=(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.Y)(indice);
pstPreFilledParam->Pos.z=(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.Z)(indice);
pstPreFilledParam->Vit.x=(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.VX)(indice);
pstPreFilledParam->Vit.y=(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.VY)(indice);
pstPreFilledParam->Vit.z=(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.VZ)(indice);
pstPreFilledParam->ucReverb=(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.REVERB)(indice);
pstPreFilledParam->ucPan=C_SOUNDPAN_MEDIAN;
pstPreFilledParam->ucSpace=C_SOUNDSPACE_FRONT;
if (!g_bDopplerActive)
pstPreFilledParam->iFlags|=C_SOUNDPARAM_NO_DOPPLER;
}
else
{
//FANTOME object no dynamic location
pstPreFilledParam->ucPan = C_SOUNDPAN_MEDIAN;
pstPreFilledParam->ucReverb = NO_REVERB;
pstPreFilledParam->ucSpace = C_SOUNDSPACE_FRONT;
pstPreFilledParam->iFlags |= (C_SOUNDPARAM_NO_POSITION | C_SOUNDPARAM_NO_DOPPLER);
}
}
else
{
if( g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.bAbsCoord )
{
//We are in absolute coordinate. Only use channel callback for position
pstPreFilledParam->Pos.x=(g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.X)(channel, indice);
pstPreFilledParam->Pos.y=(g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.Y)(channel, indice);
pstPreFilledParam->Pos.z=(g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.Z)(channel, indice);
pstPreFilledParam->Vit.x=(g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.VX)(channel, indice);
pstPreFilledParam->Vit.y=(g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.VY)(channel, indice);
pstPreFilledParam->Vit.z=(g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.VZ)(channel, indice);
pstPreFilledParam->ucReverb=(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.REVERB)(indice);
pstPreFilledParam->ucPan=C_SOUNDPAN_MEDIAN;
pstPreFilledParam->ucSpace=C_SOUNDSPACE_FRONT;
}
else
{
//We are in relative coordinate. We have to use the direction of
//the world to compute the position of the channel.
(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.VectorI)(indice, &I);
(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.VectorJ)(indice, &J);
(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.VectorK)(indice, &K);
ChannelPos.x = (g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.X)(channel, indice);
ChannelPos.y = (g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.Y)(channel, indice);
ChannelPos.z = (g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.Z)(channel, indice);
ObjectPos.x = (g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.X)(indice);
ObjectPos.y = (g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.Y)(indice);
ObjectPos.z = (g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.Z)(indice);
AbsPos = fn_vComputeRelToAbsCoord(ObjectPos, ChannelPos, I, J, K);
ChannelVit.x = (g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.VX)(channel, indice);
ChannelVit.y = (g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.VY)(channel, indice);
ChannelVit.z = (g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.VZ)(channel, indice);
ObjectVit.x = (g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.VX)(channel, indice);
ObjectVit.y = (g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.VY)(channel, indice);
ObjectVit.z = (g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.VZ)(channel, indice);
AbsVit = fn_vComputeRelToAbsCoord(ObjectVit, ChannelVit, I, J, K);
//Fill the param structure
pstPreFilledParam->Pos.x = AbsPos.x;
pstPreFilledParam->Pos.y = AbsPos.y;
pstPreFilledParam->Pos.z = AbsPos.z;
pstPreFilledParam->Vit.x = AbsVit.x;
pstPreFilledParam->Vit.y = AbsVit.y;
pstPreFilledParam->Vit.z = AbsVit.z;
pstPreFilledParam->ucReverb=(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.REVERB)(indice);
pstPreFilledParam->ucPan=C_SOUNDPAN_MEDIAN;
pstPreFilledParam->ucSpace=C_SOUNDSPACE_FRONT;
}
}
/*---link micro*/
SNDLST2_M_DynamicForEachElementOf(&micros_sound.pList,pMicro,i)
{
snd_assert(i!=pstPreFilledParam->iNbLinks);
if (indice!=SND_C_OBJET_FANTOME)
pstPreFilledParam->astMicro[i].bLinked=(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.MicroLink)(indice,(long)pMicro);
else
pstPreFilledParam->astMicro[i].bLinked=TRUE;
pstPreFilledParam->astMicro[i].lId=pMicro->sndId;
}
/*RollOff parameter*/
get_RollOff(indice,type,pstPreFilledParam);
/*Switch informations (used by PlaySnd)*/
set_SwitchParam(indice,type,pstPreFilledParam);
#ifdef SUPERVISATER
dbgSND_fn_vSetPosObject(indice,pstPreFilledParam);
#endif
}
/*--------------------------------------------------------------
Get dynamic parameters for a event/object
Parameters: indice=sound object id
type=sound object type id
evt=sound event
param(OUT)=SoundParam to compute (struct will be fiil by this function)
deTune=random detuning paraeter
pstPreFilledParam(IN)=store previous call to location callback
---------------------------------------------------------------*/
void get_param_objet2(long indice,long type,SND_tduRefEvt evt,SoundParam* param,SndReal deTune,SoundParam* pstPreFilledParam)
{
SndReal extra_par;
long extra_res;
SndReal rCoefA,rCoefB;
long lVolumeType,lVolumeObject;
/*copy of pre-filled geometrical soundparam (cf fill_pre_filled_param)*/
SND_fn_vCopySoundParam(param,pstPreFilledParam);
/*volume line*/
if (g_d_pstTypeObjectSoundInfos[type].pstVolumeLine!=NULL)
{
param->ucVol=(unsigned char)g_d_pstTypeObjectSoundInfos[type].pstVolumeLine->lVol;
param->iFlags|=C_SOUNDPARAM_COEF_VOL;
}
else
param->ucVol=C_SOUNDVOL_MAXI;
/*change-volume event*/
lVolumeType=fn_lGetVolumeForType(type);
lVolumeObject=fn_lGetVolumeForObject(indice,type);
if ((lVolumeType!=C_SOUNDVOL_MAXI) || (lVolumeObject!=C_SOUNDVOL_MAXI))
{
param->ucVol=(unsigned char)((param->ucVol*lVolumeType*lVolumeObject)>>14);
param->iFlags|=C_SOUNDPARAM_COEF_VOL;
}
/*one Detune for each Sound (not only for each object)*/
param->Freq=deTune;
/*---Extra Pitch*/
if ((evt.pstPtr->eType==EVT_SON_PITCH)
|| ((evt.pstPtr->eType==EVT_SON_EXTRA) && (evt.pstPtr->uParams.stExtraAll.rtCoefPitch)))
{
if (evt.pstPtr->eType==EVT_SON_PITCH)
{
rCoefA=evt.pstPtr->uParams.stExtraParam.CoefA;
rCoefB=evt.pstPtr->uParams.stExtraParam.CoefB;
}
else
SND_fn_vSndRealTwinToSndReal(evt.pstPtr->uParams.stExtraAll.rtCoefPitch,&rCoefA,&rCoefB);
(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.ExtraCoef)(indice,evt,&extra_par,NULL,NULL);
extra_par=SND_fn_rMulRealRealSnd(extra_par,rCoefA)+rCoefB;
param->Freq=SND_fn_rMulRealRealSnd(extra_par,param->Freq);
snd_assert(param->Freq>0);
}
/*---Extra Volume*/
if ((evt.pstPtr->eType==EVT_SON_VOLUME)
|| ((evt.pstPtr->eType==EVT_SON_EXTRA) && (evt.pstPtr->uParams.stExtraAll.rtCoefVol)))
{
if (evt.pstPtr->eType==EVT_SON_VOLUME)
{
rCoefA=evt.pstPtr->uParams.stExtraParam.CoefA;
rCoefB=evt.pstPtr->uParams.stExtraParam.CoefB;
}
else
SND_fn_vSndRealTwinToSndReal(evt.pstPtr->uParams.stExtraAll.rtCoefVol,&rCoefA,&rCoefB);
(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.ExtraCoef)(indice,evt,NULL,NULL,&extra_par);
extra_res=M_RealToIntSnd(SND_fn_rMulRealRealSnd(extra_par,rCoefA)+rCoefB);
if (extra_res<0)
param->ucVol=0;
else
{
if (extra_res<=127)
{
if (param->iFlags & C_SOUNDPARAM_COEF_VOL)
param->ucVol=(unsigned char)((extra_res*param->ucVol)>>7);
else
param->ucVol=(unsigned char)extra_res;
}
else
{
if (!(param->iFlags & C_SOUNDPARAM_COEF_VOL))
param->ucVol=C_SOUNDVOL_MAXI;
}
}
param->iFlags|=C_SOUNDPARAM_COEF_VOL;
}
/*---Extra Pan*/
if ((evt.pstPtr->eType==EVT_SON_PAN)
|| ((evt.pstPtr->eType==EVT_SON_EXTRA) && (evt.pstPtr->uParams.stExtraAll.rtCoefPan)))
{
if (evt.pstPtr->eType==EVT_SON_PAN)
{
rCoefA=evt.pstPtr->uParams.stExtraParam.CoefA;
rCoefB=evt.pstPtr->uParams.stExtraParam.CoefB;
}
else
SND_fn_vSndRealTwinToSndReal(evt.pstPtr->uParams.stExtraAll.rtCoefPan,&rCoefA,&rCoefB);
(g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound.ExtraCoef)(indice,evt,NULL,&extra_par,NULL);
extra_res=M_RealToIntSnd(SND_fn_rMulRealRealSnd(extra_par,rCoefA)+rCoefB);
if (extra_res<0)
param->ucPan=0;
else
{
if (extra_res>127) param->ucPan=127;
else param->ucPan=(unsigned char)extra_res;
}
param->iFlags|=C_SOUNDPARAM_NO_POSITION;
}
}
/*
*=============================================================================
* get_param_objet
*
* Description : Get dynamic parameters for a event/channel.
*
*=============================================================================
* Input
* channel : sound channel id
* indice : sound object id
* type : sound object type id
* evt : event associated with the object
* deTune : deTune range
*
* Output
* param : Will contain the dynaimc parameters
*
*=============================================================================
* Creation date : Author :
*=============================================================================
* Modification date : 01/06/99 Author : Pascal Lalancette
* Modifications : Changed to support channel
*=============================================================================
*/
void get_param_objet(long channel, long indice,long type,SND_tduRefEvt evt,SoundParam* param,SndReal deTune)
{
SoundParam *pstPreFilledParam;
#ifdef NB_MICRO_MAX
SoundParam stSoundParam;
#endif
#ifdef NB_MICRO_MAX
pstPreFilledParam=&stSoundParam;
stSoundParam.iNbLinks=g_iNbActiveMicros;
#else
pstPreFilledParam=SND_fn_pCreateSoundParam(g_iNbActiveMicros);
#endif
//Fill Sound Param with channel specific info
fill_pre_filled_param(channel, indice,type,pstPreFilledParam);
//Fill Sound Param with object specific info
get_param_objet2(indice,type,evt,param,deTune,pstPreFilledParam);
#ifndef NB_MICRO_MAX
SND_fn_vDestroySoundParam(pstPreFilledParam);
#endif
}
/*----------------------------------------------------------------------*/
/* Detuning parameter*/
/*----------------------------------------------------------------------*/
SndReal fn_rGetDeTune(SND_tduRefEvt evt)
{
SndReal delta;
switch (evt.pstPtr->eType)
{
case EVT_SON_PLAY:
delta=evt.pstPtr->uParams.stPlay.stDeTune.rDelta;
break;
case EVT_SON_PITCH:
case EVT_SON_VOLUME:
case EVT_SON_PAN:
delta=evt.pstPtr->uParams.stExtraParam.stDeTune.rDelta;
break;
default:
delta=NO_DETUNING;
break;
}
if (delta!=NO_DETUNING)
return (C_SNDREAL_1+SND_fn_rGetRandomSnd(delta*2)-delta);
else
return C_SNDREAL_1;
}
/*-------------------------------------------------------*/
/* default ret function*/
/*-------------------------------------------------------*/
/*
*=============================================================================
* fn_rRetObjectSoundSndRealDefault
* fn_ucRetObjectSoundREVERBDefault
* fn_vRetObjectSoundExtraCoefDefault
* fn_bRetObjectSoundMicroLinkDefault
* fn_vRetObjectSoundVectorIDefault
* fn_vRetObjectSoundVectorJDefault
* fn_vRetObjectSoundVectorKDefault
*
* Description : Default object's callback function
*
*=============================================================================
* Input
*
* Output
*
*=============================================================================
* Creation date : Author :
*=============================================================================
* Modification date : 01/06/99 Author : Pascal Lalancette
* Modifications : Added fn_vRetObjectSoundVectorIDefault,
* fn_vRetObjectSoundVectorJDefault
* and fn_vRetObjectSoundVectorKDefault functions.
*=============================================================================
*/
SndReal fn_rRetObjectSoundSndRealDefault(long indice)
{
return C_SNDREAL_0;
}
unsigned char fn_ucRetObjectSoundREVERBDefault(long indice)
{
return NO_REVERB;
}
void fn_vRetObjectSoundExtraCoefDefault(long indice,SND_tduRefEvt evt,SndReal* pitch,SndReal* pan,SndReal* vol)
{
if (pitch!=NULL)
*pitch=C_SNDREAL_1;
if (pan!=NULL)
*pan=C_SNDREAL_1;
if (vol!=NULL)
*vol=C_SNDREAL_1;
return;
}
long fn_lRetObjectSoundSwitchDefault(long indice,long type_switch)
{
return 0;
}
SndBool fn_bRetObjectSoundMicroLinkDefault(long indice,long micro)
{
return TRUE;
}
void fn_vRetObjectSoundVectorIDefault(long indice, SndVector* vect)
{
if (vect!=NULL)
{
vect->x = C_SNDREAL_1;
vect->y = C_SNDREAL_0;
vect->z = C_SNDREAL_0;
}
return;
}
void fn_vRetObjectSoundVectorJDefault(long indice, SndVector* vect)
{
if (vect!=NULL)
{
vect->x = C_SNDREAL_0;
vect->y = C_SNDREAL_1;
vect->z = C_SNDREAL_0;
}
return;
}
void fn_vRetObjectSoundVectorKDefault(long indice, SndVector* vect)
{
if (vect!=NULL)
{
vect->x = C_SNDREAL_0;
vect->y = C_SNDREAL_0;
vect->z = C_SNDREAL_1;
}
return;
}
/*-------------------------------------------------------*/
/* default RetMicroSound functions*/
/*-------------------------------------------------------*/
SndReal fn_rRetMicroSoundSndReal0Default(long indice)
{
return 0;
}
SndReal fn_rRetMicroSoundSndReal1Default(long indice)
{
return 0x10000;
}
long fn_lRetMicroSoundFILTREDefault(long indice)
{
return 0;
}
/*
*=============================================================================
* fn_rRetMicroSoundSndReal0Default,
* fn_rRetMicroSoundSndReal1Default,
* fn_bRetChannelSoundAbsCoordDefault
*
* Description : Default RetChannelSound functions
*=============================================================================
*
*=============================================================================
* Creation date : 31/05/99 Author : Pascal Lalancette
*=============================================================================
* Modification date : Author :
* Modifications :
*=============================================================================
*/
SndReal fn_rRetChannelSoundSndReal0Default(long indice, long channel)
{
return 0;
}
SndReal fn_rRetChannelSoundSndReal1Default(long indice, long channel)
{
return 0x10000;
}
SndBool fn_bRetChannelSoundActiveDefault(long indice, long channel)
{
return TRUE;
}
SndBool fn_bRetChannelSoundAbsCoordDefault(long indice, long channel)
{
return TRUE;
}
/*-------------------------------------------------------
Init of g_st_pfnRetMicroSound
------------------------------------------------------*/
void init_micro_fct(void)
{
SNDLST2_M_DynamicInitAnchor(&micros_sound.pList);
g_iNbActiveMicros=0;
g_st_pfnRetMicroSound.X=fn_rRetMicroSoundSndReal0Default;
g_st_pfnRetMicroSound.Y=fn_rRetMicroSoundSndReal0Default;
g_st_pfnRetMicroSound.Z=fn_rRetMicroSoundSndReal0Default;
g_st_pfnRetMicroSound.VX=fn_rRetMicroSoundSndReal0Default;
g_st_pfnRetMicroSound.VY=fn_rRetMicroSoundSndReal0Default;
g_st_pfnRetMicroSound.VZ=fn_rRetMicroSoundSndReal0Default;
g_st_pfnRetMicroSound.DTX=fn_rRetMicroSoundSndReal1Default;
g_st_pfnRetMicroSound.DTY=fn_rRetMicroSoundSndReal0Default;
g_st_pfnRetMicroSound.DTZ=fn_rRetMicroSoundSndReal0Default;
g_st_pfnRetMicroSound.DNX=fn_rRetMicroSoundSndReal0Default;
g_st_pfnRetMicroSound.DNY=fn_rRetMicroSoundSndReal0Default;
g_st_pfnRetMicroSound.DNZ=fn_rRetMicroSoundSndReal1Default;
g_st_pfnRetMicroSound.Filtre=fn_lRetMicroSoundFILTREDefault;
}
/*-------------------------------------------------------
Init la table de type d'objet pour RetObjectSound..
------------------------------------------------------*/
void init_object_type(void)
{
nb_object_type=0;
SND_fn_lAddObjectTypeSound(&g_astTypeObjectSoundInfosDefault);
}
/*-------------------------------------------------------
desInit la table de type d'objet
------------------------------------------------------*/
void desinit_object_type(void)
{
SND_fn_vFreeSndEx(E_ucSndBlockMain,g_d_pstTypeObjectSoundInfos);
}
/*-------------------------------------------------------
desInit la table de lignes de volumes
------------------------------------------------------*/
void desinit_volume_lines(void)
{
ptdstVolumeLine pLine,pLineNext;
int i;
SNDLST2_M_DynamicForEachMovingElementOf(&(g_VolumeLines.pList),pLine,pLineNext,i)
{
SND_fn_vFreeSndEx(E_ucSndBlockMain,pLine);
#ifdef SUPERVISATER
dbgSND_fn_vKillVolumeLine((long)pLine);
#endif
}
nb_volume_lines=0;
}
#ifdef DEBUG_SON
/*-----------------------------------------------------
genere une liste des association
-------------------------------------------------------*/
void liste_of_association(char *texte,long size)
{
char temp[256];
int i;
pASSOCIATION_DESCRIPTION pAsso;
texte[0]='\0';
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{
sprintf(temp,"V:%8x-O:%8x-Evt:%8x(Id %d)%s\xd\xa",pAsso->voice,pAsso->indice,pAsso->evt,pAsso->evt.pstPtr->Id
,((pAsso->res_hi.pstPtr->eType==TYPE_SWITCH)?" SWITCH":""));
strncat(texte,temp,size-strlen(texte)-1);
/*
sprintf(temp,"(V:%8x-O:%8x-Evt:%8x(Id %d)",pAsso->voice,pAsso->indice,pAsso->evt,pAsso->evt.pstPtr->Id);
switch (pAsso->res_hi.pstPtr->eType)
{
case TYPE_SWITCH:
strncat(temp," SWITCH)\n",size-strlen(temp)-1);break;
default:
strncat(temp," )\n",size-strlen(temp)-1);break;
}
*/
}
if (texte[0]=='\0')
sprintf(texte,"Aucune association");
}
#endif /*Debug*/
void init_association()
{
SNDLST2_M_DynamicInitAnchor(&association.pList);
}
/*-----------------------------------------------------
Check if channel function are OK
-------------------------------------------------------*/
void check_channel_fct(long type)
{
snd_assert(g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.X!=NULL);
snd_assert(g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.Y!=NULL);
snd_assert(g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.Z!=NULL);
snd_assert(g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.VX!=NULL);
snd_assert(g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.VY!=NULL);
snd_assert(g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.VZ!=NULL);
snd_assert(g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound.Active!=NULL);
}
#endif /*NO_ACP_SOUND*/
/****************************************************************************************/
/****************************************************************************************/
/* */
/* Fonctions publiques */
/* */
/* */
/****************************************************************************************/
/****************************************************************************************/
/*
*=============================================================================
* SND_fn_iInitSound
*
* Description : Initialize SOUND3D librairy
*
*=============================================================================
*
* Input
* pInitStruct : structure containing init information
*
*
* Output
* C_INITSOUND_OK if success,
* C_INITSOUND_FAILED if failed
* C_INITRUNNING if processing.
*
*=============================================================================
* Creation date : Author :
*=============================================================================
* Modification date : Author :
* Modifications :
*=============================================================================
*/
int SND_fn_iInitSound(SND_tdstInitStruct *pInitStruct)
{
#ifndef NO_ACP_SOUND
int iRet;
/*init acp*/
SND_fn_vInitThreadSnd();
SND_fn_vInitErrorSnd(pInitStruct);
SND_fn_vInitMallocSnd();
SND_fn_vInitOptions(pInitStruct);
#ifndef DREAMCAST
/*init de variables internes*/
init_object_type();
#endif /*DREAMCAST*/
init_micro_fct();
init_association();
/*init de la couche hard*/
iRet=SND_fn_iInitSnd(pInitStruct);
/* Version specific inits:*/
#ifndef NO_ACP_LDBIN
SND_fn_vInitBankSnd(NULL);
#endif
SND_fn_vQuitCriticalSectionThreadSnd();
#ifdef SUPERVISATER
SND_fn_vLaunchSupervisater(pInitStruct);
#endif
g_bInitDoneSound=TRUE;
return iRet;
#else
return C_INIT_FAILED;
#endif /*NO_ACP_SOUND*/
}
/*------------------------------------------------------------*/
/* TestInitSound:test de la fin de l'initialisation de SOUND3D*/
/* Entree:neant*/
/* Sortie:C_INITSOUND_OK si reussite,C_INITSOUND_FAILED sinon*/
/* C_INIT_RUNNING si en cours*/
/*------------------------------------------------------------*/
int SND_fn_iTestInitSound(void)
{
#ifndef NO_ACP_SOUND
/*version non asynchrone*/
return C_INITSOUND_OK;
#else
return C_INIT_FAILED;
#endif /*NO_ACP_SOUND*/
}
/*------------------------------------------------------------*/
/* InitSound:desinitialisation dela librairie SOUND3D*/
/* Entree:neant*/
/* Sortie:neant*/
/*------------------------------------------------------------*/
void SND_fn_vDesInitSound(void)
{
#ifndef NO_ACP_SOUND
#ifdef SUPERVISATER
SND_fn_vKillSupervisater();
#endif
if (g_bInitDoneSound)
{
g_bInitDoneSound=FALSE;
/*desinit de haut-niveau*/
SND_fn_vDestroyAllMicroSound();
SND_fn_vEnterCriticalSectionThreadSnd();
stop_son_all();
/*deinit de variables internes*/
desinit_object_type();
desinit_volume_lines();
/* Version specific desinits:*/
#ifdef SND_SCRIPT_VERSION
SND_fn_vDesInitScriptSnd();
#endif /*SND_SCRIPT_VERSION*/
#ifdef SND_HYBRID_VERSION
SND_fn_bDesInitDataLoadSnd();
#endif /*SND_HYBRID_VERSION*/
#ifndef NO_ACP_LDBIN
SND_fn_vDesInitBankSnd();
#endif /*NO_ACP_LDBIN*/
/*desinit de la couche hard*/
SND_fn_vDesInitSnd();
/*desinit acp*/
SND_fn_vDesInitThreadSnd();
SND_fn_vDesInitMallocSnd();
SND_fn_vDesInitErrorSnd();
SND_fn_vDesInitOptions();
}
#endif /*NO_ACP_SOUND*/
}
/*------------------------------------------------------------*/
/* SetDopplerFactorSound:change Doppler effect range*/
/* Entree:new factor for Doppler effect (1.0=normal effect=physicallly realistic*/
/* 0.0=no doppler effect*/
/* Sortie:neant*/
/*------------------------------------------------------------*/
void SND_fn_vSetDopplerFactorSound(SndReal factor)
{
#ifndef NO_ACP_SOUND
if (factor==SND_C_NO_DOPPLER)
{
g_bDopplerActive=FALSE;
}
else
{
snd_assert(factor>0);
g_bDopplerActive=TRUE;
}
SND_fn_vSetDopplerFactorSnd(factor);
#endif
}
/*------------------------------------------------------------*/
/* SND_fn_vSetDefaultRollOffSound:change default RollOff value*/
/* Parameter:new RollOff values*/
/* Sortie:neant*/
/*------------------------------------------------------------*/
void SND_fn_vSetDefaultRollOffSound(RollOffParam *rolloff)
{
#ifndef NO_ACP_SOUND
SND_fn_vSetDefaultRollOffSnd(rolloff);
#endif
}
#ifndef NO_ACP_SOUND
/*
*=============================================================================
* fn_vRajAllVolumeForLine
*
* Description : Update all volumes of a volume line (non-dyanimc included).
* Very similar to SND_SynchroSound but add non-dynamic
* volume line.
*
* Note : This function does'nt process Switch
*
*=============================================================================
* Input: pVolumeLine : Volume lime
*
* Output : None
*
*=============================================================================
* Creation date : Author :
*=============================================================================
* Modification date : 01/06/99 Author : Pascal Lalancette
* Modifications : Add Sound channel support
*=============================================================================
*/
void fn_vRajAllVolumeForLine(ptdstVolumeLine pVolumeLine)
{
int i;
SoundParam *pstSoundParam;
pASSOCIATION_DESCRIPTION pAsso,pAssoNext;
#ifdef NB_MICRO_MAX
SoundParam stSoundParam;
#endif
SND_fn_vEnterCriticalSectionThreadSnd();
#ifdef NB_MICRO_MAX
pstSoundParam=&stSoundParam;
stSoundParam.iNbLinks=g_iNbActiveMicros;
#else
pstSoundParam=SND_fn_pCreateSoundParam(g_iNbActiveMicros);
#endif
/*raj des objets*/
SNDLST2_M_DynamicForEachMovingElementOf(&association.pList,pAsso,pAssoNext,i)
{/*pour chaque association*/
if (pAsso->bValid)
{/*pour chaque association valide*/
if (g_d_pstTypeObjectSoundInfos[pAsso->type].pstVolumeLine==pVolumeLine)
{/*asso liee <20> la ligne -> raj*/
get_param_objet(pAsso->channel, pAsso->indice,pAsso->type,pAsso->evt,pstSoundParam,pAsso->rDeTune);
/*ressources Switch ou pas, meme traitement*/
/*Switch, TestIsPlaying et autres seront appeles par SynchtoSound qui est l<> pour <20>a*/
if (!SND_fn_bSetParamSnd(pAsso->voice,pstSoundParam))
{/*son fini*/
erase_association(pAsso);
}
}
/*on ne touche pas aux autres sons (<28>a sert <20> rien)*/
}
else
{/*voie desactivee*/
erase_association(pAsso);
}
}
#ifndef NB_MICRO_MAX
SND_fn_vDestroySoundParam(pstSoundParam);
#endif
SND_fn_vQuitCriticalSectionThreadSnd();
}
#endif /*no_acp_sound*/
/*
*=============================================================================
* SND_fn_vSynchroSound
*
* Description : Update all parameters of all channels and objects
*
*
*=============================================================================
* Input: None
*
* Output : None
*
*=============================================================================
* Creation date : Author :
*=============================================================================
* Modification date : 01/06/99 Author : Pascal Lalancette
* Modifications : Add Sound Channel support
*=============================================================================
*/
void SND_fn_vSynchroSound(void)
{
#ifndef NO_ACP_SOUND
int i;
MicroParam micpar;
SoundParam *pstSoundParam, *pstPreFilledParam = NULL;
pASSOCIATION_DESCRIPTION pAsso,pAssoNext;
pMICRO_DESCRIPTION pMicro;
long prev_channel = -1, prev_indice = -1, prev_type = -1;
#ifdef NB_MICRO_MAX
SoundParam stSoundParam,stPreFilledParam;
#endif
SND_fn_vEnterCriticalSectionThreadSnd();
//
//Update micros
//
SNDLST2_M_DynamicForEachElementOf(&micros_sound.pList,pMicro,i)
{
GetMicroParam((long)pMicro,&micpar);
SND_fn_vSetMicroParamSnd(pMicro->sndId,&micpar);
#ifdef SUPERVISATER
dbgSND_fn_vSetPosMicro((long)pMicro,&micpar);
#endif
}
snd_assert(g_iNbActiveMicros==i);
#ifdef NB_MICRO_MAX
pstSoundParam=&stSoundParam;
stSoundParam.iNbLinks=g_iNbActiveMicros;
#else
pstSoundParam=SND_fn_pCreateSoundParam(g_iNbActiveMicros);
#endif
//
//Update objects
//
SNDLST2_M_DynamicForEachMovingElementOf(&association.pList,pAsso,pAssoNext,i)
{/*pour chaque asso*/
if (pAsso->bValid)
{/*pour chaque asso valide*/
if ( (pAsso->evt.pstPtr->bDynamic) && pAsso->bDynamic)
//Is the channel still active?
pAsso->bDynamic = fn_bIsChannelActive(pAsso->channel, pAsso->indice, pAsso->type);
/*raj des params dynamiques*/
if (pAsso->bDynamic)
{
if (!pstPreFilledParam)
{/*first fill for pstPreFilledParam*/
#ifdef NB_MICRO_MAX
pstPreFilledParam=&stPreFilledParam;
stPreFilledParam.iNbLinks=g_iNbActiveMicros;
#else
pstPreFilledParam=SND_fn_pCreateSoundParam(g_iNbActiveMicros);
#endif
prev_channel = pAsso->channel;
prev_indice = pAsso->indice;
prev_type = pAsso->type;
fill_pre_filled_param(prev_channel, prev_indice, prev_type, pstPreFilledParam);
}
else
{
if (pAsso->channel != prev_channel || pAsso->indice != prev_indice || pAsso->type != prev_type)
{/*new object ->refill pstPreFilledParam*/
prev_channel = pAsso->channel;
prev_indice=pAsso->indice;
prev_type=pAsso->type;
fill_pre_filled_param(prev_channel, prev_indice, prev_type, pstPreFilledParam);
}
/*else */
/*object's parameters have yet been computed*/
}
get_param_objet2(pAsso->indice,pAsso->type,pAsso->evt,pstSoundParam,pAsso->rDeTune,pstPreFilledParam);
if (!SND_fn_bSetParamSnd(pAsso->voice,pstSoundParam))
{/*son fini*/
erase_association(pAsso);
}
}
else/*evt <20> ne pas remettre <20> jour dynamiquement*/
//Event or channel who doesnt need to be updated dynamicaly
if (!SND_fn_bTestIsPlayingSnd(pAsso->voice))
erase_association(pAsso);
}
else
{/*voie desactivee*/
erase_association(pAsso);
}
}
#ifndef NB_MICRO_MAX
if (pstPreFilledParam)
SND_fn_vDestroySoundParam(pstPreFilledParam);
SND_fn_vDestroySoundParam(pstSoundParam);
#endif
SND_fn_vSynchroSnd();
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
/*
*=============================================================================
* SND_fn_lSendRequestSound
*
* Description : Process an event.
*
* Note: This function is still available for compatibility purpose.
* Use SND_fn_lSendRequestCannelSound instead.
*
*=============================================================================
* Input:
* indice : object id
* evt : event to interpret
* prio : priority level of this event
* proc: Callback call when the event has finished
*
*
* Output : Event handle
*
*=============================================================================
* Creation date : Author :
*=============================================================================
* Modification date : 01/06/99 Author : Pascal Lalancette
* Modifications : Add Sound Channel support
*=============================================================================
*/
long SND_fn_lSendRequestSound(long indice,long type,SND_tduRefEvt evt,long prio,SND_td_pfn_vSoundCallback proc)
{
return SND_fn_lSendRequestChannelSound(SND_C_CHANNEL_FANTOME, indice,type, evt,prio,proc);
}
/*
*=============================================================================
* SND_fn_lSendRequestChannelSound
*
* Description : Event processing
*=============================================================================
* Input : indice : Object associated with the event (SND_C_OBJECT_FANTOME or user defined)
* type : Object type (returned by SND_fn_lAddObectTypeSound2)
* channel : Channel associated to the object
* evt : References to the event to be interpreted
* prio : Priority level
* proc : Callback function to be call when the sound is finished
*
* Output : - Id of the event instance
* - SND_C_EVT_FAILED if failure
* - callback function parameter if callback succesfull
* - SND_C_EVT_CALLBACK_FAILED
*
*=============================================================================
* Creation date : 20/05/99 Author : Pascal Lalancette
*=============================================================================
* Modification date : Author :
* Modifications :
*=============================================================================
*/
long SND_fn_lSendRequestChannelSound(long channel, long indice, long type, SND_tduRefEvt evt, long prio, SND_td_pfn_vSoundCallback proc)
{
#ifndef NO_ACP_SOUND
SoundParam *pstSoundParam;
#ifdef NB_MICRO_MAX
SoundParam stSoundParam;
#endif
tduRefRes res_hi;
#ifdef SUPERVISATER
tduRefRes res_low;
#endif
long voice;
SndBool use_callback;
SndBool evt_ok;
long lHandle;
SndReal rDeTune;
pASSOCIATION_DESCRIPTION asso=NULL;
res_hi.pstPtr=NULL;
if (evt.pstPtr==EVT_FANTOME_PTR)
return SND_C_EVT_FAILED;
SND_fn_vEnterCriticalSectionThreadSnd();
#ifdef NB_MICRO_MAX
pstSoundParam=&stSoundParam;
stSoundParam.iNbLinks=g_iNbActiveMicros;
#else
pstSoundParam=SND_fn_pCreateSoundParam(g_iNbActiveMicros);
#endif
lHandle=HandleCallback++;
if ((HandleCallback == SND_C_EVT_CALLBACK_FAILED) || (HandleCallback == SND_C_EVT_FAILED))
HandleCallback=1;
voice=-1;
use_callback = FALSE;
evt_ok = TRUE;
switch (evt.pstPtr->eType)
{
case EVT_SON_PLAY:
case EVT_SON_PITCH:
case EVT_SON_VOLUME:
case EVT_SON_PAN:
case EVT_SON_EXTRA:
if (!(asso = pre_associe_sound()))
{
evt_ok=FALSE;
break;
}
if (evt.pstPtr->eType==EVT_SON_PLAY)
res_hi.pstPtr=evt.pstPtr->uParams.stPlay.uResource.pstPtr;
else if (evt.pstPtr->eType==EVT_SON_EXTRA)
res_hi.pstPtr=evt.pstPtr->uParams.stExtraAll.uResource.pstPtr;
else
res_hi.pstPtr=evt.pstPtr->uParams.stExtraParam.uResource.pstPtr;
if (res_hi.pstPtr!=SND_C_RES_FANTOME_PTR)
{
/*tirage du parametre de DeTuning*/
rDeTune=fn_rGetDeTune(evt);
/*calcul des parametres */
get_param_objet(channel, indice,type,evt,pstSoundParam,rDeTune);
if ((voice = SND_fn_lPlaySnd(res_hi,pstSoundParam,prio,proc,lHandle,&(asso->bValid)))!=C_PLAY_FAILED)
{/*son envoye*/
associe_sound(asso, channel, indice, type, prio, voice, evt, res_hi, rDeTune, lHandle);
if (proc)
use_callback=TRUE;
}
else
{
erase_association(asso);
evt_ok=FALSE;
}
}
else
{
erase_association(asso);
evt_ok=FALSE;
}
break;
case EVT_SON_STOP:
/*traitement d'un evt StopSon (arret d'1 son d'un objet)*/
stop_un_son_objet(indice,type,evt.pstPtr->uParams.stStop.uEvt);
break;
case EVT_SON_STOP_ALL:
/*traitement d'un evenemnt StopSonALL (arret de tous les ons d'un objet)*/
stop_all_son_objet(indice,type);
break;
case EVT_SON_STOP_N_GO:
/*traitement d'un evt. Stop'n'Go (arret d'un son, lancement d'un autre)*/
stop_un_son_objet(indice,type,evt.pstPtr->uParams.stStopNGo.uEvtStop);
if ((lHandle=SND_fn_lSendRequestChannelSound(channel, indice,type,evt.pstPtr->uParams.stStopNGo.uEvtGo,prio,proc))==SND_C_EVT_FAILED)
evt_ok=FALSE;
use_callback=TRUE;
break;
case EVT_SON_EFFET:
/*evt de type SetEffect*/
SND_fn_vSetEffectSnd(evt.pstPtr->uParams.stEffect.iIdEffect);
break;
case EVT_SON_CHANGE_VOLUME:
if (evt.pstPtr->uParams.stChangeVolume.bConcernWithObjectType)
{
fn_vChangeVolumeForType(type,evt.pstPtr->uParams.stChangeVolume.lNewVolume);
SND_fn_vSynchroSound();
}
else
{
fn_vChangeVolumeForObject(indice,type,evt.pstPtr->uParams.stChangeVolume.lNewVolume);
SND_fn_vSynchroSound();
}
break;
default:
SND_M_DisplayError(E_uwSndInvalidTypeOfEvent,"");
evt_ok=FALSE;
break;
}
#ifdef SUPERVISATER
if (res_hi.pstPtr!=NULL)
res_low=SND_fn_tduGetLowestResourceSnd(res_hi,pstSoundParam,FALSE);
else
res_low.pstPtr=NULL;
dbgSND_fn_vAddHistoric(evt,indice,type,(long)asso,res_low.pstPtr);
#endif
#ifndef NB_MICRO_MAX
SND_fn_vDestroySoundParam(pstSoundParam);
#endif
/*---*/
fnSetLastEventForSoundObjectType(type,evt.pstPtr);
SND_fn_vQuitCriticalSectionThreadSnd();
if (!evt_ok)
return SND_C_EVT_FAILED;
if (proc && !use_callback)
return SND_C_EVT_CALLBACK_FAILED;
else
return lHandle;
#else
return SND_C_EVT_FAILED;
#endif /*NO_ACP_SOUND*/
}
/*------------------------------------------------------*/
/* SetEffectSnd: installer un effet sonore*/
/* Entree:id=designation de l'effet*/
/* Sortie:neant*/
/*-------------------------------------------------------*/
void SND_fn_vSetEffectSound(long id_effect)
{
#ifndef NO_ACP_SOUND
SND_fn_vSetEffectSnd(id_effect);
#endif
}
/*------------------------------------------------------------*/
/* GetPos:obtenir la position theorique courante de la ressource*/
/* but principal=lip synchro*/
/* Entree:handle=handle sur le son (code retourne par SendRequest)*/
/* Sortie:position theorique en s (diferent du temps abslou ecoule)*/
/*------------------------------------------------------------*/
SndReal SND_fn_rGetPosSound(long handle)
{
#ifndef NO_ACP_SOUND
pASSOCIATION_DESCRIPTION pAsso;
SndBool bFound=FALSE;
int i;
SndReal ret;
SND_fn_vEnterCriticalSectionThreadSnd();
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{
if (pAsso->lHandle==handle)
{
bFound=TRUE;
break;
}
}
if (bFound)
{
ret=SND_fn_rGetPosSnd(pAsso->voice);
}
else
ret=SND_C_POS_ENDED;
SND_fn_vQuitCriticalSectionThreadSnd();
return ret;
#else
return SND_C_POS_UNKNOWN;
#endif
}
/*--------------------------------------------------------------------------*/
/* GetLength: retourne la duree "theorique" de la ressource */
/* exprime en seconde (constant pour une ressource donnee) */
/* Entree: voie concernee */
/* Sortie: duree en S (SndReal) */
/*--------------------------------------------------------------------------*/
SndReal SND_fn_rGetLengthSound(long handle)
{
#ifndef NO_ACP_SOUND
pASSOCIATION_DESCRIPTION pAsso;
SndBool bFound=FALSE;
int i;
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{
if (pAsso->lHandle==handle)
{
bFound=TRUE;
break;
}
}
if (bFound)
{
return SND_fn_rGetLengthSnd(pAsso->voice);
}
else
#endif
return SND_C_LENGTH_UNKNOWN;
}
/*
*=============================================================================
* SND_fn_vKillChannelSound
*
* Description : destruction of a channel
*=============================================================================
* Input : indice : Object associated
* channel : Channel to kill
*
* Output : None
*
*=============================================================================
* Creation date : 20/05/99 Author : Pascal Lalancette
*=============================================================================
* Modification date : Author :
* Modifications :
*=============================================================================
*/
void SND_fn_vKillChannelSound(long channel, long indice, long type)
{
#ifndef NO_ACP_SOUND
pASSOCIATION_DESCRIPTION pAsso;
SND_fn_vEnterCriticalSectionThreadSnd();
if (channel != SND_C_CHANNEL_FANTOME)
{
//Get Asso
pAsso = get_association_channel(channel, indice, type, NULL);
//Stop the channel Update. The channel position will be freeze
//(the SndParam struct wont be updated anymore)
pAsso->bDynamic = FALSE;
}
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
/*
*=============================================================================
* SetRetChannelSound
*
* Description : Initialize channel callback function
*=============================================================================
* Input : ptrfct Pointer on callback funcion structure
*
* Output : None
*
*=============================================================================
* Creation date : 20/05/99 Author : Pascal Lalancette
*=============================================================================
* Modification date : Author :
* Modifications :
*=============================================================================
*/
void SND_fn_vSetRetChannelTypeSound(long type, tdstAllRetChannelSound *ptrfct)
{
#ifndef NO_ACP_SOUND
SND_fn_vEnterCriticalSectionThreadSnd();
//Copy pointer strutucure
memcpy(&g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound,ptrfct,sizeof(tdstAllRetChannelSound));
check_channel_fct(type);
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
/*------------------------------------------------------------*/
/* KillObjectSound:destruction d'un objet*/
/* Entree:indice)objet detruit*/
/* Sortie:neant*/
/*------------------------------------------------------------*/
void SND_fn_vKillObjectSound2(long indice,long type)
{
#ifndef NO_ACP_SOUND
SND_fn_vEnterCriticalSectionThreadSnd();
stop_all_son_objet(indice,type);
fn_vResetVolumeForObject(indice,type);
//fn_vChangeVolumeForObject(indice,type,C_SOUNDVOL_MAXI);
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
void SND_fn_vKillObjectSound(long indice)
{
#ifndef NO_ACP_SOUND
// long type;
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/*obsolete function: please call SND_fn_vKillObjectSound2*/
snd_assert(FALSE);
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
SND_fn_vEnterCriticalSectionThreadSnd();
/* stop_all_son_objet_old(indice);
for (type=0;type<nb_object_type;type++)
fn_vResetVolumeForObject(indice,type);
//fn_vChangeVolumeForObject(indice,type,C_SOUNDVOL_MAXI);
*/
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
/*------------------------------------------------------------*/
/* KillAllObjectTypeSound:destruction de tous les objets d'un type donne*/
/* Entree:type=type des objets <20> tuer*/
/* Sortie:neant*/
/*------------------------------------------------------------*/
void SND_fn_vKillAllObjectTypeSound(long type)
{
#ifndef NO_ACP_SOUND
SND_fn_vEnterCriticalSectionThreadSnd();
stop_son_type_all(type);
fn_vChangeVolumeForType(type,C_SOUNDVOL_MAXI);
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
/*------------------------------------------------------------*/
/* KillAllObjectSound:destruction de tous les objets*/
/* Entree:neant*/
/* Sortie:neant*/
/*------------------------------------------------------------*/
void SND_fn_vKillAllObjectSound(void)
{
#ifndef NO_ACP_SOUND
long type;
SND_fn_vEnterCriticalSectionThreadSnd();
stop_son_all();
for (type=0;type<nb_object_type;type++)
fn_vChangeVolumeForType(type,C_SOUNDVOL_MAXI);
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
/*------------------------------------------------------------*/
/* KillAllObjectButTypeSound:destruction de tous les objets sauf d'un type donne*/
/* Entree:type=type des objets <20> ne pas tuer*/
/* Sortie:neant*/
/*------------------------------------------------------------*/
void SND_fn_vKillAllObjectButTypeSound(long type)
{
#ifndef NO_ACP_SOUND
SND_fn_vEnterCriticalSectionThreadSnd();
stop_son_type_but_all(type);
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
/*------------------------------------------------------------*/
/* CreateMicro:declaration d'un micro*/
/* Entree:id utilisateur du micro <20> creer*/
/* Sortie:TRUE si OK,FALSE sinon*/
/*------------------------------------------------------------*/
long SND_fn_lCreateMicroSound(void)
{
long lRet=C_CREATEMICRO_FAILED;
#ifndef NO_ACP_SOUND
/*MicroParam par;*/
pMICRO_DESCRIPTION pMicro;
SND_fn_vEnterCriticalSectionThreadSnd();
#ifdef NB_MICRO_MAX
if (g_iNbActiveMicros==NB_MICRO_MAX)
{
SND_M_DisplayError(E_uwSndSystemError,"Too many microphone");
SND_fn_vQuitCriticalSectionThreadSnd();
return C_CREATEMICRO_FAILED;
}
#endif
g_iNbActiveMicros++;
pMicro=SND_fn_pvMallocSndEx(E_ucSndBlockMain,sizeof(MICRO_DESCRIPTION));
SNDLST2_M_DynamicInitElement(pMicro);
SNDLST2_M_DynamicAddTail(&micros_sound.pList,pMicro);
pMicro->sndId=SND_fn_lCreateMicroSnd(NULL);
lRet=(long)pMicro;
#ifdef SUPERVISATER
dbgSND_fn_vAddMicro(lRet);
#endif
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
return lRet;
}
/*------------------------------------------------------------*/
/* DestroyMicro:destruction d'un micro*/
/* Entree:id utilisateur du micro <20> detruire*/
/* Sortie:neant*/
/*------------------------------------------------------------*/
void SND_fn_vDestroyMicroSound(long Id)
{
#ifndef NO_ACP_SOUND
SND_fn_vEnterCriticalSectionThreadSnd();
g_iNbActiveMicros--;
SNDLST2_M_DynamicIsolate((pMICRO_DESCRIPTION)Id);
SND_fn_vDestroyMicroSnd(((pMICRO_DESCRIPTION)Id)->sndId);
SND_fn_vFreeSndEx(E_ucSndBlockMain,(pMICRO_DESCRIPTION)Id);
#ifdef SUPERVISATER
dbgSND_fn_vKillMicro(Id);
#endif
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
/*------------------------------------------------------------*/
/* DestroyAllMicro:destruction de tous les micros*/
/* Entree:neant*/
/* Sortie:neant*/
/*------------------------------------------------------------*/
void SND_fn_vDestroyAllMicroSound(void)
{
#ifndef NO_ACP_SOUND
pMICRO_DESCRIPTION pMicro,pMicroNext;
int i;
SND_fn_vEnterCriticalSectionThreadSnd();
g_iNbActiveMicros=0;
SNDLST2_M_DynamicForEachMovingElementOf(&micros_sound.pList,pMicro,pMicroNext,i)
{
#ifdef SUPERVISATER
dbgSND_fn_vKillMicro((long)pMicro);
#endif
SND_fn_vDestroyMicroSnd(pMicro->sndId);
SNDLST2_M_DynamicIsolate(pMicro);
SND_fn_vFreeSndEx(E_ucSndBlockMain,pMicro);
}
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
/*-----------------------------------------------------------*/
/* SetRetMicroSound:initialiser les fonction RetMicroSound*/
/* Entree:ptrfct=pointeur sur les pfn*/
/*-----------------------------------------------------------*/
void SND_fn_vSetRetMicroSound(tdstAllRetMicroSound *ptrfct)
{
#ifndef NO_ACP_SOUND
SND_fn_vEnterCriticalSectionThreadSnd();
check_micro_fct();
memcpy(&g_st_pfnRetMicroSound,ptrfct,sizeof(tdstAllRetMicroSound));
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
/*-----------------------------------------------------------------*/
/* Ajo<6A>t d'une nouvelle ligne de volume*/
/*-----------------------------------------------------------------*/
long SND_fn_lAddVolumeLineSound(void)
{
#ifndef NO_ACP_SOUND
ptdstVolumeLine pLine;
SND_fn_vEnterCriticalSectionThreadSnd();
if (!nb_volume_lines)
SNDLST2_M_DynamicInitAnchor(&(g_VolumeLines.pList));
pLine=SND_fn_pvMallocSndEx(E_ucSndBlockMain,sizeof(tdstVolumeLine));
memset(pLine,0,sizeof(tdstVolumeLine));
SNDLST2_M_DynamicInitElement(pLine);
SNDLST2_M_DynamicAddTail(&(g_VolumeLines.pList),pLine);
pLine->lVol=C_SOUNDVOL_MAXI;
nb_volume_lines++;
SND_fn_vQuitCriticalSectionThreadSnd();
#ifdef SUPERVISATER
dbgSND_fn_vAddVolumeLine((long)pLine);
#endif
return (long)pLine;
#else
return SND_C_LINE_FANTOME;
#endif /*NO_ACP_SOUND*/
}
#ifndef NO_ACP_SOUND
/*update function pointers for a sound object type*/
void fn_vUpdateTypeObjectSoundInfos(tdstAllRetObjectSound *ptrfct,tdstAllRetObjectSound *new_ptrfct)
{
/*first copy default pointers values */
memcpy(ptrfct,&g_astTypeObjectSoundInfosDefault,sizeof(tdstAllRetObjectSound));
/*second update non NULL pointer*/
#ifdef MAXI_SCHEMMING
/*this first method is quite fast and light sized, but could be dangerous for som target*/
for (i=0;i<sizeof(tdstAllRetObjectSound)/sizeof(td_pfn_rRetSoundCoord);i++)
if (*((td_pfn_rRetSoundCoord)new_ptrfct+i)!=NULL)
*((td_pfn_rRetSoundCoord)ptr_fct+i)=*((td_pfn_rRetSoundCoord)new_ptrfct+i);
#else
/*exact method, but quite big sized source code*/
if (new_ptrfct->X!=NULL)
ptrfct->X=new_ptrfct->X;
if (new_ptrfct->Y!=NULL)
ptrfct->Y=new_ptrfct->Y;
if (new_ptrfct->Z!=NULL)
ptrfct->Z=new_ptrfct->Z;
if (new_ptrfct->VX!=NULL)
ptrfct->VX=new_ptrfct->VX;
if (new_ptrfct->VY!=NULL)
ptrfct->VY=new_ptrfct->VY;
if (new_ptrfct->VZ!=NULL)
ptrfct->VZ=new_ptrfct->VZ;
if (new_ptrfct->REVERB!=NULL)
ptrfct->REVERB=new_ptrfct->REVERB;
if (new_ptrfct->ExtraCoef!=NULL)
ptrfct->ExtraCoef=new_ptrfct->ExtraCoef;
if (new_ptrfct->Switch!=NULL)
ptrfct->Switch=new_ptrfct->Switch;
if (new_ptrfct->MicroLink!=NULL)
ptrfct->MicroLink=new_ptrfct->MicroLink;
#endif
}
/*
*=============================================================================
* fn_vSetDefaultRetChannelSound
*
* Description : Initialize default Channel callback function for an object type
*=============================================================================
* Input
* None
*
* Output : None
*
*=============================================================================
* Creation date : Author :
*=============================================================================
* Modification date : 02/06/99 Author : Pascal Lalancette
* Modifications : Add default channel callback on new sound type
*=============================================================================
*/
void fn_vSetDefaultRetChannelSound(long type)
{
memcpy(&g_d_pstTypeObjectSoundInfos[type].pfnRetChannelSound, &g_astChannelSoundInfosDefault,sizeof(tdstAllRetChannelSound));
}
#endif
#ifdef DREAMCAST
/* SND_fn_vSetNbObjectTypeSound ---------------------------------------------------------------------------------------------
Purpose: This function must be called previously to SND_fn_lAddObjectTypeSound. It allocates memory for Object Type Sound,
whatever that means!
----------------------------------------------------------------------------------------------------------------------------*/
void SND_fn_vSetNbObjectTypeSound(long p_lNbObjectTypeSound)
{
#ifndef NO_ACP_SOUND
g_lNbMaxObjectType = p_lNbObjectTypeSound+1;
g_d_pstTypeObjectSoundInfos = SND_fn_pvMallocSndEx(E_ucSndBlockMain,g_lNbMaxObjectType*sizeof(tdstTypeObjectInfos));
if (g_d_pstTypeObjectSoundInfos == NULL)
{
Erm_M_ClearLastError ( C_ucErmDefaultChannel );
Erm_M_UpdateLastError( Snd, C_ucErmDefaultChannel, E_uwSndMemoryAllocError, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, "Malloc allocation");
}
nb_object_type = 0;
SND_fn_lAddObjectTypeSound2(&g_astTypeObjectSoundInfosDefault,SND_C_LINE_FANTOME);
#endif /*NO_ACP_SOUND*/
}
#endif /*DREAMCAST*/
/*
*=============================================================================
* SND_fn_lAddObjectTypeSound2
*
* Description : Create/register a new sound object type
*=============================================================================
* Input
* ptrfct: Function pointers associated with the new type
* lLine : Volume line to assosiate to this new object type
*
* Output : Volume line Id
*
*=============================================================================
* Creation date : Author :
*=============================================================================
* Modification date : 02/06/99 Author : Pascal Lalancette
* Modifications : Add default channel callback on new sound type
*=============================================================================
*/
long SND_fn_lAddObjectTypeSound2(tdstAllRetObjectSound *ptrfct,long lLine)
{
#ifndef NO_ACP_SOUND
int id_type;
ptdstVolumeLine pLine;
SND_fn_vEnterCriticalSectionThreadSnd();
#ifndef DREAMCAST
if (nb_object_type==0)
{/*type #0 is a particluar one (default type=FANTOME) = done only once during the game*/
id_type=0;
g_d_pstTypeObjectSoundInfos=SND_fn_pvMallocSndEx(E_ucSndBlockMain,sizeof(tdstTypeObjectInfos));
nb_object_type=0;
}
else
{/*add a new type*/
id_type=nb_object_type;
g_d_pstTypeObjectSoundInfos=(tdstTypeObjectInfos*)SND_fn_pvReAllocSndEx(E_ucSndBlockMain,g_d_pstTypeObjectSoundInfos,(id_type+1)*sizeof(tdstTypeObjectInfos));
}
#else
/* test if enough memory has been allocated by SND_fn_vSetNbObjectTypeSound*/
assert( g_d_pstTypeObjectSoundInfos != NULL );
assert( g_lNbMaxObjectType > nb_object_type);
id_type=nb_object_type;
#endif /*DREAMCAST*/
/*init some fields*/
memset(&g_d_pstTypeObjectSoundInfos[id_type],0,sizeof(tdstTypeObjectInfos));
g_d_pstTypeObjectSoundInfos[id_type].pstLastEvent=SND_C_RES_FANTOME_PTR;
SNDLST2_M_DynamicInitAnchor(&g_d_pstTypeObjectSoundInfos[id_type].pListVolumeChanged);
g_d_pstTypeObjectSoundInfos[id_type].lVolume=C_SOUNDVOL_MAXI;
/*init volume line to be used for this new type*/
if (lLine!=SND_C_LINE_FANTOME)
{
pLine=(ptdstVolumeLine)lLine;
g_d_pstTypeObjectSoundInfos[id_type].pstVolumeLine=pLine;
}
else
g_d_pstTypeObjectSoundInfos[id_type].pstVolumeLine=NULL;
nb_object_type++;
/*update function pointers*/
fn_vUpdateTypeObjectSoundInfos(&g_d_pstTypeObjectSoundInfos[id_type].pfnRetObjectSound,ptrfct);
//Use default pointer for channel until they are set by the user
fn_vSetDefaultRetChannelSound(id_type);
SND_fn_vQuitCriticalSectionThreadSnd();
return id_type;
#else
return -1;
#endif /*NO_ACP_SOUND*/
}
/*-----------------------------------------------------------*/
/* SND_fn_vSetRetObjectTypeSound:change functions pointers associated with a previously created sound object type*/
/* Parameter:type (IN)= sound obejct type to be changed (should have been created by previous call to SND_fn_lAddObjectTypeSound2)*/
/* ptrfct (IN)=new function pointers associated with this type*/
/*-----------------------------------------------------------*/
void SND_fn_vSetRetObjectTypeSound(long type,tdstAllRetObjectSound *ptrfct)
{
#ifndef NO_ACP_SOUND
SND_fn_vEnterCriticalSectionThreadSnd();
if (type<0 || type>=nb_object_type)
SND_M_DisplayError(E_uwSndSystemError,"Invalid sound ovejct type");
else
{
fn_vUpdateTypeObjectSoundInfos(&g_d_pstTypeObjectSoundInfos[type].pfnRetObjectSound,ptrfct);
}
SND_fn_vQuitCriticalSectionThreadSnd();
#endif
}
/*-----------------------------------------------------------*/
/* SND_fn_vSetInfoForTypeSound:associated a "Info Callback funciton" qwith a previously created sound object type*/
/* (this optionnal function return a czString for deug about sound object)*/
/* Parameter:type (IN)= sound obejct type to be associated with this function (should have been created by previous call to SND_fn_lAddObjectTypeSound2)*/
/* pfnCopy (IN)=function pointers associated with this type*/
/*-----------------------------------------------------------*/
void SND_fn_vSetInfoForTypeSound(long type,td_pfn_vCopyString pfnCopy)
{
#ifndef NO_ACP_SOUND
if (type>=0 && type<nb_object_type)
{
g_d_pstTypeObjectSoundInfos[type].pfnInfoObject=pfnCopy;
}
#endif
}
void SND_fn_vGetInfoForObjectSound(long id,long type,char* str,long size_ptr)
{
#ifndef NO_ACP_SOUND
if (g_d_pstTypeObjectSoundInfos[type].pfnInfoObject)
{
(*g_d_pstTypeObjectSoundInfos[type].pfnInfoObject)(id,str,size_ptr);
}
else
strncpy(str,"no info",size_ptr);
#endif
}
void SND_fn_vSetRollOffFunctionForTypeSound(long type,td_pfn_bRetRollOffFactor fct)
{
#ifndef NO_ACP_SOUND
if (type>=0 && type<nb_object_type)
{
g_d_pstTypeObjectSoundInfos[type].pfnRollOff=fct;
}
#endif
}
/*-----------------------------------------------------------------*/
/* Reglages des lignes de volume*/
/*-----------------------------------------------------------------*/
long SND_fn_lGetVolumeLineSound(long lLine)
{
#ifndef NO_ACP_SOUND
ptdstVolumeLine pLine;
if (lLine!=SND_C_LINE_FANTOME)
{
pLine=(ptdstVolumeLine)lLine;
return pLine->lVol;
}
else
#endif
return C_SOUNDVOL_MAXI;
}
void SND_fn_vSetVolumeLineSound(long lLine,long lNewVolume)
{
#ifndef NO_ACP_SOUND
ptdstVolumeLine pLine;
if (lLine!=SND_C_LINE_FANTOME)
{
pLine=(ptdstVolumeLine)lLine;
/*if (pLine!=NULL)*/
{
pLine->lVol=lNewVolume;
fn_vRajAllVolumeForLine(pLine);
#ifdef SUPERVISATER
dbgSND_fn_vSetVolumeLine((long)pLine,lNewVolume);
#endif
}
}
#endif
}
/*----------------------------------*/
/* Pause/resume every sounds */
/*----------------------------------*/
void SND_fn_vPauseSound(void)
{
#ifndef NO_ACP_SOUND
if (g_bInitDoneSound)
{
SND_fn_vEnterCriticalSectionThreadSnd();
SND_fn_vPauseAllSnd();
SND_fn_vQuitCriticalSectionThreadSnd();
}
#endif /*NO_ACP_SOUND*/
}
void SND_fn_vResumeSound(void)
{
#ifndef NO_ACP_SOUND
if (g_bInitDoneSound)
{
SND_fn_vEnterCriticalSectionThreadSnd();
SND_fn_vResumeAllSnd();
SND_fn_vQuitCriticalSectionThreadSnd();
}
#endif /*NO_ACP_SOUND*/
}
/*----------------------------------*/
/* Pause/resume for one object */
/*----------------------------------*/
void SND_fn_vPauseObjectSound(long indice,long type)
{
#ifndef NO_ACP_SOUND
pASSOCIATION_DESCRIPTION pAsso;
int i;
if (g_bInitDoneSound)
{
SND_fn_vEnterCriticalSectionThreadSnd();
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{/*for each asso*/
if (pAsso->bValid)
{/*check if asso is valid*/
if (pAsso->indice==indice && pAsso->type==type)
{/*found an object*/
SND_fn_vPauseSnd(pAsso->voice);
}
}
}
SND_fn_vQuitCriticalSectionThreadSnd();
}
#endif /*NO_ACP_SOUND*/
}
void SND_fn_vResumeObjectSound(long indice,long type)
{
#ifndef NO_ACP_SOUND
pASSOCIATION_DESCRIPTION pAsso;
int i;
if (g_bInitDoneSound)
{
SND_fn_vEnterCriticalSectionThreadSnd();
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{/*for each asso*/
if (pAsso->bValid)
{/*check if asso is valid*/
if (pAsso->indice==indice && pAsso->type==type)
{/*found an object*/
SND_fn_vResumeSnd(pAsso->voice);
}
}
}
SND_fn_vQuitCriticalSectionThreadSnd();
}
#endif /*NO_ACP_SOUND*/
}
/*----------------------------------*/
/* Pause/resume for one type */
/*----------------------------------*/
void SND_fn_vPauseTypeSound(long type)
{
#ifndef NO_ACP_SOUND
pASSOCIATION_DESCRIPTION pAsso;
int i;
if (g_bInitDoneSound)
{
SND_fn_vEnterCriticalSectionThreadSnd();
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{/*for each asso*/
if (pAsso->bValid)
{/*check if asso is valid*/
if (pAsso->type==type)
{/*found an object*/
SND_fn_vPauseSnd(pAsso->voice);
}
}
}
SND_fn_vQuitCriticalSectionThreadSnd();
}
#endif /*NO_ACP_SOUND*/
}
void SND_fn_vResumeTypeSound(long type)
{
#ifndef NO_ACP_SOUND
pASSOCIATION_DESCRIPTION pAsso;
int i;
if (g_bInitDoneSound)
{
SND_fn_vEnterCriticalSectionThreadSnd();
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{/*for each asso*/
if (pAsso->bValid)
{/*check if asso is valid*/
if (pAsso->type==type)
{/*found an object*/
SND_fn_vResumeSnd(pAsso->voice);
}
}
}
SND_fn_vQuitCriticalSectionThreadSnd();
}
#endif /*NO_ACP_SOUND*/
}
/*--------------------------------------*/
/* Pause/resume for all types but one */
/*--------------------------------------*/
void SND_fn_vPauseButOneTypeSound(long type)
{
#ifndef NO_ACP_SOUND
pASSOCIATION_DESCRIPTION pAsso;
int i;
if (g_bInitDoneSound)
{
SND_fn_vEnterCriticalSectionThreadSnd();
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{/*for each asso*/
if (pAsso->bValid)
{/*check if asso is valid*/
if (pAsso->type!=type)
{/*found an object*/
SND_fn_vPauseSnd(pAsso->voice);
}
}
}
SND_fn_vQuitCriticalSectionThreadSnd();
}
#endif /*NO_ACP_SOUND*/
}
void SND_fn_vResumeButOneTypeSound(long type)
{
#ifndef NO_ACP_SOUND
pASSOCIATION_DESCRIPTION pAsso;
int i;
if (g_bInitDoneSound)
{
SND_fn_vEnterCriticalSectionThreadSnd();
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{/*for each asso*/
if (pAsso->bValid)
{/*check if asso is valid*/
if (pAsso->type!=type)
{/*found an object*/
SND_fn_vResumeSnd(pAsso->voice);
}
}
}
SND_fn_vQuitCriticalSectionThreadSnd();
}
#endif /*NO_ACP_SOUND*/
}
/*relache-reprise <20> chaud des drivers bas-niveaux*/
void SND_fn_vForceReleaseDriverSound()
{
#ifndef NO_ACP_SOUND
SND_fn_vForceReleaseDriverSnd();
#endif /*NO_ACP_SOUND*/
}
void SND_fn_vForceRestoreDriverSound()
{
#ifndef NO_ACP_SOUND
SND_fn_vForceRestoreDriverSnd();
#endif /*NO_ACP_SOUND*/
}
SndBool SND_fn_bReleaseDriverSound()
{
#ifndef NO_ACP_SOUND
if (g_bInitDoneSound)
{
if (SND_fn_bEnterCriticalSectionForDriverThreadSnd())
{
SND_fn_vReleaseDriverSnd();
SND_fn_vQuitCriticalSectionThreadSnd();
return TRUE;
}
}
#endif
return FALSE;
}
SndBool SND_fn_bRestoreDriverSound()
{
#ifndef NO_ACP_SOUND
if (g_bInitDoneSound)
{
if (SND_fn_bEnterCriticalSectionForDriverThreadSnd())
{
SND_fn_vRestoreDriverSnd();
SND_fn_vQuitCriticalSectionThreadSnd();
return TRUE;
}
}
#endif
return FALSE;
}
void SND_fn_vReleaseDriverSound(void)
{
SND_fn_bReleaseDriverSound();
}
void SND_fn_vRestoreDriverSound(void)
{
SND_fn_bRestoreDriverSound();
}
/*reglage des volumes gene*/
long SND_fn_lGetVolumeSound()
{
#ifndef NO_ACP_SOUND
return (long)SND_fn_ucGetSoundVolumeSnd();
#else
return 0;
#endif
}
void SND_fn_vSetVolumeSound(long vol)
{
#ifndef NO_ACP_SOUND
SND_fn_vSetSoundVolumeSnd((unsigned char)vol);
#endif
}
void SND_fn_vSetStereoSound(SndBool active)
{
#ifndef NO_ACP_SOUND
SND_fn_vSetStereoSnd(active);
#endif
}
SndBool SND_fn_bGetStereoSound(void)
{
#ifndef NO_ACP_SOUND
return SND_fn_bGetStereoSnd();
#else
return FALSE;
#endif
}
SndBool SND_fn_bIsMusicPlayingSound(void)
{
#ifndef NO_ACP_SOUND
return SND_fn_bIsMusicPlayingSnd();
#else
return FALSE;
#endif
}
void SND_fn_vSetReverseStereoSound(SndBool active)
{
#ifndef NO_ACP_SOUND
SND_fn_vSetReverseStereoSnd(active) ;
#endif
}
SndBool SND_fn_bGetReverseStereoSound(void)
{
#ifndef NO_ACP_SOUND
return SND_fn_bGetReverseStereoSnd();
#else
return FALSE;
#endif
}
/*---------------------------------------------------------*/
/* GetTargetLabel: retourne le label designant la tareget*/
/* Entree: name=nom cible*/
/* nb_char=taille maxi de la cible*/
/*----------------------------------------------------------*/
void SND_fn_vGetTargetLabelSound(char* name,int nb_char)
{
#ifndef NO_ACP_SOUND
SND_fn_vGetTargetLabelSnd(name,nb_char);
#endif
}
void SND_fn_vSetupTargetSound(void)
{
#ifndef NO_ACP_SOUND
SND_fn_vSetupTargetSnd();
#endif
}
SndBool SND_fn_bCanSetupTargetSound(void)
{
#ifndef NO_ACP_SOUND
return SND_fn_bCanSetupTargetSnd();
#else
return FALSE;
#endif
}
long SND_fn_lCreateNewBufferSound(unsigned long nb_samples,unsigned short uwResolution,unsigned short uwNbChannels,unsigned long ulFreq,SoundParam* par,td_pfn_vRefreshBufferClient callback,long user_id)
{
#ifndef DISABLE_BUFFER_CLIENT
#ifndef NO_ACP_SOUND
return SND_fn_lCreateNewBufferSnd(nb_samples,uwResolution,uwNbChannels,ulFreq,par,callback,user_id);
#else
return SND_C_EVT_FAILED;
#endif
#else
return SND_C_EVT_FAILED;
#endif /* DISABLE_BUFFER_CLIENT*/
}
void SND_fn_vDeleteBufferSound(long id_buffer)
{
#ifndef DISABLE_BUFFER_CLIENT
#ifndef NO_ACP_SOUND
SND_fn_vDeleteBufferSnd(id_buffer);
#endif
#endif /* DISABLE_BUFFER_CLIENT*/
}
void SND_fn_vPauseBufferSound(long id_buffer)
{
#ifndef DISABLE_BUFFER_CLIENT
#ifndef NO_ACP_SOUND
SND_fn_vPauseBufferSnd(id_buffer);
#endif
#endif /* DISABLE_BUFFER_CLIENT*/
}
void SND_fn_vResumeBufferSound(long id_buffer)
{
#ifndef DISABLE_BUFFER_CLIENT
#ifndef NO_ACP_SOUND
SND_fn_vResumeBufferSnd(id_buffer);
#endif
#endif /* DISABLE_BUFFER_CLIENT*/
}
SndReal SND_fn_rGetPosBufferSound(long id_buffer)
{
#ifndef DISABLE_BUFFER_CLIENT
#ifndef NO_ACP_SOUND
return SND_fn_rGetPosBufferSnd(id_buffer);
#else
return SND_C_POS_UNKNOWN;
#endif
#else
return SND_C_POS_UNKNOWN;
#endif /* DISABLE_BUFFER_CLIENT*/
}
long SND_fn_lCreateNewBufferExSound(SND_tdstFormat* pformat,SND_tdstCallback* pCallback,SoundParam* par,long user_id)
{
#ifndef DISABLE_BUFFER_CLIENT
#ifndef NO_ACP_SOUND
return SND_fn_lCreateNewBufferExSnd(pformat,pCallback,par,user_id);
#else
return SND_C_EVT_FAILED;
#endif
#else
return SND_C_EVT_FAILED;
#endif /* DISABLE_BUFFER_CLIENT*/
}
long SND_fn_lGetPosBufferExSound(long id_buffer)
{
#ifndef DISABLE_BUFFER_CLIENT
#ifndef NO_ACP_SOUND
return SND_fn_lGetPosBufferExSnd(id_buffer);
#else
return SND_C_POS_UNKNOWN;
#endif
#else
return SND_C_POS_UNKNOWN;
#endif /* DISABLE_BUFFER_CLIENT*/
}
long SND_fn_lPushBufferExSound(long id_buffer,SND_tdstStackBuffer* pStack)
{
#ifndef DISABLE_BUFFER_CLIENT
#ifndef NO_ACP_SOUND
return SND_fn_lPushBufferExSnd(id_buffer,pStack);
#else
return SND_C_EVT_FAILED;
#endif
#else
return SND_C_EVT_FAILED;
#endif /* DISABLE_BUFFER_CLIENT*/
}
void SND_fn_vSetParamBufferSound(long id_buffer,SoundParam* par)
{
#ifndef DISABLE_BUFFER_CLIENT
#ifndef NO_ACP_SOUND
SND_fn_vSetParamBufferSnd(id_buffer,par);
#endif
#endif /* DISABLE_BUFFER_CLIENT*/
}
long SND_fn_lGetSwitchIndice(long objecttype,long objectid,tduRefRes uRes)
{
#ifndef NO_ACP_SOUND
return (g_d_pstTypeObjectSoundInfos[objecttype].pfnRetObjectSound.Switch)(objectid,uRes.pstPtr->uRes.stSwitch.lTypeSwitch);
#else
return 0;
#endif
}
long SND_fn_lGetNbVoiceOptimumSound()
{
#ifndef NO_ACP_SOUND
return SND_fn_lGetNbVoiceOptimumSnd();
#else
return 0;
#endif
}
long SND_fn_lGetNbVoiceWishedSound()
{
#ifndef NO_ACP_SOUND
return SND_fn_lGetNbVoiceWishedSnd();
#else
return 0;
#endif
}
void SND_fn_vSetNbVoiceWishedSound(long nb)
{
#ifndef NO_ACP_SOUND
SND_fn_vSetNbVoiceWishedSnd(nb);
#endif
}
/********************************************************************
Public function for object's volume management
***********************************************************************/
/*------------------------------------------------------------*/
/* Change volume for one object*/
/* Parameters:*/
/* indice=object's indice*/
/* type=object's sound type*/
/* lNewVolume=nex volume (0 to 127)*/
/*------------------------------------------------------------*/
void SND_fn_vChangeVolumeSound(long indice,long type,long lNewVolume)
{
#ifndef NO_ACP_SOUND
SND_fn_vEnterCriticalSectionThreadSnd();
fn_vChangeVolumeForObject(indice,type,lNewVolume);
SND_fn_vSynchroSound();
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
void SND_fn_vResetVolumeSound(long indice,long type)
{
#ifndef NO_ACP_SOUND
SND_fn_vEnterCriticalSectionThreadSnd();
fn_vResetVolumeForObject(indice,type);
SND_fn_vSynchroSound();
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
long SND_fn_lGetVolumeObjectSound(long indice,long type)
{
#ifndef NO_ACP_SOUND
long lVolume;
SND_fn_vEnterCriticalSectionThreadSnd();
lVolume=fn_lGetVolumeForObject(indice,type);
SND_fn_vQuitCriticalSectionThreadSnd();
return lVolume;
#endif /*NO_ACP_SOUND*/
}
/*------------------------------------------------------------*/
/* Change volume for all objects execpt one*/
/* Parameters:*/
/* indice=object's indice*/
/* type=object's sound type*/
/* lNewVolume=nex volume (0 to 127)*/
/*------------------------------------------------------------*/
void SND_fn_vChangeVolumeAllObjectButOneSound(long indice,long type,long lNewVolume)
{
#ifndef NO_ACP_SOUND
pASSOCIATION_DESCRIPTION pAsso;
int i;
SND_fn_vEnterCriticalSectionThreadSnd();
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{/*for each asso*/
if (pAsso->bValid)
if ((pAsso->indice!=indice) && (pAsso->type!=type))
fn_vChangeVolumeForObject(pAsso->indice,pAsso->type,lNewVolume);
}
SND_fn_vSynchroSound();
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
void SND_fn_vResetVolumeAllObjectButOneSound(long indice,long type)
{
#ifndef NO_ACP_SOUND
pASSOCIATION_DESCRIPTION pAsso;
int i;
SND_fn_vEnterCriticalSectionThreadSnd();
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{/*for each asso*/
if (pAsso->bValid)
if ((pAsso->indice!=indice) && (pAsso->type!=type))
fn_vResetVolumeForObject(pAsso->indice,pAsso->type);
}
SND_fn_vSynchroSound();
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
/*------------------------------------------------------------*/
/* Change volume for one object-type*/
/* Parameters:*/
/* type=object's sound type*/
/* lNewVolume=nex volume (0 to 127)*/
/*------------------------------------------------------------*/
void SND_fn_vChangeVolumeTypeSound(long type,long lNewVolume)
{
#ifndef NO_ACP_SOUND
SND_fn_vEnterCriticalSectionThreadSnd();
fn_vChangeVolumeForType(type,lNewVolume);
SND_fn_vSynchroSound();
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
void SND_fn_vResetVolumeTypeSound(long type)
{
#ifndef NO_ACP_SOUND
SND_fn_vEnterCriticalSectionThreadSnd();
fn_vChangeVolumeForType(type,C_SOUNDVOL_MAXI);
SND_fn_vSynchroSound();
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
long SND_fn_lGetVolumeTypeSound(long type)
{
#ifndef NO_ACP_SOUND
long lVolume;
SND_fn_vEnterCriticalSectionThreadSnd();
lVolume=fn_lGetVolumeForType(type);
SND_fn_vQuitCriticalSectionThreadSnd();
return lVolume;
#endif /*NO_ACP_SOUND*/
}
/*------------------------------------------------------------*/
/* Change volume for every object-type but one*/
/* Parameters:*/
/* type=object-type to not change volume of*/
/* lNewVolume=nex volume (0 to 127)*/
/*------------------------------------------------------------*/
void SND_fn_vChangeVolumeButOneTypeSound(long type,long lNewVolume)
{
#ifndef NO_ACP_SOUND
int i;
SND_fn_vEnterCriticalSectionThreadSnd();
for (i=0;i<nb_object_type;i++)
if (i!=type)
fn_vChangeVolumeForType(i,lNewVolume);
SND_fn_vSynchroSound();
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
void SND_fn_vResetVolumeButOneTypeSound(long type)
{
#ifndef NO_ACP_SOUND
int i;
SND_fn_vEnterCriticalSectionThreadSnd();
for (i=0;i<nb_object_type;i++)
if (i!=type)
fn_vResetVolumeForType(i);
SND_fn_vSynchroSound();
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
/*------------------------------------------------------------*/
/* Change volume for every objects of a specific type*/
/* Parameters:*/
/* type=object-type to change volume of*/
/* lNewVolume=nex volume (0 to 127)*/
/*------------------------------------------------------------*/
void SND_fn_vChangeVolumeAllObjectSound(long type,long lNewVolume)
{
#ifndef NO_ACP_SOUND
pASSOCIATION_DESCRIPTION pAsso;
int i;
SND_fn_vEnterCriticalSectionThreadSnd();
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{/*for each asso*/
if (pAsso->bValid)
if (pAsso->type==type)
fn_vChangeVolumeForObject(pAsso->indice,pAsso->type,lNewVolume);
}
SND_fn_vSynchroSound();
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
void SND_fn_vResetVolumeAllObjectSound(long type)
{
#ifndef NO_ACP_SOUND
pASSOCIATION_DESCRIPTION pAsso;
int i;
SND_fn_vEnterCriticalSectionThreadSnd();
SNDLST2_M_DynamicForEachElementOf(&association.pList,pAsso,i)
{/*for each asso*/
if (pAsso->bValid)
if (pAsso->type==type)
fn_vResetVolumeForObject(pAsso->indice,pAsso->type);
}
SND_fn_vSynchroSound();
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
/*------------------------------------------------------------*/
/* Change volume for every objects of a specific type*/
/* Parameters:*/
/* type=object-type to change volume of*/
/* lNewVolume=nex volume (0 to 127)*/
/*------------------------------------------------------------*/
void SND_fn_vChangeVolumeAllTypeSound(long lNewVolume)
{
#ifndef NO_ACP_SOUND
int i;
SND_fn_vEnterCriticalSectionThreadSnd();
for (i=0;i<nb_object_type;i++)
fn_vChangeVolumeForType(i,lNewVolume);
SND_fn_vSynchroSound();
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
void SND_fn_vResetVolumeAllTypeSound(void)
{
#ifndef NO_ACP_SOUND
int i;
SND_fn_vEnterCriticalSectionThreadSnd();
for (i=0;i<nb_object_type;i++)
fn_vResetVolumeForType(i);
SND_fn_vSynchroSound();
SND_fn_vQuitCriticalSectionThreadSnd();
#endif /*NO_ACP_SOUND*/
}
/*--------------------------------------------------*/
/* SND_fn_uGenerateEventPlaySound: dynamically create a SoundEvent Play from data loaded by client*/
/* Parameters:*/
/* data: pointer onto data*/
/* pformat: descruiption of data*/
/* loop: TRUE if ressource should loop*/
/* Return:*/
/* new created event Play*/
/*---------------------------------------------------*/
SND_tduRefEvt SND_fn_uGenerateEventPlaySound(void* data,SND_tdstFormat* pformat,SndBool loop)
{
#ifndef NO_ACP_SOUND
SND_tduRefEvt uEvt;
if (g_bInitDoneSound)
{
uEvt.pstPtr=SND_fn_pvMallocSndEx(E_ucSndBlockMain,sizeof(SND_tdstBlockEvent));
memset(uEvt.pstPtr,0,sizeof(SND_tdstBlockEvent));
uEvt.pstPtr->eType=EVT_SON_PLAY;
uEvt.pstPtr->bStopable=TRUE;
uEvt.pstPtr->bDynamic=TRUE;
uEvt.pstPtr->uParams.stPlay.uResource=SND_fn_uGenerateResourceSnd(data,pformat,loop);
return uEvt;
}
else
{
snd_assert(FALSE);//you should not call this function before SND_fn_vInitSound
return SND_EVT_FANTOME;
}
#else
return SND_EVT_FANTOME;
#endif /*NO_ACP_SOUND*/
}
/*--------------------------------------------------*/
/* SND_fn_uGenerateEventStopSound: dynamically create a SoundEvent Stop from another SoundEvent Play*/
/* Parameters:*/
/* event: event Play*/
/* Return:*/
/* new created event Stop*/
/*---------------------------------------------------*/
SND_tduRefEvt SND_fn_uGenerateEventStopSound(SND_tduRefEvt event)
{
#ifndef NO_ACP_SOUND
SND_tduRefEvt uEvt;
if (g_bInitDoneSound)
{
uEvt.pstPtr=SND_fn_pvMallocSndEx(E_ucSndBlockMain,sizeof(SND_tdstBlockEvent));
memset(uEvt.pstPtr,0,sizeof(SND_tdstBlockEvent));
uEvt.pstPtr->eType=EVT_SON_STOP;
uEvt.pstPtr->uParams.stStop.uEvt=event;
uEvt.pstPtr->bStopable=TRUE;
uEvt.pstPtr->bDynamic=TRUE;
return uEvt;
}
else
{
snd_assert(FALSE);//you should not call this function before SND_fn_vInitSound
return SND_EVT_FANTOME;
}
#else
return SND_EVT_FANTOME;
#endif /*NO_ACP_SOUND*/
}
/*--------------------------------------------------*/
/* SND_fn_vDestroyEventSound: destroy a event */
/* previously created by SND_fn_uGenerateEventPlaySound or*/
/* Parameters:*/
/* event: event to destroy*/
/*---------------------------------------------------*/
void SND_fn_vDestroyEventSound(SND_tduRefEvt event)
{
#ifndef NO_ACP_SOUND
if (event.pstPtr!=EVT_FANTOME_PTR)
{
switch (event.pstPtr->eType)
{
case EVT_SON_STOP:
SND_fn_vFreeSndEx(E_ucSndBlockMain,event.pstPtr);
break;
case EVT_SON_PLAY:
SND_fn_vDestroyResourceSnd(event.pstPtr->uParams.stPlay.uResource);
SND_fn_vFreeSndEx(E_ucSndBlockMain,event.pstPtr);
break;
default:
SND_M_DisplayError(E_uwSndInvalidTypeOfEvent,"");
break;
}
}
#endif /*NO_ACP_SOUND*/
}
/*----------SNDREC*/
SndBool SND_fn_bTestFormatRecordSound(SND_tdstFormat* pformat,int flags)
{
#if !defined(DISABLE_RECORD) && !defined(NO_ACP_SOUND)
return SND_fn_bTestFormatRecordSnd(pformat,flags);
#else
return FALSE;
#endif
}
long SND_fn_lCreateBufferRecordSound(SND_tdstFormat* pformat,SND_tdstCallback* pCallback)
{
#if !defined(DISABLE_RECORD) && !defined(NO_ACP_SOUND)
return SND_fn_lCreateBufferRecordSnd(pformat,pCallback);
#else
return C_PLAY_FAILED;
#endif
}
SndBool SND_fn_bIsBufferFullDuplexRecordSound(long id_buffer)
{
#if !defined(DISABLE_RECORD) && !defined(NO_ACP_SOUND)
return SND_fn_bIsBufferFullDuplexRecordSnd(id_buffer);
#else
return FALSE;
#endif
}
SndBool SND_fn_bStartRecordSound(long id_buffer)
{
#if !defined(DISABLE_RECORD) && !defined(NO_ACP_SOUND)
return SND_fn_bStartRecordSnd(id_buffer);
#else
return FALSE;
#endif
}
void SND_fn_vStopRecordSound(long id_buffer)
{
#if !defined(DISABLE_RECORD) && !defined(NO_ACP_SOUND)
SND_fn_vStopRecordSnd(id_buffer);
#endif
}
SndBool SND_fn_bIsWorkingRecordSound(long id_buffer)
{
#if !defined(DISABLE_RECORD) && !defined(NO_ACP_SOUND)
return SND_fn_bIsWorkingRecordSnd(id_buffer);
#else
return FALSE;
#endif
}
long SND_fn_lPushBufferToRecordSound(long id_buffer,void* ptr,int size_ptr)
{
#if !defined(DISABLE_RECORD) && !defined(NO_ACP_SOUND)
return SND_fn_lPushBufferToRecordSnd(id_buffer,ptr,size_ptr);
#else
return FALSE;
#endif
}
unsigned char SND_fn_ucGetInstantVuMeterRecordSound(void)
{
#if !defined(DISABLE_RECORD) && !defined(NO_ACP_SOUND)
return SND_fn_ucGetInstantVuMeterRecordSnd();
#else
return 0;
#endif
}