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

📄 dsplaybackdriver.cpp

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

Copyright (c) 1999 Microsoft Corporation

Module Name:

	DsPlaybackDriver.cpp

Abstract:

	Implementation file for the DsPlaybackDriver class.


Revision History:

	mmaguire 08/19/99


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


//////////////////////////////////////////////////////////////////////////////
//// BEGIN INCLUDES
//
// standard includes:

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



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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
DsPlaybackDriver::DsPlaybackDriver( HRESULT &hr ):
	m_ulRefCount(1),
	m_bOpened (false),
	m_nActiveBuffers(0),
	m_pDriverBuffers(NULL)
{

	hr = DS_OK;
    FUNCMSG("+DsPlaybackDriver::DsPlaybackDriver\r\n");
	InitializeCriticalSection( &m_csSoundBuffer );
	m_pCX5530Audio = CCX5530Audio::GetCX5530AudioObject();
	if (!m_pCX5530Audio)
	{
		ERRMSG("DsPlaybackDriver::DsPlaybackDriver: can't get CX5530Audio object");
		hr = DSERR_GENERIC;
	}
}

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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
DsPlaybackDriver::~DsPlaybackDriver()
{
    FUNCMSG("DsPlaybackDriver::~DsPlaybackDriver");
	
	Close();
	DeleteCriticalSection( &m_csSoundBuffer );
}



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

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

#ifdef PARAMETER_VALIDATION
    if( ! ppNew )
    {
	    ERRMSG("DsPlaybackDriver::QueryInterface -- ppNew is NULL");
        return DSERR_INVALIDPARAM;
    }
#endif
	if( IsEqualIID(IID_IUnknown, pIid) 
		|| IsEqualIID( IID_IDsDriver, pIid))
	{
		
	    INFMSG1("DsPlaybackDriver::QueryInterface -- %s", 
			IsEqualIID(IID_IUnknown, pIid)?TEXT("IID_IUnknown"): TEXT("IID_IDsDriver"));
		InterlockedIncrement( (LPLONG) &m_ulRefCount );
		*ppNew = (DsPlaybackDriver*) this;
		return NO_ERROR;
	}
    INFMSG("DsPlaybackDriver::QueryInterface -- unknown interface");

	*ppNew = NULL;
	return DSERR_NOINTERFACE;
}

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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) DsPlaybackDriver::AddRef(void)
{
    FUNCMSG1("DsPlaybackDriver::AddRef previous=%ld", m_ulRefCount);
	return InterlockedIncrement( (LPLONG) &m_ulRefCount );
}

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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) DsPlaybackDriver::Release(void)
{
    FUNCMSG1("DsPlaybackDriver::Release previous=%ld", m_ulRefCount);

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

	if( ulRefs == 0 )
	{
		INFMSG1("DsPlaybackDriver::Release final on 0x%08x", this );
		delete this;
	}
	return ulRefs;
}	

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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsPlaybackDriver::Open(void)
{
    FUNCMSG("+DsPlaybackDriver::Open");
	CriticalSectionAcquisition csa(&m_csSoundBuffer);
	if (m_bOpened)
		return DS_OK;
	
	// extra initialization here;

	m_bOpened = true;
	return DS_OK;
}	



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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsPlaybackDriver::Close(void)
{
    FUNCMSG("+DsPlaybackDriver::Close");
	CriticalSectionAcquisition csa(&m_csSoundBuffer);
	
	for ( int i = m_pCX5530Audio->GetMaxBuffers() ;i > 0; i--)
	{
		delete m_pDriverBuffers[i - 1];
	}
	
	delete[] m_pDriverBuffers;

	m_pDriverBuffers = NULL;
	m_bOpened = false;
	return DS_OK;
}	

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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsPlaybackDriver::CreateSoundBuffer( 
								   LPWAVEFORMATEX lpWaveFormatEx
								 , DWORD dwFlags
								 , DWORD dsCardAddress
								 , LPDWORD pdwcbBufferSize
								 , LPBYTE *ppbBuffer
								 , LPVOID *ppvObj 
								 )
{
    FUNCMSG2("DsPlaybackDriver::CreateSoundBuffer, %s, size %d", (dwFlags & DSBCAPS_PRIMARYBUFFER)?TEXT("Primary"):TEXT("Secondary"), *pdwcbBufferSize);

	CriticalSectionAcquisition csa(&m_csSoundBuffer);

	HRESULT hr;

	if (!m_bOpened)
	{
		ERRMSG("DsPlaybackDriver::CreateSoundBuffer: driver not opened");
		return DSERR_GENERIC;
	}

	if( ! lpWaveFormatEx )
	{
		ERRMSG("DsPlaybackDriver::CreateSoundBuffer -- lpWaveFormatEx is NULL");
		return DSERR_INVALIDPARAM;
	}
	if( ! ppvObj )
	{
		ERRMSG("DsPlaybackDriver::CreateSoundBuffer -- ppvObj is NULL");
		return DSERR_INVALIDPARAM;
	}
	if( lpWaveFormatEx->wFormatTag != WAVE_FORMAT_PCM  )
	{
		ERRMSG("DsPlaybackDriver::CreateSoundBuffer -- only WAVE_FORMAT_PCM supported");
		return DSERR_BADFORMAT;
	}

	// Can our hardware support the format?

	if (!m_pCX5530Audio->IsFormatSupported(lpWaveFormatEx))
	{
		INFMSG2("DsPlaybackDriver::CreateSoundBuffer -- %d channels/%d BPS not supported by hardware", 
			lpWaveFormatEx->nChannels, lpWaveFormatEx->wBitsPerSample);
		return DSERR_BADFORMAT;
	}

	// Can our hardware support one more buffer?

	if(m_nActiveBuffers >= m_pCX5530Audio->GetMaxBuffers()) 
	{
		INFMSG("DsPlaybackDriver::CreateSoundBuffer -- too many hardware buffers");
		return DSERR_GENERIC;
	}

	// Create the buffer object.


	ULONG ulSize;
	
	// what size buffer?

	if(dwFlags & DSBCAPS_PRIMARYBUFFER)
	{
		// For the primary buffer, we'll decide the size.
		ulSize = PRIMARY_BUFFER_SIZE;
	}
	else
	{
		// For the secondary buffer, we'll try to allocate as much as asked
		ulSize = *pdwcbBufferSize;
	}
	
	DsPlaybackDriverBuffer *pDsPlaybackDriverBuffer = NULL;
	hr = m_pCX5530Audio->CreatePlaybackBuffer(&ulSize, &pDsPlaybackDriverBuffer);

	if( ! pDsPlaybackDriverBuffer || FAILED(hr) )
	{
		ERRMSG("DsPlaybackDriver::CreateSoundBuffer -- unable to create buffer object");

		if( pDsPlaybackDriverBuffer )
		{
			pDsPlaybackDriverBuffer->Release();
		}

		if( SUCCEEDED(hr) )
		{
			// Change the error code to reflect the failure.
			hr = DSERR_OUTOFMEMORY;
		}

		*pdwcbBufferSize = 0;
		return hr;
	}

	
	// Now call on the object we've created and retrieve the
	// IDsPlaybackDriverBuffer interface.
	hr = pDsPlaybackDriverBuffer->QueryInterface( IID_IDsDriverBuffer, ppvObj );

	
	// Need to make sure RefCount on the object is correct -- whether we
	// succeeded above or failed, it is 1 higher than it should be.
	// If we  succeeded above, it is now 2, not 1 and if we failed it is 1 not 0.
	// This is because both constructor and QueryInterface increased RefCount.
	pDsPlaybackDriverBuffer->Release();

	
	if( FAILED(hr) || ! *ppvObj )
	{
	    ERRMSG("DsPlaybackDriver::CreateSoundBuffer -- QueryInterface failed");
		if( *ppvObj )
		{
			((IUnknown *) *ppvObj)->Release();
			*ppvObj = NULL;
		}

		return CLASS_E_CLASSNOTAVAILABLE;
	}

	pDsPlaybackDriverBuffer->SetFormat(lpWaveFormatEx);
	pDsPlaybackDriverBuffer->SetFrequency(lpWaveFormatEx->nSamplesPerSec);


#if defined(MY_DEBUG)

	lpWaveFormatEx->wBitsPerSample = 8;
	lpWaveFormatEx->nAvgBytesPerSec = 11025;
	lpWaveFormatEx->nChannels = 1;
	lpWaveFormatEx->nSamplesPerSec=11025;
	lpWaveFormatEx->nBlockAlign=1;
	lpWaveFormatEx->wFormatTag=0;	//PCM_TYPE_M8;

	pDsPlaybackDriverBuffer->SetFormat(lpWaveFormatEx);
	pDsPlaybackDriverBuffer->SetFrequency(lpWaveFormatEx->nSamplesPerSec);

	LPBYTE pBuf = pDsPlaybackDriverBuffer->GetVirtualAddress();
	for (DWORD dw = 0; dw < pDsPlaybackDriverBuffer->GetSize(); dw++)
		*pBuf = (BYTE)(dw & 7);
	pDsPlaybackDriverBuffer->Play(0, 0, 0);


#endif

	FUNCMSG1( "-DsPlaybackDriver::CreateSoundBuffer(size is %d)", *pdwcbBufferSize);
	return hr;
}	

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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsPlaybackDriver::DuplicateSoundBuffer(
			/* [in] */  PIDSDRIVERBUFFER,
			/* [out] */	LPVOID *
			)
{
    FUNCMSG("+DsPlaybackDriver::DuplicateSoundBuffer");
	
	//HRESULT hr = DS_OK;


	// Do what you need to do here to create a new IDsPlaybackDriverBuffer object
	// which represents a duplicate of the actual sound data in an 
	// already existing object.

	// You will most likely want to share the actual buffer that contains
	// the audio data between the two buffer.


	//return hr;

	return DSERR_INVALIDCALL;
}	

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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsPlaybackDriver::GetCaps(PDSDRIVERCAPS pDSDriverCaps)
{
    FUNCMSG("DsPlaybackDriver::GetCaps");
	
	HRESULT hr = DS_OK;


	// Fill out the DSDRIVERCAPS structure with the appropriate information.

	if(! pDSDriverCaps)
		return DSERR_GENERIC;	//invalid param

	int nMaxChannels = m_pCX5530Audio->GetMaxBuffers();

	pDSDriverCaps->dwFlags =  DSCAPS_CONTINUOUSRATE 
							| DSCAPS_PRIMARYMONO   | DSCAPS_PRIMARYSTEREO   
							| DSCAPS_PRIMARY8BIT   | DSCAPS_PRIMARY16BIT   
							| DSCAPS_SECONDARYMONO | DSCAPS_SECONDARYSTEREO 
							| DSCAPS_SECONDARY8BIT | DSCAPS_SECONDARY16BIT
							;

	pDSDriverCaps->dwMinSecondarySampleRate = 1;
	pDSDriverCaps->dwMaxSecondarySampleRate = 48000;
	pDSDriverCaps->dwPrimaryBuffers = 1;
	pDSDriverCaps->dwMaxHwMixingAllBuffers = nMaxChannels;
	pDSDriverCaps->dwMaxHwMixingStaticBuffers = 0;
	pDSDriverCaps->dwMaxHwMixingStreamingBuffers = nMaxChannels;
	pDSDriverCaps->dwFreeHwMixingAllBuffers = nMaxChannels - m_nActiveBuffers;
	pDSDriverCaps->dwFreeHwMixingStaticBuffers = 0;
	pDSDriverCaps->dwFreeHwMixingStreamingBuffers = nMaxChannels - m_nActiveBuffers;
	pDSDriverCaps->dwMaxHw3DAllBuffers = 0;
	pDSDriverCaps->dwMaxHw3DStaticBuffers = 0;
	pDSDriverCaps->dwMaxHw3DStreamingBuffers = 0;
	pDSDriverCaps->dwFreeHw3DAllBuffers = 0;
	pDSDriverCaps->dwFreeHw3DStaticBuffers = 0;
	pDSDriverCaps->dwFreeHw3DStreamingBuffers = 0;
	pDSDriverCaps->dwTotalHwMemBytes = 0;
	pDSDriverCaps->dwFreeHwMemBytes = 0;
	pDSDriverCaps->dwMaxContigFreeHwMemBytes = 0;

	return hr;
}	

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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsPlaybackDriver::GetDriverDesc(PDSDRIVERDESC pDSDriverDesc )
{
    FUNCMSG("DsPlaybackDriver::GetDriverDesc");
	
	HRESULT hr = DS_OK;


	// Fill out the DSDRIVERDESC structure with the appropriate information.

	if(! pDSDriverDesc)
		return DSERR_GENERIC;	//invalid param

	pDSDriverDesc->dwFlags = DSDDESC_DONTNEEDPRIMARYLOCK | DSDDESC_DONTNEEDSECONDARYLOCK;
    strcpy(pDSDriverDesc->szDesc, "Windows CE CX5530Audio DirectSound Driver");
	strcpy(pDSDriverDesc->szDrvname,"IDSCX5530.DLL");
    pDSDriverDesc->dnDevNode = 0;
    pDSDriverDesc->wVxdId = 0;
    pDSDriverDesc->wReserved = 0;
    pDSDriverDesc->ulDeviceNum = 0;
    pDSDriverDesc->dwHeapType = DSDHEAP_NOHEAP;
    pDSDriverDesc->pvDirectDrawHeap = 0;
    pDSDriverDesc->dwMemStartAddress = 0;
    pDSDriverDesc->dwMemEndAddress = 0;
    pDSDriverDesc->dwMemAllocExtra = 0;
    pDSDriverDesc->pvReserved1 = 0;
    pDSDriverDesc->pvReserved2 = 0;

	return hr;
}	

⌨️ 快捷键说明

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