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

📄 dsdriverbuffer.cpp

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////////////
/*****************************************************************************

Copyright (c) 1999 Microsoft Corporation

Module Name:

	DsPlaybackDriverBuffer.cpp

Abstract:

	Implementation file for the DsPlaybackDriverBuffer class.


	NOTE:  Unlike the desktop, the CE DirectSound version will NOT use 
	the waveOut API's for emulation.  On CE, the waveOut API's (in waveapi.dll) 
	speak to the underlying audio device driver (wavedev.dll) and so will
	DirectSound.  

Revision History:

	mmaguire 08/19/99 - based on waveOutRenderer


*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////



//////////////////////////////////////////////////////////////////////////////
// BEGIN INCLUDES
//
// standard includes:
//
//
// where we can find declaration for main class in this file:
//
#include "includes.h"
#include "MemoryBuffer.h"
#include "DsDriverBuffer.h"
//
//
// where we can find declarations needed in this file:
//
//
// END INCLUDES
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
/*****************************************************************************

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
DsPlaybackDriverBuffer::DsPlaybackDriverBuffer( HRESULT &hr, USHORT index, volatile struct BusMasterRegisters* pRegs):
	CHardwareBuffer(hr, index, pRegs),
	m_ulRefCount(1),
	m_dsbPlayFlags(0),
	m_dwCurrentFrequency(48000)
{
	FUNCMSG("DsPlaybackDriverBuffer::DsPlaybackDriverBuffer");
	if (FAILED(hr))
		return;
	// register to receive interrupts
	
	hr = DS_OK;
}

//////////////////////////////////////////////////////////////////////////////
/*****************************************************************************

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
DsPlaybackDriverBuffer::~DsPlaybackDriverBuffer()
{
    FUNCMSG("DsPlaybackDriverBuffer::~DsPlaybackDriverBuffer");
}

//////////////////////////////////////////////////////////////////////////////
/*****************************************************************************

QueryInterface is where DirectSound will ask us whether we support any 
additional capabilities for a buffer.  If we support other interfaces
(in other words, if we inherit from another abstract  C++ base class)
we should return a pointer to that interfaces here.

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsPlaybackDriverBuffer::QueryInterface (
	REFIID pIid,
	LPVOID *ppNew )
{
    FUNCMSG("DsPlaybackDriverBuffer::QueryInterface");
	
    DEBUGCHK(ppNew != NULL);

#ifdef PARAMETER_VALIDATIONS
	if( ! ppNew )
	{
		ERRMSG("DsPlaybackDriverBuffer::QueryInterface -- invalid pointer");
		return DSERR_INVALIDPARAM;
	}
#endif

	if( IsEqualIID(IID_IUnknown, pIid)
		|| IsEqualIID(IID_IDsDriverBuffer,pIid))
	{
		
	    DEBUGMSG(ZONE_INFO, (TEXT("DsPlaybackDriverBuffer::QueryInterface -- %s\r\n"), 
			IsEqualIID(IID_IUnknown, pIid)?				TEXT("IID_IUnknown")
			:											TEXT("IID_IDsDriverBuffer")));
		// Increase RefCount.
		InterlockedIncrement( (LPLONG) &m_ulRefCount );
		// Cast ourselves to the type of base class requested.
		
		*ppNew = (IDsDriverBuffer*)this;
		return NO_ERROR;
	}
	else if (IsEqualIID(IID_IDsDriverNotify, pIid))
	{
		INFMSG("DsPlaybackDriverBuffer::QueryInterface -- IID_IDsDriverNotify");
		// Increase RefCount.
		InterlockedIncrement( (LPLONG) &m_ulRefCount );
		// Cast ourselves to the type of base class requested.
		
		*ppNew = (IDsDriverNotify*)((CHardwareBuffer*)this);
		return NO_ERROR;
	}
	DEBUGMSG(ZONE_INFO,(TEXT("DsPlaybackDriverBuffer::QueryInterface -- unknown IID\r\n")));
	*ppNew = NULL;
	return DSERR_NOINTERFACE;
}



//////////////////////////////////////////////////////////////////////////////
/*****************************************************************************

AddRef and Release are how other clients of our component tell us that
it is no longer needed.  When the RefCount goes to zero, we know we are
not needed, and we will delete ourselves.


*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) DsPlaybackDriverBuffer::AddRef(void)
{
    DEBUGMSG(ZONE_REFCOUNT,(TEXT("DsPlaybackDriverBuffer::AddRef previous:%d\r\n"), m_ulRefCount));

	return InterlockedIncrement( (LPLONG) &m_ulRefCount );
}

//////////////////////////////////////////////////////////////////////////////
/*****************************************************************************

AddRef and Release are how other clients of our component tell us that
it is no longer needed.  When the RefCount goes to zero, we know we are
not needed, and we will delete ourselves.

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) DsPlaybackDriverBuffer::Release(void)
{
    DEBUGMSG(ZONE_REFCOUNT,(TEXT("DsPlaybackDriverBuffer::Release previous=%ld\r\n"), m_ulRefCount));
	

	ULONG ulRefs = InterlockedDecrement( (LPLONG) &m_ulRefCount );

	if( ulRefs == 0 )
	{
		DEBUGMSG(ZONE_REFCOUNT,(TEXT("DsPlaybackDriverBuffer::Release final on 0x%08x\n"), this ));
			// Unassociate from the hardware's list of buffers
		m_pCX5530->ReleasePlaybackBuffer(m_uChannel);
		delete this;
	}
	return ulRefs;
}



//////////////////////////////////////////////////////////////////////////////
/*****************************************************************************

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsPlaybackDriverBuffer::Lock(
    /* [out] */ LPLPVOID ppAudio1,
    /* [out] */ LPDWORD pAudioBytes1,
    /* [out] */ LPLPVOID ppAudio2,
    /* [out] */ LPDWORD pAudioBytes2,
    /* [in] */ DWORD dwWriteCursor,
    /* [in] */ DWORD dwWriteBytes,
    /* [in] */ DWORD dsbLockFlags
	)
{
//    FUNCMSG3("+DsPlaybackDriverBuffer::Lock dwWriteCursor 0x%x, dwWriteBytes 0x%x, buf %d\r\n", 
//		dwWriteCursor, dwWriteBytes, m_uChannel);
	
	HRESULT hr = DS_OK;

	// Do stuff here to provide access to the actual sound buffer data as requested.
	// Return pointers to that data.

	CriticalSectionAcquisition csa(&m_csBuffer);

	// Buffer is already locked (when allocated). So we'll just return appropriate positions

	if(dwWriteBytes > m_ulSize)
	{
		ERRMSG2("DsPlaybackDriverBuffer::Lock: dwWriteBytes(%d) > m_ulSize (%d)", dwWriteBytes , m_ulSize);
		return DSERR_INVALIDPARAM;
	}
	if (!ppAudio1 || !pAudioBytes1)
	{
		ERRMSG("DsPlaybackDriverBuffer::Lock: NULL pointer parameter");
		return DSERR_INVALIDPARAM;
	}
	*ppAudio1 = m_pVirtualAddress + dwWriteCursor;

	if(dwWriteBytes > m_ulSize - dwWriteCursor)	// Wraparound (need two buffers)?
	{	// yes
		INFMSG3("DsPlaybackDriverBuffer::Lock: 2 buffers\r\n\tdwWriteBytes = %d, m_ulSize = %d, dwWriteCursor = %d", 
			dwWriteBytes, m_ulSize, dwWriteCursor);
		*pAudioBytes1 = m_ulSize - dwWriteCursor;
		if(ppAudio2)
		{
			*ppAudio2 = m_pVirtualAddress;
		}
		else
		{
			ERRMSG("DsPlaybackDriverBuffer::Lock:Two buffers needed, but 2nd param is NULL");
		}
		if(pAudioBytes2)  
			*pAudioBytes2 = dwWriteBytes - *pAudioBytes1;

		//m_dwWritePosition = *pAudioBytes2;
	}
	else
	{	// no, one buffer suffices
//		INFMSG("DsPlaybackDriverBuffer::Lock: one buffer");
		*pAudioBytes1 = dwWriteBytes;

		if(ppAudio2)  
			*ppAudio2 = NULL;  
		if(pAudioBytes2)  
			*pAudioBytes2 = 0;

	}
//	FUNCMSG2("-DsPlaybackDriverBuffer::Lock: Buffer1: 0x%8.8x, size %lu", *ppAudio1, *pAudioBytes1);
//	FUNCMSG2("-DsPlaybackDriverBuffer::Lock: Buffer2: 0x%8.8x, size %lu", ppAudio2?(*ppAudio2):0, 
//		pAudioBytes2?(*pAudioBytes2):0);
	return hr;
}




//////////////////////////////////////////////////////////////////////////////
/*****************************************************************************

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsPlaybackDriverBuffer::Unlock(
    /* [in] */ void *pAudio1,
    /* [in] */ DWORD dwAudioBytes1,
    /* [in] */ void *pAudio2,
    /* [in] */ DWORD dwAudioBytes2)
{

//	FUNCMSG3("DsDriverBuffer::Unlock pAudio1 %x, pAudio2 %x, buf %d", pAudio1, pAudio2, m_uChannel);

	HRESULT hr = DS_OK;

	/*

	CriticalSectionAcquisition csa(&m_csBuffer);

	// The client of this interface is finished with accessing the actual
	// data of the buffer.  

	// Do any tasks your hardware requires here.

	// For example, if your hardware supports on-board audio RAM, and this
	// is a static buffer, you may have provided a pointer to system RAM
	// in the Lock method, the client will have written some data to it, 
	// and at this point you can move that data to on-board RAM.
	
	// just update positions
//	m_dwLastOffsetSize = dwAudioBytes1 + dwAudioBytes2;

	if(pAudio2)
		m_dwWritePosition = dwAudioBytes2;
	else
		m_dwWritePosition = ((LPBYTE)pAudio1 - m_pVirtualAddress) + dwAudioBytes1;

	if(m_dwWritePosition >= m_ulSize)
		m_dwWritePosition = 0;
*/
	return hr;

⌨️ 快捷键说明

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