1074 lines
34 KiB
C++
1074 lines
34 KiB
C++
/*
|
||
// ================================================================
|
||
// MPEG.cxx
|
||
// Ubi Sound Studios
|
||
// 24/03/1997
|
||
// Guillaume Michel
|
||
// ================================================================
|
||
*/
|
||
|
||
|
||
//added by stephane RONSE on 04/29/98
|
||
// must be set FALSE each time a new sound begin
|
||
// will be set to TRUE each time silence beginn(i.e. no more sound are played) and so the SynhtesisBuffer is reinitilized
|
||
SndBool bSynthesisBufferCleaned=TRUE;
|
||
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Description : Init MPEG Engine
|
||
//-------------------------------------------------------------------------
|
||
// MUST BE DONE ONCE AT THE BEGINING OF THE PROGRAM
|
||
//-------------------------------------------------------------------------
|
||
// Input : None
|
||
// Output : SndBool
|
||
//-------------------------------------------------------------------------
|
||
// Creation date : 18/03/97 Author : Guillaume Michel
|
||
//-------------------------------------------------------------------------
|
||
// Modifications :
|
||
// Modification Date : Author :
|
||
//-------------------------------------------------------------------------
|
||
|
||
SndBool SND_fn_bInitMPEG()
|
||
{
|
||
if (!SND_fn_bTestSnd_Processor())
|
||
{
|
||
SND_fn_vDisplayError(E_uwSndBadHostConfiguration,C_PROCESSOR_WANTED);
|
||
return C_INIT_FAILED;
|
||
}
|
||
|
||
#ifdef _PROFILE_MFC_
|
||
QueryPerformanceFrequency(&t0);
|
||
iTotalTime = iNumTime = 0;
|
||
#endif
|
||
|
||
SND_fn_vInitSignalProcessing();
|
||
return (bInitDone = SND_fn_bInitMPEGMemory());
|
||
|
||
}
|
||
|
||
SndBool SND_fn_bInitDone()
|
||
{
|
||
return bInitDone;
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Description : free memory for decrompression...
|
||
//-------------------------------------------------------------------------
|
||
// DO ALL DESALLOC (CALLED ONCE AT THE END OF THE APPLICATION)
|
||
//-------------------------------------------------------------------------
|
||
// Input : voice pointer and number of channel
|
||
// Output : SndBool
|
||
//-------------------------------------------------------------------------
|
||
// Creation date : 18/03/97 Author : Guillaume Michel
|
||
//-------------------------------------------------------------------------
|
||
// Modifications :
|
||
// Modification Date : Author :
|
||
//-------------------------------------------------------------------------
|
||
|
||
SndBool SND_fn_bFreeMPEGMemory(SND_tdstMPEGVoice* pVoice)
|
||
{
|
||
snd_assert(pVoice);
|
||
if (pVoice->pucBitAlloc) {
|
||
SND_fn_vFreeSnd(pVoice->pucBitAlloc);
|
||
pVoice->pucBitAlloc = NULL;
|
||
pVoice->pucScaleFactorPattern = NULL;
|
||
pVoice->pucScaleFactor = NULL;
|
||
}
|
||
if (pVoice->pdDiviseur) {
|
||
SND_fn_vFreeSnd(pVoice->pdDiviseur);
|
||
pVoice->pdDiviseur = NULL;
|
||
pVoice->pdScaleFactor = NULL;
|
||
pVoice->pdSumFactor = NULL;
|
||
}
|
||
if (pVoice->pwSample) {
|
||
SND_fn_vFreeSnd(pVoice->pwSample);
|
||
pVoice->pwSample = NULL;
|
||
}
|
||
pVoice->pfnCallBack = NULL;
|
||
return TRUE;
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Description : Init MPEG Engine before using it
|
||
//-------------------------------------------------------------------------
|
||
//
|
||
//-------------------------------------------------------------------------
|
||
// Input : None
|
||
// Output : None
|
||
//-------------------------------------------------------------------------
|
||
// Creation date : 24/03/97 Author : Guillaume Michel
|
||
//-------------------------------------------------------------------------
|
||
// Modifications :
|
||
// Modification Date : Author :
|
||
//-------------------------------------------------------------------------
|
||
|
||
SndBool SND_fn_bStartMPEGEngine()
|
||
{
|
||
int i;
|
||
SND_tdstMPEGVoice* pVoice;
|
||
|
||
// MPEG Engine INITS
|
||
for (i = 0; i < (kNumVoice+1); i++) {
|
||
pVoice = &MPEGvoices[i];
|
||
pVoice->bIsFree = TRUE;
|
||
pVoice->bIsMuted = FALSE;
|
||
pVoice->bIsPlaying = FALSE;
|
||
|
||
pVoice->bIsFading = FALSE;
|
||
pVoice->iFadeVolume = 0;
|
||
pVoice->iFadeIncrement = 0;
|
||
|
||
|
||
pVoice->bIsPaused = FALSE;
|
||
pVoice->bIsOneShot = FALSE;
|
||
pVoice->bIsSurround = FALSE;
|
||
pVoice->bIsFullSurround = FALSE;
|
||
pVoice->bIsFinishing = FALSE;
|
||
pVoice->ulNumSampleBeforeEnd = 0;
|
||
|
||
SND_fn_bInitBitStream(&(pVoice->bitstream));
|
||
pVoice->pfnCallBack = NULL;
|
||
}
|
||
|
||
pSwapVoice[0] = &MPEGvoices[0]; // playing voice
|
||
pSwapVoice[1] = &MPEGvoices[1]; // waiting voice
|
||
iOffset[0] = iOffset[1] = 64;
|
||
bSwitchPart = FALSE;
|
||
|
||
iMiniFrameTheme=12;
|
||
iIndexTheme=3;
|
||
iMiniFrameSample=12;
|
||
iIndexSample=3;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Description : Open a new voice from File
|
||
//-------------------------------------------------------------------------
|
||
//
|
||
//-------------------------------------------------------------------------
|
||
// Input : filename and number of channel
|
||
// Output : voice pointer
|
||
//-------------------------------------------------------------------------
|
||
// Creation date : 18/03/97 Author : Guillaume Michel
|
||
//-------------------------------------------------------------------------
|
||
// Modifications :
|
||
// Modification Date : Author :
|
||
//-------------------------------------------------------------------------
|
||
|
||
SND_tdstMPEGVoice* SND_fn_pAllocateMPEGVoiceFile(char* pFileName, unsigned long ulOffset)
|
||
{
|
||
int i;
|
||
unsigned long param;
|
||
SND_td_pfn_vSoundCallback cb;
|
||
SND_tdstMPEGVoice* pCurrentVoice;
|
||
|
||
if (pSwapVoice[0]->bIsFree) {
|
||
i = 0; // La voie principale est libre: on d<>marre dessus
|
||
} else {
|
||
// on <20>crase la voie secondaire (imp<6D>ratif th<74>me)
|
||
SND_fn_bFreeMPEGVoice(pSwapVoice[1]);
|
||
i = 1;
|
||
}
|
||
pCurrentVoice = pSwapVoice[i];
|
||
cb = pCurrentVoice->pfnCallBack;
|
||
param = pCurrentVoice->ulParam;
|
||
|
||
if (SND_fn_bOpenBitStreamFile(pCurrentVoice->pRealBitStream,pFileName,ulOffset)) {
|
||
// This voice will be used...
|
||
pCurrentVoice->bIsFree = FALSE;
|
||
//pCurrentVoice->ucVolume = 127;
|
||
//pCurrentVoice->ucVolumeIndex = 0;
|
||
pCurrentVoice->bIsPaused = pCurrentVoice->bIsMuted = FALSE;
|
||
|
||
pCurrentVoice->ulPos = 0;
|
||
pCurrentVoice->ulFinalSize = pCurrentVoice->pRealBitStream->ulFinalSize ;
|
||
|
||
pCurrentVoice->bIsFullSurround = (pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR2');
|
||
pCurrentVoice->bIsSurround = ((pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR2') ||
|
||
(pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR1'));
|
||
|
||
if (pCurrentVoice->bIsSurround) {
|
||
pCurrentVoice->pAssociatedVoice = pCurrentVoice + (kNumVoice+1);
|
||
pCurrentVoice->pAssociatedVoice->bIsPlaying = TRUE;
|
||
//pCurrentVoice->pAssociatedVoice->ucVolume = 127;
|
||
//pCurrentVoice->pAssociatedVoice->ucVolumeIndex = 0;
|
||
pCurrentVoice->pAssociatedVoice->bIsMuted = FALSE;
|
||
} else {
|
||
pCurrentVoice->pAssociatedVoice = NULL;
|
||
}
|
||
|
||
pCurrentVoice->pfnCallBack = cb;
|
||
pCurrentVoice->ulParam = param;
|
||
pCurrentVoice->bIsPlaying = TRUE;
|
||
pCurrentVoice->bIsFinishing = FALSE;
|
||
pCurrentVoice->ulNumSampleBeforeEnd = 0;
|
||
|
||
pCurrentVoice->bIsFading = FALSE;
|
||
pCurrentVoice->iFadeVolume = 0;
|
||
pCurrentVoice->iFadeIncrement = 0;
|
||
|
||
return pCurrentVoice;
|
||
} else return NULL;
|
||
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Description : Open a new voice from memory
|
||
//-------------------------------------------------------------------------
|
||
//
|
||
//-------------------------------------------------------------------------
|
||
// Input : buffer pointer, buffer size, voice pointer and number of channel
|
||
// Output : voice pointer
|
||
//-------------------------------------------------------------------------
|
||
// Creation date : 18/03/97 Author : Guillaume Michel
|
||
//-------------------------------------------------------------------------
|
||
// Modifications :
|
||
// Modification Date : Author :
|
||
//-------------------------------------------------------------------------
|
||
|
||
SND_tdstMPEGVoice* SND_fn_pAllocateMPEGVoiceMem(unsigned char* pBuffer, unsigned long ulSize)
|
||
{
|
||
int i;
|
||
unsigned long param;
|
||
SND_td_pfn_vSoundCallback cb;
|
||
|
||
SND_tdstMPEGVoice* pCurrentVoice;
|
||
|
||
if (pSwapVoice[0]->bIsFree) {
|
||
i = 0;
|
||
} else {
|
||
// on <20>crase la voie secondaire (imp<6D>ratif th<74>me)
|
||
SND_fn_bFreeMPEGVoice(pSwapVoice[1]);
|
||
i = 1;
|
||
}
|
||
pCurrentVoice = pSwapVoice[i];
|
||
cb = pCurrentVoice->pfnCallBack;
|
||
param = pCurrentVoice->ulParam;
|
||
|
||
if (SND_fn_bOpenBitStreamMem(pCurrentVoice->pRealBitStream,pBuffer,ulSize)) {
|
||
// This voice will be used...
|
||
pCurrentVoice->bIsFree = FALSE;
|
||
//pCurrentVoice->ucVolume = 127;
|
||
//pCurrentVoice->ucVolumeIndex = 0;
|
||
pCurrentVoice->bIsPaused = pCurrentVoice->bIsMuted = FALSE;
|
||
|
||
pCurrentVoice->ulPos = 0;
|
||
pCurrentVoice->ulFinalSize = pCurrentVoice->pRealBitStream->ulFinalSize ;
|
||
pCurrentVoice->bIsFullSurround = (pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR2');
|
||
pCurrentVoice->bIsSurround = (pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR2') ||
|
||
(pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR1');
|
||
|
||
if (pCurrentVoice->bIsSurround) {
|
||
pCurrentVoice->pAssociatedVoice = pCurrentVoice + (kNumVoice+1);
|
||
pCurrentVoice->pAssociatedVoice->bIsPlaying = TRUE;
|
||
//pCurrentVoice->pAssociatedVoice->ucVolume = 127;
|
||
//pCurrentVoice->pAssociatedVoice->ucVolumeIndex = 0;
|
||
pCurrentVoice->pAssociatedVoice->bIsMuted = FALSE;
|
||
} else {
|
||
pCurrentVoice->pAssociatedVoice = NULL;
|
||
}
|
||
pCurrentVoice->pfnCallBack = cb;
|
||
pCurrentVoice->ulParam = param;
|
||
pCurrentVoice->bIsPlaying = TRUE;
|
||
pCurrentVoice->bIsFinishing = FALSE;
|
||
pCurrentVoice->ulNumSampleBeforeEnd = 0;
|
||
|
||
pCurrentVoice->bIsFading = FALSE;
|
||
pCurrentVoice->iFadeVolume = 0;
|
||
pCurrentVoice->iFadeIncrement = 0;
|
||
|
||
return pCurrentVoice;
|
||
} else return NULL;
|
||
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Description : Open a new voice from File
|
||
//-------------------------------------------------------------------------
|
||
//
|
||
//-------------------------------------------------------------------------
|
||
// Input : filename and number of channel
|
||
// Output : voice pointer
|
||
//-------------------------------------------------------------------------
|
||
// Creation date : 18/03/97 Author : Guillaume Michel
|
||
//-------------------------------------------------------------------------
|
||
// Modifications :
|
||
// Modification Date : Author :
|
||
//-------------------------------------------------------------------------
|
||
|
||
SND_tdstMPEGVoice* SND_fn_pSimpleAllocateMPEGVoiceFile(char* pFileName, unsigned long ulOffset)
|
||
{
|
||
SND_tdstMPEGVoice* pCurrentVoice;
|
||
|
||
pCurrentVoice = pSwapVoice[0];
|
||
if (!pCurrentVoice->bIsFree) {
|
||
return NULL;
|
||
}
|
||
|
||
|
||
//added by stepahen RONSE on 04/29/98
|
||
bSynthesisBufferCleaned=FALSE;
|
||
|
||
if (SND_fn_bOpenBitStreamFile(pCurrentVoice->pRealBitStream,pFileName, ulOffset)) {
|
||
// This voice will be used...
|
||
pCurrentVoice->bIsFree = FALSE;
|
||
pCurrentVoice->bIsPlaying = TRUE;
|
||
//pCurrentVoice->ucVolume = 127;
|
||
//pCurrentVoice->ucVolumeIndex = 0;
|
||
pCurrentVoice->bIsPaused = pCurrentVoice->bIsMuted = FALSE;
|
||
|
||
pCurrentVoice->bIsFullSurround = (pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR2');
|
||
pCurrentVoice->bIsSurround = (pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR2') ||
|
||
(pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR1');
|
||
|
||
if (pCurrentVoice->bIsSurround) {
|
||
pCurrentVoice->pAssociatedVoice = pCurrentVoice + (kNumVoice+1);
|
||
pCurrentVoice->pAssociatedVoice->bIsPlaying = TRUE;
|
||
//pCurrentVoice->pAssociatedVoice->ucVolume = 127;
|
||
//pCurrentVoice->pAssociatedVoice->ucVolumeIndex = 0;
|
||
pCurrentVoice->pAssociatedVoice->bIsMuted = FALSE;
|
||
} else {
|
||
pCurrentVoice->pAssociatedVoice = NULL;
|
||
}
|
||
pCurrentVoice->ulPos = 0;
|
||
pCurrentVoice->ulFinalSize = pCurrentVoice->pRealBitStream->ulFinalSize ;
|
||
pCurrentVoice->bIsFinishing = FALSE;
|
||
pCurrentVoice->ulNumSampleBeforeEnd = 0;
|
||
|
||
pCurrentVoice->bIsFading = FALSE;
|
||
pCurrentVoice->iFadeVolume = 0;
|
||
pCurrentVoice->iFadeIncrement = 0;
|
||
|
||
return pCurrentVoice;
|
||
} else return NULL;
|
||
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Description : Open a new voice from memory
|
||
//-------------------------------------------------------------------------
|
||
//
|
||
//-------------------------------------------------------------------------
|
||
// Input : buffer pointer, buffer size, voice pointer and number of channel
|
||
// Output : voice pointer
|
||
//-------------------------------------------------------------------------
|
||
// Creation date : 18/03/97 Author : Guillaume Michel
|
||
//-------------------------------------------------------------------------
|
||
// Modifications :
|
||
// Modification Date : Author :
|
||
//-------------------------------------------------------------------------
|
||
|
||
SND_tdstMPEGVoice* SND_fn_pSimpleAllocateMPEGVoiceMem(unsigned char* pBuffer, unsigned long ulSize)
|
||
{
|
||
SND_tdstMPEGVoice* pCurrentVoice;
|
||
|
||
pCurrentVoice = pSwapVoice[0];
|
||
if (!pCurrentVoice->bIsFree) {
|
||
return NULL;
|
||
}
|
||
|
||
//added by stepahen RONSE on 04/29/98
|
||
bSynthesisBufferCleaned=FALSE;
|
||
|
||
if (SND_fn_bOpenBitStreamMem(pCurrentVoice->pRealBitStream,pBuffer,ulSize)) {
|
||
// This voice will be used...
|
||
pCurrentVoice->bIsFree = FALSE;
|
||
pCurrentVoice->bIsPlaying = TRUE;
|
||
//pCurrentVoice->ucVolume = 127;
|
||
//pCurrentVoice->ucVolumeIndex = 0;
|
||
pCurrentVoice->bIsPaused = pCurrentVoice->bIsMuted = FALSE;
|
||
pCurrentVoice->bIsFullSurround = (pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR2');
|
||
pCurrentVoice->bIsSurround = (pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR2') ||
|
||
(pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR1');
|
||
|
||
if (pCurrentVoice->bIsSurround) {
|
||
pCurrentVoice->pAssociatedVoice = pCurrentVoice + (kNumVoice+1);
|
||
pCurrentVoice->pAssociatedVoice->bIsPlaying = TRUE;
|
||
//pCurrentVoice->pAssociatedVoice->ucVolume = 127;
|
||
//pCurrentVoice->pAssociatedVoice->ucVolumeIndex = 0;
|
||
pCurrentVoice->pAssociatedVoice->bIsMuted = FALSE;
|
||
} else {
|
||
pCurrentVoice->pAssociatedVoice = NULL;
|
||
}
|
||
pCurrentVoice->ulPos = 0;
|
||
pCurrentVoice->ulFinalSize = pCurrentVoice->pRealBitStream->ulFinalSize ;
|
||
pCurrentVoice->bIsFinishing = FALSE;
|
||
pCurrentVoice->ulNumSampleBeforeEnd = 0;
|
||
|
||
pCurrentVoice->bIsFading = FALSE;
|
||
pCurrentVoice->iFadeVolume = 0;
|
||
pCurrentVoice->iFadeIncrement = 0;
|
||
|
||
return pCurrentVoice;
|
||
} else return NULL;
|
||
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Description : Open a new voice from File
|
||
//-------------------------------------------------------------------------
|
||
//
|
||
//-------------------------------------------------------------------------
|
||
// Input : filename and number of channel
|
||
// Output : voice pointer
|
||
//-------------------------------------------------------------------------
|
||
// Creation date : 18/03/97 Author : Guillaume Michel
|
||
//-------------------------------------------------------------------------
|
||
// Modifications :
|
||
// Modification Date : Author :
|
||
//-------------------------------------------------------------------------
|
||
|
||
SND_tdstMPEGVoice* SND_fn_pSampleAllocateMPEGVoiceFile(char* pFileName, unsigned long ulOffset)
|
||
{
|
||
SND_tdstMPEGVoice* pCurrentVoice;
|
||
|
||
pCurrentVoice = &(MPEGvoices[2]);
|
||
if (!pCurrentVoice->bIsFree) {
|
||
SND_fn_vDisplayErrorEx(E_uwSndTooManySamples,"Too many MPEG streaming voices",SNDERR_DISPLAY_IF_WANTED);
|
||
return NULL;
|
||
}
|
||
|
||
//added by stepahen RONSE on 04/29/98
|
||
bSynthesisBufferCleaned=FALSE;
|
||
|
||
if (SND_fn_bOpenBitStreamFile(pCurrentVoice->pRealBitStream,pFileName,ulOffset)) {
|
||
// This voice will be used...
|
||
pCurrentVoice->bIsFree = FALSE;
|
||
pCurrentVoice->ucVolume = 127;
|
||
pCurrentVoice->ucCurrentVolume = 127;
|
||
pCurrentVoice->ucVolumeIndex = 0;
|
||
pCurrentVoice->bIsPaused = pCurrentVoice->bIsMuted = FALSE;
|
||
pCurrentVoice->bIsOneShot = TRUE;
|
||
pCurrentVoice->bIsFullSurround = (pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR2');
|
||
pCurrentVoice->bIsSurround = (pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR2') ||
|
||
(pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR1');
|
||
|
||
if (pCurrentVoice->bIsSurround) {
|
||
pCurrentVoice->pAssociatedVoice = pCurrentVoice + (kNumVoice+1);
|
||
pCurrentVoice->pAssociatedVoice->bIsPlaying = TRUE;
|
||
pCurrentVoice->pAssociatedVoice->ucVolume = 127;
|
||
pCurrentVoice->pAssociatedVoice->ucCurrentVolume = 127;
|
||
pCurrentVoice->pAssociatedVoice->ucVolumeIndex = 0;
|
||
pCurrentVoice->pAssociatedVoice->bIsMuted = FALSE;
|
||
} else {
|
||
pCurrentVoice->pAssociatedVoice = NULL;
|
||
}
|
||
pCurrentVoice->ulPos = 0;
|
||
pCurrentVoice->ulFinalSize = pCurrentVoice->pRealBitStream->ulFinalSize;
|
||
pCurrentVoice->bIsPlaying = TRUE;
|
||
pCurrentVoice->bIsFinishing = FALSE;
|
||
pCurrentVoice->ulNumSampleBeforeEnd = 0;
|
||
|
||
pCurrentVoice->bIsFading = FALSE;
|
||
pCurrentVoice->iFadeVolume = 0;
|
||
pCurrentVoice->iFadeIncrement = 0;
|
||
|
||
return pCurrentVoice;
|
||
} else return NULL;
|
||
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Description : Open a new voice from memory
|
||
//-------------------------------------------------------------------------
|
||
//
|
||
//-------------------------------------------------------------------------
|
||
// Input : buffer pointer, buffer size, voice pointer and number of channel
|
||
// Output : voice pointer
|
||
//-------------------------------------------------------------------------
|
||
// Creation date : 18/03/97 Author : Guillaume Michel
|
||
//-------------------------------------------------------------------------
|
||
// Modifications :
|
||
// Modification Date : Author :
|
||
//-------------------------------------------------------------------------
|
||
|
||
SND_tdstMPEGVoice* SND_fn_pSampleAllocateMPEGVoiceMem(unsigned char* pBuffer, unsigned long ulSize)
|
||
{
|
||
SND_tdstMPEGVoice* pCurrentVoice;
|
||
|
||
pCurrentVoice = &(MPEGvoices[2]);
|
||
if (!pCurrentVoice->bIsFree) {
|
||
return NULL;
|
||
}
|
||
|
||
//added by stepahen RONSE on 04/29/98
|
||
bSynthesisBufferCleaned=FALSE;
|
||
|
||
if (SND_fn_bOpenBitStreamMem(pCurrentVoice->pRealBitStream,pBuffer,ulSize)) {
|
||
// This voice will be used...
|
||
pCurrentVoice->bIsFree = FALSE;
|
||
pCurrentVoice->bIsPlaying = TRUE;
|
||
pCurrentVoice->ucVolume = 127;
|
||
pCurrentVoice->ucCurrentVolume = 127;
|
||
pCurrentVoice->ucVolumeIndex = 0;
|
||
pCurrentVoice->bIsPaused = pCurrentVoice->bIsMuted = FALSE;
|
||
pCurrentVoice->bIsOneShot = TRUE;
|
||
pCurrentVoice->bIsFullSurround = (pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR2');
|
||
pCurrentVoice->bIsSurround = (pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR2') ||
|
||
(pCurrentVoice->pRealBitStream->ulDolbyMark == 'SUR1');
|
||
|
||
if (pCurrentVoice->bIsSurround) {
|
||
pCurrentVoice->pAssociatedVoice = pCurrentVoice + (kNumVoice+1);
|
||
pCurrentVoice->pAssociatedVoice->bIsPlaying = TRUE;
|
||
pCurrentVoice->pAssociatedVoice->ucVolume = 127;
|
||
pCurrentVoice->pAssociatedVoice->ucCurrentVolume = 127;
|
||
pCurrentVoice->pAssociatedVoice->ucVolumeIndex = 0;
|
||
pCurrentVoice->pAssociatedVoice->bIsMuted = FALSE;
|
||
} else {
|
||
pCurrentVoice->pAssociatedVoice = NULL;
|
||
}
|
||
|
||
pCurrentVoice->ulPos = 0;
|
||
pCurrentVoice->ulFinalSize = pCurrentVoice->pRealBitStream->ulFinalSize;
|
||
pCurrentVoice->bIsFinishing = FALSE;
|
||
pCurrentVoice->ulNumSampleBeforeEnd = 0;
|
||
|
||
pCurrentVoice->bIsFading = FALSE;
|
||
pCurrentVoice->iFadeVolume = 0;
|
||
pCurrentVoice->iFadeIncrement = 0;
|
||
|
||
return pCurrentVoice;
|
||
} else return NULL;
|
||
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Description : close a voice
|
||
//-------------------------------------------------------------------------
|
||
//
|
||
//-------------------------------------------------------------------------
|
||
// Input : voice pointer
|
||
// Output : SndBool
|
||
//-------------------------------------------------------------------------
|
||
// Creation date : 18/03/97 Author : Guillaume Michel
|
||
//-------------------------------------------------------------------------
|
||
// Modifications :
|
||
// Modification Date : Author :
|
||
//-------------------------------------------------------------------------
|
||
|
||
SndBool SND_fn_bFreeMPEGVoice(SND_tdstMPEGVoice* pVoice)
|
||
{
|
||
snd_assert(pVoice);
|
||
snd_assert(pVoice->pRealBitStream == &pVoice->bitstream);
|
||
|
||
pVoice->bIsPlaying = FALSE;
|
||
pVoice->bIsPaused = FALSE;
|
||
|
||
SND_fn_bCloseBitStream(pVoice->pRealBitStream);
|
||
//pVoice->ucVolume = 0;
|
||
//pVoice->ucVolumeIndex = 0;
|
||
pVoice->bIsMuted = FALSE;
|
||
pVoice->ulPos = 0;
|
||
pVoice->ulFinalSize = 0;
|
||
pVoice->bIsOneShot = FALSE;
|
||
pVoice->bIsSurround = FALSE;
|
||
pVoice->pAssociatedVoice = NULL;
|
||
pVoice->bIsFinishing = FALSE;
|
||
pVoice->ulNumSampleBeforeEnd = 0;
|
||
|
||
// DO NOT CLEAR CALLBACK AND PARAM FIELDS !!!
|
||
|
||
if (pVoice == &MPEGvoices[2]) {
|
||
// one shot voices
|
||
iMiniFrameSample=12;
|
||
iIndexSample=3;
|
||
}
|
||
|
||
pVoice->bIsFree = TRUE;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Description : read datas from the bit stream (Part I)
|
||
//-------------------------------------------------------------------------
|
||
//
|
||
//-------------------------------------------------------------------------
|
||
// Input : voice pointer
|
||
// Output : SndBool
|
||
//-------------------------------------------------------------------------
|
||
// Creation date : 18/03/97 Author : Guillaume Michel
|
||
//-------------------------------------------------------------------------
|
||
// Modifications :
|
||
// Modification Date : Author :
|
||
//-------------------------------------------------------------------------
|
||
|
||
SndBool SND_fn_bReadPartI(SND_tdstMPEGVoice* pVoice)
|
||
{
|
||
int i,j,k,l,m;
|
||
unsigned char *pucBitAlloc;
|
||
unsigned char *pucScaleFactorPattern;
|
||
unsigned char *pucScaleFactor;
|
||
SND_tdstBitStream *pbitstream;
|
||
unsigned short uwMode, uwExtMode, uwTmp;
|
||
unsigned char ucTmp;
|
||
|
||
snd_assert(pVoice);
|
||
|
||
pbitstream = pVoice->pRealBitStream;
|
||
if(SND_fn_bSeekSynch(pbitstream)) {
|
||
|
||
// We have found a synch word -> there is at least one frame
|
||
GETBITS(4,&uwMode,pbitstream);
|
||
|
||
uwExtMode = uwMode & 0x3,
|
||
uwMode >>= 2; // Tell us if we are in stereo mode, joint mode or mono mode
|
||
|
||
k = pVoice->ucNbChannel = (uwMode == kMono) ? 1 : 2;
|
||
l = pVoice->ucJointBound = (uwMode != kJointStereo) ? kSubBandLimit : iJointMode[uwExtMode];
|
||
|
||
// First READ bits allocations...
|
||
// before Joint boundary there are two bits allocation values
|
||
pucBitAlloc = pVoice->pucBitAlloc;
|
||
for (i = 0; i < l; i++) {
|
||
m = iNumBitPerChannel[i];
|
||
for (j = 0; j < k; j++) {
|
||
GETBITS((unsigned char)m,&uwTmp,pbitstream);
|
||
*pucBitAlloc++ = (unsigned char) uwTmp;
|
||
}
|
||
}
|
||
|
||
// after Joint boundary the same bit allocation value is used for left and right
|
||
for (i = l; i < kSubBandLimit; i++) {
|
||
GETBITS((unsigned char)iNumBitPerChannel[i],&uwTmp,pbitstream);
|
||
*pucBitAlloc++ = ucTmp = (unsigned char) uwTmp;
|
||
*pucBitAlloc++ = ucTmp;
|
||
}
|
||
|
||
// Now we can read scales factors...
|
||
pucBitAlloc = pVoice->pucBitAlloc;
|
||
pucScaleFactorPattern = pVoice->pucScaleFactorPattern;
|
||
for (i = 0; i < kSubBandLimit; i++) {
|
||
for(j = 0; j < k; j++) {
|
||
if(*pucBitAlloc++) {
|
||
GETBITS(2,&uwTmp,pbitstream);
|
||
*pucScaleFactorPattern = (unsigned char) uwTmp;
|
||
}
|
||
|
||
pucScaleFactorPattern++;
|
||
}
|
||
}
|
||
|
||
// Then we can read scale factor index
|
||
pucBitAlloc = pVoice->pucBitAlloc;
|
||
pucScaleFactorPattern = pVoice->pucScaleFactorPattern;
|
||
pucScaleFactor = pVoice->pucScaleFactor;
|
||
for (i = 0; i < kSubBandLimit; i++) {
|
||
for (j = 0; j < k; j++) {
|
||
if(*pucBitAlloc++) {
|
||
switch(*pucScaleFactorPattern++) {
|
||
case 0: // three different scale factors
|
||
GETBITS(6,&uwTmp,pbitstream);
|
||
*pucScaleFactor++ = (unsigned char) uwTmp;
|
||
GETBITS(6,&uwTmp,pbitstream);
|
||
*pucScaleFactor++ = (unsigned char) uwTmp;
|
||
GETBITS(6,&uwTmp,pbitstream);
|
||
*pucScaleFactor++ = (unsigned char) uwTmp;
|
||
break;
|
||
case 1:// two
|
||
GETBITS(6,&uwTmp,pbitstream);
|
||
*pucScaleFactor++ = ucTmp = (unsigned char) uwTmp;
|
||
*pucScaleFactor++ = ucTmp;
|
||
GETBITS(6,&uwTmp,pbitstream);
|
||
*pucScaleFactor++ = (unsigned char) uwTmp;
|
||
break;
|
||
case 3:// two
|
||
GETBITS(6,&uwTmp,pbitstream);
|
||
*pucScaleFactor++ = (unsigned char) uwTmp;
|
||
GETBITS(6,&uwTmp,pbitstream);
|
||
*pucScaleFactor++ = ucTmp = (unsigned char) uwTmp;
|
||
*pucScaleFactor++ = ucTmp;
|
||
break;
|
||
case 2:// one scale factor...
|
||
GETBITS(6,&uwTmp,pbitstream);
|
||
*pucScaleFactor++ = ucTmp = (unsigned char) uwTmp;
|
||
*pucScaleFactor++ = ucTmp;
|
||
*pucScaleFactor++ = ucTmp;
|
||
break;
|
||
default:
|
||
snd_assert(0); // should not happen
|
||
break;
|
||
}
|
||
} else {
|
||
pucScaleFactorPattern++;
|
||
pucScaleFactor += 3;
|
||
}
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
} else return FALSE; // No more synch word -> EOF
|
||
|
||
}
|
||
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Description : read datas from the bit stream (Part II)
|
||
//-------------------------------------------------------------------------
|
||
//
|
||
//-------------------------------------------------------------------------
|
||
// Input : voice pointer
|
||
// Output : SndBool
|
||
//-------------------------------------------------------------------------
|
||
// Creation date : 19/03/97 Author : Guillaume Michel
|
||
//-------------------------------------------------------------------------
|
||
// Modifications :
|
||
// Modification Date : Author :
|
||
//-------------------------------------------------------------------------
|
||
|
||
void SND_fn_vReadPartII(SND_tdstMPEGVoice* pVoice)
|
||
{
|
||
int i, j, jointboundary, k, ba, l, m;
|
||
unsigned short wTmp;
|
||
short *pwSample;
|
||
short *pwOldSample;
|
||
unsigned char *pucBitAlloc,ucl;
|
||
sb_alloc *pAllocTable;
|
||
sb_alloc *pAllocTable2;
|
||
SND_tdstBitStream *pBitStream;
|
||
|
||
|
||
jointboundary = pVoice->ucJointBound;
|
||
k = pVoice->ucNbChannel;
|
||
pBitStream = pVoice->pRealBitStream;
|
||
pwSample = pVoice->pwSample;
|
||
|
||
pucBitAlloc = pVoice->pucBitAlloc;
|
||
for (i = 0; i < kSubBandLimit; i++) {
|
||
pAllocTable2 = &AllocationTable[i][0];
|
||
for (j = 0; j < ((i < jointboundary) ? k : 1); j++) {
|
||
if ( ba = (*pucBitAlloc++)) {
|
||
// There are samples to read
|
||
ba--;
|
||
pAllocTable = pAllocTable2 + ba;
|
||
l = pAllocTable->bits;
|
||
ucl = (unsigned char) l;
|
||
|
||
if (pAllocTable->group == 3) {
|
||
// No Grouping...
|
||
GETBITS(ucl,(unsigned short*)(pwSample++),pBitStream);
|
||
GETBITS(ucl,(unsigned short*)(pwSample++),pBitStream);
|
||
GETBITS(ucl,(unsigned short*)(pwSample++),pBitStream);
|
||
|
||
|
||
} else {
|
||
// Grouping...
|
||
m = pAllocTable->steps;
|
||
GETBITS(ucl,&wTmp,pBitStream);
|
||
|
||
// degroup...
|
||
#if defined(__WATCOMC__) && (__WATCOMC__<1100)
|
||
*pwSample++ = wTmp % m;
|
||
wTmp /= m;
|
||
*pwSample++ = wTmp % m;
|
||
wTmp /= m;
|
||
*pwSample++ = wTmp;
|
||
#else
|
||
_asm {
|
||
xor eax,eax
|
||
mov esi, pwSample
|
||
xor edx, edx
|
||
mov ax, wTmp
|
||
div m
|
||
mov word ptr [esi], dx
|
||
|
||
xor edx, edx
|
||
div m
|
||
mov word ptr [esi + 2], dx
|
||
mov word ptr [esi + 4], ax
|
||
add esi, 6
|
||
mov pwSample,esi
|
||
}
|
||
#endif //Watcom
|
||
|
||
}
|
||
} else {
|
||
*pwSample++ = 0;
|
||
*pwSample++ = 0;
|
||
*pwSample++ = 0;
|
||
}
|
||
}
|
||
if( (k == 2) && (i >= jointboundary)) {
|
||
pwOldSample = pwSample - 3; // last three sample read
|
||
*pwSample++ = *pwOldSample++;
|
||
*pwSample++ = *pwOldSample++;
|
||
*pwSample++ = *pwOldSample++;
|
||
pucBitAlloc++;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
SndBool SND_fn_bRead(SND_tdstMPEGVoice* pVoice)
|
||
{
|
||
if ((pVoice->bIsPlaying)&&(!pVoice->bIsPaused)) {
|
||
if (SND_fn_bReadPartI(pVoice)) {
|
||
SND_fn_vEvaluateSCF(pVoice);
|
||
} else {
|
||
pVoice->bIsPlaying = FALSE;
|
||
|
||
if (pVoice == &MPEGvoices[2]) {
|
||
// voix offs
|
||
pVoice->bIsFinishing = TRUE;
|
||
pVoice->ulNumSampleBeforeEnd = 32*kFrameSize;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
return pVoice->bIsPlaying;
|
||
}
|
||
SndBool SND_fn_bFinishRead(SND_tdstMPEGVoice* pVoice)
|
||
{
|
||
int j;
|
||
if ((pVoice->bIsPlaying)&&(!pVoice->bIsPaused)) {
|
||
for(j =0; j < 12; j++) {
|
||
SND_fn_vReadPartII(pVoice);
|
||
if (!((pVoice->ucVolume==0) || pVoice->bIsMuted))
|
||
SND_fn_vDequantizeSample(pVoice,j);
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
SndBool SND_fn_bSwitchPart()
|
||
{
|
||
unsigned long ulPar;
|
||
SndBool bPartIsFading;
|
||
SND_td_pfn_vSoundCallback pcb;
|
||
SND_tdstMPEGVoice* pOldVoice = pSwapVoice[0];
|
||
SND_tdstMPEGVoice* pNewVoice = pSwapVoice[1];
|
||
bPartIsFading=pOldVoice->bIsFading;
|
||
pcb = pOldVoice->pfnCallBack;
|
||
ulPar = pOldVoice->ulParam;
|
||
pOldVoice->bIsPlaying = FALSE;
|
||
// TRY WITH NEXT ONE...
|
||
if (pSwapVoice[1]->bIsPlaying)
|
||
{
|
||
// OutputDebugString("Switch part called, ");
|
||
// WE MUST TRY VOICE TWO
|
||
// swap the voices...
|
||
pSwapVoice[0] = pNewVoice;
|
||
pSwapVoice[1] = pOldVoice;
|
||
if (bPartIsFading)
|
||
{// copy fade params from previous voice to new one:
|
||
pNewVoice->bIsFading = TRUE;
|
||
pNewVoice->iFadeVolume = pOldVoice->iFadeVolume;
|
||
pNewVoice->iFadeIncrement = pOldVoice->iFadeIncrement;
|
||
}
|
||
// We either launch a transition because of a forecoming transition with fade,
|
||
// in which case we disable the callback, or we call the callback as usual:
|
||
if (SND_g_uFadeRes.pstPtr!=NULL)
|
||
{
|
||
// OutputDebugString("Calling set transition \n");
|
||
SND_fn_bSetNextTransitionMPEG(0,SND_g_uFadeRes);
|
||
SND_g_uFadeRes.pstPtr=NULL;
|
||
}
|
||
else if (pcb)
|
||
{
|
||
// OutputDebugString("Calling callback \n");
|
||
pcb(ulPar);
|
||
}
|
||
else
|
||
pcb=pcb;
|
||
|
||
return TRUE;
|
||
} else
|
||
{
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Description: do the mix to fill the client buffer
|
||
// in the case of SINGLE CHANNEL, if one voice can't fill the client buffer
|
||
// we try with the next voice...
|
||
//-------------------------------------------------------------------------
|
||
//
|
||
//-------------------------------------------------------------------------
|
||
// Input : buffer pointer and size in samples
|
||
// Output : SndBool
|
||
//-------------------------------------------------------------------------
|
||
// Creation date : 20/03/97 Author : Guillaume Michel
|
||
//-------------------------------------------------------------------------
|
||
// Modifications :
|
||
// Modification Date : Author :
|
||
//-------------------------------------------------------------------------
|
||
|
||
SndBool SND_fn_bFillBufferTwice(short* pwBuffer, unsigned long ulSize)
|
||
{
|
||
unsigned long ulNbSample;
|
||
int iResultDecoder = 0;
|
||
int iMaxFrameToDo;
|
||
SndBool bVoiceEnded;//TRUE si une voie s'est arret<65>e pendant le mixage->SWAP?
|
||
|
||
while ( ulSize ) {
|
||
//on regarde si il y a des r<>sidus <20> caser...
|
||
/*
|
||
* Currently we get previous remain decompress data size
|
||
*/
|
||
ulNbSample = pwOutBufferEnd2 - pwOutBufferPos;
|
||
ulNbSample >>= 1;
|
||
if (ulNbSample) {
|
||
// il y a encore des restes
|
||
if (ulSize <= ulNbSample) {
|
||
// il y en a assez...
|
||
memcpy(pwBuffer,pwOutBufferPos,(ulSize<<1)*sizeof(short));
|
||
pwOutBufferPos += (ulSize<<1);
|
||
return TRUE;
|
||
} else {
|
||
memcpy(pwBuffer,pwOutBufferPos,(ulNbSample<<1)*sizeof(short));
|
||
pwOutBufferPos = pwOutBufferEnd2;
|
||
pwBuffer += (ulNbSample<<1);
|
||
ulSize -= ulNbSample;
|
||
}
|
||
}
|
||
|
||
if (ulSize < kNumChannel) {
|
||
// on doit d<>coder dans le buffer temporaire
|
||
bVoiceEnded=SND_fn_bGetOneFrame(pwOutBuffer,1,&iResultDecoder);
|
||
if (bVoiceEnded || (iResultDecoder != kNumChannel)) {
|
||
pwOutBufferEnd2 = pwOutBuffer +(iResultDecoder<<1);
|
||
if (bSwitchPart) {
|
||
// On swapp: il y a donc quelque chose dans le buffer temporiare
|
||
if(SND_fn_bSwitchPart()) {
|
||
// On peut swapper de part en part
|
||
if (ulSize >= (unsigned long)iResultDecoder) {
|
||
// on n'a pas d<>cod<6F> assez...
|
||
memcpy(pwBuffer,pwOutBuffer,(iResultDecoder<<1)*sizeof(short));
|
||
pwOutBufferPos = pwOutBufferEnd2;
|
||
ulSize -= iResultDecoder;
|
||
pwBuffer += (iResultDecoder<<1);
|
||
} else {
|
||
// on a d<>cod<6F> assez...
|
||
memcpy(pwBuffer,pwOutBuffer,(ulSize<<1)*sizeof(short));
|
||
pwOutBufferPos = pwOutBuffer + (ulSize<<1);
|
||
return TRUE;
|
||
}
|
||
|
||
} else {
|
||
// On ne peut pas swapper
|
||
if (ulSize >= (unsigned long)iResultDecoder) {
|
||
// on n'a pas d<>cod<6F> assez...
|
||
memcpy(pwBuffer,pwOutBuffer,(iResultDecoder<<1)*sizeof(short));
|
||
pwOutBufferPos = pwOutBufferEnd2;
|
||
ulSize -= iResultDecoder;
|
||
memset(pwBuffer+(iResultDecoder<<1),0,(ulSize<<1)*sizeof(short));
|
||
} else {
|
||
// on a d<>cod<6F> assez...
|
||
memcpy(pwBuffer,pwOutBuffer,(ulSize<<1)*sizeof(short));
|
||
pwOutBufferPos = pwOutBuffer + (ulSize<<1);
|
||
ulSize = 0;
|
||
}
|
||
|
||
//added by stephane RONSe on 04/29/98
|
||
if (!bSynthesisBufferCleaned)
|
||
{
|
||
fn_vCleanSynthesisBuffer();
|
||
bSynthesisBufferCleaned=TRUE;
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
} else {
|
||
// Pas de switch -> arr<72>t normal -> pas de d<>codage
|
||
pwOutBufferPos = pwOutBufferEnd2;
|
||
memset(pwBuffer,0, (ulSize<<1)*sizeof(short));
|
||
|
||
//added by stephane RONSe on 04/29/98
|
||
if (!bSynthesisBufferCleaned)
|
||
{
|
||
fn_vCleanSynthesisBuffer();
|
||
bSynthesisBufferCleaned=TRUE;
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
} else {
|
||
// tout est ok... on continu
|
||
memcpy(pwBuffer,pwOutBuffer,(ulSize<<1)*sizeof(short));
|
||
pwBuffer += (ulSize<<1);
|
||
pwOutBufferPos = pwOutBuffer + (ulSize<<1);
|
||
pwOutBufferEnd2 = pwOutBuffer +(kNumChannel<<1);
|
||
ulSize = 0;
|
||
// normalement cela doit <20>tre termin<69>...
|
||
}
|
||
} else {
|
||
iMaxFrameToDo = ulSize>>5;
|
||
|
||
// on peut d<>coder directement au bon endroit
|
||
bVoiceEnded=SND_fn_bGetOneFrame(pwBuffer,iMaxFrameToDo,&iResultDecoder);
|
||
if (bVoiceEnded || (iResultDecoder != (iMaxFrameToDo<<5))) {
|
||
if (bSwitchPart) {
|
||
if(SND_fn_bSwitchPart()) {
|
||
pwBuffer += (iResultDecoder<<1);
|
||
ulSize -= iResultDecoder;
|
||
} else {
|
||
memset(pwBuffer+(iResultDecoder<<1),0, ((ulSize-iResultDecoder)<<1)*sizeof(short));
|
||
|
||
//added by stephane RONSe on 04/29/98
|
||
if (!bSynthesisBufferCleaned)
|
||
{
|
||
fn_vCleanSynthesisBuffer();
|
||
bSynthesisBufferCleaned=TRUE;
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
} else {
|
||
memset(pwBuffer,0, (ulSize<<1)*sizeof(short));
|
||
|
||
//added by stephane RONSe on 04/29/98
|
||
if (!bSynthesisBufferCleaned)
|
||
{
|
||
fn_vCleanSynthesisBuffer();
|
||
bSynthesisBufferCleaned=TRUE;
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
} else {
|
||
// tout est ok... on continu
|
||
ulSize -= iResultDecoder;
|
||
pwBuffer += (iResultDecoder<<1);
|
||
}
|
||
}
|
||
}
|
||
return TRUE;
|
||
|
||
}
|
||
|
||
void WINAPI SND_fn_vRefreshMPEG(long idBuffer,unsigned long idSample, unsigned long nbSample, void* pvBuffer)
|
||
{
|
||
bInMPEGDecomp = TRUE; //MUTEX
|
||
SND_fn_bFillBufferTwice((short*)pvBuffer,nbSample);
|
||
|
||
//memcpy(pBigInBuffer,pvBuffer,nbSample*2*2);
|
||
//pBigInBuffer+=2*nbSample;
|
||
|
||
bInMPEGDecomp = FALSE; // MUTEX
|
||
}
|
||
|
||
void SND_fnvStopAllVoicesMPEGTheme()
|
||
{
|
||
// Stop the two voices associated with theme player...
|
||
// both voices are stopped...
|
||
pSwapVoice[1]->bIsPlaying = pSwapVoice[0]->bIsPlaying = FALSE;
|
||
pSwapVoice[1]->bIsPaused = pSwapVoice[0]->bIsPaused = FALSE;
|
||
|
||
// wait for end of the current frame decompression
|
||
// this function and GetOneFrame MUST BE IN TWO DIFFERENT THREADS !!!
|
||
while(bInMPEGDecomp){
|
||
Sleep(30);
|
||
}
|
||
|
||
iMiniFrameTheme=12;
|
||
iIndexTheme=3;
|
||
|
||
SND_fn_bFreeMPEGVoice(pSwapVoice[0]);
|
||
SND_fn_bFreeMPEGVoice(pSwapVoice[1]);
|
||
}
|