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

📄 dsdriverbuffer.cpp

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




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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsPlaybackDriverBuffer::Play(
    /* [in] */ DWORD reserved1,
    /* [in] */ DWORD reserved2,
    /* [in] */ DWORD dsbPlayFlags)
{
    FUNCMSG1("DsDriverBuffer::Play, loop = %s", 
		((dsbPlayFlags & DSBPLAY_LOOPING) != 0)? TEXT("TRUE"):TEXT("FALSE"));

	HRESULT hr = S_OK;

	// Tell the device to start playing this buffer.
	CriticalSectionAcquisition csa(&m_csBuffer);

	// save flags
	m_dsbPlayFlags = dsbPlayFlags;

	// If already playing, return OK
	// Special case -- for Single shot buffers, we need to restart
	if(m_bIsRunning && (m_dsbPlayFlags & DSBPLAY_LOOPING) )
		return hr;

	// IDsDriverBuffer::Play does not support SetPosition other than 0.
	// several things would have to get generalized here... including figuring out which
	// chunk we're starting on and what the initial count would be.

	if (!m_pCX5530->SetupPlay(m_uChannel, m_wfxFormat.nChannels, m_wfxFormat.wBitsPerSample, m_dwCurrentFrequency, (m_dsbPlayFlags & DSBPLAY_LOOPING) != 0))
		return DSERR_GENERIC;
	
	SetDMABuffer();
	StartDMAChannel();

	FUNCMSG("-DsPlaybackDriverBuffer::Play");
	return hr;
}

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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsPlaybackDriverBuffer::Stop(void)
{
	FUNCMSG1("DsDriverBuffer::Stop -- buf %d", m_uChannel);
	
	HRESULT hr = DS_OK;

	if(!m_bIsRunning)
		return hr;

	// Stop the buffer from playing here.

	StopDMAChannel();


	// --for SetEvent
	// We need to have the right ACL's to be able to set the events
	// which were created in another process.
	// Save the old permissions.
	DWORD dwSavedPermissions = GetCurrentPermissions();
	SetProcPermissions( DWORD (-1) );

	__try
	{
		// set the Stop notification, if one is registered
		if (m_hEventStop != NULL) {
			SetEvent(m_hEventStop);
		}
	}
	__except(1 /*EXCEPTION_EXECUTE_HANDLER*/)
	{
		// happens when you kill the client process
		ERRMSG("DsDriverBuffer::Stop -- Error setting notification event");
	}

	// Restore the old permissions.
	SetProcPermissions( dwSavedPermissions );

	m_bIsRunning = false;

	return hr;
}


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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsPlaybackDriverBuffer::GetPosition( LPDWORD pdwPlay, LPDWORD pdwWrite)
{
    //FUNCMSG("+DsPlaybackDriverBuffer::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(!pdwPlay || !pdwWrite)
	{
		ERRMSG("DsPlaybackDriverBuffer::GetPosition: bad parms");
		return DSERR_INVALIDPARAM;
	}

	if (! m_bIsRunning) 
	{
		//ERRMSG("DsPlaybackDriverBuffer::GetPosition: buffer not playing");
		*pdwPlay = *pdwWrite = 0;
		return hr;
	}

	// the current DMA position for the curent channel, as a
	
	*pdwPlay = GetDMAPosition();

	// Since the card DMA reads data 8 long words(32 bytes) at a time, the write position 
	// will be the next block of 32 bytes that is going to be transferred. For more safety,
	// we'll keep the write position another 32 byte chunk ahead.
	*pdwWrite = (*pdwPlay + (32 - *pdwPlay % 32) + 32) % m_ulSize;

//	FUNCMSG3("-DsDriverBuffer::GetPosition: size 0x%x, write 0x%x, play 0x%x\r\n",
//		m_ulSize, *pdwWrite, *pdwPlay);

    return hr;

}



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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsPlaybackDriverBuffer::SetPosition(/* [in] */ DWORD dwPosition)
{
    FUNCMSG("DsDriverBuffer::SetPosition");


	HRESULT hr = DS_OK;


	// Move play position of buffer to specified position.
	if (dwPosition == 0)
	{
		// all we really support is setting the position to 0
		return DS_OK;
	}

	return DSERR_UNSUPPORTED;

	//return hr;

}



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

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

    FUNCMSG("DsDriverBuffer::SetFormat");

	if (m_bIsRunning)
	{
		return DSERR_INVALIDCALL;
	}
	
	if (!pwfxFormatEx || !m_pCX5530->IsFormatSupported(pwfxFormatEx))
	{
		WARNMSG("DsPlaybackDriverBuffer::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;
}



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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsPlaybackDriverBuffer::SetVolumePan(/* [in] */ PDSVOLUMEPAN pdsVolumePan)
{
    FUNCMSG("+DsPlaybackDriverBuffer::SetVolumePan");

	HRESULT hr = DS_OK;

	CriticalSectionAcquisition csa(&m_csBuffer);
	// Set the volume and pan for this buffer.
	return m_pCX5530->SetVolumePan(m_uChannel, pdsVolumePan);
}



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

*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DsPlaybackDriverBuffer::SetFrequency(/* [in] */ DWORD dwFrequency) 
{
    FUNCMSG1("DsPlaybackDriverBuffer::SetFrequency: %d", dwFrequency);
	
	CriticalSectionAcquisition csa(&m_csBuffer);

	if (dwFrequency == DSBFREQUENCY_ORIGINAL)
	{
		// restore original freq
		dwFrequency = m_wfxFormat.nSamplesPerSec;
	}
	
	HRESULT hr = m_pCX5530->SetFrequency(false, dwFrequency);
	
	if (SUCCEEDED(hr))
		m_dwCurrentFrequency = dwFrequency;
	
	return hr;
}


STDMETHODIMP DsPlaybackDriverBuffer::GetStatus( LPDWORD pdwStatus)
{
    FUNCMSG("+DsDriverBuffer::GetStatus");

	if (!pdwStatus)
	{
		ERRMSG("DsPlaybackDriverBuffer::GetStatus: bad parms");
		return DSERR_INVALIDPARAM;
	}

	if (m_bIsRunning) 
	{
		if (m_dsbPlayFlags & DSBPLAY_LOOPING) 
		{
			*pdwStatus = DSBSTATUS_PLAYING | DSBSTATUS_LOOPING;
		}
		else 
		{
			*pdwStatus = DSBSTATUS_PLAYING;
		}
	}
	else 
	{
		*pdwStatus = 0;
	}

	return DS_OK;
}

void DsPlaybackDriverBuffer::ProcessInterrupt()
{
//	FUNCMSG2("+DsPlaybackDriverBuffer::ProcessInterrupt(%d) at %d", intsrc, GetTickCount());

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


	// test for looping
	// note that single-shot mode and notification positions are not mutually exclusive
	//If LOOP is not specified (one shot buffers)
	// we'll stop the buffer on an interrupt
	
	if(bStop && !(m_dsbPlayFlags & DSBPLAY_LOOPING))
	{
		//reset the hardware dma channel
		INFMSG("DsPlaybackDriverBuffer::ProcessInterrupt calling Stop");
		Stop();
	}
}

⌨️ 快捷键说明

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