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

📄 dscapturedriverbuffer.cpp

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 CPP
字号:
/*++

THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Copyright (c) 2000 Microsoft Corporation

Module Name:   DsCaptureDriverBuffer.cpp

Abstract:

Notes: 

History:

	coscor 7/5/2000 Created.

--*/

template<class T> T min(T x, T y){return (x < y)?x:y;}

#define MIN(x,y) min<DWORD>(x,y)


#include "includes.h"
#include "DsCaptureDriverBuffer.h"

// A reference count to track DuplicateSoundBuffer
DWORD DsCaptureDriverBuffer::dwCloneRefCount = 0;



// Function name	: DsCaptureDriverBuffer::DsCaptureDriverBuffer
// Description	    : 
// Return type		: 
// Argument         : HRESULT &hr
// Argument         : int iIndex	: the DMA channel index in the DMA channels array used by the hardware object

DsCaptureDriverBuffer::DsCaptureDriverBuffer(HRESULT &hr, int iIndex, volatile struct BusMasterRegisters* pRegs):
	CHardwareBuffer(hr, iIndex, pRegs),
	m_ulRefCount(1),
	m_bIsLooping (false)
{
    FUNCMSG("+DsCaptureDriverBuffer::DsCaptureDriverBuffer");
	if (FAILED(hr))
		return;
	hr = DS_OK;

}



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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
DsCaptureDriverBuffer::~DsCaptureDriverBuffer()
{
    FUNCMSG("+DsCaptureDriverBuffer::~DsCaptureDriverBuffer");


	// Insert shutdown code here.

	if(m_bIsRunning)
	{
		Stop();
		Sleep(2000);
	}
    FUNCMSG("-DsCaptureDriverBuffer::~DsCaptureDriverBuffer");
}



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

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 DsCaptureDriverBuffer::QueryInterface (
	REFIID pIid,
	LPVOID *ppNew )
{
    FUNCMSG("+DsCaptureDriverBuffer::QueryInterface");
	

    DEBUGCHK(ppNew != NULL);


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


	if( IsEqualIID(IID_IUnknown, pIid)
		|| IsEqualIID(IID_IDsCaptureDriverBuffer,pIid)
		)
	{
		
		// Increase RefCount.
		InterlockedIncrement( (LPLONG) &m_ulRefCount );


		// Cast ourselves to the type of base class requested.
		*ppNew = (IDsCaptureDriverBuffer *)this;
		return NO_ERROR;
	}
	else if ( IsEqualIID(IID_IDsDriverNotify, pIid) )
	{

		// Increase RefCount.
		InterlockedIncrement( (LPLONG) &m_ulRefCount );

		// Cast ourselves to the type of base class requested.
		*ppNew = (IDsDriverNotify *)(this);
		return NO_ERROR;
	}


	*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) DsCaptureDriverBuffer::AddRef(void)
{
    DEBUGMSG(ZONE_REFCOUNT,(TEXT("DsCaptureDriverBuffer::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) DsCaptureDriverBuffer::Release(void)
{
    DEBUGMSG(ZONE_REFCOUNT,(TEXT("DsCaptureDriverBuffer::Release previous=%ld\r\n"), m_ulRefCount));
	

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

	if( ulRefs == 0 )
	{
		DEBUGMSG(ZONE_REFCOUNT,(TEXT("DsCaptureDriverBuffer::Release final on 0x%08x\n"), this ));
		m_pCX5530->ReleaseCaptureBuffer(m_uChannel);
		delete this;
	}
	return ulRefs;
}



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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsCaptureDriverBuffer::Lock(
    /* [out] */ LPLPVOID ppAudio1,
    /* [out] */ LPDWORD pAudioBytes1,
    /* [out] */ LPLPVOID ppAudio2,
    /* [out] */ LPDWORD pAudioBytes2,
    /* [in] */ DWORD dwWriteCursor,
    /* [in] */ DWORD dwWriteBytes,
    /* [in] */ DWORD dsbLockFlags
	)
{
    FUNCMSG3("+DsCaptureDriverBuffer::Lock dwWriteCursor %x, dwWriteBytes %x dsbLockFlags %x", dwWriteCursor, dwWriteBytes, dsbLockFlags);

	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);

	if(dsbLockFlags & DSCBLOCK_ENTIREBUFFER)
		dwWriteBytes = GetSize();

	// just return appropriate positions
	if(dwWriteBytes > GetSize())
		return DSERR_INVALIDPARAM;

	*ppAudio1 = GetVirtualAddress() + dwWriteCursor;

	if(dwWriteBytes > GetSize() - dwWriteCursor)
	{
		*pAudioBytes1 = GetSize() - dwWriteCursor;
		if(ppAudio2)  *ppAudio2 = GetVirtualAddress();
		if(pAudioBytes2)  *pAudioBytes2 = dwWriteBytes - *pAudioBytes1;
	}
	else
	{
		*pAudioBytes1 = dwWriteBytes;

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

	FUNCMSG2("-DsCaptureDriverBuffer::Lock: buf: 0x%8.8x, size %d", *ppAudio1, *pAudioBytes1);
	return hr;

}






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

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

    //FUNCMSG("DsCaptureDriverBuffer::Unlock");
	

	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.
	
	// Nothing to do for the DMA based chips


	return hr;

}




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

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


STDMETHODIMP DsCaptureDriverBuffer::Start(
    /* [in] */ DWORD dsbPlayFlags)
{
    FUNCMSG("+DsCaptureDriverBuffer::Start");
	
	
	HRESULT hr = DS_OK;
	
	// Tell the device to start playing this buffer.
	CriticalSectionAcquisition csa(&m_csBuffer);
	
	if(m_bIsRunning)
		return DS_OK;
	
	if (dsbPlayFlags & DSCBSTART_LOOPING) 
	{
		m_bIsLooping = TRUE;
	}
	
	if (!m_pCX5530->SetupCapture(m_uChannel, m_wfxFormat.nChannels, m_wfxFormat.wBitsPerSample, m_wfxFormat.nSamplesPerSec))
		return DSERR_GENERIC;

	SetDMABuffer();
	
	if(m_dwWritePosition >= GetSize())
		m_dwWritePosition = 0;
		
	// Start the DMA channel
	StartDMAChannel();

	FUNCMSG("-DsCaptureDriverBuffer::Start");

	return hr;
}

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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsCaptureDriverBuffer::Stop(void)
{
    FUNCMSG("DsCaptureDriverBuffer::Stop");
	
	HRESULT hr = DS_OK;
	
	CriticalSectionAcquisition csa(&m_csBuffer);
	
	if(!m_bIsRunning)
		return DS_OK;
	
	// Stop the dma buffer from recording
	StopDMAChannel();
	
	m_bIsRunning = false;
    m_bIsLooping = false;
		// Set last event if it applies.
	if (m_hEventStop)
	{
		SetEvent(m_hEventStop);
	}

	
	return hr;
	
}

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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsCaptureDriverBuffer::GetStatus( LPDWORD pdwStatus)
{
    FUNCMSG("+DsDriverBuffer::GetStatus");
	
	CriticalSectionAcquisition csa(&m_csBuffer);
	
	//DWORD dwPlay;
	
	if (m_bIsRunning) 
	{
		if (m_bIsLooping) 
		{
			// we're playing and looping. It's easy
			*pdwStatus = DSCBSTATUS_CAPTURING | DSCBSTATUS_LOOPING;
		}
		else 
		{
			*pdwStatus = DSCBSTATUS_CAPTURING;
		}
	}
	else 
	{
		*pdwStatus = 0;
	}
	
	return DS_OK;
}


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

  Notes:
Both the read pointer and the capture pointer represent
"first invalid" positions, meaning the client will want to
read up to BUT NOT INCLUDING the reported read position.
The read pointer trails the capture pointer and
marks the first "not necessarily valid" byte in the no-man's
land between the read cursor and the capture cursor
The idea is that the capture position represents where
the hardware is at, and the read position represents the data
we the client can actually get at. For example, if you're buffering
in from a smaller dma buffer, the the read cursor points to the
next byte you will copy in from the dma buffer.

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsCaptureDriverBuffer::GetPosition( LPDWORD pdwCapture, LPDWORD pdwRead)
{
    FUNCMSG("+DsCaptureDriverBuffer::GetPosition");

	HRESULT hr = DS_OK;

	CriticalSectionAcquisition csa(&m_csBuffer);

	// Return the current play and write positions in the buffer.
	// Play is what's currently coming out of the speaker.
	// Write is what's already committed (so place ahead of
	// which it is OK to write new data.

//	if(!pdwCapture || !pdwRead)
//		return DSERR_INVALIDPARAM;

	if (! m_bIsRunning) 
	{
		if(pdwCapture) *pdwCapture = 0;
		if(pdwRead) *pdwRead = 0; 
		return DS_OK;
	}

	// Capture position is where the hardware is at currently
	if(pdwCapture)
		*pdwCapture = m_ulLastOffset;

	// Read position should mark the end of valid data
	if(pdwRead) 
		*pdwRead = m_ulLastOffset;


    return hr;

}


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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsCaptureDriverBuffer::SetFormat(
    /* [in] */ LPWAVEFORMATEX pwfxFormatEx)
{

    FUNCMSG("+DsCaptureDriverBuffer::SetFormat");
	if (m_bIsRunning)
	{
		return DSERR_INVALIDCALL;
	}
	if (!pwfxFormatEx || !m_pCX5530->IsFormatSupported(pwfxFormatEx))
	{
		WARNMSG("DsCaptureDriverBuffer::SetFormat: Format not supported");
		return DSERR_UNSUPPORTED;
	}
	CriticalSectionAcquisition csa(&m_csBuffer);

	// Change format of existing buffer.

	//save format
	memcpy(&m_wfxFormat, pwfxFormatEx, sizeof(WAVEFORMATEX));
    return DS_OK;
}




void DsCaptureDriverBuffer::ProcessInterrupt()
{
	//FUNCMSG("+DsCaptureDriverBuffer::ProcessInterrupt");

	bool bStop = IsStopInterrupt();
	CHardwareBuffer::ProcessInterrupt();

	if(bStop && !m_bIsLooping)
	{
		//reset the hardware dma channel
		INFMSG("DsCaptureDriverBuffer::ProcessInterrupt calling stop event");
		Stop();
	}
}


⌨️ 快捷键说明

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