📄 dsplaybackdriver.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 + -