hwctxt.cpp
字号:
// If the timer has already started, reset the timer
// and signal the output mute thread to run again.
//
if ( !m_pWMAudioDeviceData->OutputMuteTimerStarted )
{
SetEvent( m_hOutputMuteIntEvent );
}
else
{
Lock();
SetEvent( m_hOutputMuteTimeoutEvent );
SetEvent( m_hOutputMuteIntEvent );
Unlock();
}
#endif
//
// Unlock access to the global data.
//
UnlockGlobalData( m_hGlobalDataDeviceMutex );
return;
};
//-----------------------------------------------------------------------------
// Member function: StartVoiceInputDMA
//
// Makes sure DMA is running for the Voice input stream.
//
// Parameters:
// none
//
// Returns: void
//-----------------------------------------------------------------------------
void HardwareContext::StartVoiceInputDMA()
{
DWORD retval = MMSYSERR_NOERROR;
WMSTATUS status = WMS_SUCCESS;
//
// Check that we have a valid pointer to the global audio data.
//
if ( !m_pWMAudioDeviceData )
{
ASSERT( 0 );
retval = MMSYSERR_ERROR;
goto exit;
}
//
// Lock our global data access
//
retval = LockGlobalData( m_hGlobalDataDeviceMutex );
if ( MMSYSERR_ERROR == retval )
{
goto exit;
}
if (!m_pWMAudioDeviceData->VoiceInputDMARunning)
{
// For now, pretend input dma is running in case we accidentally get reentered
m_pWMAudioDeviceData->VoiceInputDMARunning = TRUE;
m_VoiceInBytes[0] = m_VoiceInBytes[1]=0;
m_nextVoiceInputBuf = 0;
m_VoiceInputStarted = FALSE;
//
// Enable the input paths.
//
retval = private_PrepareInputPaths( WM_STREAM_VOICE_IN, m_pWMAudioDeviceData, TRUE );
if ( MMSYSERR_NOERROR != retval )
{
DEBUGMSG( ZONE_ERROR,
( TEXT( "StartVoiceInputDMA - preparing input paths failed\r\n") ) );
goto exit;
}
WMAudioStartRecording( m_hAudioDevice, m_hVoiceInputStream );
DEBUGMSG( ZONE_DMA, (TEXT("Started Voice input DMA\r\n")));
}
exit:
if ( MMSYSERR_NOERROR != retval )
{
m_pWMAudioDeviceData->VoiceInputDMARunning = FALSE;
}
//
// Unlock access to the global data.
//
UnlockGlobalData( m_hGlobalDataDeviceMutex );
return;
}
//-----------------------------------------------------------------------------
// Member function: StopVoiceInputDMA
//
// Stops the DMA for the Voice input stream.
//
// Parameters:
// pWMAudioData pointer to the global audio data
//
// Returns: void
//-----------------------------------------------------------------------------
void HardwareContext::StopVoiceInputDMA( volatile WM_SHARED_AUDIO_DATA *pWMAudioData )
{
DWORD retval = MMSYSERR_NOERROR;
WMSTATUS status = WMS_SUCCESS;
WM_POWERFLAG powerSections = WM_POWER_NONE;
//
// Check that we have a valid pointer to the global audio data.
//
if ( !pWMAudioData )
{
ASSERT( 0 );
retval = MMSYSERR_ERROR;
goto exit;
}
//
// Lock our global data access
//
retval = LockGlobalData( m_hGlobalDataDeviceMutex );
if ( MMSYSERR_ERROR == retval )
{
goto exit;
}
if ( pWMAudioData->VoiceInputDMARunning )
{
WMAudioStop( m_hAudioDevice, m_hVoiceInputStream );
pWMAudioData->VoiceInputDMARunning = FALSE;
//
// Disable the input paths.
//
retval = private_PrepareInputPaths( WM_STREAM_VOICE_IN, pWMAudioData, FALSE );
if ( MMSYSERR_NOERROR != retval )
{
DEBUGMSG( ZONE_ERROR,
( TEXT( "StopVoiceInputDMA - disabling input paths failed\r\n") ) );
goto exit;
}
DEBUGMSG( ZONE_DMA, (TEXT("Stopped Voice input DMA\r\n")));
}
exit:
//
// Unlock access to the global data.
//
UnlockGlobalData( m_hGlobalDataDeviceMutex );
return;
}
#endif // WM_VOICE
#if WM_MONODAC
//-----------------------------------------------------------------------------
// Member function: StartMonoOutputDMA
//
// Makes sure DMA is running for the Voice output stream, and transmits the first
// buffer-fulls of data.
//
// Parameters:
// none
//
// Returns: void
//-----------------------------------------------------------------------------
void HardwareContext::StartMonoOutputDMA()
{
DWORD retval = MMSYSERR_NOERROR;
WMSTATUS status = WMS_SUCCESS;
//
// Check that we have a valid pointer to the global audio data.
//
if ( !m_pWMAudioDeviceData )
{
ASSERT( 0 );
retval = MMSYSERR_ERROR;
goto exit;
}
//
// Lock our global data access
//
retval = LockGlobalData( m_hGlobalDataDeviceMutex );
if ( MMSYSERR_ERROR == retval )
{
goto exit;
}
if ( !m_pWMAudioDeviceData->MonoOutputDMARunning )
{
ULONG OutputTransferred = 0;
// For now, pretend output dma is running in case we accidentally get reentered
m_pWMAudioDeviceData->MonoOutputDMARunning = TRUE;
m_MonoOutBytes[0] = m_MonoOutBytes[1]=0;
m_nextMonoOutputBuf = 0;
m_MonoOutputStarted = FALSE;
#if WM_OUTPUT_MUTE_DELAY
if ( m_pWMAudioDeviceData->MonoOutputMuted )
#endif
{
//
// Enable the output paths.
//
retval = private_PrepareOutputPaths( WM_STREAM_MONO_OUT, m_pWMAudioDeviceData, TRUE );
if ( MMSYSERR_NOERROR != retval )
{
DEBUGMSG( ZONE_ERROR,
( TEXT( "StartMonoOutputDMA - preparing output paths failed\r\n") ) );
goto exit;
}
#if WM_OUTPUT_MUTE_DELAY
/*
* The outputs are now unmuted.
*/
m_pWMAudioDeviceData->MonoOutputMuted = FALSE;
#endif
}
#if WM_OUTPUT_MUTE_DELAY
/*
* Check to see if the output mute timer has already started.
* If it has reset it.
*/
if ( m_pWMAudioDeviceData->OutputMuteTimerStarted )
{
SetEvent( m_hOutputMuteTimeoutEvent );
}
#endif
// Prime the output buffer and turn on DMA if anything got transferred
OutputTransferred = TransferMonoOutputBuffers();
// If we did transfer any data to the DMA buffers, go ahead and enable DMA
if ( OutputTransferred )
{
DEBUGMSG( ZONE_DMA, (TEXT("Started Mono output DMA\r\n")));
}
else // We didn't transfer any data, so DMA wasn't enabled
{
retval = MMSYSERR_ERROR;
}
}
exit:
if ( MMSYSERR_NOERROR != retval )
{
m_pWMAudioDeviceData->MonoOutputDMARunning = FALSE;
}
//
// Unlock access to the global data.
//
UnlockGlobalData( m_hGlobalDataDeviceMutex );
return;
}
//-----------------------------------------------------------------------------
// Member function: StopMonoOutputDMA
//
// Stops the Mono output DMA. Note any data still in the buffers will be lost.
//
// Parameters:
// pWMAudioData pointer to the global audio data
//
// Returns: void
//-----------------------------------------------------------------------------
void HardwareContext::StopMonoOutputDMA( volatile WM_SHARED_AUDIO_DATA *pWMAudioData )
{
DWORD retval = MMSYSERR_NOERROR;
WMSTATUS status = WMS_SUCCESS;
WM_POWERFLAG powerSections = WM_POWER_NONE;
//
// Check that we have a valid pointer to the global audio data.
//
if ( !pWMAudioData )
{
ASSERT( 0 );
retval = MMSYSERR_ERROR;
goto exit;
}
//
// Lock our global data access
//
retval = LockGlobalData( m_hGlobalDataDeviceMutex );
if ( MMSYSERR_ERROR == retval )
{
goto exit;
}
if ( pWMAudioData->MonoOutputDMARunning )
{
WMAudioStop( m_hAudioDevice, m_hMonoOutputStream );
pWMAudioData->MonoOutputDMARunning = FALSE;
#if !WM_OUTPUT_MUTE_DELAY
//
// Disable the output paths.
//
retval = private_PrepareOutputPaths( WM_STREAM_MONO_OUT, pWMAudioData, FALSE );
if ( MMSYSERR_NOERROR != retval )
{
DEBUGMSG( ZONE_ERROR,
( TEXT( "StopMonoOutputDMA - disabling output paths failed\r\n") ) );
goto exit;
}
#endif
DEBUGMSG( ZONE_DMA, (TEXT("Stopped Mono output DMA\r\n")));
}
exit:
#if WM_OUTPUT_MUTE_DELAY
//
// Check to see if the output mute timer has already
// started. If it hasn't signal timer to disable the
// output paths after a defined amount of time.
// If the timer has already started, reset the timer
// and signal the output mute thread to run again.
//
if ( !m_pWMAudioDeviceData->OutputMuteTimerStarted )
{
SetEvent( m_hOutputMuteIntEvent );
}
else
{
Lock();
SetEvent( m_hOutputMuteTimeoutEvent );
SetEvent( m_hOutputMuteIntEvent );
Unlock();
}
#endif
//
// Unlock access to the global data.
//
UnlockGlobalData( m_hGlobalDataDeviceMutex );
return;
};
#endif // WM_MONODAC
//-----------------------------------------------------------------------------
// Member function: GetInterruptThreadPriority
//
// Queries the registry to find the priority to give the interrupt thread.
//
// Parameters:
// none
//
// Returns: DWORD
// Priority to use.
//-----------------------------------------------------------------------------
DWORD HardwareContext::GetInterruptThreadPriority()
{
HKEY hDevKey;
DWORD dwValType;
DWORD dwValLen;
DWORD dwPrio = 249; // Default priority
hDevKey = OpenDeviceKey((LPWSTR)m_DriverIndex);
if (hDevKey)
{
dwValLen = sizeof(DWORD);
RegQueryValueEx(
hDevKey,
TEXT("Priority256"),
NULL,
&dwValType,
(PUCHAR)&dwPrio,
&dwValLen);
RegCloseKey(hDevKey);
}
return dwPrio;
}
//-----------------------------------------------------------------------------
// Member function: InitInterruptThread
//
// Initialises interrupts, creates the signal event, and sets the interrupt
// thread running.
//
// Parameters:
// none
//
// Returns: BOOL
// TRUE = success
// FALSE = failure
//-----------------------------------------------------------------------------
BOOL HardwareContext::InitInterruptThread()
{
BOOL bSuccess = TRUE;
DEBUGMSG(ZONE_INIT|ZONE_FUNCTION, (TEXT("+InitInterruptThread\r\n")));
#if WM_USE_DYNAMIC_DMA_CHANNEL
if ( WM_HANDLE_INVALID != m_hHiFiInputStream )
{
m_hAudioHiFiInputInterruptThread = CreateThread( (LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)CallHiFiInputInterruptThread,
this,
0,
NULL
);
if (!m_hAudioHiFiInputInterruptThread)
{
goto error;
}
}
m_hAudioHiFiOutputInterruptThread = CreateThread( (LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)CallHiFiOutputInterruptThread,
this,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -