📄 pingpongpio.cpp
字号:
//**********************************************************************
//
// Filename: pingpongpio.h
//
// Description: Contians the class information for the software (FAKE)
// DMA.
//
// 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.
//
// Use of this source code is subject to the terms of the Cirrus end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to
// use this source code. For a copy of the EULA, please see the
// EULA.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2005, All Rights Reserved
//
//**********************************************************************
#include "wavecommon.h"
//****************************************************************************
// PingPongSwDma::PingPongSwDma
//****************************************************************************
// Constructore for the PingPongSwDma Class. Initialized variables.
//
//
PingPongSwDma::PingPongSwDma(void):
m_pulDma(0),
m_ulSysIntr(0),
m_bExitThread(FALSE),
m_hEvent(0),
m_hThread(0)
{
}
//****************************************************************************
// PingPongSwDma::~PingPongSwDma
//****************************************************************************
// Destructor
//
//
PingPongSwDma::~PingPongSwDma(void)
{
FUNC_DMA((L"+PingPongSwDma::~PingPongSwDma\n"));
//
// Kill the interrupt thread. I need to know the proper way to do
// this.
//
if(m_hThread)
{
m_bExitThread = TRUE;
WaitForSingleObject
(
m_hThread,
INFINITE
);
}
if(m_hEvent)
{
CloseHandle(m_hEvent);
}
FUNC_DMA((L"-PingPongSwDma::~PingPongSwDma\n"));
}
//****************************************************************************
// PingPongSwDma::Initialize
//****************************************************************************
//
// Since a constructor cannot return an error value we must return the
// use an initialize function.
//
MMRESULT PingPongSwDma::Initialize
(
void * pWaveDevice,
ULONG ulBufferSize,
BOOL bAC97,
BOOL bPlayBack
)
{
MMRESULT Result = MMSYSERR_NOERROR;
BOOL bIntInit;
PIOBufferParameters sPio;
m_pWaveDevice=pWaveDevice;
FUNC_DMA((L"+PingPongSwDma::Initialize\n"));
m_bPlayBack = bPlayBack;
//
// Create an event and a thread, and then associate them.
//
if(Result == MMSYSERR_NOERROR)
{
m_hEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
if(!m_hEvent)
{
ERRMSG((L"PingPongSwDma::Initialize Failed to Create Interrupt Event.\r\n"));
Result = MMSYSERR_NOMEM;
}
}
//
// Get the event handle, register the interrupt, and then
// associate it with the event.
//
if(Result == MMSYSERR_NOERROR)
{
m_ulSysIntr = bPlayBack ? SYSINTR_PIO_PLAYBACK : SYSINTR_PIO_RECORD;
sPio.ulBufferSize = m_ulBufferSize = ulBufferSize;
sPio.bAC97 = bAC97;
bIntInit = InterruptInitialize(m_ulSysIntr, m_hEvent, (void *)&sPio, sizeof(PIOBufferParameters)) ;
m_pBuffer = sPio.pulBuffer;
if(!bIntInit)
{
ERRMSG((L"PingPongSwDma::Initialize Failed to hook interrupt \r\n"));
Result = MMSYSERR_NOMEM;
}
}
//
// Create the thread for the IST, passing it the event handle.
// The IST code calls WaitOnSingleObject, so give it the event handle.
//
if(Result == MMSYSERR_NOERROR)
{
m_hThread = CreateThread
(
(LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)IST,
(PVOID)this,
0,
NULL
);
if(!m_hThread)
{
ERRMSG((L"PingPongSwDma::Initialize Failed to Create IST Thread.\r\n"));
Result = MMSYSERR_NOMEM;
}
}
if(Result == MMSYSERR_NOERROR)
{
//
// Set the new thread priority to a high priority.
// This thread priority may be too low.
//
//CeSetThreadPriority(m_hThread, 249);
CeSetThreadPriority(m_hThread, 200);
Flush();
}
FUNC_DMA((L"-PingPongSwDma::Initialize\n"));
return(Result);
}
//****************************************************************************
// PingPongSwDma::Flush
//****************************************************************************
// Flushs the audio buffer. Sets the position to the start of the buffer.
//
//
void PingPongSwDma::Flush(void)
{
ASSERT(!m_bPlaying);
HalAudioSetPosition(m_bPlayBack,(ULONG)m_pBuffer);
}
//****************************************************************************
// PingPongSwDma::Start
//****************************************************************************
// Start DMA running
//
// return 0 - Success
// 1 - Error
//
MMRESULT PingPongSwDma::Start(void)
{
FUNC_DMA((L"+PingPongSwDma::Start\n"));
//
// Start Audio Playback.
//
HalAudioStartStop(m_bPlayBack, TRUE);
m_bPlaying = TRUE;
FUNC_DMA((L"-PingPongSwDma::Start\n"));
return(MMSYSERR_NOERROR);
}
//****************************************************************************
// PingPongSwDma::Stop
//****************************************************************************
// Stops DMA
//
//
MMRESULT PingPongSwDma::Stop(void)
{
FUNC_DMA((L"+PingPongSwDma::Stop\n"));
//
// Stop Audio Playback.
//
HalAudioStartStop(m_bPlayBack, FALSE);
m_bPlaying = FALSE;
Flush();
FUNC_DMA((L"-PingPongSwDma::Stop\n"));
return(MMSYSERR_NOERROR);
}
//****************************************************************************
// PingPongSwDma::Pause
//****************************************************************************
// Pauses DMA
//
// return 0 - Success
// 1 - Error
//
MMRESULT PingPongSwDma::Pause(void)
{
FUNC_DMA((L"+PingPongSwDma::Pause\n"));
//
// Pause Audio Playback.
//
HalAudioStartStop(m_bPlayBack, FALSE);
m_bPlaying = FALSE;
FUNC_DMA((L"-PingPongSwDma::Pause\n"));
return(MMSYSERR_NOERROR);
}
//****************************************************************************
// PingPongSwDma::CurrentPosition
//****************************************************************************
//
// return 0 - Success
// 1 - Error
//
ULONG PingPongSwDma::CurrentPosition(void)
{
ULONG ulPosition = 0;
FUNC_DMA((L"+PingPongSwDma::CurrentPosition\n"));
//
// Get the currect buffer position from the kernel.
//
HalAudioGetPosition(m_bPlayBack, &ulPosition);
FUNC_DMA((L"-PingPongSwDma::CurrentPosition\n"));
return ulPosition;
}
//****************************************************************************
// PingPongSwDma::IST
//****************************************************************************
// Interrupt Service thread for the Dma channel.
//
//
DWORD WINAPI PingPongSwDma::IST(LPVOID lpParameter)
{
PingPongSwDma *t = (PingPongSwDma *)lpParameter;
// ULONG ulInterrupt,ulStatus;
BOOL bNext;
ULONG ulPosition;
ASSERT(t);
FUNC_DMA((L"+PingPongSwDma::IST\n"));
while(TRUE)
{
WaitForSingleObject(t->m_hEvent, INFINITE);
//
// Check to see if we need to exit the thread.
//
if(t->m_bExitThread)
{
break;
}
//
// Call the call back function.
//
if(t->m_pfnCallBack && t->m_hCallBackHandle)
{
HalAudioGetPosition(t->m_bPlayBack, &ulPosition);
if(ulPosition > ((ULONG)t->m_pBuffer + (t->m_ulBufferSize>>1)))
{
bNext = FALSE;
}
else
{
bNext = TRUE;
}
t->m_pfnCallBack(t->m_hCallBackHandle, bNext);
}
InterruptDone(t->m_ulSysIntr);
}
FUNC_DMA((L"-PingPongSwDma::IST\n"));
return (0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -