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

1036 lines
31 KiB
C

/******************************************************************
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 <process.h>
#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) ulFadeSize=ulCurrentSizeLeft;
}
else
{
if (ulCurrentSizeLeft>=ulFadeSize)
{ /* enough time left in this part to fade:*/
bFadeInPart=TRUE;
}
else
{ /* We'll fade on two parts:*/
if ((ulCurrentSizeLeft+pNextVoice->ulFinalSize)<ulFadeSize)
ulFadeSize=ulCurrentSizeLeft+pNextVoice->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;
}