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

📄 dsutil.cpp

📁 mpeg4 video codec mpeg4 video codec
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    if( strWaveFileName == NULL || ppStreamingSound == NULL || hNotifyEvent == NULL )        return E_INVALIDARG;    LPDIRECTSOUNDBUFFER pDSBuffer      = NULL;    DWORD               dwDSBufferSize = NULL;    CWaveFile*          pWaveFile      = NULL;    DSBPOSITIONNOTIFY*  aPosNotify     = NULL;     LPDIRECTSOUNDNOTIFY pDSNotify      = NULL;    pWaveFile = new CWaveFile();    if( pWaveFile == NULL )        return E_OUTOFMEMORY;    pWaveFile->Open( strWaveFileName, NULL, WAVEFILE_READ );    // Figure out how big the DSound buffer should be     dwDSBufferSize = dwNotifySize * dwNotifyCount;    // Set up the direct sound buffer.  Request the NOTIFY flag, so    // that we are notified as the sound buffer plays.  Note, that using this flag    // may limit the amount of hardware acceleration that can occur.     DSBUFFERDESC dsbd;    ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );    dsbd.dwSize          = sizeof(DSBUFFERDESC);    dsbd.dwFlags         = dwCreationFlags |                            DSBCAPS_CTRLPOSITIONNOTIFY |                            DSBCAPS_GETCURRENTPOSITION2;    dsbd.dwBufferBytes   = dwDSBufferSize;    dsbd.guid3DAlgorithm = guid3DAlgorithm;    dsbd.lpwfxFormat     = pWaveFile->m_pwfx;    if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &pDSBuffer, NULL ) ) )    {        // If wave format isn't then it will return         // either DSERR_BADFORMAT or E_INVALIDARG        if( hr == DSERR_BADFORMAT || hr == E_INVALIDARG )            return DXTRACE_ERR( TEXT("CreateSoundBuffer"), hr );        return DXTRACE_ERR( TEXT("CreateSoundBuffer"), hr );    }    // Create the notification events, so that we know when to fill    // the buffer as the sound plays.     if( FAILED( hr = pDSBuffer->QueryInterface( IID_IDirectSoundNotify,                                                 (VOID**)&pDSNotify ) ) )    {        SAFE_DELETE_ARRAY( aPosNotify );        return DXTRACE_ERR( TEXT("QueryInterface"), hr );    }    aPosNotify = new DSBPOSITIONNOTIFY[ dwNotifyCount ];    if( aPosNotify == NULL )        return E_OUTOFMEMORY;    for( DWORD i = 0; i < dwNotifyCount; i++ )    {        aPosNotify[i].dwOffset     = (dwNotifySize * i) + dwNotifySize - 1;        aPosNotify[i].hEventNotify = hNotifyEvent;                 }        // Tell DirectSound when to notify us. The notification will come in the from     // of signaled events that are handled in WinMain()    if( FAILED( hr = pDSNotify->SetNotificationPositions( dwNotifyCount,                                                           aPosNotify ) ) )    {        SAFE_RELEASE( pDSNotify );        SAFE_DELETE_ARRAY( aPosNotify );        return DXTRACE_ERR( TEXT("SetNotificationPositions"), hr );    }    SAFE_RELEASE( pDSNotify );    SAFE_DELETE_ARRAY( aPosNotify );    // Create the sound    *ppStreamingSound = new CStreamingSound( pDSBuffer, dwDSBufferSize, pWaveFile, dwNotifySize );    return S_OK;}//-----------------------------------------------------------------------------// Name: CSound::CSound()// Desc: Constructs the class//-----------------------------------------------------------------------------CSound::CSound( LPDIRECTSOUNDBUFFER* apDSBuffer, DWORD dwDSBufferSize,                 DWORD dwNumBuffers, CWaveFile* pWaveFile, DWORD dwCreationFlags ){    DWORD i;    m_apDSBuffer = new LPDIRECTSOUNDBUFFER[dwNumBuffers];    if( NULL != m_apDSBuffer )    {        for( i=0; i<dwNumBuffers; i++ )            m_apDSBuffer[i] = apDSBuffer[i];            m_dwDSBufferSize = dwDSBufferSize;        m_dwNumBuffers   = dwNumBuffers;        m_pWaveFile      = pWaveFile;        m_dwCreationFlags = dwCreationFlags;                FillBufferWithSound( m_apDSBuffer[0], false );    }}//-----------------------------------------------------------------------------// Name: CSound::~CSound()// Desc: Destroys the class//-----------------------------------------------------------------------------CSound::~CSound(){    for( DWORD i=0; i<m_dwNumBuffers; i++ )    {        SAFE_RELEASE( m_apDSBuffer[i] );     }    SAFE_DELETE_ARRAY( m_apDSBuffer );     SAFE_DELETE( m_pWaveFile );}//-----------------------------------------------------------------------------// Name: CSound::FillBufferWithSound()// Desc: Fills a DirectSound buffer with a sound file //-----------------------------------------------------------------------------HRESULT CSound::FillBufferWithSound( LPDIRECTSOUNDBUFFER pDSB, BOOL bRepeatWavIfBufferLarger ){    HRESULT hr;     VOID*   pDSLockedBuffer      = NULL; // Pointer to locked buffer memory    DWORD   dwDSLockedBufferSize = 0;    // Size of the locked DirectSound buffer    DWORD   dwWavDataRead        = 0;    // Amount of data read from the wav file     if( pDSB == NULL )        return CO_E_NOTINITIALIZED;    // Make sure we have focus, and we didn't just switch in from    // an app which had a DirectSound device    if( FAILED( hr = RestoreBuffer( pDSB, NULL ) ) )         return DXTRACE_ERR( TEXT("RestoreBuffer"), hr );    // Lock the buffer down    if( FAILED( hr = pDSB->Lock( 0, m_dwDSBufferSize,                                  &pDSLockedBuffer, &dwDSLockedBufferSize,                                  NULL, NULL, 0L ) ) )        return DXTRACE_ERR( TEXT("Lock"), hr );    // Reset the wave file to the beginning     m_pWaveFile->ResetFile();    if( FAILED( hr = m_pWaveFile->Read( (BYTE*) pDSLockedBuffer,                                        dwDSLockedBufferSize,                                         &dwWavDataRead ) ) )                   return DXTRACE_ERR( TEXT("Read"), hr );    if( dwWavDataRead == 0 )    {        // Wav is blank, so just fill with silence        FillMemory( (BYTE*) pDSLockedBuffer,                     dwDSLockedBufferSize,                     (BYTE)(m_pWaveFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) );    }    else if( dwWavDataRead < dwDSLockedBufferSize )    {        // If the wav file was smaller than the DirectSound buffer,         // we need to fill the remainder of the buffer with data         if( bRepeatWavIfBufferLarger )        {                   // Reset the file and fill the buffer with wav data            DWORD dwReadSoFar = dwWavDataRead;    // From previous call above.            while( dwReadSoFar < dwDSLockedBufferSize )            {                  // This will keep reading in until the buffer is full                 // for very short files                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        {            // Don't repeat the wav file, just fill in silence             FillMemory( (BYTE*) pDSLockedBuffer + dwWavDataRead,                         dwDSLockedBufferSize - dwWavDataRead,                         (BYTE)(m_pWaveFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) );        }    }    // Unlock the buffer, we don't need it anymore.    pDSB->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );    return S_OK;}//-----------------------------------------------------------------------------// Name: CSound::RestoreBuffer()// Desc: Restores the lost buffer. *pbWasRestored returns true if the buffer was //       restored.  It can also NULL if the information is not needed.//-----------------------------------------------------------------------------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 )    {        // Since the app could have just been activated, then        // DirectSound may not be giving us control yet, so         // the restoring the buffer may fail.          // If it does, sleep until DirectSound gives us control.        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;    }}//-----------------------------------------------------------------------------// Name: CSound::GetFreeBuffer()// Desc: Finding the first buffer that is not playing and return a pointer to //       it, or if all are playing return a pointer to a randomly selected buffer.//-----------------------------------------------------------------------------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 ];}//-----------------------------------------------------------------------------// Name: CSound::GetBuffer()// Desc: //-----------------------------------------------------------------------------LPDIRECTSOUNDBUFFER CSound::GetBuffer( DWORD dwIndex ){    if( m_apDSBuffer == NULL )        return NULL;    if( dwIndex >= m_dwNumBuffers )        return NULL;    return m_apDSBuffer[dwIndex];}//-----------------------------------------------------------------------------// Name: CSound::Get3DBufferInterface()// Desc: //-----------------------------------------------------------------------------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 );}//-----------------------------------------------------------------------------// Name: CSound::Play()// Desc: Plays the sound using voice management flags.  Pass in DSBPLAY_LOOPING//       in the dwFlags to loop the sound//-----------------------------------------------------------------------------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 );    // Restore the buffer if it was lost    if( FAILED( hr = RestoreBuffer( pDSB, &bRestored ) ) )        return DXTRACE_ERR( TEXT("RestoreBuffer"), hr );    if( bRestored )    {        // The buffer was restored, so we need to fill it with new data        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 );}//-----------------------------------------------------------------------------// Name: CSound::Play3D()// Desc: Plays the sound using voice management flags.  Pass in DSBPLAY_LOOPING//       in the dwFlags to loop the sound//-----------------------------------------------------------------------------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 );    // Restore the buffer if it was lost    if( FAILED( hr = RestoreBuffer( pDSB, &bRestored ) ) )        return DXTRACE_ERR( TEXT("RestoreBuffer"), hr );    if( bRestored )    {        // The buffer was restored, so we need to fill it with new data        if( FAILED( hr = FillBufferWithSound( pDSB, false ) ) )            return DXTRACE_ERR( TEXT("FillBufferWithSound"), hr );    }    if( m_dwCreationFlags & DSBCAPS_CTRLFREQUENCY )    {        pDSB->GetFrequency( &dwBaseFrequency );        pDSB->SetFrequency( dwBaseFrequency + lFrequency );    }    // QI for the 3D buffer     LPDIRECTSOUND3DBUFFER pDS3DBuffer;    hr = pDSB->QueryInterface( IID_IDirectSound3DBuffer, (VOID**) &pDS3DBuffer );    if( SUCCEEDED( hr ) )    {        hr = pDS3DBuffer->SetAllParameters( p3DBuffer, DS3D_IMMEDIATE );        if( SUCCEEDED( hr ) )

⌨️ 快捷键说明

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