/* ////////////////////////////////////////////////////////////// // 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 #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 #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=0) g_d_pstTypeObjectSoundInfos[type].pstLastEvent=evt; } SND_tdstBlockEvent* SND_fn_pstGetLastEventForObjectTypeSound(long type) { if (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(µs_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(µs_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 à 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 ça*/ if (!SND_fn_bSetParamSnd(pAsso->voice,pstSoundParam)) {/*son fini*/ erase_association(pAsso); } } /*on ne touche pas aux autres sons (ça sert à 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(µs_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 à ne pas remettre à 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;typesndId=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 à 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(µs_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û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;iX!=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=0 && typelVol; } 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 à 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;ibValid) 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;ieType=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 }