コード例 #1
0
ファイル: SDKsound.cpp プロジェクト: Brainiarc7/smaa
//-----------------------------------------------------------------------------
// Name: CSoundManager::Get3DListenerInterface()
// Desc: Returns the 3D listener interface associated with primary buffer.
//-----------------------------------------------------------------------------
HRESULT CSoundManager::Get3DListenerInterface( LPDIRECTSOUND3DLISTENER* ppDSListener )
{
    HRESULT hr;
    DSBUFFERDESC dsbdesc;
    LPDIRECTSOUNDBUFFER pDSBPrimary = NULL;

    if( ppDSListener == NULL )
        return E_INVALIDARG;
    if( m_pDS == NULL )
        return CO_E_NOTINITIALIZED;

    *ppDSListener = NULL;

    // Obtain primary buffer, asking it for 3D control
    ZeroMemory( &dsbdesc, sizeof( DSBUFFERDESC ) );
    dsbdesc.dwSize = sizeof( DSBUFFERDESC );
    dsbdesc.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;
    if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbdesc, &pDSBPrimary, NULL ) ) )
        return DXUT_ERR( L"CreateSoundBuffer", hr );

    if( FAILED( hr = pDSBPrimary->QueryInterface( IID_IDirectSound3DListener,
                                                  ( VOID** )ppDSListener ) ) )
    {
        SAFE_RELEASE( pDSBPrimary );
        return DXUT_ERR( L"QueryInterface", hr );
    }

    // Release the primary buffer, since it is not need anymore
    SAFE_RELEASE( pDSBPrimary );

    return S_OK;
}
コード例 #2
0
ファイル: SDKsound.cpp プロジェクト: Brainiarc7/smaa
//-----------------------------------------------------------------------------
// Name: CStreamingSound::Reset()
// Desc: Resets the sound so it will begin playing at the beginning
//-----------------------------------------------------------------------------
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;

    // Restore the buffer if it was lost
    BOOL bRestored;
    if( FAILED( hr = RestoreBuffer( m_apDSBuffer[0], &bRestored ) ) )
        return DXUT_ERR( L"RestoreBuffer", hr );

    if( bRestored )
    {
        // The buffer was restored, so we need to fill it with new data
        if( FAILED( hr = FillBufferWithSound( m_apDSBuffer[0], FALSE ) ) )
            return DXUT_ERR( L"FillBufferWithSound", hr );
    }

    m_pWaveFile->ResetFile();

    return m_apDSBuffer[0]->SetCurrentPosition( 0L );
}
コード例 #3
0
    // ////////////////////////////////////////////////////////////////////
    //
    // ////////////////////////////////////////////////////////////////////
    HRESULT DirectSound8Audio::SetPrimaryBufferFormat(
        DWORD dwPrimaryChannels,
        DWORD dwPrimaryFreq,
        DWORD dwPrimaryBitRate)
    {
        // !WARNING! - Setting the primary buffer format and then using this
        // it for DirectMusic messes up DirectMusic!
        //
        // If you want your primary buffer format to be 22kHz stereo, 16-bit
        // call with these parameters:  SetPrimaryBufferFormat(2, 22050, 16);

        HRESULT             hr;
        LPDIRECTSOUNDBUFFER pDSBPrimary = NULL;

        if(m_pDS == NULL) {
            return (CO_E_NOTINITIALIZED);
        }

        // Get the primary buffer
        DSBUFFERDESC dsbd;
        ZeroMemory(&dsbd, sizeof(DSBUFFERDESC));
        dsbd.dwSize        = sizeof(DSBUFFERDESC);
        dsbd.dwFlags       = DSBCAPS_PRIMARYBUFFER;
        dsbd.dwBufferBytes = 0;
        dsbd.lpwfxFormat   = NULL;

        if(FAILED(hr = m_pDS->CreateSoundBuffer(&dsbd, &pDSBPrimary, NULL))) {
            return (DXUT_ERR(L"CreateSoundBuffer", hr));
        }

        WAVEFORMATEX wfx;
        ZeroMemory(&wfx, sizeof(WAVEFORMATEX));
        wfx.wFormatTag      = (WORD) WAVE_FORMAT_PCM;
        wfx.nChannels       = (WORD) dwPrimaryChannels;
        wfx.nSamplesPerSec  = (DWORD) dwPrimaryFreq;
        wfx.wBitsPerSample  = (WORD) dwPrimaryBitRate;
        wfx.nBlockAlign     = (WORD)(wfx.wBitsPerSample / 8 * wfx.nChannels);
        wfx.nAvgBytesPerSec = (DWORD)(wfx.nSamplesPerSec * wfx.nBlockAlign);

        if(FAILED(hr = pDSBPrimary->SetFormat(&wfx))) {
            return (DXUT_ERR(L"SetFormat", hr));
        }

        Release(pDSBPrimary);

        return (S_OK);
    }
コード例 #4
0
ファイル: SDKsound.cpp プロジェクト: Brainiarc7/smaa
//-----------------------------------------------------------------------------
// Name: CSoundManager::Initialize()
// Desc: Initializes the IDirectSound object and also sets the primary buffer
//       format.  This function must be called before any others.
//-----------------------------------------------------------------------------
HRESULT CSoundManager::Initialize( HWND hWnd,
                                   DWORD dwCoopLevel )
{
    HRESULT hr;

    SAFE_RELEASE( m_pDS );

    // Create IDirectSound using the primary sound device
    if( FAILED( hr = DirectSoundCreate8( NULL, &m_pDS, NULL ) ) )
        return DXUT_ERR( L"DirectSoundCreate8", hr );

    // Set DirectSound coop level
    if( FAILED( hr = m_pDS->SetCooperativeLevel( hWnd, dwCoopLevel ) ) )
        return DXUT_ERR( L"SetCooperativeLevel", hr );

    return S_OK;
}
コード例 #5
0
ファイル: SDKsound.cpp プロジェクト: Brainiarc7/smaa
//-----------------------------------------------------------------------------
// 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 DXUT_ERR( L"GetFreeBuffer", E_FAIL );

    // Restore the buffer if it was lost
    if( FAILED( hr = RestoreBuffer( pDSB, &bRestored ) ) )
        return DXUT_ERR( L"RestoreBuffer", hr );

    if( bRestored )
    {
        // The buffer was restored, so we need to fill it with new data
        if( FAILED( hr = FillBufferWithSound( pDSB, FALSE ) ) )
            return DXUT_ERR( L"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 ) )
        {
            hr = pDSB->Play( 0, dwPriority, dwFlags );
        }

        pDS3DBuffer->Release();
    }

    return hr;
}
コード例 #6
0
bool RenderWin32DX9Imp::createDevice( bool bWindowed, int nSuggestedWidth, int nSuggestedHeight ) {
    const HRESULT hr = DXUTCreateDevice( bWindowed, nSuggestedWidth, nSuggestedHeight );
    if( FAILED( hr ) ) {
        DXUT_ERR( L"RenderWin32DX9Imp::createDevice", hr );
        return false;
    }
    return true;
}
コード例 #7
0
void SurfaceDX9Imp::unlock( SurfaceLockedRectDX9 * lockedRect )
{
    const HRESULT hr = dx9Surface_->UnlockRect();
    if( FAILED( hr ) )
        DXUT_ERR( L"SurfaceDX9Imp::unlock", hr );

    lockedRect_.reset();
}
コード例 #8
0
    // ////////////////////////////////////////////////////////////////////
    //
    // ////////////////////////////////////////////////////////////////////
    HRESULT DirectSound8AudioBuffer::FillBufferWithSound(void)
    {
        HRESULT hr;
        VOID    *pDSLockedBuffer = NULL;     // a pointer to the DirectSound buffer
        DWORD   dwDSLockedBufferSize = 0;    // Size of the locked DirectSound buffer
        DWORD   dwWavDataRead        = 0;    // Amount of data read from the wav file

        if(m_Sample == 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(NULL))) {
            return DXUT_ERR(L"RestoreBuffer", hr);
        }

        I32 pcmBufferSize = m_Resource->GetPCMBufferSize();
        // Lock the buffer down
        if(FAILED(hr = m_Sample->Lock(0, pcmBufferSize,
                                      &pDSLockedBuffer, &dwDSLockedBufferSize,
                                      NULL, NULL, 0L))) {
            return (DXUT_ERR(L"Lock", hr));
        }

        if(pcmBufferSize == 0) {
            // Wav is blank, so just fill with silence
            FillMemory((BYTE*) pDSLockedBuffer,
                       dwDSLockedBufferSize,
                       (BYTE)(m_Resource->GetFormat()->wBitsPerSample == 8 ? 128 : 0));
        } else {
            CopyMemory(pDSLockedBuffer, m_Resource->GetPCMBuffer(), pcmBufferSize);
            if(pcmBufferSize < static_cast<I32>(dwDSLockedBufferSize)) {
                // If the buffer sizes are different fill in the rest with silence
                FillMemory((BYTE*) pDSLockedBuffer + pcmBufferSize,
                           dwDSLockedBufferSize - pcmBufferSize,
                           (BYTE)(m_Resource->GetFormat()->wBitsPerSample == 8 ? 128 : 0));
            }
        }

        // Unlock the buffer, we don't need it anymore.
        m_Sample->Unlock(pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0);

        return (S_OK);
    }
コード例 #9
0
ファイル: SDKsound.cpp プロジェクト: Brainiarc7/smaa
//-----------------------------------------------------------------------------
// 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 DXUT_ERR( L"GetFreeBuffer", E_FAIL );

    // Restore the buffer if it was lost
    if( FAILED( hr = RestoreBuffer( pDSB, &bRestored ) ) )
        return DXUT_ERR( L"RestoreBuffer", hr );

    if( bRestored )
    {
        // The buffer was restored, so we need to fill it with new data
        if( FAILED( hr = FillBufferWithSound( pDSB, FALSE ) ) )
            return DXUT_ERR( L"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 );
}
コード例 #10
0
D3DSURFACE_DESC RenderWin32DX9Imp::getRenderTargetDesc() {
    LPDIRECT3DSURFACE9 currentRenderTarget = NULL;
    const HRESULT hr = getD3D9Device()->GetRenderTarget( 0, & currentRenderTarget );
    if( FAILED( hr ) ) {
        DXUT_ERR( L"RenderWin32DX9Imp::getHeight", hr );
        throw exception();
    }

    D3DSURFACE_DESC desc;
    currentRenderTarget->GetDesc( & desc );
    SAFE_RELEASE( currentRenderTarget );

    return desc;
}
コード例 #11
0
ファイル: SDKsound.cpp プロジェクト: Brainiarc7/smaa
//-----------------------------------------------------------------------------
// Name: CSoundManager::SetPrimaryBufferFormat()
// Desc: Set primary buffer to a specified format
//       !WARNING! - Setting the primary buffer format and then using this
//                   same DirectSound object for DirectMusic messes up
//                   DirectMusic!
//       For example, to set the primary buffer format to 22kHz stereo, 16-bit
//       then:   dwPrimaryChannels = 2
//               dwPrimaryFreq     = 22050,
//               dwPrimaryBitRate  = 16
//-----------------------------------------------------------------------------
HRESULT CSoundManager::SetPrimaryBufferFormat( DWORD dwPrimaryChannels,
                                               DWORD dwPrimaryFreq,
                                               DWORD dwPrimaryBitRate )
{
    HRESULT hr;
    LPDIRECTSOUNDBUFFER pDSBPrimary = NULL;

    if( m_pDS == NULL )
        return CO_E_NOTINITIALIZED;

    // Get the primary buffer
    DSBUFFERDESC dsbd;
    ZeroMemory( &dsbd, sizeof( DSBUFFERDESC ) );
    dsbd.dwSize = sizeof( DSBUFFERDESC );
    dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
    dsbd.dwBufferBytes = 0;
    dsbd.lpwfxFormat = NULL;

    if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL ) ) )
        return DXUT_ERR( L"CreateSoundBuffer", hr );

    WAVEFORMATEX wfx;
    ZeroMemory( &wfx, sizeof( WAVEFORMATEX ) );
    wfx.wFormatTag = ( WORD )WAVE_FORMAT_PCM;
    wfx.nChannels = ( WORD )dwPrimaryChannels;
    wfx.nSamplesPerSec = ( DWORD )dwPrimaryFreq;
    wfx.wBitsPerSample = ( WORD )dwPrimaryBitRate;
    wfx.nBlockAlign = ( WORD )( wfx.wBitsPerSample / 8 * wfx.nChannels );
    wfx.nAvgBytesPerSec = ( DWORD )( wfx.nSamplesPerSec * wfx.nBlockAlign );

    if( FAILED( hr = pDSBPrimary->SetFormat( &wfx ) ) )
        return DXUT_ERR( L"SetFormat", hr );

    SAFE_RELEASE( pDSBPrimary );

    return S_OK;
}
コード例 #12
0
    // ////////////////////////////////////////////////////////////////////
    //
    // ////////////////////////////////////////////////////////////////////
    HRESULT DirectSound8AudioBuffer::RestoreBuffer(BOOL* pbWasRestored)
    {
        HRESULT hr;

        if(m_Sample == NULL) {
            return CO_E_NOTINITIALIZED;
        }

        if(pbWasRestored) {
            *pbWasRestored = FALSE;
        }

        DWORD dwStatus;
        if(FAILED(hr = m_Sample->GetStatus(&dwStatus))) {
            return DXUT_ERR(L"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.

            // We will try to restore it a maxmimum number of times before giving up.
            const I32 NUM_RETRIES = 20;
            I32 i = 1;
            do {
                hr = m_Sample->Restore();
                if(hr == DSERR_BUFFERLOST) {
                    Sleep(10);
                }

                ++i;
            } while((i <= NUM_RETRIES) && ((hr = m_Sample->Restore()) == DSERR_BUFFERLOST));

            if(i >= NUM_RETRIES) {
                GF_LOG_TRACE_DEB("DirectSound8AudioBuffer::RestoreBuffer()", "Failed to restore the buffer after NUM_RETRIES tries.  DirectSound seems to be in a broken state...");
            } else {
                if(pbWasRestored) {
                    *pbWasRestored = TRUE;
                }
            }

            return (S_OK);
        } else {
            return (S_FALSE);
        }
    }
コード例 #13
0
ファイル: SDKsound.cpp プロジェクト: Brainiarc7/smaa
//-----------------------------------------------------------------------------
// 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 DXUT_ERR( L"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;
    }
}
コード例 #14
0
ファイル: SDKsound.cpp プロジェクト: Brainiarc7/smaa
//-----------------------------------------------------------------------------
// 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 DXUT_ERR( L"RestoreBuffer", hr );

    // Lock the buffer down
    if( FAILED( hr = pDSB->Lock( 0, m_dwDSBufferSize,
                                 &pDSLockedBuffer, &dwDSLockedBufferSize,
                                 NULL, NULL, 0L ) ) )
        return DXUT_ERR( L"Lock", hr );

    // Reset the wave file to the beginning
    m_pWaveFile->ResetFile();

    if( FAILED( hr = m_pWaveFile->Read( ( BYTE* )pDSLockedBuffer,
                                        dwDSLockedBufferSize,
                                        &dwWavDataRead ) ) )
        return DXUT_ERR( L"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 DXUT_ERR( L"ResetFile", hr );

                hr = m_pWaveFile->Read( ( BYTE* )pDSLockedBuffer + dwReadSoFar,
                                        dwDSLockedBufferSize - dwReadSoFar,
                                        &dwWavDataRead );
                if( FAILED( hr ) )
                    return DXUT_ERR( L"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;
}
コード例 #15
0
ファイル: SDKsound.cpp プロジェクト: Brainiarc7/smaa
//-----------------------------------------------------------------------------
// Name: CSoundManager::Create()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CSoundManager::Create( CSound** ppSound,
                               LPWSTR strWaveFileName,
                               DWORD dwCreationFlags,
                               GUID guid3DAlgorithm,
                               DWORD dwNumBuffers )
{
    HRESULT hr;
    HRESULT hrRet = S_OK;
    DWORD i;
    LPDIRECTSOUNDBUFFER* apDSBuffer = NULL;
    DWORD dwDSBufferSize = NULL;
    CWaveFile* pWaveFile = NULL;

    if( m_pDS == NULL )
        return CO_E_NOTINITIALIZED;
    if( strWaveFileName == NULL || ppSound == NULL || dwNumBuffers < 1 )
        return E_INVALIDARG;

    apDSBuffer = new LPDIRECTSOUNDBUFFER[dwNumBuffers];
    if( apDSBuffer == NULL )
    {
        hr = E_OUTOFMEMORY;
        goto LFail;
    }

    pWaveFile = new CWaveFile();
    if( pWaveFile == NULL )
    {
        hr = E_OUTOFMEMORY;
        goto LFail;
    }

    pWaveFile->Open( strWaveFileName, NULL, WAVEFILE_READ );

    if( pWaveFile->GetSize() == 0 )
    {
        // Wave is blank, so don't create it.
        hr = E_FAIL;
        goto LFail;
    }

    // Make the DirectSound buffer the same size as the wav file
    dwDSBufferSize = pWaveFile->GetSize();

    // Create the direct sound buffer, and only request the flags needed
    // since each requires some overhead and limits if the buffer can
    // be hardware accelerated
    DSBUFFERDESC dsbd;
    ZeroMemory( &dsbd, sizeof( DSBUFFERDESC ) );
    dsbd.dwSize = sizeof( DSBUFFERDESC );
    dsbd.dwFlags = dwCreationFlags;
    dsbd.dwBufferBytes = dwDSBufferSize;
    dsbd.guid3DAlgorithm = guid3DAlgorithm;
    dsbd.lpwfxFormat = pWaveFile->m_pwfx;

    // DirectSound is only guarenteed to play PCM data.  Other
    // formats may or may not work depending the sound card driver.
    hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer[0], NULL );

    // Be sure to return this error code if it occurs so the
    // callers knows this happened.
    if( hr == DS_NO_VIRTUALIZATION )
        hrRet = DS_NO_VIRTUALIZATION;

    if( FAILED( hr ) )
    {
        // DSERR_BUFFERTOOSMALL will be returned if the buffer is
        // less than DSBSIZE_FX_MIN and the buffer is created
        // with DSBCAPS_CTRLFX.

        // It might also fail if hardware buffer mixing was requested
        // on a device that doesn't support it.
        DXUT_ERR( L"CreateSoundBuffer", hr );

        goto LFail;
    }

    // Default to use DuplicateSoundBuffer() when created extra buffers since always
    // create a buffer that uses the same memory however DuplicateSoundBuffer() will fail if
    // DSBCAPS_CTRLFX is used, so use CreateSoundBuffer() instead in this case.
    if( ( dwCreationFlags & DSBCAPS_CTRLFX ) == 0 )
    {
        for( i = 1; i < dwNumBuffers; i++ )
        {
            if( FAILED( hr = m_pDS->DuplicateSoundBuffer( apDSBuffer[0], &apDSBuffer[i] ) ) )
            {
                DXUT_ERR( L"DuplicateSoundBuffer", hr );
                goto LFail;
            }
        }
    }
    else
    {
        for( i = 1; i < dwNumBuffers; i++ )
        {
            hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer[i], NULL );
            if( FAILED( hr ) )
            {
                DXUT_ERR( L"CreateSoundBuffer", hr );
                goto LFail;
            }
        }
    }

    // Create the sound
    *ppSound = new CSound( apDSBuffer, dwDSBufferSize, dwNumBuffers, pWaveFile, dwCreationFlags );

    SAFE_DELETE_ARRAY( apDSBuffer );
    return hrRet;

LFail:
    // Cleanup
    SAFE_DELETE( pWaveFile );
    SAFE_DELETE_ARRAY( apDSBuffer );
    return hr;
}
コード例 #16
0
ファイル: SDKsound.cpp プロジェクト: Brainiarc7/smaa
//-----------------------------------------------------------------------------
// Name: CSoundManager::CreateFromMemory()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CSoundManager::CreateFromMemory( CSound** ppSound,
                                         BYTE* pbData,
                                         ULONG ulDataSize,
                                         LPWAVEFORMATEX pwfx,
                                         DWORD dwCreationFlags,
                                         GUID guid3DAlgorithm,
                                         DWORD dwNumBuffers )
{
    HRESULT hr;
    DWORD i;
    LPDIRECTSOUNDBUFFER* apDSBuffer = NULL;
    DWORD dwDSBufferSize = NULL;
    CWaveFile* pWaveFile = NULL;

    if( m_pDS == NULL )
        return CO_E_NOTINITIALIZED;
    if( pbData == NULL || ppSound == NULL || dwNumBuffers < 1 )
        return E_INVALIDARG;

    apDSBuffer = new LPDIRECTSOUNDBUFFER[dwNumBuffers];
    if( apDSBuffer == NULL )
    {
        hr = E_OUTOFMEMORY;
        goto LFail;
    }

    pWaveFile = new CWaveFile();
    if( pWaveFile == NULL )
    {
        hr = E_OUTOFMEMORY;
        goto LFail;
    }

    pWaveFile->OpenFromMemory( pbData, ulDataSize, pwfx, WAVEFILE_READ );


    // Make the DirectSound buffer the same size as the wav file
    dwDSBufferSize = ulDataSize;

    // Create the direct sound buffer, and only request the flags needed
    // since each requires some overhead and limits if the buffer can
    // be hardware accelerated
    DSBUFFERDESC dsbd;
    ZeroMemory( &dsbd, sizeof( DSBUFFERDESC ) );
    dsbd.dwSize = sizeof( DSBUFFERDESC );
    dsbd.dwFlags = dwCreationFlags;
    dsbd.dwBufferBytes = dwDSBufferSize;
    dsbd.guid3DAlgorithm = guid3DAlgorithm;
    dsbd.lpwfxFormat = pwfx;

    if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer[0], NULL ) ) )
    {
        DXUT_ERR( L"CreateSoundBuffer", hr );
        goto LFail;
    }

    // Default to use DuplicateSoundBuffer() when created extra buffers since always
    // create a buffer that uses the same memory however DuplicateSoundBuffer() will fail if
    // DSBCAPS_CTRLFX is used, so use CreateSoundBuffer() instead in this case.
    if( ( dwCreationFlags & DSBCAPS_CTRLFX ) == 0 )
    {
        for( i = 1; i < dwNumBuffers; i++ )
        {
            if( FAILED( hr = m_pDS->DuplicateSoundBuffer( apDSBuffer[0], &apDSBuffer[i] ) ) )
            {
                DXUT_ERR( L"DuplicateSoundBuffer", hr );
                goto LFail;
            }
        }
    }
    else
    {
        for( i = 1; i < dwNumBuffers; i++ )
        {
            hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer[i], NULL );
            if( FAILED( hr ) )
            {
                DXUT_ERR( L"CreateSoundBuffer", hr );
                goto LFail;
            }
        }
    }

    // Create the sound
    *ppSound = new CSound( apDSBuffer, dwDSBufferSize, dwNumBuffers, pWaveFile, dwCreationFlags );

    SAFE_DELETE_ARRAY( apDSBuffer );
    return S_OK;

LFail:
    // Cleanup

    SAFE_DELETE_ARRAY( apDSBuffer );
    return hr;
}
コード例 #17
0
ファイル: SDKsound.cpp プロジェクト: Brainiarc7/smaa
//-----------------------------------------------------------------------------
// Name: CStreamingSound::HandleWaveStreamNotification()
// Desc: Handle the notification that tells us to put more wav data in the
//       circular buffer
//-----------------------------------------------------------------------------
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;

    // Restore the buffer if it was lost
    BOOL bRestored;
    if( FAILED( hr = RestoreBuffer( m_apDSBuffer[0], &bRestored ) ) )
        return DXUT_ERR( L"RestoreBuffer", hr );

    if( bRestored )
    {
        // The buffer was restored, so we need to fill it with new data
        if( FAILED( hr = FillBufferWithSound( m_apDSBuffer[0], FALSE ) ) )
            return DXUT_ERR( L"FillBufferWithSound", hr );
        return S_OK;
    }

    // Lock the DirectSound buffer
    if( FAILED( hr = m_apDSBuffer[0]->Lock( m_dwNextWriteOffset, m_dwNotifySize,
                                            &pDSLockedBuffer, &dwDSLockedBufferSize,
                                            &pDSLockedBuffer2, &dwDSLockedBufferSize2, 0L ) ) )
        return DXUT_ERR( L"Lock", hr );

    // m_dwDSBufferSize and m_dwNextWriteOffset are both multiples of m_dwNotifySize,
    // it should the second buffer, so it should never be valid
    if( pDSLockedBuffer2 != NULL )
        return E_UNEXPECTED;

    if( !m_bFillNextNotificationWithSilence )
    {
        // Fill the DirectSound buffer with wav data
        if( FAILED( hr = m_pWaveFile->Read( ( BYTE* )pDSLockedBuffer,
                                            dwDSLockedBufferSize,
                                            &dwBytesWrittenToBuffer ) ) )
            return DXUT_ERR( L"Read", hr );
    }
    else
    {
        // Fill the DirectSound buffer with silence
        FillMemory( pDSLockedBuffer, dwDSLockedBufferSize,
                    ( BYTE )( m_pWaveFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) );
        dwBytesWrittenToBuffer = dwDSLockedBufferSize;
    }

    // If the number of bytes written is less than the
    // amount we requested, we have a short file.
    if( dwBytesWrittenToBuffer < dwDSLockedBufferSize )
    {
        if( !bLoopedPlay )
        {
            // Fill in silence for the rest of the buffer.
            FillMemory( ( BYTE* )pDSLockedBuffer + dwBytesWrittenToBuffer,
                        dwDSLockedBufferSize - dwBytesWrittenToBuffer,
                        ( BYTE )( m_pWaveFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) );

            // Any future notifications should just fill the buffer with silence
            m_bFillNextNotificationWithSilence = TRUE;
        }
        else
        {
            // We are looping, so reset the file and fill the buffer with wav data
            DWORD dwReadSoFar = dwBytesWrittenToBuffer;    // 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 DXUT_ERR( L"ResetFile", hr );

                if( FAILED( hr = m_pWaveFile->Read( ( BYTE* )pDSLockedBuffer + dwReadSoFar,
                                                    dwDSLockedBufferSize - dwReadSoFar,
                                                    &dwBytesWrittenToBuffer ) ) )
                    return DXUT_ERR( L"Read", hr );

                dwReadSoFar += dwBytesWrittenToBuffer;
            }
        }
    }

    // Unlock the DirectSound buffer
    m_apDSBuffer[0]->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );

    // Figure out how much data has been played so far.  When we have played
    // past the end of the file, we will either need to start filling the
    // buffer with silence or starting reading from the beginning of the file,
    // depending if the user wants to loop the sound
    if( FAILED( hr = m_apDSBuffer[0]->GetCurrentPosition( &dwCurrentPlayPos, NULL ) ) )
        return DXUT_ERR( L"GetCurrentPosition", hr );

    // Check to see if the position counter looped
    if( dwCurrentPlayPos < m_dwLastPlayPos )
        dwPlayDelta = ( m_dwDSBufferSize - m_dwLastPlayPos ) + dwCurrentPlayPos;
    else
        dwPlayDelta = dwCurrentPlayPos - m_dwLastPlayPos;

    m_dwPlayProgress += dwPlayDelta;
    m_dwLastPlayPos = dwCurrentPlayPos;

    // If we are now filling the buffer with silence, then we have found the end so
    // check to see if the entire sound has played, if it has then stop the buffer.
    if( m_bFillNextNotificationWithSilence )
    {
        // We don't want to cut off the sound before it's done playing.
        if( m_dwPlayProgress >= m_pWaveFile->GetSize() )
        {
            m_apDSBuffer[0]->Stop();
        }
    }

    // Update where the buffer will lock (for next time)
    m_dwNextWriteOffset += dwDSLockedBufferSize;
    m_dwNextWriteOffset %= m_dwDSBufferSize; // Circular buffer

    return S_OK;
}
コード例 #18
0
ファイル: SDKsound.cpp プロジェクト: Brainiarc7/smaa
//-----------------------------------------------------------------------------
// Name: CSoundManager::CreateStreaming()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CSoundManager::CreateStreaming( CStreamingSound** ppStreamingSound,
                                        LPWSTR strWaveFileName,
                                        DWORD dwCreationFlags,
                                        GUID guid3DAlgorithm,
                                        DWORD dwNotifyCount,
                                        DWORD dwNotifySize,
                                        HANDLE hNotifyEvent )
{
    HRESULT hr;

    if( m_pDS == NULL )
        return CO_E_NOTINITIALIZED;
    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 DirectSound 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 DXUT_ERR( L"CreateSoundBuffer", hr );

        return DXUT_ERR( L"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 DXUT_ERR( L"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 DXUT_ERR( L"SetNotificationPositions", hr );
    }

    SAFE_RELEASE( pDSNotify );
    SAFE_DELETE_ARRAY( aPosNotify );

    // Create the sound
    *ppStreamingSound = new CStreamingSound( pDSBuffer, dwDSBufferSize, pWaveFile, dwNotifySize );

    return S_OK;
}