/* ////////////////////////////////////////////////////////// // Module SNDPLAY Version 2.0 // ////////////////////////////////////////////////////////// */ #include "SNDinc.h" #ifdef DEBUG_SON #include #endif #if defined(_DLL_COMPILATION_MODE) #include "snddll.h" #else #include "sndcd.h" #include "sndmidi.h" #ifndef DISABLE_MULTIWAV #include "sndxd.h" #else #include "sndxdwav.h" #endif #endif #ifndef DISABLE_RECORD #include "sndrec.h" #endif #include "sndres.h" #include "sndplay.h" #include "sndtheme.h" #include "sndseq.h" #include "sndspace.h" #include "sndrndom.h" #include "sndswtch.h" #ifndef NO_ACP_SOUND /*---------------- fonctions privees --------------------*/ typedef void SND_CALL td_fn_vPauseFunc(long); typedef void SND_CALL td_fn_vResumeFunc(long); typedef SndBool SND_CALL td_fn_bSetParamFunc(long,SoundParam*); typedef void SND_CALL td_fn_vStopFunc(long); typedef SndReal SND_CALL td_fn_rGetPosFunc(long); typedef SndBool SND_CALL td_fn_bTestIsPlayingFunc(long); typedef struct _td_st_Func { td_fn_vPauseFunc *pfnPause; td_fn_vResumeFunc *pfnResume; td_fn_bSetParamFunc *pfnSetParam; td_fn_vStopFunc *pfnStop; td_fn_rGetPosFunc *pfnGetPos; td_fn_bTestIsPlayingFunc *pfnTestIsPlaying; } td_st_Func; /*global array storing function pointer for each ressource type (to avoid switch)*/ static td_st_Func a_fnFunc[NB_TYPES_RESOURCES] ={ {NULL,NULL,NULL,NULL,NULL,NULL}, {SND_fn_vPauseSxd,SND_fn_vResumeSxd,SND_fn_bSetParamSxd,SND_fn_vStopSxd,SND_fn_rGetPosSxd,SND_fn_bTestIsPlayingSxd}, {SND_fn_vPauseMidi,SND_fn_vResumeMidi,SND_fn_bSetParamMidi,SND_fn_vStopMidi,SND_fn_rGetPosMidi,SND_fn_bTestIsPlayingMidi}, #ifndef DISABLE_CD {SND_fn_vPauseCD,SND_fn_vResumeCD,SND_fn_bSetParamCD,SND_fn_vStopCD,SND_fn_rGetPosCD,SND_fn_bTestIsPlayingCD}, #else {NULL,NULL,NULL,NULL,NULL,NULL}, #endif #ifndef DISABLE_SEQUENCE {SND_fn_vPauseSeq,SND_fn_vResumeSeq,SND_fn_bSetParamSeq,SND_fn_vStopSeq,SND_fn_rGetPosSeq,SND_fn_bTestIsPlayingSeq}, #else {NULL,NULL,NULL,NULL,NULL,NULL}, #endif {NULL,NULL,NULL,NULL,NULL,NULL}, #ifndef DISABLE_SPLIT {SND_fn_vPauseSplit,SND_fn_vResumeSplit,SND_fn_bSetParamSplit,SND_fn_vStopSplit,SND_fn_rGetPosSplit,SND_fn_bTestIsPlayingSplit}, #else {NULL,NULL,NULL,NULL,NULL,NULL}, #endif {NULL,NULL,NULL,NULL,NULL,NULL}, {SND_fn_vPauseSwitch,SND_fn_vResumeSwitch,SND_fn_bSetParamSwitch,SND_fn_vStopSwitch,SND_fn_rGetPosSwitch,SND_fn_bTestIsPlayingSwitch}, {NULL,NULL,NULL,NULL,NULL,NULL}, {SND_fn_vPauseRandom,SND_fn_vResumeRandom,SND_fn_bSetParamRandom,SND_fn_vStopRandom,SND_fn_rGetPosRandom,SND_fn_bTestIsPlayingRandom}, #ifndef DISABLE_THEME {SND_fn_vPauseTheme,SND_fn_vResumeTheme,SND_fn_bSetParamTheme,SND_fn_vStopTheme,SND_fn_rGetPosTheme,SND_fn_bTestIsPlayingTheme}, #else {NULL,NULL,NULL,NULL,NULL,NULL}, #endif } ; typedef struct { long voice_sxd; /*voie bas-niveau associee*/ tduRefRes res; /*ressource associee*/ /* long prio; */ SndBool_field_decl(free); /*si TRUE, infos non valides, element disponible*/ SndBool_field_decl(association_running); /*TRUE si en cours d'allocation (entre preassocie et associe/desassocie)*/ SndBool_field_decl(bTransition); /*TRUE si voie PlayTransition, FALSE si PlaySnd*/ SndBool bValid; SndBool* pbValid; /*ptr sur le Booleen à mettre à FALSE en cas de reattribution frauduleuse*/ long lPauseInstance; /*0 si pas en pause, sinon Id de l'instane de Pause responsable*/ /* td_fn_vPauseFunc *fnPause;*/ /* td_fn_vResumeFunc *fnResume;*/ /* td_fn_bSetParamFunc *fnSetParam;*/ /* td_fn_vStopFunc *fnStop;*/ /* td_fn_rGetPosFunc *fnGetPos;*/ /* td_fn_bTestIsPlayingFunc *fnTestIsPlaying;*/ } voice_description; #define NB_VOICE_MAX 64 static voice_description voice_snd[NB_VOICE_MAX]; /* //---pour le type switch typedef struct { long voice_snd; //voie associee à l'element valide tduRefRes res_switch; //ressource switch associee tduRefRes res_current; //element valide long prio; SndBool bValid; //FALSE si voice_snd valid SndBool *pbValid; //mettre à FALSE à la liberetion de la voie SndBool free; //si TRUE, infos non valides, element disponible } switch_description; #define NB_SWITCH_MAX 32 switch_description switch_snd[NB_SWITCH_MAX]; */ #ifndef DISABLE_SPLIT /*---pour le type split*/ typedef struct _active_plage *p_active_plage; SNDLST2_M_DynamicUseListOf(p_active_plage); typedef struct _active_plage { long voice_snd; /*voie associe à la plage*/ tdstRangeSplitMem* pRange; /*ressource associee*/ SndBool bValid; /*FALSE si voice_snd invalid*/ SNDLST2_M_DynamicElementDeclaration(p_active_plage) /*insertion dans la liste ACP*/ } active_plage; typedef struct _split_description { tduRefRes res_split; /*ressource split associee*/ long prio; SndBool *pbValid; /*mettre à FALSE à la liberetion de la voie*/ SndBool free; /*si TRUE, infos non valides, element disponible*/ SNDLST2_M_DynamicAnchorDeclaration(p_active_plage) pList; } split_description; #define NB_SPLIT_MAX 32 static split_description split_snd[NB_SPLIT_MAX]; #endif /*DISABLE_SPLIT*/ static SndBool g_iInitSxd,g_iInitCD,g_iInitMidi; /*codes de retour des InitXXX*/ tduRefRes SND_RES_FANTOME={(unsigned long)SND_C_RES_FANTOME_PTR}; static int g_lCurrentGlobalPauseInstance=1;/*id de la prochaine instance de Pause*/ /*---- fonctions de gestion de SoundParam*/ /* long SND_fn_lGetSizeOfSoundParam(SoundParam* _pObj) { return (sizeof(SoundParam)+(_pObj->iNbLinks-NB_LINK)*sizeof(MicroLink)+sizeof(RollOffParam)); } */ #ifndef NB_MICRO_MAX /*---- cree une structure SoundParam dont le champ iNbLink est VALIDE*/ SoundParam* SND_fn_pCreateSoundParam(int nb_micro) { SoundParam* tmp; tmp=SND_fn_pvMallocSndEx(E_ucSndBlockMain, SND_M_lGetSizeOfSoundParamFromNbLink(nb_micro)); tmp->iNbLinks=nb_micro; return tmp; } void SND_fn_vDestroySoundParam(SoundParam* _pObj) { SND_fn_vFreeSndEx(E_ucSndBlockMain,_pObj); } #endif void SND_fn_vCopySoundParam(SoundParam*_pDest,SoundParam* _pSrc) { memcpy(_pDest,_pSrc,SND_M_lGetSizeOfSoundParam(_pSrc)); } /*----renvoie la liste des voies*/ void liste_of_voices(char* texte,long size) { #ifdef DEBUG_SON SndBool no_voices=TRUE; /* SndBool no_switch=TRUE;*/ SndBool no_split=TRUE; #ifndef DISABLE_SPLIT p_active_plage plage; int j; #endif int i; char temp[128]; texte[0]='\0'; for (i=0;iId); strncat(texte,temp,size-strlen(texte)-1); switch (voice_snd[i].res.pstPtr->eType) { case TYPE_INVALID: strncat(texte,"INVALID !!!!!)\xd\xa",size-strlen(texte)-1);break; case TYPE_SAMPLE: strncat(texte,"wav)\xd\xa",size-strlen(texte)-1);break; case TYPE_MIDI: strncat(texte,"midi)\xd\xa",size-strlen(texte)-1);break; case TYPE_CDAUDIO: strncat(texte,"cdA)\xd\xa",size-strlen(texte)-1);break; case TYPE_SEQUENCE: strncat(texte,"seq)\xd\xa",size-strlen(texte)-1);break; case TYPE_SWITCH: strncat(texte,"switch)\xd\xa",size-strlen(texte)-1);break; case TYPE_SPLIT: strncat(texte,"split)\xd\xa",size-strlen(texte)-1);break; case TYPE_RANDOM: strncat(texte,"random)\xd\xa",size-strlen(texte)-1);break; default: strncat(texte,"??)\xd\xa",size-strlen(texte)-1);break; } } else { strncat(texte,"NULL)\xd\xa",size-strlen(texte)-1); } } } if (no_voices) { strcpy(texte,"Aucune voie active\xd\xa"); } /*------liste des switch*/ /* for (i=0;ivoice_snd,plage->pRange->uRes.pstPtr); strncat(texte,temp,size-strlen(texte)-1); } if (j==0) { sprintf(temp,"no range"); strncat(texte,temp,size-strlen(texte)-1); } sprintf(temp,")\xd\xa"); strncat(texte,temp,size-strlen(texte)-1); } } #endif /*DISABLE_SPLIT*/ if (no_split) { strcpy(temp,"Aucun split actif"); strncat(texte,temp,size-strlen(texte)-1); } #endif /*DEBUG_SON*/ } /*--------trouver un candidat à un associe_snd et le reserve*/ long pre_associe_snd(void) { int i; /*trouver une association libre...*/ i=0; for (i=0;ifree=TRUE; ((voice_description*)voice)->pbValid=NULL; } /*-------libere une voie Hi*/ void desassocie_snd(long voice) { if (((voice_description*)voice)->pbValid!=NULL) { *(((voice_description*)voice)->pbValid)=FALSE; ((voice_description*)voice)->pbValid=NULL; } ((voice_description*)voice)->free=TRUE; } /*brise la reference de SNDPLAY vers SOUND3D*/ void invalidate_ptrvalid_snd(long voice) { ((voice_description*)voice)->pbValid=NULL; } /*-------associe une voie Hi à la voie Low retournee et à la ressource justifiant la voie Hi (pas celle justifiant la voie Low)*/ /* en profite pour faire une carbage-nettoyage*/ long associe_snd(long id_asso,long voice_sxd,tduRefRes res,long prio,SndBool* valid,SndBool transition) { int i; voice_description* voice_local;/*syn. de &voice_snd[i]*/ /*nettoyage des voies reattribuees trop vite*/ for (i=0,voice_local=&voice_snd[0];ifree==FALSE) && (((voice_local->voice_sxd==C_PLAY_FAILED) && (voice_local->association_running==FALSE)) || ((voice_sxd!=C_PLAY_FAILED) && (voice_local->voice_sxd==voice_sxd) && (res.pstPtr->eType==voice_local->res.pstPtr->eType)) || (!voice_local->bValid))) {/*double attribution frauduleuse=l'ancienne doit etre detruite*/ desassocie_snd((long)voice_local); } } /*creer la nouvelle association*/ if (voice_sxd!=C_PLAY_FAILED) { ((voice_description*)id_asso)->voice_sxd=voice_sxd; ((voice_description*)id_asso)->res=res; /* ((voice_description*)id_asso)->prio=prio;*/ ((voice_description*)id_asso)->free=FALSE; ((voice_description*)id_asso)->association_running=FALSE; ((voice_description*)id_asso)->bValid=TRUE; ((voice_description*)id_asso)->pbValid=valid; ((voice_description*)id_asso)->bTransition=transition; ((voice_description*)id_asso)->lPauseInstance=0; if (((voice_description*)id_asso)->pbValid) *(((voice_description*)id_asso)->pbValid)=TRUE; if (res.pstPtr!=SND_RES_FANTOME.pstPtr) { /* ((voice_description*)id_asso)->fnPause=a_fnPauseFunc[res.pstPtr->eType];*/ /* ((voice_description*)id_asso)->fnResume=a_fnResumeFunc[res.pstPtr->eType];*/ /* ((voice_description*)id_asso)->fnSetParam=a_fnSetParamFunc[res.pstPtr->eType];*/ /* ((voice_description*)id_asso)->fnStop=a_fnStopFunc[res.pstPtr->eType];*/ /* ((voice_description*)id_asso)->fnGetPos=a_fnGetPosFunc[res.pstPtr->eType];*/ /* ((voice_description*)id_asso)->fnTestIsPlaying=a_fnTestIsPlayingFunc[res.pstPtr->eType];*/ } else { /* ((voice_description*)id_asso)->fnPause=NULL;*/ /* ((voice_description*)id_asso)->fnResume=NULL;*/ /* ((voice_description*)id_asso)->fnSetParam=NULL;*/ /* ((voice_description*)id_asso)->fnStop=NULL;*/ /* ((voice_description*)id_asso)->fnGetPos=NULL;*/ /* ((voice_description*)id_asso)->fnTestIsPlaying=NULL;*/ } return (long)(id_asso); } else { ((voice_description*)id_asso)->free=TRUE; ((voice_description*)id_asso)->pbValid=NULL; return C_PLAY_FAILED; } } /**************************************************************/ /********** Gestion des SWITCH */ /**************************************************************/ /*---------------------------------------------------------------- Trouver une association libre et la reserve retourne l'id de l'association candidate -----------------------------------------------------------------*/ /* long pre_associe_switch() { int i; //trouver une association libre... i=0; for (i=0;ifree=TRUE; if (((switch_description*)voice)->pbValid) *(((switch_description*)voice)->pbValid)=FALSE; } //-------associe une voie Hi à la voie Low retournee et à la ressource justifiant la voie Hi (pas celle justifiant la voie Low) // Entrees:voice=id de l'asso à creer (retourne par un precedent appel à pre_associe) // voice_snd=voie bas-niveau à associee // res_switch=resource switch associee // res_current=resource bas-niveau activee // prio=prio du PlaySnd originel // valid=à mettre à FALSE si le switch se desactive // Sortie:id effectif de l'asso long associe_switch(long voice,long par_voice_snd,tduRefRes res_switch,tduRefRes res_current,long prio,SndBool *valid) { switch_description *switch_asso; int i; //----garbage collector for (i=0,switch_asso=&switch_snd[0];ifree) && (((switch_asso->voice_snd==par_voice_snd) && (switch_asso->res_current.pstPtr->Id==res_current.pstPtr->Id)) || (!switch_asso->bValid))) { desassocie_switch((long)switch_asso); } } //--------------- if (par_voice_snd!=C_PLAY_FAILED) { //creer la nouvelle association ((switch_description*)voice)->free=FALSE; ((switch_description*)voice)->voice_snd=par_voice_snd; ((switch_description*)voice)->res_switch=res_switch; ((switch_description*)voice)->res_current=res_current; ((switch_description*)voice)->prio=prio; ((switch_description*)voice)->bValid=TRUE; ((switch_description*)voice)->pbValid=valid; return voice; } else { ((switch_description*)voice)->free=TRUE; return C_PLAY_FAILED; } } */ #ifndef DISABLE_SPLIT /**************************************************************/ /********** Gestion des SPLIT */ /**************************************************************/ /*ajouter une plage invalide à un split actif*/ active_plage* add_active_plage(long voice) { p_active_plage plage; plage=SND_fn_pvMallocSndEx(E_ucSndBlockMain,sizeof(active_plage)); SNDLST2_M_DynamicInitElement(plage); plage->pRange=NULL; SNDLST2_M_DynamicAddTail(&(((split_description*)voice)->pList),plage); return plage; } /*supprimer une plage invalide à un split actif*/ void sup_active_plage(p_active_plage plage) { SNDLST2_M_DynamicIsolate(plage); SND_fn_vFreeSndEx(E_ucSndBlockMain,plage); } /*supprimer un split invalide*/ void desassocie_split(long voice) { ((split_description*)voice)->free=TRUE; if (((split_description*)voice)->pbValid) { *(((split_description*)voice)->pbValid)=FALSE; ((split_description*)voice)->pbValid=NULL; } } /*-------associe une voie split à une voie SND*/ /* Entrees:res_split=resource split associee*/ /* prio=prio du PlaySnd originel*/ /* valid=à mettre à FALSE si le split se desactive*/ /* Sortie:id effectif de l'asso*/ long associe_split(tduRefRes res_split,long prio,SndBool *valid) { split_description *voice; p_active_plage plage,next_plage; int i,j; /*----garbage collector*/ for (i=0,voice=&split_snd[0];ifree) { SNDLST2_M_DynamicForEachMovingElementOf( &voice->pList, plage, next_plage, j) { if (!plage->bValid) sup_active_plage(plage); } } } /*trouver une association libre...*/ for (i=0;ifree=FALSE; voice->res_split=res_split; voice->prio=prio; voice->pbValid=valid; SNDLST2_M_DynamicInitAnchor(&voice->pList); return (long)voice; } /*obtenir les parametres dynamiques pour une plage*/ void get_plage_param(tdstRangeSplitMem* range,SoundParam* par,SoundParam* par_plage) { SND_fn_vCopySoundParam(par_plage,par); par_plage->iFlags|=(/*C_SOUNDPARAM_COEF_VOL | */C_SOUNDPARAM_COEF_FREQ); par_plage->Freq=SND_fn_rMulRealRealSnd(par->Freq,range->rCoefPitch); if ((par->Freq<=range->rPitchA) || (par->Freq>=range->rPitchD)) { par_plage->ucVol=0; return; } if ((par->Freq>=range->rPitchB) && (par->Freq<=range->rPitchC)) { par_plage->ucVol=(unsigned char)(((int)par->ucVol*(int)range->ucVolume)>>7); return; } if ((par->FreqrPitchB)/* && (par->Freq>range->rPitchA)*/) { par_plage->ucVol=(unsigned char)SND_fn_rMulRealRealSnd(par->Freq-range->rPitchA,range->rCoefMagAB); return; } if ((par->Freq>range->rPitchC)/* && (par->FreqrPitchD)*/) { par_plage->ucVol=(unsigned char)SND_fn_rMulRealRealSnd(par->Freq-range->rPitchD,range->rCoefMagCD); return; } } /*obtenir le nombre de plages actives*/ long get_active_plage(long voice) { p_active_plage plage; int i; SNDLST2_M_DynamicForEachElementOf(&((split_description*)voice)->pList, plage, i) {/*pour chacune des voies actuellement effectivement active */ } return i; } #define NB_RANGE_WISHED_MAX 10 /*----raj des plages d'un split*/ long raj_active_plage(long voice,SoundParam* par) { int i,j; tduRefRes res_split; p_active_plage plage,next_plage; tdstRangeSplitMem* range; tdstRangeSplitMem* range_wished[NB_RANGE_WISHED_MAX]; p_active_plage checked_range[NB_RANGE_WISHED_MAX]; int nb_range_wished=0; SoundParam *p_par_plage; #ifdef NB_MICRO_MAX SoundParam par_plage; #endif #ifdef NB_MICRO_MAX p_par_plage=&par_plage; par_plage.iNbLinks=par->iNbLinks; #else p_par_plage=SND_fn_pCreateSoundParam(par->iNbLinks); #endif if ((voice==C_PLAY_FAILED) || ((split_description*)voice)->free) return 0; res_split=((split_description*)voice)->res_split; /*etablir la liste des ranges qui doivent etre actifs*/ SNDLST2_M_StaticForEachElementOf( &(res_split.pstPtr->uRes.stSplit.stRangeList), range, i) { if ((range->rPitchA<=par->Freq) && (range->rPitchD>=par->Freq)) { range_wished[nb_range_wished++]=range; } } /*init checked_range*/ for (i=0;ipList) , plage, next_plage, i) {/*pour chacune des voies actuellement effectivement active */ j=0; while ((plage->pRange!=range_wished[j]) && (jbValid) { plage->bValid=FALSE; SND_fn_vStopSnd(plage->voice_snd); } sup_active_plage(plage); } else checked_range[j]=plage; } /*lancement des nouvelles voies + raj des voies toujours actives*/ for (i=0;ibValid) checked_range[i]->bValid=SND_fn_bSetParamSnd(checked_range[i]->voice_snd,p_par_plage); else sup_active_plage(checked_range[i]); } else {/*nouvelle plage*/ plage=add_active_plage(voice); plage->pRange=range_wished[i]; get_plage_param(plage->pRange,par,p_par_plage); plage->voice_snd=SND_fn_lPlaySnd(range_wished[i]->uRes,p_par_plage,((split_description*)voice)->prio,NULL,0,&(plage->bValid)); } } #ifndef NB_MICRO_MAX SND_fn_vDestroySoundParam(p_par_plage); #endif return nb_range_wished; } #endif /*DISABLE_SPLIT*/ /*************************************************************/ /********** Fonctions publiques ****************************/ /*************************************************************/ /*---------------------------------------------------*/ /*----initialize a BlockMem and make it operational*/ /*----initialize a BlockMem and make it operational*/ /* void SND_fn_vLoadResFromDiskSnd(tdstBlockResourceDisk* disk,tdstBlockResourceMem* mem) { switch (disk->eType) { case TYPE_SAMPLE: SND_fn_vLoadResFromDiskSxd(disk,mem); break; case TYPE_MIDI: SND_fn_vLoadResFromDiskMidi(disk,mem); break; default: //no binaries data ->convert is sufficient SND_fn_vConvertOneResDiskToMem(disk,mem,NULL); } } */ #if !defined(NO_ACP_SCRIPT) /*this function must be defined in Script/Hybrid or DLL mode*/ /* ***********************************************************************/ /* * SND_fn_bLoadResFromDiskScript: **/ /* * Initializes a BlocResourceMem according to a BlockResourceDisk, **/ /* * with respect to the script mode. **/ /* ***********************************************************************/ SndBool SND_fn_bLoadResScriptSnd(tdstBlockResourceDisk* disk,tdstBlockResourceMem* mem) { /*init minimunm pour le mode fake*/ mem->eType=disk->eType; switch (disk->eType) { case TYPE_SAMPLE: return(SND_fn_bLoadResScriptSxd(disk,mem)); break; case TYPE_MIDI: return(SND_fn_bLoadResScriptMidi(disk,mem)); break; #ifndef DISABLE_CD case TYPE_CDAUDIO: return(SND_fn_bLoadResScriptCd(disk,mem)); break; #endif #ifndef DISABLE_SEQUENCE case TYPE_SEQUENCE: return(SND_fn_bLoadResScriptSeq(disk,mem)); break; #endif case TYPE_SWITCH: return(SND_fn_bLoadResScriptSwitch(disk,mem)); break; #ifndef DISABLE_SPLIT case TYPE_SPLIT: return(SND_fn_bLoadResScriptSplit(disk,mem)); break; #endif case TYPE_THEME: return(SND_fn_bLoadResScriptTheme(disk,mem)); break; case TYPE_RANDOM: return(SND_fn_bLoadResScriptRandom(disk,mem)); break; default: /* ERROR! UNKNOWN RES TYPE;*/ SND_M_DisplayError(E_uwSndInvalidTypeOfResource,""); return FALSE; break; } } #endif #ifndef NO_ACP_LDBIN /* ***************************************************************************/ /* * SND_fn_bLoadResFromDiskBinary: **/ /* * Initializes a BlocResourceMem according to a BlockResourceDisk, **/ /* * with respect to the Binary mode. **/ /* * Returns true if the associated data must be freed after load(SoundXd) **/ /* ***************************************************************************/ SndBool SND_fn_bLoadResBinarySnd(tdstBlockResourceDisk* disk,tdstBlockResourceMem* mem,char *pDataBloc) { /*init minimunm pour le mode fake*/ mem->eType=disk->eType; switch (disk->eType) { case TYPE_SAMPLE: return(SND_fn_bLoadResBinarySxd(disk,mem,pDataBloc)); break; case TYPE_MIDI: return(SND_fn_bLoadResBinaryMidi(disk,mem,pDataBloc)); break; #ifndef DISABLE_CD case TYPE_CDAUDIO: return(SND_fn_bLoadResBinaryCd(disk,mem,pDataBloc)); break; #endif #ifndef DISABLE_SEQUENCE case TYPE_SEQUENCE: return(SND_fn_bLoadResBinarySeq(disk,mem,pDataBloc)); break; #endif case TYPE_SWITCH_OLD: return(SND_fn_bLoadResBinarySwitchOld(disk,mem,pDataBloc)); break; case TYPE_SWITCH: return(SND_fn_bLoadResBinarySwitch(disk,mem,pDataBloc)); break; #ifndef DISABLE_SPLIT case TYPE_SPLIT: return(SND_fn_bLoadResBinarySplit(disk,mem,pDataBloc)); break; #endif #ifndef DISABLE_THEME case TYPE_THEME: return(SND_fn_bLoadResBinaryTheme(disk,mem,pDataBloc)); break; #endif case TYPE_RANDOM: return(SND_fn_bLoadResBinaryRandom(disk,mem,pDataBloc)); break; default: /* ERROR! UNKNOWN RES TYPE;*/ SND_M_DisplayError(E_uwSndInvalidTypeOfResource,""); return FALSE; break; } } #endif /* NO_ACP_LDBIN*/ /*----stop all low-level resources for the block resource to allow call to SND_fn_vUnLoadResSnd*/ void SND_fn_vStopBeforeUnLoadResSnd(tdstBlockResourceMem* mem) { int i; for (i=0;ieType) { case TYPE_SAMPLE: SND_fn_vUnLoadResSxd(mem); break; #ifndef DISABLE_MIDI case TYPE_MIDI: SND_fn_vUnLoadResMidi(mem); break; #endif #ifndef DISABLE_THEME case TYPE_THEME: SND_fn_vUnLoadResTheme(mem); break; #endif } mem->eType=TYPE_INVALID; } #ifndef DISABLE_SPLIT /*--- init des champs du block tdstRangeSplitMem charge*/ void SND_fn_vInitRangeSplit(tdstRangeSplitMem* pRange) { if (pRange->rPitchB-pRange->rPitchA!=0) pRange->rCoefMagAB=SND_fn_rDivRealRealSnd(pRange->ucVolume,pRange->rPitchB-pRange->rPitchA); else pRange->rCoefMagAB=M_IntToRealSnd(1); if (pRange->rPitchC-pRange->rPitchD!=0) pRange->rCoefMagCD=SND_fn_rDivRealRealSnd(pRange->ucVolume,pRange->rPitchC-pRange->rPitchD); else pRange->rCoefMagCD=M_IntToRealSnd(1); } /*--- gestion des ressource Split*/ long SND_fn_lPlaySplit(tduRefRes num_res,SoundParam* par,long prio,SND_td_pfn_vSoundCallback fn_callback,long par_callback,SndBool* valid) { long voice; long nb_active_plage; snd_assert(num_res.pstPtr->eType==TYPE_SPLIT); voice=associe_split(num_res,prio,valid); nb_active_plage=raj_active_plage(voice,par); if (!nb_active_plage && !num_res.pstPtr->uRes.stSplit.bStayActive) {/*aucune voie active->desactivation de la voie*/ desassocie_split(voice); return C_PLAY_FAILED; } else return voice; } SndBool SND_CALL SND_fn_bSetParamSplit(long voice,SoundParam* par) { long nb_active_plage; nb_active_plage=raj_active_plage(voice,par); if (!nb_active_plage && !((split_description*)voice)->res_split.pstPtr->uRes.stSplit.bStayActive) {/*aucune voie active->desactivation de la voie*/ desassocie_split(voice); return FALSE; } else return voice; } SndBool SND_CALL SND_fn_bTestIsPlayingSplit(long voice) { if (!get_active_plage(voice) && !((split_description*)voice)->res_split.pstPtr->uRes.stSplit.bStayActive) return FALSE; else return TRUE; } void SND_CALL SND_fn_vStopSplit(long voice) { p_active_plage plage,next_plage; int i; SNDLST2_M_DynamicForEachMovingElementOf(&((split_description*)voice)->pList, plage, next_plage, i) {/*pour chacune des voies actuellement effectivement active */ if (plage->bValid) { plage->bValid=FALSE; SND_fn_vStopSnd(plage->voice_snd); } sup_active_plage(plage); } desassocie_split(voice); } void SND_CALL SND_fn_vPauseSplit(long voie) { } void SND_CALL SND_fn_vResumeSplit(long voie) { } void SND_fn_vRemoveCallbackSplit(long voie) { } void SND_fn_vConvertResDiskToMemSplit(tdstBlockResourceDisk* disk,tdstBlockResourceMem* mem,void* ptrBegin) { mem->Id=disk->Id; mem->eType=disk->eType; mem->eStorage=disk->eStorage; mem->ucVolume=disk->ucVolume; mem->bIsLoaded=TRUE; /*partie specifique au type de ressource*/ mem->uRes.stSplit.ulNbRanges = disk->uRes.stSplit.ulNbRanges; mem->uRes.stSplit.bStayActive= disk->uRes.stSplit.bStayActive; } #ifndef NO_ACP_SCRIPT SndBool SND_fn_bLoadResScriptSplit(tdstBlockResourceDisk *disk,tdstBlockResourceMem *mem) { SND_fn_vConvertResDiskToMemSplit(disk,mem,NULL); return TRUE; } #endif #ifndef NO_ACP_LDBIN SndBool SND_fn_bLoadResBinarySplit(tdstBlockResourceDisk *_pBRDisk,tdstBlockResourceMem *_pBRMem,char *pDataBloc) { tdstRangeSplitMem *pRangeArray,*pRange; int iPos; /* Convert the ulDataOffset member to a pointer:*/ pRangeArray=(tdstRangeSplitMem *)(pDataBloc + _pBRDisk->ulDataOffset); /* Set pointers to range list:*/ /*SNDLST2_M_StaticSetFirstElement(&_pBRMem->uRes.stSplit.stRangeList,pRangeArray);*/ SNDLST2_M_StaticSetMember(&_pBRMem->uRes.stSplit.stRangeList,hFirstElement,pRangeArray); /*SNDLST2_M_StaticSetMember( &_pBRMem->uRes.stSplit.stRangeList, hFirstElement, pRangeArray);*/ SNDLST2_M_StaticSetMember(&_pBRMem->uRes.stSplit.stRangeList, lNumberOfElements, _pBRDisk->uRes.stSplit.ulNbRanges); /* Reset pointers in range:*/ SNDLST2_M_StaticForEachElementOf( &_pBRMem->uRes.stSplit.stRangeList, pRange, iPos) { pRange->uRes.pstPtr=SND_fn_pGetBinRes(pRange->uRes.Id); SND_fn_vInitRangeSplit(pRange); } SND_fn_vConvertResDiskToMemSplit(_pBRDisk,_pBRMem,NULL); return FALSE; } #endif /* NO_ACP_LDBIN*/ /*---------------------------------------------------------*/ /* GetPos: retourne la position "theorique" de la ressource*/ /* exprime en seconde depuis le debut*/ /* different du temps absolu (car pitch, derive..)*/ /* Entree: voie concernee*/ /* Sortie: temps en S (SndReal)*/ /*----------------------------------------------------------*/ SndReal SND_CALL SND_fn_rGetPosSplit(long voie) { return SND_C_POS_UNKNOWN; } /*---------------------------------------------------------*/ /* 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_CALL SND_fn_rGetLengthSplit(long voie) { return SND_C_POS_UNKNOWN; } SndBool SND_fn_bSetResourceStaticVolumeSplit(tdstBlockResourceMem* pstRes,unsigned char ucVolume) { pstRes->ucVolume=ucVolume; return TRUE; } #endif /*DISABLE_SPLIT*/ /*---------------- fonctions publiques generales ------------------*/ void pre_initSnd() { int i; /*----*/ for (i=0;ieType) { case TYPE_SAMPLE: voice_sxd=SND_fn_lPlaySxd(res,par,prio,fn_callback,par_callback); break; case TYPE_MIDI: voice_sxd=SND_fn_lPlayMidi(res,par,prio,fn_callback,par_callback); break; #ifndef DISABLE_CD case TYPE_CDAUDIO: voice_sxd=SND_fn_lPlayCD(res,par,prio,fn_callback,par_callback); break; #endif #ifndef DISABLE_SEQUENCE case TYPE_SEQUENCE: voice_sxd=SND_fn_lPlaySeq(res,par,prio,fn_callback,par_callback,&((voice_description*)pre_voice_snd)->bValid); break; #endif #ifndef DISABLE_SPLIT case TYPE_SPLIT: voice_sxd=SND_fn_lPlaySplit(res,par,prio,fn_callback,par_callback,&((voice_description*)pre_voice_snd)->bValid); break; #endif #ifndef DISABLE_THEME case TYPE_THEME: voice_sxd=SND_fn_lPlayTheme(C_PLAY_FAILED,res,par,prio,fn_callback,par_callback,&((voice_description*)pre_voice_snd)->bValid); break; #endif case TYPE_RANDOM: voice_sxd=SND_fn_lPlayRandom(res,par,prio,fn_callback,par_callback); break; case TYPE_SWITCH: voice_sxd=SND_fn_lPlaySwitch(res,par,prio,fn_callback,par_callback); break; case TYPE_THEME_OLD:/*obsolete*/ case TYPE_SWITCH_OLD:/*obsolete*/ default: SND_M_DisplayError(E_uwSndInvalidTypeOfResource,""); voice_sxd=C_PLAY_FAILED; } return associe_snd(pre_voice_snd,voice_sxd,res,prio,valid,FALSE); } /*---------------------------------------------------------*/ /* SetParamSnd: modifier les parametres sonores d'une ressource*/ /* Entrees:voie=voie associee à la ressource*/ /* par=nouveaux parametres*/ /* Sortie:FALSE si ressource treminee, TRUE sinon*/ /*----------------------------------------------------------*/ SndBool SND_CALL SND_fn_bSetParamSnd(long voie,SoundParam* par) { SndBool ret; ret=(*a_fnFunc[((voice_description*)voie)->res.pstPtr->eType].pfnSetParam)(((voice_description*)voie)->voice_sxd,par); /* ret=((voice_description*)voie)->fnSetParam(((voice_description*)voie)->voice_sxd,par);*/ if (ret==FALSE) desassocie_snd(voie); return ret; } /*-----------------------------------------------------*/ /* TestIsPlayingSnd: test si uneressource est terminee*/ /* Entree:voie=voie associee à la ressource*/ /* Sortie:FALSE si ressource terminee, TRUE sinon*/ /*-------------------------------------------------------*/ SndBool SND_fn_bTestIsPlayingSnd(long voie) { SndBool ret; ret=(*a_fnFunc[((voice_description*)voie)->res.pstPtr->eType].pfnTestIsPlaying)(((voice_description*)voie)->voice_sxd); /* ret=((voice_description*)voie)->fnTestIsPlaying(((voice_description*)voie)->voice_sxd);*/ if (ret==FALSE) desassocie_snd(voie); return ret; } /*------------------------------------------------------*/ /* StopSnd: stopper une ressource*/ /* Entree:voie=voie asociee à la ressource*/ /* Sortie:neant*/ /*-------------------------------------------------------*/ void SND_CALL SND_fn_vStopSnd(long voie) { if (!((voice_description*)voie)->free) //check if voice has not yet been stopped (*a_fnFunc[((voice_description*)voie)->res.pstPtr->eType].pfnStop)(((voice_description*)voie)->voice_sxd); desassocie_snd(voie); return; } /*------------------------------------------------------*/ /* PauseSnd: suspendre une ressource*/ /* Entree:voie=voie asociee à la ressource*/ /* Sortie:neant*/ /*-------------------------------------------------------*/ void SND_CALL SND_fn_vPauseSnd(long voie) { if ((voie != 0) && (((voice_description*)voie)->res.pstPtr != NULL)) (*a_fnFunc[((voice_description*)voie)->res.pstPtr->eType].pfnPause)(((voice_description*)voie)->voice_sxd); /* ((voice_description*)voie)->fnPause(((voice_description*)voie)->voice_sxd);*/ } /*------------------------------------------------------*/ /* ResumeSnd: reprendre une ressource*/ /* Entree:voie=voie asociee à la ressource*/ /* Sortie:neant*/ /*-------------------------------------------------------*/ void SND_CALL SND_fn_vResumeSnd(long voie) { (*a_fnFunc[((voice_description*)voie)->res.pstPtr->eType].pfnResume)(((voice_description*)voie)->voice_sxd); /* ((voice_description*)voie)->fnResume(((voice_description*)voie)->voice_sxd);*/ } /*--------------------------------------------------*/ /* RemoveCallbackSnd: annule une callback en attent*/ /* Entree:voies sur laquelle la callback est en attent*/ /*---------------------------------------------------*/ void SND_fn_vRemoveCallbackSnd(long voie) { switch (((voice_description*)voie)->res.pstPtr->eType) { case TYPE_SAMPLE: SND_fn_vRemoveCallbackSxd(((voice_description*)voie)->voice_sxd); break; case TYPE_MIDI: SND_fn_vRemoveCallbackMidi(((voice_description*)voie)->voice_sxd); break; #ifndef DISABLE_CD case TYPE_CDAUDIO: SND_fn_vRemoveCallbackCD(((voice_description*)voie)->voice_sxd); break; #endif #ifndef DISABLE_SEQUENCE case TYPE_SEQUENCE: SND_fn_vRemoveCallbackSeq(((voice_description*)voie)->voice_sxd); break; #endif #ifndef DISABLE_SPLIT case TYPE_SPLIT: SND_fn_vRemoveCallbackSplit(((voice_description*)voie)->voice_sxd); break; #endif #ifndef DISABLE_THEME case TYPE_THEME: SND_fn_vRemoveCallbackTheme(((voice_description*)voie)->voice_sxd); break; #endif case TYPE_SWITCH: SND_fn_vRemoveCallbackSwitch(((voice_description*)voie)->voice_sxd); break; case TYPE_RANDOM: SND_fn_vRemoveCallbackRandom(((voice_description*)voie)->voice_sxd); break; case TYPE_SWITCH_OLD: default: SND_M_DisplayError(E_uwSndInvalidTypeOfResource,""); break; } return; } void SND_fn_vPauseAllSnd(void) { voice_description* voie; int i; for (i=0,voie=&voice_snd[0];ibValid && !voie->free && !voie->lPauseInstance) { voie->lPauseInstance=g_lCurrentGlobalPauseInstance; if (voie->bTransition) SND_fn_vPauseTransitionSnd((long)voie); else SND_fn_vPauseSnd((long)voie); } } g_lCurrentGlobalPauseInstance++; } void SND_fn_vResumeAllSnd(void) { voice_description* voie; int i; g_lCurrentGlobalPauseInstance--; for (i=0,voie=&voice_snd[0];ibValid && !voie->free && (voie->lPauseInstance<=g_lCurrentGlobalPauseInstance)) { voie->lPauseInstance=0; if (voie->bTransition) SND_fn_vResumeTransitionSnd((long)voie); else SND_fn_vResumeSnd((long)voie); } } } /*------------------------------------------------------*/ /* SetSoundVolumeSnd: changer le volume des ressources sample*/ /* Entree:new_vol=nouveau volume (format MIDI)*/ /* Sortie:neant*/ /*-------------------------------------------------------*/ void SND_fn_vSetSoundVolumeSnd(char new_vol) { SND_fn_vSetSoundVolumeSxd(new_vol); } /*------------------------------------------------------*/ /* GetSoundVolumeSnd: obtenir le volume des ressources sample*/ /* Entree:neant*/ /* Sortie:volume au format midi*/ /*-------------------------------------------------------*/ unsigned char SND_fn_ucGetSoundVolumeSnd(void) { return SND_fn_ucGetSoundVolumeSxd(); } /*------------------------------------------------------*/ /* SetStereoSnd: mise en stereo des sons de sorties*/ /* Entree:TRUE pour passer en stereo, FALSE pour mono*/ /* Sortie:neant*/ /*-------------------------------------------------------*/ void SND_fn_vSetStereoSnd(SndBool active) { /*SND_fn_vSetStereoMusic(active);*/ SND_fn_vSetStereoSxd(active); } /*------------------------------------------------------*/ /* GetStereoSnd: obtenir le mode stereo*/ /* Entree:neant*/ /* Sortie:TRUE si sortie stereo, FALSE si mono*/ /*-------------------------------------------------------*/ SndBool SND_fn_bGetStereoSnd(void) { return SND_fn_bGetStereoSxd(); } /*------------------------------------------------------*/ /* IsMusicPlayingSnd: obtenir le mode stereo*/ /* Entree:neant*/ /* Sortie:TRUE s'il y a theme actuellement en cours, FALSE sinon*/ /*-------------------------------------------------------*/ SndBool SND_fn_bIsMusicPlayingSnd(void) { return SND_fn_bAnyPlayingTheme(); } /*------------------------------------------------------*/ /* SetReevrseStereoSnd: inverse la steraoeo*/ /* Entree:neant*/ /*-------------------------------------------------------*/ void SND_fn_vSetReverseStereoSnd(SndBool active) { SND_fn_vSetReverseStereoSxd(active); } /*------------------------------------------------------*/ /* GetStereoSnd: obtenir l'orientation de la stereo*/ /* Entree:neant*/ /* Sortie:TRUE si stereo normale, FALSE si inverse*/ /*-------------------------------------------------------*/ SndBool SND_fn_bGetReverseStereoSnd(void) { return SND_fn_bGetReverseStereoSxd(); } /*------------------------------------------------------*/ /* TestInitSnd: test la fin de l'init asynchrone*/ /* Entree:neant*/ /* Sortie:FALSE tant que l'init n'est pas finie*/ /*-------------------------------------------------------*/ SndBool SND_fn_bTestInitSnd(void) { return (SND_fn_bTestInitSxd() #ifndef DISABLE_CD && SND_fn_bTestInitCD() #endif && SND_fn_bTestInitMidi()); } /*------------------------------------------------------*/ /* DesInitSnd: desiniter le module de traitement des ressources*/ /* Entree:neant*/ /* Sortie:neant*/ /*-------------------------------------------------------*/ void SND_fn_vDesInitSnd(void) { #ifndef DISABLE_THEME SND_fn_vDesInitTheme(); #endif #ifndef DISABLE_SEQUENCE SND_fn_vDesInitSeq(); #endif #ifndef DISABLE_RECORD SND_fn_vDesInitRecord(); #endif #ifndef DISABLE_CD if (g_iInitCD==C_INIT_OK) SND_fn_vDesInitCD(); #endif if (g_iInitMidi==C_INIT_OK) SND_fn_vDesInitMidi(); if (g_iInitSxd==C_INIT_OK) SND_fn_vDesInitSxd(); } /*------------------------------------------------------*/ /* InitBnkSnd: initialiser une banque de ressources*/ /* Entree:num=designation de la banque*/ /* Sortie:code de retour(C_INIT_FAILED,C_INIT_RUNNING ou C_INIT_OK*/ /*-------------------------------------------------------*/ int SND_fn_iInitBnkSnd(long num) { /* init_music=SND_fn_iInitBnkMusic(num); if (init_music==C_INIT_FAILED) { SND_fn_vDesInitBnkSxd(num); return C_INIT_FAILED; } if ((init_music==C_INIT_RUNNING) || (init_sxd==C_INIT_RUNNING)) return C_INIT_RUNNING; */ return C_INIT_OK; } /*------------------------------------------------------*/ /* TestInitBnkSnd:tester la fin de l'init asynchrone d'une banque*/ /* Entree:num=designation de labanque en cours de chargement*/ /* Sortie:FALSE tant que la banque n'est pas operationnelle*/ /*-------------------------------------------------------*/ SndBool SND_fn_bTestInitBnkSnd(long num) { return TRUE; } /*------------------------------------------------------*/ /* DesInitBnkSnd: relacher une banque*/ /* Entree:num=designation de la banque*/ /* Sortie:neant*/ /*-------------------------------------------------------*/ void SND_fn_vDesInitBnkSnd(long num) { } /*------------------------------------------------------*/ /* DesInitAllBnkSnd: relacher toutes les banques*/ /* Entree:neant*/ /* Sortie:neant*/ /*-------------------------------------------------------*/ void SND_fn_vDesInitAllBnkSnd(void) { } /*------------------------------------------------------*/ /* SetEffectSnd: installer un effet sonore*/ /* Entree:id=designation de l'effet*/ /* Sortie:neant*/ /*-------------------------------------------------------*/ void SND_fn_vSetEffectSnd(long id) { SND_fn_vSetEffectSxd(id); } /*------------------------------------------------------*/ /* CreateMicroSnd: ajouter un micro à la liste*/ /* Entree:sndID=id associe au micro*/ /* par=parametres du micro*/ /* Sortie:neant*/ /*-------------------------------------------------------*/ long SND_fn_lCreateMicroSnd(MicroParam *par) { return SND_fn_lCreateMicroSxd(par); } /*------------------------------------------------------*/ /* DestroyMicroSnd: retirer un micro à la liste*/ /* Entree:sndID=id associe au micro*/ /* Sortie:neant*/ /*-------------------------------------------------------*/ void SND_fn_vDestroyMicroSnd(long sndId) { SND_fn_vDestroyMicroSxd(sndId); } /*------------------------------------------------------*/ /* SetMicroParamSnd: modifier les parametres d'un micro */ /* Entree:sndID=id associe au micro*/ /* par=parametres du micro*/ /* Sortie:neant*/ /*-------------------------------------------------------*/ void SND_fn_vSetMicroParamSnd(long sndId,MicroParam *par) { SND_fn_vSetMicroParamSxd(sndId,par); } /******************** THEMES ********************************************/ /*------------------------------------------------------------------------*/ /* PlayTransitionSnd:lance un theme*/ /* Entrees:FirstRes=ressource de la 1° part*/ /* NextRes=ressource prevue pour la prochaine transition*/ /* transition_callback=fct à appeler à chaque tra,sition*/ /* Retour=id du theme*/ /*------------------------------------------------------------------------*/ long SND_fn_lPlayTransitionSnd(tduRefRes FirstRes,tduRefRes NextRes,SND_td_pfn_vSoundCallback transition_callback,long param_callback,SoundParam* par) { long voice_sxd; long pre_voice_snd; if ((pre_voice_snd=pre_associe_snd())==C_PLAY_FAILED) return C_PLAY_FAILED; if (FirstRes.pstPtr == NULL) return C_PLAY_FAILED; switch (FirstRes.pstPtr->eType) { #ifndef DISABLE_THEME_WAVE case TYPE_SAMPLE: voice_sxd=SND_fn_lPlayTransitionExSxd(FirstRes,NextRes,transition_callback,param_callback,par); break; #endif /* DISABLE_THEME_WAVE*/ #ifndef DISABLE_THEME_MIDI case TYPE_MIDI: voice_sxd=SND_fn_lPlayTransitionMidi(FirstRes,NextRes,transition_callback,param_callback,par); break; #endif /* DISABLE_THEME_MIDI*/ default: SND_M_DisplayError(E_uwSndInvalidTypeOfResource,""); voice_sxd=C_PLAY_FAILED; break; } return associe_snd(pre_voice_snd,voice_sxd,FirstRes,0,NULL,TRUE); } SndBool SND_fn_bSetParamTransitionSnd(long voice,SoundParam *par) { SndBool ret; switch (((voice_description*)voice)->res.pstPtr->eType) { #ifndef DISABLE_THEME_WAVE case TYPE_SAMPLE: ret=SND_fn_bSetParamTransitionSxd(((voice_description*)voice)->voice_sxd,par); break; #endif /* DISABLE_THEME_WAVE*/ #ifndef DISABLE_THEME_MIDI case TYPE_MIDI: ret=SND_fn_bSetParamTransitionMidi(((voice_description*)voice)->voice_sxd,par); break; #endif /* DISABLE_THEME_MIDI*/ default: SND_M_DisplayError(E_uwSndInvalidTypeOfResource,""); ret=FALSE; break; } if (ret==FALSE) desassocie_snd(voice); return ret; } /*------------------------------------------------------------------------*/ /* SetNextTransitionSnd:modifie la ressource prevue pour untheme actif*/ /* Entrees:voice=voie du theme*/ /* NewRes=ressource prevue à la prochaine transition*/ /* Retour=TRUE si OK,FALSE si theme HS*/ /*------------------------------------------------------------------------*/ SndBool SND_fn_bSetNextTransitionSnd(long voice,tduRefRes new_res) { SndBool ret; switch (((voice_description*)voice)->res.pstPtr->eType) { #ifndef DISABLE_THEME_WAVE case TYPE_SAMPLE: ret=SND_fn_bSetNextTransitionSxd(((voice_description*)voice)->voice_sxd,new_res); break; #endif /* DISABLE_THEME_WAVE*/ #ifndef DISABLE_THEME_MIDI case TYPE_MIDI: ret=SND_fn_bSetNextTransitionMidi(((voice_description*)voice)->voice_sxd,new_res); break; #endif /* DISABLE_THEME_MIDI*/ default: SND_M_DisplayError(E_uwSndInvalidTypeOfResource,""); ret=FALSE; break; } /* code de retour non defini if (ret==FALSE) desassocie_snd(voice); */ ((voice_description*)voice)->res.pstPtr=new_res.pstPtr; return ret; } SndBool SND_fn_bDoTransitionWithFadeSnd(long voice,tduRefRes new_res) { SndBool ret; switch (((voice_description*)voice)->res.pstPtr->eType) { #ifndef DISABLE_THEME_WAVE case TYPE_SAMPLE: ret=SND_fn_bDoTransitionWithFadeSxd(((voice_description*)voice)->voice_sxd,new_res); break; #endif /* DISABLE_THEME_WAVE*/ #ifndef DISABLE_THEME_MIDI case TYPE_MIDI: ret=SND_fn_bDoTransitionWithFadeMidi(((voice_description*)voice)->voice_sxd,new_res); break; #endif /* DISABLE_THEME_MIDI*/ default: SND_M_DisplayError(E_uwSndInvalidTypeOfResource,""); ret=FALSE; break; } /* code de retour non defini if (ret==FALSE) desassocie_snd(voice); */ ((voice_description*)voice)->res.pstPtr=new_res.pstPtr; return ret; } SndBool SND_fn_bDoTransitionWithFadeSnd2( long voice, tduRefRes new_res, SndReal rDuration ) { register voice_description* pstVoice; SndBool ret; pstVoice = (voice_description*)voice; switch( pstVoice->res.pstPtr->eType ) { #ifndef DISABLE_THEME_WAVE case TYPE_SAMPLE: ret = SND_fn_bDoTransitionWithFadeSxd2( pstVoice->voice_sxd, new_res, rDuration ); break; #endif /* DISABLE_THEME_WAVE*/ #ifndef DISABLE_THEME_MIDI case TYPE_MIDI: ret = SND_fn_bDoTransitionWithFadeMidi2( pstVoice->voice_sxd, new_res, rDuration ); break; #endif /* DISABLE_THEME_MIDI*/ default: SND_M_DisplayError(E_uwSndInvalidTypeOfResource,""); ret = FALSE; break; } /* code de retour non defini if (ret==FALSE) desassocie_snd(voice); */ return ret; } /*------------------------------------------------------------------------*/ /* Stoppe brutalement un theme en cours*/ /* Entrees:voice=voie du theme*/ /* Retour:neant*/ /*------------------------------------------------------------------------*/ void SND_fn_vStopTransitionSnd(long voice) { if (!((voice_description*)voice)->free) {//check if voice has not yet been stopped switch (((voice_description*)voice)->res.pstPtr->eType) { #ifndef DISABLE_THEME_WAVE case TYPE_SAMPLE: SND_fn_vStopTransitionSxd(((voice_description*)voice)->voice_sxd); break; #endif /* DISABLE_THEME_WAVE*/ #ifndef DISABLE_THEME_MIDI case TYPE_MIDI: SND_fn_vStopTransitionMidi(((voice_description*)voice)->voice_sxd); break; #endif /* DISABLE_THEME_MIDI*/ default: SND_M_DisplayError(E_uwSndInvalidTypeOfResource,""); break; } } desassocie_snd(voice); return; } /*------------------------------------------------------------------------*/ /* Resume un theme en cours*/ /* Entrees:voice=voie du theme*/ /* Retour:neant*/ /*------------------------------------------------------------------------*/ void SND_fn_vResumeTransitionSnd(long voice) { switch (((voice_description*)voice)->res.pstPtr->eType) { #ifndef DISABLE_THEME_WAVE case TYPE_SAMPLE: SND_fn_vResumeTransitionSxd(((voice_description*)voice)->voice_sxd); break; #endif /* DISABLE_THEME_WAVE*/ #ifndef DISABLE_THEME_MIDI case TYPE_MIDI: SND_fn_vResumeTransitionMidi(((voice_description*)voice)->voice_sxd); break; #endif /* DISABLE_THEME_MIDI*/ default: SND_M_DisplayError(E_uwSndInvalidTypeOfResource,""); break; } } /*------------------------------------------------------------------------*/ /* Pauseun theme en cours*/ /* Entrees:voice=voie du theme*/ /* Retour:neant*/ /*------------------------------------------------------------------------*/ void SND_fn_vPauseTransitionSnd(long voice) { switch (((voice_description*)voice)->res.pstPtr->eType) { #ifndef DISABLE_THEME_WAVE case TYPE_SAMPLE: SND_fn_vPauseTransitionSxd(((voice_description*)voice)->voice_sxd); break; #endif /* DISABLE_THEME_WAVE*/ #ifndef DISABLE_THEME_MIDI case TYPE_MIDI: SND_fn_vPauseTransitionMidi(((voice_description*)voice)->voice_sxd); break; #endif /* DISABLE_THEME_MIDI*/ default: SND_M_DisplayError(E_uwSndInvalidTypeOfResource,""); break; } } /*------------------------------------------*/ /* relache-reprise a chaud des drivers*/ /*-------------------------------------------*/ void SND_fn_vReleaseDriverSnd(void) { #ifndef DISABLE_CD SND_fn_vReleaseDriverCD(); #endif SND_fn_vReleaseDriverMidi(); SND_fn_vReleaseDriverSxd(); } void SND_fn_vRestoreDriverSnd(void) { SND_fn_vRestoreDriverSxd(); SND_fn_vRestoreDriverMidi(); #ifndef DISABLE_CD SND_fn_vRestoreDriverCD(); #endif } void SND_fn_vForceReleaseDriverSnd(void) { SND_fn_vForceReleaseDriverSxd(); } void SND_fn_vForceRestoreDriverSnd(void) { SND_fn_vForceRestoreDriverSxd(); } /*------------------------------------------*/ /* obtenir la position courante de la voie */ /* different du temps abslou (derive, pitch ..)*/ /*-------------------------------------------*/ SndReal SND_CALL SND_fn_rGetPosSnd(long voie) { if (((voice_description*)voie)->bValid) return (*a_fnFunc[((voice_description*)voie)->res.pstPtr->eType].pfnGetPos)(((voice_description*)voie)->voice_sxd); /* return ((voice_description*)voie)->fnGetPos(((voice_description*)voie)->voice_sxd);*/ else return SND_C_POS_ENDED; } /*---------------------------------------------------------*/ /* 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_CALL SND_fn_rGetLengthSnd(long voie) { if (((voice_description*)voie)->bValid) switch (((voice_description*)voie)->res.pstPtr->eType) { case TYPE_SAMPLE: return SND_fn_rGetLengthSxd(((voice_description*)voie)->voice_sxd); break; case TYPE_MIDI: return SND_fn_rGetLengthMidi(((voice_description*)voie)->voice_sxd); break; #ifndef DISABLE_CD case TYPE_CDAUDIO: return SND_fn_rGetLengthCD(((voice_description*)voie)->voice_sxd); break; #endif #ifndef DISABLE_SEQUENCE case TYPE_SEQUENCE: return SND_fn_rGetLengthSeq(((voice_description*)voie)->voice_sxd); break; #endif #ifndef DISABLE_SPLIT case TYPE_SPLIT: return SND_fn_rGetLengthSplit(((voice_description*)voie)->voice_sxd); break; #endif #ifndef DISABLE_THEME case TYPE_THEME: return SND_fn_rGetLengthTheme(((voice_description*)voie)->voice_sxd); break; #endif case TYPE_RANDOM: return SND_fn_rGetLengthRandom(((voice_description*)voie)->voice_sxd); break; case TYPE_SWITCH: return SND_fn_rGetLengthSwitch(((voice_description*)voie)->voice_sxd); break; case TYPE_SWITCH_OLD: default: SND_M_DisplayError(E_uwSndInvalidTypeOfResource,""); return SND_C_LENGTH_UNKNOWN; break; } else return SND_C_LENGTH_UNKNOWN; } /*---------------------------------------------------------*/ /* GetTargetLabel: retourne le label designant la tareget*/ /* Entree: name=nom cible*/ /* nb_char=taille maxi de la cible*/ /*----------------------------------------------------------*/ void SND_fn_vGetTargetLabelSnd(char* name,int nb_char) { SND_fn_vGetTargetLabelSxd(name,nb_char); } void SND_fn_vSetupTargetSnd(void) { SND_fn_vSetupTargetSxd(); } SndBool SND_fn_bCanSetupTargetSnd(void) { return SND_fn_bCanSetupTargetSxd(); } #ifndef DISABLE_BUFFER_CLIENT long SND_fn_lCreateNewBufferSnd(unsigned long nb_samples,unsigned short uwResolution,unsigned short uwNbChannels,unsigned long ulFreq,SoundParam* par,td_pfn_vRefreshBufferClient callback,long user_id) { return SND_fn_lCreateNewBufferSxd(nb_samples,uwResolution,uwNbChannels,ulFreq,par,callback,user_id); } void SND_fn_vDeleteBufferSnd(long id_buffer) { SND_fn_vDeleteBufferSxd(id_buffer); } void SND_fn_vPauseBufferSnd(long id_buffer) { SND_fn_vPauseBufferSxd(id_buffer); } void SND_fn_vResumeBufferSnd(long id_buffer) { SND_fn_vResumeBufferSxd(id_buffer); } SndReal SND_fn_rGetPosBufferSnd(long id_buffer) { return SND_fn_rGetPosBufferSxd(id_buffer); } long SND_fn_lCreateNewBufferExSnd(SND_tdstFormat* pformat,SND_tdstCallback* pCallback,SoundParam* par,long user_id) { return SND_fn_lCreateNewBufferExSxd(pformat,pCallback,par,user_id); } long SND_fn_lGetPosBufferExSnd(long id_buffer) { return SND_fn_lGetPosBufferExSxd(id_buffer); } long SND_fn_lPushBufferExSnd(long id_buffer,SND_tdstStackBuffer* pStack) { return SND_fn_lPushBufferExSxd(id_buffer,pStack); } void SND_fn_vSetParamBufferSnd(long id_buffer,SoundParam* par) { SND_fn_vSetParamBufferSxd(id_buffer,par); } #endif /* DISABLE_BUFFER_CLIENT*/ void SND_fn_vSynchroSnd() { SND_fn_vSynchroSxd(); #ifndef DISABLE_CD SND_fn_vSynchroCD(); #endif SND_fn_vSynchroMidi(); #ifdef DREAMCAST sdSysServer(); #endif } SndBool SND_fn_bCheckVersionResourceSnd(tdstBlockResourceDisk* disk) { switch (disk->eType) { case TYPE_SAMPLE: return SND_fn_bCheckVersionResourceSxd(disk); break; case TYPE_MIDI: return SND_fn_bCheckVersionResourceMidi(disk); break; #ifndef DISABLE_CD case TYPE_CDAUDIO: return SND_fn_bCheckVersionResourceCD(disk); break; #endif default: return TRUE; break; } } /*********************************************************************** SND_fn_tduGetLowestResourceSnd: get the lowest resource associated with an other one (ie get effective resource choosen by a SWITCH) In: uHighRes=high level resource (ie SWITCH) par=dynamic parameters to be used for evaluation eval=TRUE if new evaluation nedded for RANDOM; FALSE if used previously done evaluation Out:low-level resource associated ******************************************************************************/ tduRefRes SND_fn_tduGetLowestResourceSnd(tduRefRes uHighRes,SoundParam* par,SndBool eval) { if (uHighRes.pstPtr==SND_C_RES_FANTOME_PTR) return uHighRes; switch (uHighRes.pstPtr->eType) { case TYPE_SAMPLE: case TYPE_MIDI: case TYPE_CDAUDIO: case TYPE_SEQUENCE: case TYPE_THEME: return uHighRes; case TYPE_RANDOM: return SND_fn_tduGetLowestResourceRandom(uHighRes,par,eval); case TYPE_SWITCH: return SND_fn_tduGetLowestResourceSwitch(uHighRes,par,eval); case TYPE_SPLIT: case TYPE_INVALID: default: SND_M_DisplayError(E_uwSndInvalidTypeOfResource,""); return SND_RES_FANTOME; } } long SND_fn_lGetNbVoiceOptimumSnd() { return SND_fn_lGetNbVoiceOptimumSxd(); } long SND_fn_lGetNbVoiceWishedSnd() { return SND_fn_lGetNbVoiceWishedSxd(); } void SND_fn_vSetNbVoiceWishedSnd(long nb) { SND_fn_vSetNbVoiceWishedSxd(SND_fn_eGetMainFormatSxd(),nb); } /*----------------------------------------*/ #ifndef DISABLE_RECORD /*----------SNDREC*/ SndBool SND_fn_bTestFormatRecordSnd(SND_tdstFormat* pformat,int flags) { #ifndef DISABLE_RECORD return SND_fn_bTestFormatRecord(pformat,flags); #else return FALSE; #endif } long SND_fn_lCreateBufferRecordSnd(SND_tdstFormat* pformat,SND_tdstCallback* pCallback) { #ifndef DISABLE_RECORD return SND_fn_lCreateBufferRecord(pformat,pCallback); #else return C_PLAY_FAILED; #endif } SndBool SND_fn_bIsBufferFullDuplexRecordSnd(long id_buffer) { #ifndef DISABLE_RECORD return SND_fn_bIsBufferFullDuplexRecord(id_buffer); #else return FALSE; #endif } SndBool SND_fn_bStartRecordSnd(long id_buffer) { #ifndef DISABLE_RECORD return SND_fn_bStartRecord(id_buffer); #else return FALSE; #endif } void SND_fn_vStopRecordSnd(long id_buffer) { #ifndef DISABLE_RECORD SND_fn_vStopRecord(id_buffer); #endif } SndBool SND_fn_bIsWorkingRecordSnd(long id_buffer) { #ifndef DISABLE_RECORD return SND_fn_bIsWorkingRecord(id_buffer); #else return FALSE; #endif } long SND_fn_lPushBufferToRecordSnd(long id_buffer,void* ptr,int size_ptr) { #ifndef DISABLE_RECORD return SND_fn_lPushBufferToRecord(id_buffer,ptr,size_ptr); #else return FALSE; #endif } unsigned char SND_fn_ucGetInstantVuMeterRecordSnd(void) { #ifndef DISABLE_RECORD return SND_fn_ucGetInstantVuMeterRecord(); #else return 0; #endif } #endif tduRefRes SND_fn_uGenerateResourceSnd(void* data,SND_tdstFormat* pformat,SndBool loop) { #if !defined(GAMECONSOLE) && !defined(GENERIC) tdstBlockResourceMem* pstResMem; tdstBlockResourceDisk stResDisk; #endif tduRefRes uRes; #if !defined(GAMECONSOLE) && !defined(GENERIC) memset(&stResDisk,0,sizeof(stResDisk)); stResDisk.eType=TYPE_SAMPLE; switch (pformat->eZip) { case SAMPLE_PCM: stResDisk.ulDataSize=pformat->uFormat.stPCM.ulNbSamples; if (pformat->uFormat.stPCM.uwResolution==16) stResDisk.ulDataSize<<=1; if (pformat->uFormat.stPCM.uwNbChannels==2) stResDisk.ulDataSize<<=1; break; default: SND_M_DisplayError(E_uwSndInvalidTypeOfResource,""); return SND_RES_FANTOME; } stResDisk.eStorage=TYPE_MEGAFILE; stResDisk.ulDataOffset=0; stResDisk.ucVolume=127; stResDisk.uRes.stSample.bPitchable=TRUE; stResDisk.uRes.stSample.bVolable=TRUE; stResDisk.uRes.stSample.bPanable=TRUE; stResDisk.uRes.stSample.bSpacable=TRUE; stResDisk.uRes.stSample.bReverbable=TRUE; stResDisk.uRes.stSample.bStream=FALSE; stResDisk.uRes.stSample.bLoop=loop; stResDisk.uRes.stSample.ulStartLoop=0; stResDisk.uRes.stSample.ulLoopLength=stResDisk.ulDataSize; stResDisk.uRes.stSample.ulFreq=pformat->uFormat.stPCM.ulFreq; stResDisk.uRes.stSample.uwResolution=pformat->uFormat.stPCM.uwResolution; stResDisk.uRes.stSample.uwNbChannels=pformat->uFormat.stPCM.uwNbChannels; stResDisk.uRes.stSample.eZip=SAMPLE_PCM; pstResMem=SND_fn_pvMallocSndEx(E_ucSndBlockMain,sizeof(tdstBlockResourceMem)); memset(pstResMem,0,sizeof(pstResMem)); SND_fn_vConvertResDiskToMemSxd(&stResDisk,pstResMem,data); uRes.pstPtr=pstResMem; #else uRes.pstPtr=SND_C_RES_FANTOME_PTR; #endif return uRes; } void SND_fn_vDestroyResourceSnd(tduRefRes uRes) { #if !defined(GAMECONSOLE) && !defined(GENERIC) SND_fn_vStopBeforeUnLoadResSnd(uRes.pstPtr); SND_fn_vUnLoadResSnd(uRes.pstPtr); SND_fn_vFreeSndEx(E_ucSndBlockMain,uRes.pstPtr); #endif } /*********************************************************************** SND_fn_bSetResourceStaticVolumeSnd: change the volume for a specific resource given its Editor ID ******************************************************************************/ SndBool SND_fn_bSetResourceStaticVolumeSnd(tdstBlockResourceMem* pstRes,unsigned char ucVolume) { if (pstRes!=NULL) { switch (pstRes->eType) { case TYPE_SAMPLE: return SND_fn_bSetResourceStaticVolumeSxd(pstRes,ucVolume); break; #ifndef DISABLE_MIDI case TYPE_MIDI: return SND_fn_bSetResourceStaticVolumeMidi(pstRes,ucVolume); break; #endif #ifndef DISABLE_CD case TYPE_CDAUDIO: return SND_fn_bSetResourceStaticVolumeCD(pstRes,ucVolume); break; #endif #ifndef DISABLE_SEQUENCE case TYPE_SEQUENCE: return SND_fn_bSetResourceStaticVolumeSeq(pstRes,ucVolume); break; #endif case TYPE_SWITCH: return SND_fn_bSetResourceStaticVolumeSwitch(pstRes,ucVolume); break; #ifndef DISABLE_SPLIT case TYPE_SPLIT: return SND_fn_bSetResourceStaticVolumeSplit(pstRes,ucVolume); break; #endif case TYPE_RANDOM: return SND_fn_bSetResourceStaticVolumeRandom(pstRes,ucVolume); break; #ifndef DISABLE_THEME case TYPE_THEME: return SND_fn_bSetResourceStaticVolumeTheme(pstRes,ucVolume); break; #endif } } return FALSE; } #endif /* NO_ACP_SOUND*/