?? hwctxt.cpp
字號:
case D0:
if (m_Dx != D0)
{
m_Dx = D0;
PowerUp();
Lock();
if (m_bSavedOutputDMARunning)
{
m_bSavedOutputDMARunning = FALSE;
SetInterruptEvent(m_dwSysintrOutput);
//StartOutputDMA();
}
Unlock();
}
break;
default:
if (m_Dx != (_CEDEVICE_POWER_STATE)D4)
{
// Save last DMA state before Power Down
m_bSavedInputDMARunning = m_bInputDMARunning;
m_bSavedOutputDMARunning = m_bOutputDMARunning;
m_Dx = (_CEDEVICE_POWER_STATE)D4;
Lock();
StopOutputDMA();
StopInputDMA();
Unlock();
PowerDown();
}
break;
}
// return our state
*(PCEDEVICE_POWER_STATE)pBufOut = m_Dx;
*pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
WAV_INF((_T("[WAV:INF] IOCTL_POWER_SET -> [D%d]\n\r"), m_Dx));
}
else
{
bRc = FALSE;
dwErr = ERROR_INVALID_PARAMETER;
WAV_ERR((_T("[WAV:ERR] CEDEVICE_POWER_STATE : Invalid Parameter Dx\n\r")));
}
}
break;
case IOCTL_POWER_GET:
if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(CEDEVICE_POWER_STATE)) )
{
bRc = FALSE;
dwErr = ERROR_INVALID_PARAMETER;
break;
}
*(PCEDEVICE_POWER_STATE)pBufOut = m_Dx;
WAV_INF((_T("WAVEDEV: IOCTL_POWER_GET: D%u \r\n"), m_Dx));
*pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
break;
default:
bRc = FALSE;
dwErr = ERROR_INVALID_FUNCTION;
WAV_INF((_T(" Unsupported ioctl 0x%X\r\n"), dwCode));
break;
}
if (!bRc)
{
SetLastError(dwErr);
}
return(bRc);
}
BOOL
HardwareContext::StartOutputDMA()
{
ULONG OutputTransferred;
WAV_MSG((_T("[WAV] StartOutputDMA()\r\n")));
if((m_bOutputDMARunning == FALSE) && (m_Dx == D0))
{
m_bOutputDMARunning = TRUE;
m_nOutByte[OUTPUT_DMA_BUFFER0] = 0;
m_nOutByte[OUTPUT_DMA_BUFFER1] = 0;
m_nOutputBufferInUse = OUTPUT_DMA_BUFFER0; // Start DMA with Buffer 0
m_OutputDMAStatus = (DMA_DONEA | DMA_DONEB) & ~DMA_BIU;
OutputTransferred = TransferOutputBuffer(m_OutputDMAStatus);
if(OutputTransferred)
{
CodecPowerControl(); // Turn Output Channel
CodecMuteControl(DMA_CH_OUT, FALSE); // Unmute Output Channel
// AC97 PCM output enable
AC97_set_pcmout_transfer_mode(AC97_CH_DMA);
// Output DMA Start
DMA_set_channel_source(&g_OutputDMA, m_OutputDMABufferPhyPage[OUTPUT_DMA_BUFFER0], WORD_UNIT, BURST_1, INCREASE);
DMA_set_channel_destination(&g_OutputDMA, AC97_get_pcmout_physical_buffer_address(), WORD_UNIT, BURST_1, FIXED);
DMA_set_channel_transfer_size(&g_OutputDMA, AUDIO_DMA_PAGE_SIZE);
DMA_set_initial_LLI(&g_OutputDMA, 1);
DMA_channel_start(&g_OutputDMA);
}
else
{
WAV_ERR((_T("[WAV:ERR] StartOutputDMA() : There is no data to transfer\r\n")));
m_bOutputDMARunning = FALSE;
}
}
else
{
WAV_ERR((_T("[WAV:ERR] StartOutputDMA() : Output DMA is already running or m_Dx[%d] is not D0\r\n"), m_Dx));
return FALSE;
}
return TRUE;
}
void
HardwareContext::StopOutputDMA()
{
WAV_MSG((_T("[WAV] StopOutputDMA()\r\n")));
if (m_bOutputDMARunning)
{
m_OutputDMAStatus = DMA_CLEAR;
// Stop output DMA
DMA_channel_stop(&g_OutputDMA);
// AC97 PCM output disable
AC97_set_pcmout_transfer_mode(AC97_CH_OFF);
}
m_bOutputDMARunning = FALSE;
CodecMuteControl(DMA_CH_OUT, TRUE);
CodecPowerControl();
}
BOOL
HardwareContext::StartInputDMA()
{
WAV_MSG((_T("[WAV] StartInputDMA()\r\n")));
if(m_bInputDMARunning == FALSE)
{
m_bInputDMARunning = TRUE;
m_nInByte[INPUT_DMA_BUFFER0] = 0;
m_nInByte[INPUT_DMA_BUFFER1] = 0;
m_nInputBufferInUse = INPUT_DMA_BUFFER0; // Start DMA with Buffer 0
m_InputDMAStatus = (DMA_DONEA | DMA_DONEB) & ~DMA_BIU;
CodecPowerControl(); // Turn On Channel
CodecMuteControl(DMA_CH_IN, FALSE); // Unmute Input Channel
// AC97 PCM input enable
AC97_set_pcmin_transfer_mode(AC97_CH_DMA);
DMA_set_channel_source(&g_InputDMA, AC97_get_pcmin_physical_buffer_address(), WORD_UNIT, BURST_1, FIXED);
DMA_set_channel_destination(&g_InputDMA, m_InputDMABufferPhyPage[INPUT_DMA_BUFFER0], WORD_UNIT, BURST_1, INCREASE);
DMA_set_channel_transfer_size(&g_InputDMA, AUDIO_DMA_PAGE_SIZE);
DMA_set_initial_LLI(&g_InputDMA, 1);
DMA_channel_start(&g_InputDMA);
}
else
{
WAV_ERR((_T("[WAV:ERR] StartInputDMA() : Input DMA is already running\r\n")));
return FALSE;
}
return TRUE;
}
void
HardwareContext::StopInputDMA()
{
WAV_MSG((_T("[WAV] StopInputDMA()\r\n")));
if (m_bInputDMARunning)
{
DMA_channel_stop(&g_InputDMA);
AC97_set_pcmin_transfer_mode(AC97_CH_OFF);
m_InputDMAStatus = DMA_CLEAR;
}
m_bInputDMARunning = FALSE;
CodecMuteControl(DMA_CH_IN, TRUE);
CodecPowerControl();
}
DWORD
HardwareContext::GetOutputGain (void)
{
return m_dwOutputGain;
}
MMRESULT
HardwareContext::SetOutputGain (DWORD dwGain)
{
WAV_MSG((_T("[WAV] SetOutputGain(0x%08x)\r\n"), dwGain));
m_dwOutputGain = dwGain & 0xffff; // save off so we can return this from GetGain - but only MONO
// convert 16-bit gain to 5-bit attenuation
UCHAR ucGain;
if (m_dwOutputGain == 0)
{
ucGain = 0x3F; // mute: set maximum attenuation
}
else
{
ucGain = (UCHAR) ((0xffff - m_dwOutputGain) >> 11); // codec supports 64dB attenuation, we'll only use 32
}
//ASSERT((ucGain & 0xC0) == 0); // bits 6,7 clear indicate DATA0 in Volume mode.
return MMSYSERR_NOERROR;
}
DWORD
HardwareContext::GetInputGain (void)
{
return m_dwInputGain;
}
MMRESULT
HardwareContext::SetInputGain (DWORD dwGain)
{
WAV_MSG((_T("[WAV] SetInputGain(0x%08x)\r\n"), dwGain));
m_dwInputGain = dwGain;
if (!m_bInputMute)
{
m_InputDeviceContext.SetGain(dwGain);
}
return MMSYSERR_NOERROR;
}
BOOL
HardwareContext::GetOutputMute (void)
{
return m_bOutputMute;
}
MMRESULT
HardwareContext::SetOutputMute (BOOL bMute)
{
USHORT CodecReg;
m_bOutputMute = bMute;
CodecReg = ReadCodecRegister(WM9713_HEADPHONE_VOL);
if (bMute)
{
CodecReg |= 0x8080;
}
else
{
CodecReg &= ~0x8080;
}
WriteCodecRegister(WM9713_HEADPHONE_VOL, CodecReg);
return MMSYSERR_NOERROR;
}
BOOL
HardwareContext::GetInputMute (void)
{
return m_bInputMute;
}
MMRESULT
HardwareContext::SetInputMute (BOOL bMute)
{
m_bInputMute = bMute;
return m_InputDeviceContext.SetGain(bMute ? 0: m_dwInputGain);
}
DWORD
HardwareContext::ForceSpeaker(BOOL bForceSpeaker)
{
// If m_NumForcedSpeaker is non-zero, audio should be routed to an
// external speaker (if hw permits).
if (bForceSpeaker)
{
m_NumForcedSpeaker++;
if (m_NumForcedSpeaker == 1)
{
SetSpeakerEnable(TRUE);
}
}
else
{
m_NumForcedSpeaker--;
if (m_NumForcedSpeaker ==0)
{
SetSpeakerEnable(FALSE);
}
}
return MMSYSERR_NOERROR;
}
void
HardwareContext::InterruptThreadOutputDMA()
{
ULONG OutputTransferred;
#if (_WIN32_WCE < 600)
// Fast way to access embedded pointers in wave headers in other processes.
SetProcPermissions((DWORD)-1);
#endif
WAV_INF((_T("[WAV:INF] ++InterruptThreadOutputDMA()\n\r")));
while(TRUE)
{
WaitForSingleObject(m_hOutputDMAInterrupt, INFINITE);
Lock();
__try
{
DMA_set_interrupt_mask(&g_OutputDMA);
DMA_clear_interrupt_pending(&g_OutputDMA);
InterruptDone(m_dwSysintrOutput);
DMA_clear_interrupt_mask(&g_OutputDMA);
if ( m_Dx == D0 )
{
// DMA Output Buffer is Changed by LLI
if (m_nOutputBufferInUse == OUTPUT_DMA_BUFFER0)
{
// Buffer0 DMA finished
// DMA start with Buffer 1
m_nOutputBufferInUse = OUTPUT_DMA_BUFFER1;
}
else
{
// Buffer 1 DMA finished
// DMA start with Buffer 0
m_nOutputBufferInUse = OUTPUT_DMA_BUFFER0;
}
if(m_OutputDMAStatus & DMA_BIU)
{
m_OutputDMAStatus &= ~DMA_STRTB; // Buffer B just completed...
m_OutputDMAStatus |= DMA_DONEB;
m_OutputDMAStatus &= ~DMA_BIU; // Buffer A is in use
}
else
{
m_OutputDMAStatus &= ~DMA_STRTA; // Buffer A just completed...
m_OutputDMAStatus |= DMA_DONEA;
m_OutputDMAStatus |= DMA_BIU; // Buffer B is in use
}
OutputTransferred = TransferOutputBuffer(m_OutputDMAStatus);
}
}
__except(GetExceptionCode()==STATUS_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
WAV_ERR((_T("WAVDEV2.DLL:InterruptThreadOutputDMA() - EXCEPTION: %d"), GetExceptionCode()));
}
Unlock();
}
WAV_INF((_T("[WAV:INF] --InterruptThreadOutputDMA()\n\r")));
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -