/****************************************************************** CPA-SND : Sound module MPEG ressources ******************************************************************/ #include "SNDinc.h" #include "sndres.h" #include "sndmpeg.h" #if defined(_DLL_COMPILATION_MODE) #include "snddll.h" #else #include "sndxd.h" #endif #ifndef DISABLE_MPEG #include "mpeg.hxx" #include #endif /*DISABLE_MPEG*/ #ifndef DISABLE_MPEG extern unsigned char ucVolume[128]; static unsigned long ulIdBufferClient; extern SndBool bInMPEGDecomp; static SndBool bIsClientPaused; static SndBool bIsMPEGReleased; static SndBool bIsMPEGOk=FALSE; extern SND_tdstMPEGVoice MPEGvoices[(kNumVoice+1)*2]; extern SND_tdstMPEGVoice *pSwapVoice[2]; /* Pointeur sur les deux fichiers MPEG à décoder pour un thème*/ tdstBlockResourceMem* MPEGCurrentRes[(kNumVoice+1)*2]; #define M_SND_MPEG_BUFFERFREQ 44100 /* * FADE OF 10 SECONDS EXPRESSED IN SNDREAL */ #define M_FADE_DURATION_MPEG M_IntToRealSnd( 4 ) /*thread lancée à chaque occurence de callback*/ /*int WINAPI start_callback_thread(DWORD *param)*/ #if defined(__WATCOMC__) && (__WATCOMC__<1100) void start_callback_threadMPEG(callback_paramMPEG *callback_par) #else void __cdecl start_callback_threadMPEG(callback_paramMPEG *callback_par) #endif { (callback_par->fct)(callback_par->param); GlobalFree(callback_par); /*return 0;*/ } /*fct appelée par genere en cas de Callback*/ /**buffer_dispo dans esi*/ void __stdcall start_callbackMPEG(SND_tdstMPEGVoice* pVoice) { /* BUFFER_DISPO *buffer;*/ /* DWORD id_thread;*/ callback_paramMPEG *callback_par; callback_par=GlobalAlloc(GMEM_FIXED,sizeof(callback_paramMPEG)); callback_par->fct=pVoice->pfnCallBack; callback_par->param=pVoice->ulParam; /*CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)start_callback_thread,param,0,&id_thread);*/ #if defined(__WATCOMC__) && (__WATCOMC__<1100) _beginthread(start_callback_threadMPEG,NULL,0,(void*)callback_par); #else _beginthread(start_callback_threadMPEG,0,(void*)callback_par); #endif } #endif /*DISABLE_MPEG*/ long SND_CALL SND_fn_lPlayMPEG(tduRefRes num_sample,SampleParam *par,long prio,SND_td_pfn_vSoundCallback fn_callback,long par_callback) { #ifndef DISABLE_MPEG short wVolume; SND_tdstMPEGVoice *pVoice; tdstSampleMemory *pMemory; tdstSampleStreaming *pStream; tdstTypeSampleMem *pSample = &(num_sample.pstPtr->uRes.stSample); if (bIsMPEGOk) { if (bIsClientPaused) { SND_fn_vResumeBufferSxd(ulIdBufferClient); bIsClientPaused = FALSE; } /*_RPT0(_CRT_WARN,"PLAY---------------\n");*/ if (pSample->bStream) { pStream = &(pSample->uData.stStream); pVoice = SND_fn_pSampleAllocateMPEGVoiceFile(pStream->szFileName,pStream->ulOffsetFirst); if (pVoice) { if (pSample->bVolable) wVolume = (par->ucVol*num_sample.pstPtr->ucVolume)>>7; else wVolume = num_sample.pstPtr->ucVolume; pVoice->ucVolume = num_sample.pstPtr->ucVolume; pVoice->ucCurrentVolume = (unsigned char)wVolume; pVoice->ucVolumeIndex = ucVolume[wVolume]; pVoice->bVolable = pSample->bVolable; if (pVoice->pAssociatedVoice) { pVoice->pAssociatedVoice->ucVolume = num_sample.pstPtr->ucVolume; pVoice->pAssociatedVoice->ucCurrentVolume = (unsigned char)wVolume; pVoice->pAssociatedVoice->ucVolumeIndex = ucVolume[wVolume]; pVoice->pAssociatedVoice->bVolable = pSample->bVolable; } if (fn_callback) { pVoice->pfnCallBack = fn_callback; pVoice->ulParam = par_callback; } else pVoice->pfnCallBack = NULL; MPEGCurrentRes[((unsigned long)pVoice-(unsigned long)MPEGvoices)/sizeof(SND_tdstMPEGVoice)]=num_sample.pstPtr; return (long)pVoice; } } else { pMemory = &(pSample->uData.stMem); pVoice = SND_fn_pSampleAllocateMPEGVoiceMem(pMemory->pvPtrFirst,pMemory->ulNbEch); if (pVoice) { if (pSample->bVolable) wVolume = (par->ucVol*num_sample.pstPtr->ucVolume)>>7; else wVolume = num_sample.pstPtr->ucVolume; pVoice->ucVolume = num_sample.pstPtr->ucVolume; pVoice->ucCurrentVolume = (unsigned char)wVolume; pVoice->ucVolumeIndex = ucVolume[wVolume]; pVoice->bVolable = pSample->bVolable; if (pVoice->pAssociatedVoice) { pVoice->pAssociatedVoice->ucVolume = num_sample.pstPtr->ucVolume; pVoice->pAssociatedVoice->ucCurrentVolume = (unsigned char)wVolume; pVoice->pAssociatedVoice->ucVolumeIndex = ucVolume[wVolume]; pVoice->pAssociatedVoice->bVolable = pSample->bVolable; } if (fn_callback) { pVoice->pfnCallBack = fn_callback; pVoice->ulParam = par_callback; } else pVoice->pfnCallBack = NULL; MPEGCurrentRes[((unsigned long)pVoice-(unsigned long)MPEGvoices)/sizeof(SND_tdstMPEGVoice)]=num_sample.pstPtr; return (long)pVoice; } } } else return C_PLAY_FAILED; #endif /*DISABLE_MPEG*/ return C_PLAY_FAILED; } void SND_CALL SND_fn_vRemoveCallbackMPEG(long voice) { #ifndef DISABLE_MPEG SND_tdstMPEGVoice *pVoice; if (voice && voice!=C_PLAY_FAILED) { pVoice = (SND_tdstMPEGVoice*)voice; if (pVoice->pfnCallBack) { pVoice->pfnCallBack = NULL; pVoice->ulParam = 0; } } #endif /*DISABLE_MPEG*/ } SndBool SND_CALL SND_fn_bSetParamMPEG(long voice,SampleParam *par) { #ifndef DISABLE_MPEG SND_tdstMPEGVoice *pVoice; short wInitialVol; if (voice && voice!=C_PLAY_FAILED) { pVoice = (SND_tdstMPEGVoice*)voice; if((!pVoice->bIsPlaying)&&(!pVoice->bIsFinishing)) { SND_fn_bFreeMPEGVoice(pVoice); if (pVoice->pfnCallBack) { start_callbackMPEG(pVoice); } pVoice->pfnCallBack = NULL; return FALSE; } else { /* do modifications...*/ if (pVoice->bVolable) { wInitialVol = pVoice->ucVolume; wInitialVol *= par->ucVol; wInitialVol >>= 7; pVoice->ucCurrentVolume = (unsigned char)wInitialVol; pVoice->ucVolumeIndex = ucVolume[wInitialVol]; if (pVoice->pAssociatedVoice) { pVoice->pAssociatedVoice->ucCurrentVolume = (unsigned char)wInitialVol; pVoice->pAssociatedVoice->ucVolumeIndex = ucVolume[wInitialVol]; } } } } return TRUE; #else return FALSE; #endif /*DISABLE_MPEG*/ } SndBool SND_CALL SND_fn_bTestIsPlayingMPEG(long voice) { #ifndef DISABLE_MPEG SND_tdstMPEGVoice *pVoice; if (voice && voice!=C_PLAY_FAILED) { pVoice = (SND_tdstMPEGVoice*)voice; if((!pVoice->bIsPlaying)&&(!pVoice->bIsFinishing)) { SND_fn_bFreeMPEGVoice(pVoice); if (pVoice->pfnCallBack) { start_callbackMPEG(pVoice); } pVoice->pfnCallBack = NULL; return FALSE; } } return TRUE; #else return FALSE; #endif /*DISABLE_MPEG*/ } void SND_CALL SND_fn_vStopMPEG(long voice) { #ifndef DISABLE_MPEG SND_tdstMPEGVoice *pVoice; if (voice && voice!=C_PLAY_FAILED) { pVoice = (SND_tdstMPEGVoice*)voice; pVoice->bIsPlaying = FALSE; while(bInMPEGDecomp) { Sleep(30); } SND_fn_bFreeMPEGVoice(pVoice); if (pVoice->pfnCallBack) { start_callbackMPEG(pVoice); } pVoice->pfnCallBack = NULL; } #endif /*DISABLE_MPEG*/ } void SND_CALL SND_fn_vPauseMPEG(long voice) { #ifndef DISABLE_MPEG if (!bIsClientPaused) { SND_fn_vPauseBufferSxd(ulIdBufferClient); bIsClientPaused = TRUE; } /* if (voice) { ((SND_tdstMPEGVoice*)voice)->bIsPaused = TRUE; } */ #endif /*DISABLE_MPEG*/ } void SND_CALL SND_fn_vResumeMPEG(long voice) { #ifndef DISABLE_MPEG /*on réactive la voie...*/ /* if (voice) { ((SND_tdstMPEGVoice*)voice)->bIsPaused = FALSE; } */ /*...puis on relance le buffer client*/ if (bIsClientPaused) { SND_fn_vResumeBufferSxd(ulIdBufferClient); bIsClientPaused = FALSE; } #endif /*DISABLE_MPEG*/ } int SND_CALL SND_fn_iInitMPEG(SND_tdstInitStruct *pInitStruct) { #ifndef DISABLE_MPEG SND_tdstFormat formatclient; SND_tdstCallback callback; int i; #if defined(_DLL_COMPILATION_MODE) SND_DllInitEntryPoints_StaticFunctions((HMODULE)pInitStruct->hProcessInstance ); SND_DllInitEntryPoints_WavFunctions(SND_hWavModule); #endif for (i=0;i<(kNumVoice+1)*2;i++) { MPEGCurrentRes[i]=NULL; } if(SND_fn_bInitMPEG()) { if(SND_fn_bStartMPEGEngine()) { formatclient.eZip=SAMPLE_PCM; formatclient.uFormat.stPCM.ulNbSamples=0; /*formatclient.uFormat.stPCM.ulNbSamples=32*kFrameSize;*/ formatclient.uFormat.stPCM.uwResolution=16; formatclient.uFormat.stPCM.uwNbChannels=2; // formatclient.uFormat.stPCM.ulFreq=44100; formatclient.uFormat.stPCM.ulFreq=M_SND_MPEG_BUFFERFREQ; memset(&callback,0,sizeof(callback)); callback.eType=BUFFER_SYNCHRONE; callback.uCallback.CallbackASynchrone=SND_fn_vRefreshMPEG; ulIdBufferClient=SND_fn_lCreateNewBufferExSxd(&formatclient,&callback,NULL,0); /*ulIdBufferClient = SND_fn_lCreateNewBufferSxd(32*kFrameSize,16,2,44100,NULL,SND_fn_vRefreshMPEG,0);*/ /*ulIdBufferClient = SND_fn_lCreateNewBufferSxd(32*kFrameSize,16,2,M_SND_MPEG_BUFFERFREQ,NULL,SND_fn_vRefreshMPEG,0);*/ bIsMPEGReleased = FALSE; bIsClientPaused= FALSE; if (ulIdBufferClient==C_PLAY_FAILED) return FALSE; bIsMPEGOk=TRUE; return TRUE; } } return FALSE; #else return C_INIT_FAILED; #endif /*DISABLE_MPEG*/ } SndBool SND_CALL SND_fn_bTestInitMPEG(void) { #ifndef DISABLE_MPEG return SND_fn_bInitDone(); #else return FALSE; #endif /*DISABLE_MPEG*/ } void SND_CALL SND_fn_vDesInitMPEG(void) { #ifndef DISABLE_MPEG SND_fn_vDeleteBufferSxd(ulIdBufferClient); SND_fn_bDesInitMPEG(); #endif /*DISABLE_MPEG*/ } tduRefRes SND_CALL SND_fn_tdGetResForVoiceMPEG(long voice) { tduRefRes r={0}; return r; } void SND_CALL SND_fn_vConvertResDiskToMemMPEG(tdstBlockResourceDisk *disk ,tdstBlockResourceMem *mem ,void* ptrBegin) { snd_assert(disk->eType==TYPE_SAMPLE); snd_assert(disk->uRes.stSample.eZip==SAMPLE_MPEG); mem->Id=disk->Id; mem->eType=disk->eType; mem->eStorage=disk->eStorage; mem->ucVolume=disk->ucVolume; mem->bIsLoaded=TRUE; mem->uRes.stSample.eZip=SAMPLE_MPEG; #ifndef DISABLE_MPEG /*partie spécifique au type de ressource*/ /**/ mem->uRes.stSample.bPitchable=FALSE; mem->uRes.stSample.bVolable=disk->uRes.stSample.bVolable; mem->uRes.stSample.bPanable=FALSE; mem->uRes.stSample.bSpacable=FALSE; mem->uRes.stSample.bReverbable=FALSE; mem->uRes.stSample.bStream=disk->uRes.stSample.bStream; mem->uRes.stSample.bLoop=FALSE; mem->uRes.stSample.ulInc0=0; mem->uRes.stSample.uwResolution=16; mem->uRes.stSample.uwNbChannels=disk->uRes.stSample.uwNbChannels; if (disk->uRes.stSample.bStream) {/*sample streamé*/ strcpy(mem->uRes.stSample.uData.stStream.szFileName,disk->uRes.stSample.czFileName); mem->uRes.stSample.uData.stStream.ulOffsetFirst=disk->ulDataOffset; mem->uRes.stSample.uData.stStream.ulOffsetLoop=0; mem->uRes.stSample.uData.stStream.ulOffsetLast=disk->ulDataSize; } else {/*sample non streamé*/ mem->uRes.stSample.uData.stMem.ulNbEchLoop=0; mem->uRes.stSample.uData.stMem.ulNbEch=disk->ulDataSize; if (ptrBegin!=NULL) mem->uRes.stSample.uData.stMem.pvPtrFirst=(void*)((unsigned long)ptrBegin/*+disk->ulDataOffset*/); else mem->uRes.stSample.uData.stMem.pvPtrFirst=NULL; } /*le sample est prêt à l'emploi*/ #endif /*DISABLE_MPEG*/ } #if !defined(NO_ACP_SCRIPT) || defined(_DLL_COMPILATION_MODE) /*this function must be defined in Script/Hybrid or DLL mode*/ SndBool SND_CALL SND_fn_bLoadResScriptMPEG(tdstBlockResourceDisk *disk,tdstBlockResourceMem *mem) { #ifndef DISABLE_MPEG void* data; char file_name[256]; unsigned long ulSize; if (!disk->uRes.stSample.bStream) { /* for MMX compatibility size should be mod 8*/ ulSize = disk->ulDataSize; ulSize >>= 3; ulSize++; ulSize <<=3; data=SND_fn_pvMallocSnd(ulSize); SND_fn_vResolveFileName(disk->uRes.stSample.czFileName,file_name); if (!SND_fn_bLoadDataInMem(data,disk->ulDataSize,file_name,disk->ulDataOffset)) { SND_fn_vDisplayError(E_uwSndErrorReadingFile,""); SND_fn_vFreeSnd(data); data=NULL; } } else data=NULL; SND_fn_vConvertResDiskToMemMPEG(disk,mem,data); /*en script, chaque ressources charge ces propres data (on ne tient pas compte de eStorage)*/ mem->eStorage=TYPE_EXTERNAL; return TRUE; #else return FALSE; #endif /*DISABLE_MPEG*/ } #endif SndBool SND_CALL SND_fn_bLoadResBinaryMPEG(tdstBlockResourceDisk *disk,tdstBlockResourceMem *mem,char *pDataBloc) { #ifndef DISABLE_MPEG void* pData; char file_name[256]; unsigned long ulSize; if (!disk->uRes.stSample.bStream) { /* Sample is not streaming: must be really loaded in memory*/ if (disk->eStorage!=TYPE_EXTERNAL) { /* Sample is in the bank: its position is known relatively to the BRMem:*/ pData=(void *)(pDataBloc +disk->ulDataOffset); } else { /* Sample is external: it must be loaded from a file:*/ ulSize = disk->ulDataSize; ulSize >>= 3; ulSize++; ulSize <<=3; pData=SND_fn_pvMallocSnd(ulSize); SND_fn_vResolveFileName(disk->uRes.stSample.czFileName,file_name); if (!SND_fn_bLoadDataInMem(pData,disk->ulDataSize,file_name,disk->ulDataOffset)) { SND_fn_vDisplayError(E_uwSndErrorReadingFile,""); SND_fn_vFreeSnd(pData); pData=NULL; } } } else pData=NULL; /* Sample is streaming*/ SND_fn_vConvertResDiskToMemMPEG(disk,mem,pData); return TRUE; #else return FALSE; #endif /*DISABLE_MPEG*/ } /* void SND_CALL SND_fn_vLoadResFromDiskMPEG(tdstBlockResourceDisk* disk,tdstBlockResourceMem* mem) { #ifndef DISABLE_MPEG void* data; char file_name[256]; unsigned long ulSize; if (!disk->uRes.stSample.bStream) { // for MMX compatibility size should be mod 8 ulSize = disk->ulDataSize; ulSize >>= 3; ulSize++; ulSize <<=3; data=SND_fn_pvMallocSnd(ulSize); SND_fn_vResolveFileName(disk->uRes.stSample.czFileName,file_name); if (!SND_fn_bLoadDataInMem(data,disk->ulDataSize,file_name,0)) { SND_fn_vDisplayError(E_uwSndErrorReadingFile,""); SND_fn_vFreeSnd(data); data=NULL; } } else data=NULL; SND_fn_vConvertResDiskToMemMPEG(disk,mem,data); #endif } */ void SND_CALL SND_fn_vUnLoadResMPEG(tdstBlockResourceMem* mem) { #ifndef DISABLE_MPEG if (!mem->uRes.stSample.bStream) { if ((mem->uRes.stSample.uData.stMem.pvPtrFirst!=NULL) && (mem->eStorage==TYPE_EXTERNAL)) SND_fn_vFreeSnd(mem->uRes.stSample.uData.stMem.pvPtrFirst); } mem->uRes.stSample.uData.stMem.pvPtrFirst=NULL; mem->eType=TYPE_INVALID; #endif } SndBool SND_CALL SND_fn_bIsResLoadedMPEG(tdstBlockResourceMem *mem) { #ifndef DISABLE_MPEG if (mem->uRes.stSample.bStream) return TRUE;/* Streaming sample is always "loaded"*/ else return (mem->uRes.stSample.uData.stMem.pvPtrFirst!=NULL); #else return FALSE; #endif /*DISABLE_MPEG*/ } /* void SND_CALL SND_fn_vSetResUnloadedMPEG(tdstBlockResourceMem *pResMem) { #ifndef DISABLE_MPEG pResMem->uRes.stSample.bStream=FALSE; pResMem->uRes.stSample.uData.stMem.pvPtrFirst=NULL; #endif //DISABLE_MPEG } */ /* THEMES*/ long SND_CALL SND_fn_lPlayTransitionMPEG(tduRefRes FirstRes,tduRefRes NextRes,SND_td_pfn_vSoundCallback transition_callback,long param_callback,SampleParam* par) { #ifndef DISABLE_MPEG short wVolume; SND_tdstMPEGVoice *pVoice; tdstSampleMemory *pMemory; tdstSampleStreaming *pStream; tdstTypeSampleMem *pSample = &(FirstRes.pstPtr->uRes.stSample); snd_assert(FirstRes.pstPtr->uRes.stSample.eZip==SAMPLE_MPEG); snd_assert(NextRes.pstPtr->uRes.stSample.eZip==SAMPLE_MPEG); if (bIsMPEGOk) { /* STOP CURRENT THEME OR MPEG SOUND*/ /*SND_fnvStopAllVoicesMPEGTheme();*/ if (bIsClientPaused) { SND_fn_vResumeBufferSxd(ulIdBufferClient); bIsClientPaused = FALSE; } /* START FIRST VOICE...*/ if (pSample->bStream) { pStream = &(pSample->uData.stStream); pVoice = SND_fn_pSimpleAllocateMPEGVoiceFile(pStream->szFileName,pStream->ulOffsetFirst); if (pVoice) { if (transition_callback) { pVoice->pfnCallBack = transition_callback; pVoice->ulParam = param_callback; } else pVoice->pfnCallBack = NULL; } else return C_PLAY_FAILED; } else { pMemory = &(pSample->uData.stMem); pVoice = SND_fn_pSimpleAllocateMPEGVoiceMem(pMemory->pvPtrFirst,pMemory->ulNbEch); if (pVoice) { if (transition_callback) { pVoice->pfnCallBack = transition_callback; pVoice->ulParam = param_callback; } else pVoice->pfnCallBack = NULL; } else return C_PLAY_FAILED; } /* SET SECOND VOICE...*/ pSample = &(NextRes.pstPtr->uRes.stSample); if (pSample->bStream) { pStream = &(pSample->uData.stStream); pVoice = SND_fn_pAllocateMPEGVoiceFile(pStream->szFileName,pStream->ulOffsetFirst); if (pVoice) { if (transition_callback) { pVoice->pfnCallBack = transition_callback; pVoice->ulParam = param_callback; } else pVoice->pfnCallBack = NULL; } else return C_PLAY_FAILED; } else { pMemory = &(pSample->uData.stMem); pVoice = SND_fn_pAllocateMPEGVoiceMem(pMemory->pvPtrFirst,pMemory->ulNbEch); if (pVoice) { if (transition_callback) { pVoice->pfnCallBack = transition_callback; pVoice->ulParam = param_callback; } else pVoice->pfnCallBack = NULL; } else return C_PLAY_FAILED; } wVolume = par->ucVol;/*NextRes.pstPtr->ucVolume;*/ if (wVolume < 0) wVolume =0; if (wVolume > 127) wVolume = 127; pSwapVoice[0]->ucVolume = (unsigned char)wVolume;/*NextRes.pstPtr->ucVolume;*/ pSwapVoice[0]->ucCurrentVolume = (unsigned char)wVolume; pSwapVoice[0]->ucVolumeIndex = ucVolume[wVolume]; pSwapVoice[1]->ucVolume = (unsigned char)wVolume;/*NextRes.pstPtr->ucVolume;*/ pSwapVoice[1]->ucCurrentVolume = (unsigned char)wVolume; pSwapVoice[1]->ucVolumeIndex = ucVolume[wVolume]; if (pSwapVoice[0]->pAssociatedVoice) { pSwapVoice[0]->pAssociatedVoice->ucVolume = (unsigned char)wVolume;/*NextRes.pstPtr->ucVolume;*/ pSwapVoice[0]->pAssociatedVoice->ucCurrentVolume = (unsigned char)wVolume;/*NextRes.pstPtr->ucVolume;*/ pSwapVoice[0]->pAssociatedVoice->ucVolumeIndex = ucVolume[wVolume]; } if (pSwapVoice[1]->pAssociatedVoice) { pSwapVoice[1]->pAssociatedVoice->ucVolume = (unsigned char)wVolume;/*NextRes.pstPtr->ucVolume;*/ pSwapVoice[1]->pAssociatedVoice->ucCurrentVolume = (unsigned char)wVolume;/*NextRes.pstPtr->ucVolume;*/ pSwapVoice[1]->pAssociatedVoice->ucVolumeIndex = ucVolume[wVolume]; } return 0; } else return C_PLAY_FAILED; #else return C_PLAY_FAILED; #endif /*DISABLE_MPEG*/ } SndBool SND_CALL SND_fn_bSetParamTransitionMPEG(long voice,SampleParam* par) { #ifndef DISABLE_MPEG /*SND_tdstMPEGVoice *pVoice;*/ short wVolume; wVolume = par->ucVol;/*NextRes.pstPtr->ucVolume;*/ if (wVolume < 0) wVolume =0; if (wVolume > 127) wVolume = 127; pSwapVoice[0]->ucVolume = (unsigned char)wVolume;/*NextRes.pstPtr->ucVolume;*/ pSwapVoice[0]->ucCurrentVolume = (unsigned char)wVolume; pSwapVoice[0]->ucVolumeIndex = ucVolume[wVolume]; pSwapVoice[1]->ucVolume = (unsigned char)wVolume;/*NextRes.pstPtr->ucVolume;*/ pSwapVoice[1]->ucCurrentVolume = (unsigned char)wVolume; pSwapVoice[1]->ucVolumeIndex = ucVolume[wVolume]; if (pSwapVoice[0]->pAssociatedVoice) { pSwapVoice[0]->pAssociatedVoice->ucVolume = (unsigned char)wVolume;/*NextRes.pstPtr->ucVolume;*/ pSwapVoice[0]->pAssociatedVoice->ucCurrentVolume = (unsigned char)wVolume;/*NextRes.pstPtr->ucVolume;*/ pSwapVoice[0]->pAssociatedVoice->ucVolumeIndex = ucVolume[wVolume]; } if (pSwapVoice[1]->pAssociatedVoice) { pSwapVoice[1]->pAssociatedVoice->ucVolume = (unsigned char)wVolume;/*NextRes.pstPtr->ucVolume;*/ pSwapVoice[1]->pAssociatedVoice->ucCurrentVolume = (unsigned char)wVolume;/*NextRes.pstPtr->ucVolume;*/ pSwapVoice[1]->pAssociatedVoice->ucVolumeIndex = ucVolume[wVolume]; } return TRUE; #else return FALSE; #endif } tduRefRes SND_g_uFadeRes; SndBool SND_CALL SND_fn_bSetNextTransitionMPEG(long voice,tduRefRes new_res) { #ifndef DISABLE_MPEG /*short wVolume;*/ SND_tdstMPEGVoice *pVoice; tdstSampleMemory *pMemory; tdstSampleStreaming *pStream; tdstTypeSampleMem *pSample = &(new_res.pstPtr->uRes.stSample); snd_assert(new_res.pstPtr->uRes.stSample.eZip==SAMPLE_MPEG); /* char szTemp[256];*/ /* SET THE NEXT MPEG VOICE TO PLAY*/ if (pSample->bStream) { pStream = &(pSample->uData.stStream); pVoice = SND_fn_pAllocateMPEGVoiceFile(pStream->szFileName,pStream->ulOffsetFirst); if (pVoice) { pVoice->bVolable = pSample->bVolable; } else return FALSE; } else { pMemory = &(pSample->uData.stMem); pVoice = SND_fn_pAllocateMPEGVoiceMem(pMemory->pvPtrFirst,pMemory->ulNbEch); if (pVoice) { pVoice->bVolable = pSample->bVolable; } else return FALSE; } return TRUE; #else return FALSE; #endif /*DISABLE_MPEG*/ } SndBool SND_CALL SND_fn_bDoTransitionWithFadeMPEG2( long voice, tduRefRes new_res, SndReal rDuration ) { #ifndef DISABLE_MPEG SND_tdstMPEGVoice *pCurrentVoice,*pNextVoice; unsigned long ulFadeSize,ulCurrentSizeLeft; SndBool bFadeInPart; int iFadeFrameNumber; #ifndef M_FRED_DECREAU _int64 _iFade; #endif if (bIsMPEGOk) { pCurrentVoice=pSwapVoice[0]; pNextVoice=pSwapVoice[1]; bFadeInPart=FALSE; #ifdef M_FRED_DECREAU ulFadeSize=32*2000; /* On voudrait fader sur 1300 miniframes de 32 samples*/ /* ulFadeSize=32*3000; // test avec 3 secondes..*/ #else /* * Estimate the fade duration in sample unit */ pCurrentVoice->rDuration = rDuration; pNextVoice->rDuration = rDuration; _iFade = rDuration; _iFade = M_RealToIntSnd( M_MulIntRealSnd( _iFade, M_SND_MPEG_BUFFERFREQ - 32 * 48 ) ); ulFadeSize = (unsigned long)_iFade; /* * The Fade duration in sample must be a modulo of 32. Because in MPEG data are * decompressed Frame after Frame, and a Frame length is 32 sample long */ ulFadeSize -= ulFadeSize % 32; #endif ulCurrentSizeLeft=pCurrentVoice->ulFinalSize-pCurrentVoice->ulPos; /* Set bFadeInPart and ulFadeTime:*/ if (!pNextVoice->bIsPlaying) { bFadeInPart=TRUE; /* No next part->fade in part!*/ /* Adjust fade time with remaining time:*/ if (ulCurrentSizeLeft=ulFadeSize) { /* enough time left in this part to fade:*/ bFadeInPart=TRUE; } else { /* We'll fade on two parts:*/ if ((ulCurrentSizeLeft+pNextVoice->ulFinalSize)ulFinalSize; bFadeInPart=FALSE; } } /* * Calculate the number of fade frame = iFadeFrameNumber * Volume decrement. Decreament linearly the volume * Set part as fading and fade parameters: */ iFadeFrameNumber=ulFadeSize/32; pCurrentVoice->bIsFading=TRUE; #if M_FRED_DECREAU pCurrentVoice->iFadeIncrement=-((1<<16)/iFadeFrameNumber); #else pCurrentVoice->iFadeIncrement=-(rDuration/iFadeFrameNumber); #endif pCurrentVoice->iFadeVolume=(-pCurrentVoice->iFadeIncrement)*iFadeFrameNumber; if( pCurrentVoice->pAssociatedVoice ) { pCurrentVoice->pAssociatedVoice->bIsFading = TRUE; pCurrentVoice->pAssociatedVoice->rDuration = rDuration; pCurrentVoice->pAssociatedVoice->iFadeIncrement = pCurrentVoice->iFadeIncrement; pCurrentVoice->pAssociatedVoice->iFadeVolume = pCurrentVoice->iFadeVolume; } if (bFadeInPart) { /* OutputDebugString("start of fade: fade in part\n");*/ /* Shorten current voice if necessary:*/ pCurrentVoice->ulFinalSize=pCurrentVoice->ulPos+ulFadeSize; /* Set a new transition with the new_res:*/ SND_fn_bSetNextTransitionMPEG(voice,new_res); SND_g_uFadeRes.pstPtr=NULL; } else { /* Fade in two parts:*/ /* OutputDebugString("start of fade: two parts fade\n");*/ SND_g_uFadeRes=new_res; /* Shorten next voice if necessary:*/ pNextVoice->ulFinalSize=ulFadeSize-ulCurrentSizeLeft; } } return FALSE; #else return FALSE; #endif } SndBool SND_CALL SND_fn_bDoTransitionWithFadeMPEG( long voice, tduRefRes new_res ) { #ifndef DISABLE_MPEG return SND_fn_bDoTransitionWithFadeMPEG2( voice, new_res, M_FADE_DURATION_MPEG ); #endif /*DISABLE_MPEG*/ } void SND_CALL SND_fn_vStopTransitionMPEG(long voice) { #ifndef DISABLE_MPEG SND_fnvStopAllVoicesMPEGTheme(); #endif /*DISABLE_MPEG*/ } void SND_CALL SND_fn_vPauseTransitionMPEG(long voice) { #ifndef DISABLE_MPEG /*pSwapVoice[0]->bIsPaused = TRUE;*/ if (!bIsClientPaused && bIsMPEGOk) { /* pSwapVoice[0]->bIsPaused = TRUE;*/ SND_fn_vPauseBufferSxd(ulIdBufferClient); bIsClientPaused = TRUE; } #endif } void SND_CALL SND_fn_vResumeTransitionMPEG(long voice) { #ifndef DISABLE_MPEG /*pSwapVoice[0]->bIsPaused = FALSE;*/ if (bIsClientPaused && bIsMPEGOk) { /* pSwapVoice[0]->bIsPaused = FALSE;*/ SND_fn_vResumeBufferSxd(ulIdBufferClient); bIsClientPaused = FALSE; } #endif } #ifndef NO_ACP_LDBIN SndBool SND_CALL SND_fn_bCanFreeDataMPEG(void) { return FALSE; } #endif /*-------------------------------------------------- relache-reprise a chaud des drives ---------------------------------------------------------*/ void SND_CALL SND_fn_vReleaseDriverMPEG() { #ifndef DISABLE_MPEG if (!bIsMPEGOk) return; if (bIsMPEGReleased) return; /* FAIRE TOUT CE QU'IL FAUT...*/ bIsMPEGReleased = TRUE; #endif } void SND_CALL SND_fn_vRestoreDriverMPEG() { #ifndef DISABLE_MPEG SndReal rBufferState; if (!bIsMPEGOk) return; if (!bIsMPEGReleased) return; /* FAIRE TOUT CE QU'IL FAUT...*/ rBufferState=SND_fn_rGetPosBufferSxd(ulIdBufferClient); if ((rBufferState==SND_C_POS_ENDED) || (rBufferState==SND_C_POS_UNKNOWN)) /*driver WAV perdu -> MPEG kaput*/ bIsMPEGOk=FALSE; bIsMPEGReleased = FALSE; #endif } /*---------------------------------------------------------*/ /* GetPos: retourne la position "théorique" de la ressource*/ /* exprimé en seconde depuis le début*/ /* différent du temps absolu (car pitch, dérive..)*/ /* Entrée: voie concernée*/ /* Sortie: temps en S (SndReal)*/ /*----------------------------------------------------------*/ SndReal SND_CALL SND_fn_rGetPosMPEG(long voice) { #ifndef DISABLE_MPEG SND_tdstMPEGVoice *pVoice; long temp; if (bIsMPEGOk && voice!=C_PLAY_FAILED && voice) { pVoice = (SND_tdstMPEGVoice*)voice; if((pVoice->bIsPlaying) || (pVoice->bIsFinishing)) { // temp=M_DoubleToRealSnd(((double)pVoice->ulPos/*-32.0*kFrameSize*/-480)/44100.); temp=M_DoubleToRealSnd(((double)pVoice->ulPos/*-32.0*kFrameSize*/-480)/M_SND_MPEG_BUFFERFREQ.); if (temp>0) return temp; else return 0; } } #endif return SND_C_POS_UNKNOWN; } /*---------------------------------------------------------*/ /* GetLength: retourne la durée "théorique" de la ressource*/ /* exprimé en seconde (constant pour une ressource donnée)*/ /* Entrée: voie concernée*/ /* Sortie: durée en S (SndReal)*/ /*----------------------------------------------------------*/ SndReal SND_CALL SND_fn_rGetLengthMPEG(long voice) { #ifndef DISABLE_MPEG SND_tdstMPEGVoice *pVoice; if (voice!=C_PLAY_FAILED && voice) { pVoice = (SND_tdstMPEGVoice*)voice; if(pVoice->bIsPlaying) // return SND_fn_rDivRealRealSnd(pVoice->ulFinalSize,44100); return SND_fn_rDivRealRealSnd(pVoice->ulFinalSize,M_SND_MPEG_BUFFERFREQ); } #endif return SND_C_LENGTH_UNKNOWN; } /*-------------------------------------------------*/ /* Fonction de synchro moteur*/ /* ne sert à rien pour MPEG*/ /*-------------------------------------------------*/ void SND_CALL SND_fn_vSynchroMPEG() { } /*nouveau buffers clients*/ long SND_CALL SND_fn_lCreateNewBufferExMPEG(SND_tdstFormat* pformat,SND_tdstCallback* pCallback,SoundParam* par,long user_id) { return C_PLAY_FAILED; } long SND_CALL SND_fn_lGetPosBufferExMPEG(long id_buffer) { return SND_C_POS_UNKNOWN; } long SND_CALL SND_fn_lPushBufferExMPEG(long id_buffer,SND_tdstStackBuffer* pStack) { return C_PLAY_FAILED; } void SND_CALL SND_fn_vSetDefaultRollOffMPEG(RollOffParam* rolloff) { /*nothing to do in, this version*/ } SndBool SND_CALL SND_fn_bCheckVersionResourceMPEG(tdstBlockResourceDisk *disk) { return TRUE; } SndBool SND_CALL SND_fn_bSetResourceStaticVolumeMPEG(tdstBlockResourceMem* pstRes,unsigned char ucVolume) { #ifndef DISABLE_MPEG SND_tdstMPEGVoice *pVoice; int i; pstRes->ucVolume=ucVolume; for (i=0,pVoice=&MPEGvoices[0];i<(kNumVoice+1)*2;i++,pVoice++) { if (MPEGCurrentRes[i]!=NULL) if (MPEGCurrentRes[i]==pstRes) { MPEGvoices[i].ucVolume=ucVolume; } } #endif /*DISABLE_MPEG*/ return TRUE; }