📄 dsapi.cpp
字号:
{
/* Zero out the rest of this block */
if( lpwiWave->pwfx->wBitsPerSample == 8 )
memset( lpWrite2+uChkErr, 128, ((UINT)dwLen2-uChkErr));
else if( lpwiWave->pwfx->wBitsPerSample == 16 )
memset( lpWrite2+uChkErr, 0, ((UINT)dwLen2-uChkErr));
/* Enable play completion detection code at the beginning
* of the next call
*/
lpwiWave->bFoundEnd = TRUE;
if( dwPlay > lpwiWave->dwNextWriteOffset )
lpwiWave->nRemainingSegments = (lpwiWave->dwNextWriteOffset
+ lpwiWave->dwBufferSize - dwPlay)
/ lpwiWave->dwBufferSegSize;
else
lpwiWave->nRemainingSegments = (lpwiWave->dwNextWriteOffset
- dwPlay)
/ lpwiWave->dwBufferSegSize;
}
else
{
lpTemp = lpWrite2;
do
{
/* Continue decrementing our count and moving our temp
* pointer forward until we've read the file enough times
* to fill the buffer. NOTE: It's probably not efficient
* to bother with the overhead of streaming a file that's
* not at least as large as the buffer... */
lpTemp += uChkErr;
dwLen2 -= uChkErr;
nChkErr = WaveStartDataRead( &lpwiWave->hmmio,
&lpwiWave->mmck,
&lpwiWave->mmckInRIFF );
nChkErr = WaveReadFile( lpwiWave->hmmio, (UINT)dwLen2,
lpTemp,
&lpwiWave->mmck, &uChkErr );
} while( uChkErr < dwLen2 );
}
}
}
else if( dwLen2 && lpwiWave->bDonePlaying )
{
// Set the appropriate silence value
memset( lpWrite2,
lpwiWave->pwfx->wBitsPerSample == 8 ? 128 : 0,
dwLen2 );
}
#ifdef __TEST_SOUND__
ASSERT( lpwdWaves[dwUser] == lpwiWave );
#endif
lpwiWave->lpDSBStreamBuffer->Unlock( (LPVOID)lpWrite1, dwLen1,
(LPVOID)lpWrite2, dwLen2 );
#ifdef __TEST_SOUND__
ASSERT( lpwdWaves[dwUser] == lpwiWave );
#endif
lpwiWave->dwNextWriteOffset += lpwiWave->dwBufferSegSize;
if( lpwiWave->dwNextWriteOffset >= lpwiWave->dwBufferSize )
lpwiWave->dwNextWriteOffset -= lpwiWave->dwBufferSize;
#ifdef __TEST_SOUND__
ASSERT( lpwdWaves[dwUser] == lpwiWave );
#endif
//OutputString( DS_nVolume, "\n" );
// set volume
if( lpwiWave->lpDSBStreamBuffer->SetVolume( DS_nVolume ) != DS_OK )
{
OutputDebugString( "DS dynamic error: set volume!\n" );
//-----debug
#ifdef _DS_LOG_
FILE*fp=fopen( "DSTest.log","at" );
fprintf(fp,"E" );
fclose(fp);
#endif
//-----debug
goto END_TIME;
}
// set pan
if( lpwiWave->lpDSBStreamBuffer->SetPan( DS_nPan ) != DS_OK )
{
OutputDebugString( "DS dynamic error: set pan!\n" );
//-----debug
#ifdef _DS_LOG_
FILE*fp=fopen( "DSTest.log","at" );
fprintf(fp,"F" );
fclose(fp);
#endif
//-----debug
goto END_TIME;
}
// fade in or fade out
if( DS_nFadeMode == DS_FADE_OUT )
{
if( lpwiWave->FadeOut() )
DS_nFadeMode = DS_FADE_NONE; // end fade session
}
if( DS_nFadeMode == DS_FADE_IN )
{
if( lpwiWave->FadeIn() )
DS_nFadeMode = DS_FADE_NONE; // end fade session
}
END_TIME:
bInTimer = FALSE;
ReleaseMutex( hMutex );
}
//////////////////
//==========================================================================
//
// class WAVESTATIC
//
//==========================================================================
//////////////////
// used by class WAVESTATIC
// load sound buffer
// nIndex : ID in global wave array
// return value : 0 if succeeded, otherwise error number,
int StreamBufferSetupS( int nIndex );
// release sound buffer
// nIndex : ID in global wave array
void StreamBufferReleaseS( int nIndex );
// set lpswWave by index in lpwsWaves
// nIndex : ID in global wave array
LPWAVESTATIC SetToGlobalS( int nIndex );
// constructor
WAVESTATIC::CStaticWave()
{
nID = WAVE_OBJECT_NONE; /* ID, if not equals to WAVE_OBJECT_NONE,
the wave file is opened */
//strFileName[65]; /* wave file name */
bLoopFile = FALSE; /* Should we loop playback? */
bPlaying = FALSE; /* if wave file is playing */
lpDSBStreamBuffer = NULL; /* Points to DirectSoundBuffer */
cbSize = 0;
pbData = NULL;
}
// destructor
WAVESTATIC::~CStaticWave()
{
if( nID != WAVE_OBJECT_NONE )
{
PostMessage( DS_hwndGame, WM_DSSTREAM_DONE, (WPARAM)nID, (LPARAM)1 );
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 WAVESTATIC::Load( LPCTSTR filename )
{
// register this sound buffer to global array
BOOL bSuccess = FALSE;
for( int i=0; i< WAVE_OBJECT_MAXS; i++ )
{
if( lpwsWaves[i] == NULL )
{
lpwsWaves[i] = this;
nID = i;
bSuccess = TRUE;
#ifdef __TEST_SOUND__
for( int x=0; x<WAVE_OBJECT_MAXS; x++ )
{
if( nID == x ) continue;
if( !lpwsWaves[x] ) continue;
ASSERT( this != lpwsWaves[x] );
}
#endif
break;
}
}
if( !bSuccess )
{
return FALSE;
}
// load sound with a wave format file
strcpy( strFileName, filename );
if(StreamBufferSetupS( nID ) != 0 )
{
// Error opening the WAVE file so abort
lpwsWaves[nID] = NULL;
nID = WAVE_OBJECT_NONE;
return FALSE;
}
nSWaveCounter++;
#ifdef __TEST_SOUND__
ASSERT( lpwsWaves[nID]->lpDSBStreamBuffer );
#endif
#ifdef _DEBUG
char tmp[33];
itoa( nSWaveCounter, tmp, 10 );
// OutputDebugString( "DS Static wave Load:" );
// OutputDebugString(tmp);
// OutputDebugString("\n");
#endif
return TRUE;
}
// release sound buffer
void WAVESTATIC::Close()
{
if( nID == WAVE_OBJECT_NONE ) return;
// WaitForSingleObject( hMutex, INFINITE );
// release sound buffer, and unregister from global array
StreamBufferReleaseS( nID );
lpwsWaves[nID] = NULL;
nID = WAVE_OBJECT_NONE;
nSWaveCounter--;
#ifdef _DEBUG
char tmp[33];
itoa( nSWaveCounter, tmp, 10 );
// ReleaseMutex( hMutex );
// OutputDebugString( "DS Static wave Close:" );
// OutputDebugString(tmp);
// OutputDebugString("\n");
#endif
}
// dwFlags : TRUE if looping
// pos : position to play from
// return value : TRUE if played
// if this object is playing, stop and playing again
BOOL WAVESTATIC::Play( DWORD dwFlags/*=DSBPLAY_LOOPING*/, DWORD pos/*=0*/ )
{
if( !DS_bSoundEnable ) return TRUE;
// release stoped wave files previously played
DS_CloseStopedSoundS();
// stop if the current buffer is playing
if( bPlaying == TRUE )
{
PostMessage( DS_hwndGame, WM_DSSTREAM_DONE, (WPARAM)nID, (LPARAM)1 );
Stop();
}
if( !Load( strFileName ) )
return FALSE;
#ifdef __TEST_SOUND__
ASSERT( nID != WAVE_OBJECT_NONE );
ASSERT( lpDSBStreamBuffer );
#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, dwFlags ) != DS_OK )
return FALSE;
bPlaying = TRUE;
bLoopFile = dwFlags;
return TRUE;
}
// stop playing
// if has stoped, no effects
void WAVESTATIC::Stop()
{
HRESULT dsrval;
// WaitForSingleObject( hMutex, INFINITE );
#ifdef __TEST_SOUND__
ASSERT( bPlaying );
#endif
if( bPlaying )
{
bPlaying = FALSE;
dsrval = lpDSBStreamBuffer->Stop();
// ReleaseMutex( hMutex );
Close();
// WaitForSingleObject( hMutex, INFINITE );
}
// ReleaseMutex( hMutex );
return;
}
BOOL WAVESTATIC::IfPlaying()
{
HRESULT dsrval;
DWORD dwStatus;
if( lpDSBStreamBuffer == NULL ) return FALSE;
dsrval = lpDSBStreamBuffer->GetStatus( &dwStatus );
if ( DS_OK != dsrval ) return FALSE;
if( !(dwStatus & DSBSTATUS_PLAYING) )
{
// must be sendmessage, cannot use postmessage
// LPARAM : 1 if it is static wave object
SendMessage( DS_hwndGame, WM_DSSTREAM_DONE, (WPARAM)nID, (LPARAM)1 );
Stop();
return FALSE;
}
return TRUE;
}
// nIndex : ID in global wave array
// return value : 0 if succeeded, otherwise error number,
int StreamBufferSetupS( int nIndex )
{
DWORD dwSamples;
DSBUFFERDESC dsbd;
HRESULT dsRetVal;
LPBYTE lpWrite1, lpWrite2;
DWORD dwLen1, dwLen2;
int nChkErr = 0;
WAVESTATIC * lpswWave = NULL;
lpswWave = SetToGlobalS( nIndex );
// open the whole wave file, read data to pbData, and close it
if( WaveLoadFile( lpswWave->strFileName, &lpswWave->cbSize,
&dwSamples, &lpswWave->pwfx, &lpswWave->pbData ) != 0 )
{
nChkErr = ERR_WAVE_OPEN_FAILED;
//SoundFail( DS_hwndGame, nChkErr );
goto END_SETUP;
}
// test if the format is correct
if( lpswWave->pwfx->wFormatTag != WAVE_FORMAT_PCM )
{
nChkErr = ERR_WAVE_INVALID_FORMAT;
//SoundFail( DS_hwndGame, nChkErr );
goto END_SETUP;
}
/*
* 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 = lpswWave->cbSize;
#ifdef __TEST_SOUND__
ASSERT( lpwsWaves[nIndex] == lpswWave );
#endif
/* Set Format properties according to the WAVE file we just opened */
//LPDIRECTSOUNDBUFFER lpDSB = NULL;
dsbd.lpwfxFormat = lpswWave->pwfx;
dsRetVal = lpDS->CreateSoundBuffer( &dsbd,
&lpswWave->lpDSBStreamBuffer,
NULL );
if( dsRetVal != DS_OK )
{
nChkErr = ERR_CREATEDSB_FAILED;
//SoundFail( DS_hwndGame, nChkErr );
goto END_SETUP;
}
/*
// set wave format
if ((dsRetVal = lpDSBPrimary->SetFormat(&wfx)) != DS_OK)
{
nChkErr = ERR_WAVE_FORMAT_INVALID;
SoundFail( DS_hwndGame, nChkErr );
goto END_SETUP;
}
*/
// lock buffer and copy sound data to it
dsRetVal = lpswWave->lpDSBStreamBuffer->Lock( 0, lpswWave->cbSize,
(void**)&lpWrite1, (&dwLen1),
(void**)&lpWrite2, (&dwLen2),
0 );
if( dsRetVal != DS_OK )
{
nChkErr = ERR_CREATEDSB_LOST;
//SoundFail( DS_hwndGame, nChkErr );
lpswWave->lpDSBStreamBuffer->Release();
lpswWave->lpDSBStreamBuffer = NULL;
goto END_SETUP;
}
// copy data
memcpy( lpWrite1, lpswWave->pbData, dwLen1 );
memcpy( lpWrite2, lpswWave->pbData+dwLen1, dwLen2 );
// unlock
dsRetVal = lpswWave->lpDSBStreamBuffer->Unlock( (LPVOID)lpWrite1, dwLen1,
(LPVOID)lpWrite2, 0 );
// LPARAM : 0 if it is dynamic wave object
SendMessage( DS_hwndGame, WM_DSSTREAM_PROGRESS, 0L, 0L );
nChkErr = 0;
END_SETUP:
return nChkErr;
}
void StreamBufferReleaseS( int nIndex )
{
WAVESTATIC * lpswWave = NULL;
lpswWave = SetToGlobalS( nIndex );
// release sound buffer, and unregister from global array
// wave file has been closed in Load()
// just free some data
GlobalFree(lpswWave->pwfx); lpswWave->pwfx = NULL;
GlobalFree(lpswWave->pbData); lpswWave->pbData = NULL;
if( lpswWave->lpDSBStreamBuffer )
lpswWave->lpDSBStreamBuffer->Release();
lpswWave->lpDSBStreamBuffer = NULL;
}
LPWAVESTATIC SetToGlobalS( int nIndex )
{
return lpwsWaves[nIndex];
}
// for static wave only
// called if the static sound buffer got the end
// clear all the sounds played prviously, and now they are stoped.
void DS_CloseStopedSoundS()
{
HRESULT dsrval;
// close static sound buffers that previously opened.
for( int i=0; i<WAVE_OBJECT_MAXS; i++ )
{
if( lpwsWaves[i] != NULL )
{
DWORD dwStatus;
#ifdef __TEST_SOUND__
ASSERT( lpwsWaves[i]->nID != WAVE_OBJECT_NONE );
#endif
dsrval = lpwsWaves[i]->lpDSBStreamBuffer->GetStatus( &dwStatus );
if ( DS_OK != dsrval ) continue;
if( !(dwStatus & DSBSTATUS_PLAYING) )
{
// must be sendmessage, cannot use postmessage
// LPARAM : 1 if it is static wave object
SendMessage( DS_hwndGame, WM_DSSTREAM_DONE, (WPARAM)lpwsWaves[i]->nID, (LPARAM)1 );
lpwsWaves[i]->Stop();
}
}
}
}
//////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -