⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsapi.cpp

📁 赤壁之战的游戏源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    dwProgress = 0;        /* Used with above to show prog. */
    bDonePlaying = TRUE;      /* Signals early abort to timer */
    bLoopFile = FALSE;         /* Should we loop playback? */
    bFoundEnd = TRUE;         /* Timer found file end */
    nRemainingSegments = 0;/* Segments 'til timer shutdown */
	
	//char	strFileName[65];				/* wave file name */
	nID = WAVE_OBJECT_NONE;				// ID, and if wave file has been opened 
	bPlaying =  FALSE, bTimerInstalled = FALSE;	// if is playing, timer has been installed
	uTimerID = 0, uLastPercent = 0;		// timer ID and percent has been played 
//	return 1;
}

// destructor
CDynamicWave::~CDynamicWave()
{
	if( nID != WAVE_OBJECT_NONE )
	{
        PostMessage( DS_hwndGame, WM_DSSTREAM_DONE, (WPARAM)nID, (LPARAM)0 );
		Stop();
		OutputDebugString( "DS Warning: not stop playing sound before destroy sound buffer!\n" );
	}
}

// load sound buffer
// filename		:	wave file name
// return value	:	TRUE if succeeded
BOOL WAVEDYNAMIC::Load( LPCTSTR filename )
{
	// register this sound buffer to global array
	BOOL bSuccess = FALSE;
	for( int i=0; i< WAVE_OBJECT_MAX; i++ )
	{
		if( lpwdWaves[i] == NULL )
		{
			lpwdWaves[i] = this;
			nID = i;
			bSuccess = TRUE;
#ifdef	__TEST_SOUND__
			for( int x=0; x<WAVE_OBJECT_MAX; x++ )
			{
				if( nID == x )	continue;
				if( !lpwdWaves[x] ) continue;
				ASSERT( this != lpwdWaves[x] );
			}
#endif
			break;
		}
	}
	if( !bSuccess )
	{
		return FALSE;
	}
	
	// load sound with a wave format file
	strcpy( strFileName, filename );
	if(StreamBufferSetup( nID ) != 0 )
	{
		// Error opening the WAVE file so abort
		lpwdWaves[nID] = NULL;
		nID = WAVE_OBJECT_NONE;
		return FALSE;
	}
	nWaveCounter++;

#ifdef	__TEST_SOUND__
	ASSERT( lpwdWaves[nID]->lpDSBStreamBuffer );
#endif

#ifdef	_DEBUG
	char	tmp[33];
	itoa( nWaveCounter, tmp, 10 );
//	OutputDebugString( "DS Dynamic wave Load:" );
//	OutputDebugString(tmp);
//	OutputDebugString("\n");
#endif

	return TRUE;
}

// release sound buffer
void WAVEDYNAMIC::Close()
{
	if( nID == WAVE_OBJECT_NONE )	return;
	//OutputDebugString( "Wait2," );
	WaitForSingleObject( hMutex, INFINITE );

	// release sound buffer, and unregister from global array
	StreamBufferRelease( nID );
	lpwdWaves[nID] = NULL;
	nID = WAVE_OBJECT_NONE;
	nWaveCounter--;

	ReleaseMutex( hMutex );
	//OutputDebugString( "End Wait2\n" );
#ifdef	_DEBUG
	char	tmp[33];
	itoa( nWaveCounter, tmp, 10 );
//	OutputDebugString( "DS Dynamic wave Close:" );
//	OutputDebugString(tmp);
//	OutputDebugString("\n");
#endif
}

// play wave file
// dwFlags		:	TRUE if looping
// pos			:	position to play from
// return value	:	TRUE if played
// if this object is playing, stop and playing again
// Warning:	a bug report here: the last sound in segment buffer 
//          cannot be played, so you need the file larger than 
//          normal at last, with a period of slience.
BOOL WAVEDYNAMIC::Play( DWORD dwFlags/*=DSBPLAY_LOOPING*/, DWORD pos/*=0*/ )
{
    HRESULT dsrval;
	
	if( !DS_bSoundEnable )	return TRUE;

	if( bPlaying == TRUE )
	{
        PostMessage( DS_hwndGame, WM_DSSTREAM_DONE, (WPARAM)nID, (LPARAM)0 );
		Stop();
	}

	if( !Load( strFileName ) )	
		return FALSE;

#ifdef	__TEST_SOUND__
	ASSERT( nID != WAVE_OBJECT_NONE );
	ASSERT( lpDSBStreamBuffer );
#endif

#ifdef	__TEST_SOUND__
	ASSERT( bPlaying == FALSE );
#endif
    // Ensure that position is at 0, ready to go
	// set position
    if( lpDSBStreamBuffer->SetCurrentPosition( pos ) != DS_OK )
		return FALSE;

	// set volume
    if( lpDSBStreamBuffer->SetVolume( DS_nVolume ) != DS_OK )
		return FALSE;

	// set pan
    if( lpDSBStreamBuffer->SetPan( DS_nPan ) != DS_OK )
		return FALSE;

	// play
    if( lpDSBStreamBuffer->Play( 0, 0, DSBPLAY_LOOPING ) != DS_OK )
		return FALSE;
	bPlaying = TRUE;

    if( timeBeginPeriod( PLAYBACK_TIMER_PERIOD
                            / PLAYBACK_OVERSAMPLE ) != TIMERR_NOERROR )
        {
        /* Can't create timer! */
        dsrval = lpDSBStreamBuffer->Stop();
        bPlaying = bTimerInstalled = FALSE;
		Close();
        return FALSE;
        }
    else
    {
        if(( uTimerID = timeSetEvent( PLAYBACK_TIMER_PERIOD
                                       / PLAYBACK_OVERSAMPLE,
                                       PLAYBACK_TIMER_ACCURACY,
                                       TimeFunc, (DWORD)nID,
                                       /*TIME_ONESHOT*/TIME_PERIODIC )) != 0 )
		{
			bTimerInstalled = TRUE;
#ifdef	__TEST_SOUND__
			for( int i=0; i< WAVE_OBJECT_MAX; i++ )
			{
				if( i == nID )	continue;
				if( !lpwdWaves[i] ) continue;
				ASSERT( uTimerID != lpwdWaves[i]->uTimerID );
			}
#endif
		}
		else
		{
			timeEndPeriod( PLAYBACK_TIMER_PERIOD
		                   / PLAYBACK_OVERSAMPLE );
	        dsrval = lpDSBStreamBuffer->Stop();
			bPlaying = bTimerInstalled = FALSE;
			Close();
			return FALSE;
		}
    }
	bLoopFile = dwFlags;
	return TRUE;
}

// reset wave player, avoid to use
void WAVEDYNAMIC::Reset()
{
	ResetWavePlayer( nID );
}

// stop playing
// if has stoped, no effects
void WAVEDYNAMIC::Stop()
{
    HRESULT dsrval;

	if( nID == WAVE_OBJECT_NONE )	return;
	WaitForSingleObject( hMutex, INFINITE );

#ifdef	__TEST_SOUND__
    ASSERT( !bDonePlaying );
#endif
	bDonePlaying = TRUE;
#ifdef	__TEST_SOUND__
	ASSERT( bTimerInstalled );
#endif
    if( bTimerInstalled )
    {
        bTimerInstalled = FALSE;
        timeKillEvent( uTimerID );
        timeEndPeriod( PLAYBACK_TIMER_PERIOD
                        / PLAYBACK_OVERSAMPLE );
		uTimerID = 0;
    }
#ifdef	__TEST_SOUND__
	ASSERT( bPlaying );
#endif
    if( bPlaying )
    {
        bPlaying = FALSE;
		dsrval = lpDSBStreamBuffer->Stop();
		ReleaseMutex( hMutex );
		Close();
		WaitForSingleObject( hMutex, INFINITE );
    }

	ReleaseMutex( hMutex );
}

// for fade out
// to make the sound lower and lower
// return value	:	TRUE if succeeded
BOOL WAVEDYNAMIC::FadeOut()
{
	LONG lVolume;
	int	 nStep;
	BOOL retrn = FALSE;
	if( lpDSBStreamBuffer->GetVolume( &lVolume ) == DS_OK )
	{
		nStep = 100;//0 - lVolume+50;
		if( lVolume-nStep > -2000 )
			lVolume = lVolume - nStep;
		else
		{
			lVolume = -2000; retrn = TRUE;
		}
		if( lpDSBStreamBuffer->SetVolume( lVolume ) != DS_OK )
		{
			retrn = TRUE;
		}
	}
	else	retrn = TRUE;
	return retrn;
}

// to make the sound louder and louder
// return value	:	TRUE if succeeded
BOOL WAVEDYNAMIC::FadeIn()
{
	LONG lVolume;
	int	 nStep;
	BOOL retrn = FALSE;
	if( lpDSBStreamBuffer->GetVolume( &lVolume ) == DS_OK )
	{
		nStep = 100;//0 - lVolume + 50;
		if( lVolume+nStep > 0 )
		{
			lVolume = 0; retrn = TRUE;
		}
		else
		{
			lVolume = lVolume + nStep;
		}
		if( lpDSBStreamBuffer->SetVolume( lVolume ) != DS_OK )
		{
			retrn = TRUE;
		}
	}
	else	retrn = TRUE;
	return retrn;
}
//////////////////

// functinos used by WAVEDYNAMIC
//////////////////
/*****************************************************************************/
/* SetToGlobal()															 */
/*                                                                           */
/* this functions call is to get WAVEDYNAMIC object from global array		 */
/*                                                                           */
/*****************************************************************************/
// nIndex		:	ID in global wave array
// return value	:	WAVEDYNAMIC pointer
inline LPWAVEDYNAMIC SetToGlobal( int nIndex )
{
	return lpwdWaves[nIndex];
}

/*****************************************************************************/
/* StreamBufferSetup()                                                       */
/*                                                                           */
/*    This function uses the filename stored in the global character array to*/
/* open a WAVE file. Then it creates a secondary DirectSoundBuffer object    */
/* which will later be used to stream that file from disk during playback.   */
/*                                                                           */
/*****************************************************************************/
// nIndex		:	ID in global wave array
// return value	:	0 if succeeded, otherwise error number,
int StreamBufferSetup( int nIndex )
    {
    DSBUFFERDESC dsbd;
    HRESULT      dsRetVal;
    LPBYTE       lpWrite1, lpWrite2;
    DWORD        dwLen1, dwLen2;
    UINT         uChkErr;
        
    int nChkErr;
	LPWAVEDYNAMIC lpwiWave = NULL;

	// set lpwdWaves[nIndex] to lpwiWave
	// so that you can use lpwiWave directly
#ifdef	__TEST_SOUND__
	ASSERT( nIndex >= 0 );
#endif
	lpwiWave = SetToGlobal( nIndex );

#ifdef	__TEST_SOUND__
	ASSERT( lpwdWaves[nIndex] == lpwiWave );
#endif

    /* This portion of the WAVE I/O is patterned after what's in DSTRWAVE, which
     * was in turn adopted from WAVE.C which is part of the DSSHOW sample.
     */

    if(( nChkErr = WaveOpenFile( lpwiWave->strFileName, &lpwiWave->hmmio, &lpwiWave->pwfx, &lpwiWave->mmckInRIFF )) != 0 )
        {
        nChkErr =  ERR_WAVE_OPEN_FAILED;
	    //SoundFail( DS_hwndGame, nChkErr );
		goto END_SETUP;
        }

#ifdef	__TEST_SOUND__
	ASSERT( lpwdWaves[nIndex] == lpwiWave );
#endif

    if( lpwiWave->pwfx->wFormatTag != WAVE_FORMAT_PCM )
        {
		nChkErr = ERR_WAVE_INVALID_FORMAT;
        //SoundFail( DS_hwndGame, nChkErr );
        WaveCloseReadFile( &lpwiWave->hmmio, &lpwiWave->pwfx );
		goto END_SETUP;
        }
    /* Seek to the data chunk */
    if(( nChkErr = WaveStartDataRead( &lpwiWave->hmmio, &lpwiWave->mmck, &lpwiWave->mmckInRIFF )) != 0 )
        {
		nChkErr = ERR_WAVE_CORRUPTED_FILE;
        //SoundFail( DS_hwndGame, nChkErr );
        WaveCloseReadFile( &lpwiWave->hmmio, &lpwiWave->pwfx );
		goto END_SETUP;
        }
    /* As a side note, mmck.ckSize will be the size of all the data in this file.
     * That's something which might be handy when calculating the length... */

#ifdef	__TEST_SOUND__
	ASSERT( lpwdWaves[nIndex] == lpwiWave );
#endif

    /* Calculate a buffer length, making sure it is an exact multiple of the
     * buffer segment size.
     */
    lpwiWave->dwBufferSize = ((DWORD)lpwiWave->pwfx->nAvgBytesPerSec
                            * (((NUM_BUFFER_SEGMENTS * PLAYBACK_TIMER_PERIOD)
                            / 10)) / 100);

#ifdef	__TEST_SOUND__
	ASSERT( lpwdWaves[nIndex] == lpwiWave );
#endif

    lpwiWave->dwBufferSegSize = lpwiWave->dwBufferSize / NUM_BUFFER_SEGMENTS;
    lpwiWave->dwBufferSize = lpwiWave->dwBufferSegSize * NUM_BUFFER_SEGMENTS;

    /*
     * Create the secondary DirectSoundBuffer object to receive our sound data.
     */
    memset( &dsbd, 0, sizeof( DSBUFFERDESC ));
    dsbd.dwSize = sizeof( DSBUFFERDESC );
    dsbd.dwFlags = DSBCAPS_CTRLDEFAULT;
    dsbd.dwBufferBytes = lpwiWave->dwBufferSize;

#ifdef	__TEST_SOUND__
	ASSERT( lpwdWaves[nIndex] == lpwiWave );
#endif

    /* Set Format properties according to the WAVE file we just opened */
	//LPDIRECTSOUNDBUFFER     lpDSB = NULL;
    dsbd.lpwfxFormat = lpwiWave->pwfx;
    dsRetVal = lpDS->CreateSoundBuffer( &dsbd,
                                        &lpwiWave->lpDSBStreamBuffer,
                                        NULL );
    if( dsRetVal != DS_OK )
        {
		nChkErr = ERR_CREATEDSB_FAILED;
        //SoundFail( DS_hwndGame, nChkErr );
        WaveCloseReadFile( &lpwiWave->hmmio, &lpwiWave->pwfx );
		goto END_SETUP;
        }
/*
	// set wave format 
    if ((dsRetVal = lpDSBPrimary->SetFormat(&wfx)) != DS_OK)
	{
		nChkErr = ERR_WAVE_FORMAT_INVALID;
		SoundFail( DS_hwndGame, nChkErr );
        WaveCloseReadFile( &lpwiWave->hmmio, &lpwiWave->pwfx );
		goto END_SETUP;
	}
*/
#ifdef	__TEST_SOUND__
	ASSERT( lpwiWave->lpDSBStreamBuffer );
#endif
#ifdef	__TEST_SOUND__
	ASSERT( lpwdWaves[nIndex] == lpwiWave );
#endif

    //lpwiWave->lpDSBStreamBuffer = lpDSBStreamBuffer;
    lpwiWave->bFoundEnd = FALSE;
    lpwiWave->nRemainingSegments = 0;

    dsRetVal = lpwiWave->lpDSBStreamBuffer->Lock( 0, lpwiWave->dwBufferSize,
								               (void**)&lpWrite1, &dwLen1,
											   (void**)&lpWrite2, &dwLen2,
											   0 );
    if( dsRetVal != DS_OK )
        {
		nChkErr = ERR_CREATEDSB_LOST;
        //SoundFail( DS_hwndGame, nChkErr );
        WaveCloseReadFile( &lpwiWave->hmmio, &lpwiWave->pwfx );
		lpwiWave->lpDSBStreamBuffer->Release();
		lpwiWave->lpDSBStreamBuffer = NULL;
		goto END_SETUP;
        }

#ifdef	__TEST_SOUND__
	ASSERT( lpwiWave->lpDSBStreamBuffer );
#endif
#ifdef	__TEST_SOUND__
	ASSERT( lpwdWaves[nIndex] == lpwiWave );
#endif

    if( dwLen1 )
        {
        nChkErr = WaveReadFile( lpwiWave->hmmio, (UINT)dwLen1, lpWrite1,
                                &lpwiWave->mmck, &uChkErr );
        if( uChkErr < dwLen1 )
            {
            if( lpwiWave->bLoopFile )
                {
    /* If the file is shorter than the buffer and we're looping, we need to
     * read the file in again so that we don't get a block of silence before
     * the timer loops playback.
     */
                LPBYTE lpTemp = lpWrite1;

                do
                    {
                    /* Continue decrementing our count and moving our temp

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -