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

📄 csound.cpp

📁 Visual C++ 游戏开发与设计实例 源代码(所有)
💻 CPP
字号:
// CMAIN LIB - APPLICATION AND DIRECT WRAPPER
//
// Written by Mauricio Teichmann Ritter
//
// Copyright (C) 2002, Brazil. All rights reserved.
// 
//

// cSound.cpp: implementation of the cSound class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "cSound.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

cSound::cSound()
{
	m_bIsPlaying = FALSE;
	m_sFileName  = NULL;
	m_pWaveFile = NULL;
	m_pSoundBuffer = NULL;
	m_p3DInterface = NULL;
}

cSound::~cSound()
{
	if(m_sFileName)
		free(m_sFileName);

	if(m_pWaveFile)
		delete m_pWaveFile;

	if(m_pSoundBuffer)
	{
		Stop();
		m_pSoundBuffer->Release();
		m_pSoundBuffer = NULL;
	}
}


HRESULT cSound::Create(LPTSTR lpszFileName, DWORD dwCreationFlags, GUID guid3DAlgorithm)
{

	Destroy();

    HRESULT hr;
    HRESULT hrRet = S_OK;

    DWORD                dwDSBufferSize = NULL;


	cSoundInterface		 pSoundInterface;


/*	if(MAKEINTRESOURCE(lpszFileName))
	{
	m_sFileName = (char*)malloc(strlen(lpszFileName)+1);
	strcpy(m_sFileName, lpszFileName);
	}
	else
	{
		m_sFileName = lpszFileName;
	}*/


    if( lpszFileName == NULL )
        return E_INVALIDARG;


    m_pWaveFile = new cWavFile();

    if( m_pWaveFile == NULL )
    {
        hr = E_OUTOFMEMORY;
        goto LFail;
    }

    if(m_pWaveFile->Open( lpszFileName, NULL, WAVEFILE_READ ) != 0)
	{
		DXTRACE_MSG("Didn磘 find resource!");
	}

    if( m_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 = m_pWaveFile->GetSize();
	m_dwDSBufferSize = dwDSBufferSize;
    // 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     = m_pWaveFile->m_pwfx;

    // DirectSound is only guarenteed to play PCM data.  Other
    // formats may or may not work depending the sound card driver.
    hr = pSoundInterface.GetDirectSound()->CreateSoundBuffer( &dsbd, &m_pSoundBuffer, 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 (100ms) and the buffer is created
        // with DSBCAPS_CTRLFX.
        if( hr != DSERR_BUFFERTOOSMALL )
            DXTRACE_ERR( TEXT("CreateSoundBuffer"), hr );
            
        goto LFail;
    }


    // 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 DXTRACE_ERR( TEXT("RestoreBuffer"), hr );

	FillBuffer();

    return S_OK;
LFail:
    // Cleanup
    return hr;
}

HRESULT cSound::Play(DWORD dwPriority, DWORD dwFlags)
{
	BOOL	bRestored;
	HRESULT	hRet;
	DWORD	dwStatus;


	hRet = m_pSoundBuffer->GetStatus(&dwStatus);
	if(hRet != 0)
		return -1;

	if( !(dwStatus & DSBSTATUS_PLAYING) )
		m_bIsPlaying = FALSE;


	if(m_bIsPlaying == TRUE)
		return S_OK;

	RestoreBuffer(&bRestored);
	if(bRestored)
		FillBuffer();
//	else
//		DXTRACE_MSG("BUFFER NOT RESTORED");

//	DXTRACE_MSG("START PLAY");
	m_pSoundBuffer->Play(0, dwPriority, dwFlags);
	m_bIsPlaying = TRUE;

	return S_OK;
}

HRESULT cSound::RestoreBuffer(BOOL *bRestored)
{
    HRESULT hr;

    if( m_pSoundBuffer == NULL )
        return CO_E_NOTINITIALIZED;
    if( bRestored )
        *bRestored = FALSE;

    DWORD dwStatus;

    if( FAILED( hr = m_pSoundBuffer->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 restoring the buffer may fail.  
        // If it does, sleep until DirectSound gives us control.
        do 
        {
            hr = m_pSoundBuffer->Restore();
            if( hr == DSERR_BUFFERLOST )
                Sleep( 10 );
        }
        while( hr != DS_OK );

        if( bRestored != NULL )
            *bRestored = TRUE;

        return S_OK;
    }
    else
    {
        return S_FALSE;
    }
}

LPDIRECTSOUND3DBUFFER cSound::Get3DInterface()
{

    if(!m_p3DInterface)
	{
		m_pSoundBuffer->QueryInterface( IID_IDirectSound3DBuffer, 
                                                  (VOID**)&m_p3DInterface );
	}

	return m_p3DInterface;

}

HRESULT cSound::Stop(BOOL bOverride)
{

	if(bOverride)
	{
		if(m_bIsPlaying == FALSE)
			return S_OK;
	}

//	DXTRACE_MSG("SOUND STOPPED");	
	

	m_pSoundBuffer->Stop();
	m_bIsPlaying = FALSE;

	return S_OK;
}


HRESULT cSound::FillBuffer()
{
	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 

    // Lock the buffer down
    if( FAILED( hr = m_pSoundBuffer->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 ) );
    }

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

	return 0;
}

void cSound::SetPosition(float fX, float fY, float fZ)
{
	Get3DInterface()->SetPosition(fX, fY, fZ, DS3D_IMMEDIATE);
}

void cSound::SetVelocity(float fX, float fY, float fZ)
{
	Get3DInterface()->SetVelocity(fX, fY, fZ, DS3D_IMMEDIATE);
}

void cSound::Destroy()
{
	if(m_sFileName)
		free(m_sFileName);

	if(m_pWaveFile)
		delete m_pWaveFile;

	if(m_p3DInterface)
	{
		m_p3DInterface->Release();
		m_p3DInterface = NULL;
	}

	if(m_pSoundBuffer)
	{
		Stop();
		m_pSoundBuffer->Release();
		m_pSoundBuffer = NULL;
	}
}

⌨️ 快捷键说明

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