📄 dsutil.cpp
字号:
DWORD dwWavDataRead = 0;
if( pDSB == NULL )
return CO_E_NOTINITIALIZED;
if( FAILED( hr = RestoreBuffer( pDSB, NULL ) ) )
return DXTRACE_ERR( TEXT("RestoreBuffer"), hr );
if( FAILED( hr = pDSB->Lock( 0, m_dwDSBufferSize,
&pDSLockedBuffer, &dwDSLockedBufferSize,
NULL, NULL, 0L ) ) )
return DXTRACE_ERR( TEXT("Lock"), hr );
m_pWaveFile->ResetFile();
if( FAILED( hr = m_pWaveFile->Read( (BYTE*) pDSLockedBuffer,
dwDSLockedBufferSize,
&dwWavDataRead ) ) )
return DXTRACE_ERR( TEXT("Read"), hr );
if( dwWavDataRead == 0 )
{
FillMemory( (BYTE*) pDSLockedBuffer,
dwDSLockedBufferSize,
(BYTE)(m_pWaveFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) );
}
else if( dwWavDataRead < dwDSLockedBufferSize )
{
if( bRepeatWavIfBufferLarger )
{
DWORD dwReadSoFar = dwWavDataRead;
while( dwReadSoFar < dwDSLockedBufferSize )
{
if( FAILED( hr = m_pWaveFile->ResetFile() ) )
return DXTRACE_ERR( TEXT("ResetFile"), hr );
hr = m_pWaveFile->Read( (BYTE*)pDSLockedBuffer + dwReadSoFar,
dwDSLockedBufferSize - dwReadSoFar,
&dwWavDataRead );
if( FAILED(hr) )
return DXTRACE_ERR( TEXT("Read"), hr );
dwReadSoFar += dwWavDataRead;
}
}
else
{
FillMemory( (BYTE*) pDSLockedBuffer + dwWavDataRead,
dwDSLockedBufferSize - dwWavDataRead,
(BYTE)(m_pWaveFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) );
}
}
pDSB->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );
return S_OK;
}
HRESULT CSound::RestoreBuffer( LPDIRECTSOUNDBUFFER pDSB, BOOL* pbWasRestored )
{
HRESULT hr;
if( pDSB == NULL )
return CO_E_NOTINITIALIZED;
if( pbWasRestored )
*pbWasRestored = FALSE;
DWORD dwStatus;
if( FAILED( hr = pDSB->GetStatus( &dwStatus ) ) )
return DXTRACE_ERR( TEXT("GetStatus"), hr );
if( dwStatus & DSBSTATUS_BUFFERLOST )
{
do
{
hr = pDSB->Restore();
if( hr == DSERR_BUFFERLOST )
Sleep( 10 );
}
while( ( hr = pDSB->Restore() ) == DSERR_BUFFERLOST );
if( pbWasRestored != NULL )
*pbWasRestored = TRUE;
return S_OK;
}
else
{
return S_FALSE;
}
}
LPDIRECTSOUNDBUFFER CSound::GetFreeBuffer()
{
if( m_apDSBuffer == NULL )
return FALSE;
for( DWORD i=0; i<m_dwNumBuffers; i++ )
{
if( m_apDSBuffer[i] )
{
DWORD dwStatus = 0;
m_apDSBuffer[i]->GetStatus( &dwStatus );
if ( ( dwStatus & DSBSTATUS_PLAYING ) == 0 )
break;
}
}
if( i != m_dwNumBuffers )
return m_apDSBuffer[ i ];
else
return m_apDSBuffer[ rand() % m_dwNumBuffers ];
}
LPDIRECTSOUNDBUFFER CSound::GetBuffer( DWORD dwIndex )
{
if( m_apDSBuffer == NULL )
return NULL;
if( dwIndex >= m_dwNumBuffers )
return NULL;
return m_apDSBuffer[dwIndex];
}
HRESULT CSound::Get3DBufferInterface( DWORD dwIndex, LPDIRECTSOUND3DBUFFER* ppDS3DBuffer )
{
if( m_apDSBuffer == NULL )
return CO_E_NOTINITIALIZED;
if( dwIndex >= m_dwNumBuffers )
return E_INVALIDARG;
*ppDS3DBuffer = NULL;
return m_apDSBuffer[dwIndex]->QueryInterface( IID_IDirectSound3DBuffer,
(VOID**)ppDS3DBuffer );
}
HRESULT CSound::Play( DWORD dwPriority, DWORD dwFlags, LONG lVolume, LONG lFrequency, LONG lPan )
{
HRESULT hr;
BOOL bRestored;
if( m_apDSBuffer == NULL )
return CO_E_NOTINITIALIZED;
LPDIRECTSOUNDBUFFER pDSB = GetFreeBuffer();
if( pDSB == NULL )
return DXTRACE_ERR( TEXT("GetFreeBuffer"), E_FAIL );
if( FAILED( hr = RestoreBuffer( pDSB, &bRestored ) ) )
return DXTRACE_ERR( TEXT("RestoreBuffer"), hr );
if( bRestored )
{
if( FAILED( hr = FillBufferWithSound( pDSB, FALSE ) ) )
return DXTRACE_ERR( TEXT("FillBufferWithSound"), hr );
}
if( m_dwCreationFlags & DSBCAPS_CTRLVOLUME )
{
pDSB->SetVolume( lVolume );
}
if( lFrequency != -1 &&
(m_dwCreationFlags & DSBCAPS_CTRLFREQUENCY) )
{
pDSB->SetFrequency( lFrequency );
}
if( m_dwCreationFlags & DSBCAPS_CTRLPAN )
{
pDSB->SetPan( lPan );
}
return pDSB->Play( 0, dwPriority, dwFlags );
}
HRESULT CSound::Play3D( LPDS3DBUFFER p3DBuffer, DWORD dwPriority, DWORD dwFlags, LONG lFrequency )
{
HRESULT hr;
BOOL bRestored;
DWORD dwBaseFrequency;
if( m_apDSBuffer == NULL )
return CO_E_NOTINITIALIZED;
LPDIRECTSOUNDBUFFER pDSB = GetFreeBuffer();
if( pDSB == NULL )
return DXTRACE_ERR( TEXT("GetFreeBuffer"), E_FAIL );
if( FAILED( hr = RestoreBuffer( pDSB, &bRestored ) ) )
return DXTRACE_ERR( TEXT("RestoreBuffer"), hr );
if( bRestored )
{
if( FAILED( hr = FillBufferWithSound( pDSB, FALSE ) ) )
return DXTRACE_ERR( TEXT("FillBufferWithSound"), hr );
}
if( m_dwCreationFlags & DSBCAPS_CTRLFREQUENCY )
{
pDSB->GetFrequency( &dwBaseFrequency );
pDSB->SetFrequency( dwBaseFrequency + lFrequency );
}
LPDIRECTSOUND3DBUFFER pDS3DBuffer;
hr = pDSB->QueryInterface( IID_IDirectSound3DBuffer, (VOID**) &pDS3DBuffer );
if( SUCCEEDED( hr ) )
{
hr = pDS3DBuffer->SetAllParameters( p3DBuffer, DS3D_IMMEDIATE );
if( SUCCEEDED( hr ) )
{
hr = pDSB->Play( 0, dwPriority, dwFlags );
}
pDS3DBuffer->Release();
}
return hr;
}
HRESULT CSound::Stop()
{
if( m_apDSBuffer == NULL )
return CO_E_NOTINITIALIZED;
HRESULT hr = 0;
for( DWORD i=0; i<m_dwNumBuffers; i++ )
hr |= m_apDSBuffer[i]->Stop();
return hr;
}
HRESULT CSound::Reset()
{
if( m_apDSBuffer == NULL )
return CO_E_NOTINITIALIZED;
HRESULT hr = 0;
for( DWORD i=0; i<m_dwNumBuffers; i++ )
hr |= m_apDSBuffer[i]->SetCurrentPosition( 0 );
return hr;
}
BOOL CSound::IsSoundPlaying()
{
BOOL bIsPlaying = FALSE;
if( m_apDSBuffer == NULL )
return FALSE;
for( DWORD i=0; i<m_dwNumBuffers; i++ )
{
if( m_apDSBuffer[i] )
{
DWORD dwStatus = 0;
m_apDSBuffer[i]->GetStatus( &dwStatus );
bIsPlaying |= ( ( dwStatus & DSBSTATUS_PLAYING ) != 0 );
}
}
return bIsPlaying;
}
CStreamingSound::CStreamingSound( LPDIRECTSOUNDBUFFER pDSBuffer, DWORD dwDSBufferSize,
CWaveFile* pWaveFile, DWORD dwNotifySize )
: CSound( &pDSBuffer, dwDSBufferSize, 1, pWaveFile, 0 )
{
m_dwLastPlayPos = 0;
m_dwPlayProgress = 0;
m_dwNotifySize = dwNotifySize;
m_dwNextWriteOffset = 0;
m_bFillNextNotificationWithSilence = FALSE;
}
CStreamingSound::~CStreamingSound()
{
}
HRESULT CStreamingSound::HandleWaveStreamNotification( BOOL bLoopedPlay )
{
HRESULT hr;
DWORD dwCurrentPlayPos;
DWORD dwPlayDelta;
DWORD dwBytesWrittenToBuffer;
VOID* pDSLockedBuffer = NULL;
VOID* pDSLockedBuffer2 = NULL;
DWORD dwDSLockedBufferSize;
DWORD dwDSLockedBufferSize2;
if( m_apDSBuffer == NULL || m_pWaveFile == NULL )
return CO_E_NOTINITIALIZED;
BOOL bRestored;
if( FAILED( hr = RestoreBuffer( m_apDSBuffer[0], &bRestored ) ) )
return DXTRACE_ERR( TEXT("RestoreBuffer"), hr );
if( bRestored )
{
if( FAILED( hr = FillBufferWithSound( m_apDSBuffer[0], FALSE ) ) )
return DXTRACE_ERR( TEXT("FillBufferWithSound"), hr );
return S_OK;
}
if( FAILED( hr = m_apDSBuffer[0]->Lock( m_dwNextWriteOffset, m_dwNotifySize,
&pDSLockedBuffer, &dwDSLockedBufferSize,
&pDSLockedBuffer2, &dwDSLockedBufferSize2, 0L ) ) )
return DXTRACE_ERR( TEXT("Lock"), hr );
if( pDSLockedBuffer2 != NULL )
return E_UNEXPECTED;
if( !m_bFillNextNotificationWithSilence )
{
if( FAILED( hr = m_pWaveFile->Read( (BYTE*) pDSLockedBuffer,
dwDSLockedBufferSize,
&dwBytesWrittenToBuffer ) ) )
return DXTRACE_ERR( TEXT("Read"), hr );
}
else
{
FillMemory( pDSLockedBuffer, dwDSLockedBufferSize,
(BYTE)( m_pWaveFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) );
dwBytesWrittenToBuffer = dwDSLockedBufferSize;
}
if( dwBytesWrittenToBuffer < dwDSLockedBufferSize )
{
if( !bLoopedPlay )
{
FillMemory( (BYTE*) pDSLockedBuffer + dwBytesWrittenToBuffer,
dwDSLockedBufferSize - dwBytesWrittenToBuffer,
(BYTE)(m_pWaveFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) );
m_bFillNextNotificationWithSilence = TRUE;
}
else
{
DWORD dwReadSoFar = dwBytesWrittenToBuffer;
while( dwReadSoFar < dwDSLockedBufferSize )
{
if( FAILED( hr = m_pWaveFile->ResetFile() ) )
return DXTRACE_ERR( TEXT("ResetFile"), hr );
if( FAILED( hr = m_pWaveFile->Read( (BYTE*)pDSLockedBuffer + dwReadSoFar,
dwDSLockedBufferSize - dwReadSoFar,
&dwBytesWrittenToBuffer ) ) )
return DXTRACE_ERR( TEXT("Read"), hr );
dwReadSoFar += dwBytesWrittenToBuffer;
}
}
}
m_apDSBuffer[0]->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );
if( FAILED( hr = m_apDSBuffer[0]->GetCurrentPosition( &dwCurrentPlayPos, NULL ) ) )
return DXTRACE_ERR( TEXT("GetCurrentPosition"), hr );
if( dwCurrentPlayPos < m_dwLastPlayPos )
dwPlayDelta = ( m_dwDSBufferSize - m_dwLastPlayPos ) + dwCurrentPlayPos;
else
dwPlayDelta = dwCurrentPlayPos - m_dwLastPlayPos;
m_dwPlayProgress += dwPlayDelta;
m_dwLastPlayPos = dwCurrentPlayPos;
if( m_bFillNextNotificationWithSilence )
{
if( m_dwPlayProgress >= m_pWaveFile->GetSize() )
{
m_apDSBuffer[0]->Stop();
}
}
m_dwNextWriteOffset += dwDSLockedBufferSize;
m_dwNextWriteOffset %= m_dwDSBufferSize;
return S_OK;
}
HRESULT CStreamingSound::Reset()
{
HRESULT hr;
if( m_apDSBuffer[0] == NULL || m_pWaveFile == NULL )
return CO_E_NOTINITIALIZED;
m_dwLastPlayPos = 0;
m_dwPlayProgress = 0;
m_dwNextWriteOffset = 0;
m_bFillNextNotificationWithSilence = FALSE;
BOOL bRestored;
if( FAILED( hr = RestoreBuffer( m_apDSBuffer[0], &bRestored ) ) )
return DXTRACE_ERR( TEXT("RestoreBuffer"), hr );
if( bRestored )
{
if( FAILED( hr = FillBufferWithSound( m_apDSBuffer[0], FALSE ) ) )
return DXTRACE_ERR( TEXT("FillBufferWithSound"), hr );
}
m_pWaveFile->ResetFile();
return m_apDSBuffer[0]->SetCurrentPosition( 0L );
}
CWaveFile::CWaveFile()
{
m_pwfx = NULL;
m_hmmio = NULL;
m_pResourceBuffer = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -