📄 hwctxt.cpp
字号:
DEBUGMSG(ZONE_FUNCTION,(_T("-HardwareContext::Init\n")));
return m_Initialized;
}
//-----------------------------------------------------------------------------
//
// Function: Deinit
//
// This function deinitializes the hardware context for the audio device.
//
// Parameters:
// None.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL HardwareContext::Deinit()
{
DEBUGMSG(ZONE_FUNCTION,(_T("+HardwareContext::Deinit\n")));
Lock();
#ifdef AUDIO_RECORDING_ENABLED
// Terminate input (recording) DMA operation if it is currently running.
if (m_InputDMARunning)
{
StopInputDMA();
}
#endif
if (m_OutputDMARunning)
{
StopOutputDMA();
}
Unlock();
// Unmap the audio control registers and DMA buffers.
BSPAudioDeinit();
UnmapDMABuffers();
m_Initialized = FALSE;
DEBUGMSG(ZONE_FUNCTION,(_T("-HardwareContext::Deinit\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: MapDMABuffers
//
// This function maps the DMA buffers used for audio input/output.
//
// Parameters:
// None.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL HardwareContext::MapDMABuffers()
{
PBYTE pVirtDMABufferAddr = NULL;
DEBUGMSG(ZONE_FUNCTION,(_T("+HardwareContext::MapDMABuffers\n")));
// Allocate a block of virtual memory (physically contiguous) for the
// DMA buffers. Note that a platform-specific API call is used here to
// allow for the DMA buffers to be allocated from different memory regions
// (e.g., internal vs. external memory).
pVirtDMABufferAddr = BSPAudioAllocDMABuffers(&g_PhysDMABufferAddr);
if (pVirtDMABufferAddr == NULL)
{
RETAILMSG(TRUE, (TEXT("WAVEDEV.DLL:HardwareContext::MapDMABuffers() - ")
TEXT("Failed to allocate DMA buffer.\r\n")));
return(FALSE);
}
// Setup the DMA page pointers.
//
// NOTE: Currently, input and output each have two DMA pages: these pages
// are used in a round-robin fashion so that the OS can read/write
// one buffer while the audio codec chip read/writes the other buffer.
//
m_Output_pbDMA_PAGES[0] = pVirtDMABufferAddr;
m_Output_pbDMA_PAGES[1] = pVirtDMABufferAddr + AUDIO_DMA_PAGE_SIZE;
#ifdef AUDIO_RECORDING_ENABLED
m_Input_pbDMA_PAGES[0] = pVirtDMABufferAddr + (2 * AUDIO_DMA_PAGE_SIZE);
m_Input_pbDMA_PAGES[1] = pVirtDMABufferAddr + (3 * AUDIO_DMA_PAGE_SIZE);
#endif
DEBUGMSG(ZONE_FUNCTION,(_T("-HardwareContext::MapDMABuffers\n")));
return(TRUE);
}
//-----------------------------------------------------------------------------
//
// Function: UnmapDMABuffers
//
// This function unmaps the DMA buffers previously mapped with the
// MapDMABuffers function.
//
// Parameters:
// None.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL HardwareContext::UnmapDMABuffers()
{
DEBUGMSG(ZONE_FUNCTION,(_T("+HardwareContext::UnmapDMABuffers\n")));
if (m_Output_pbDMA_PAGES[0])
{
BSPAudioDeallocDMABuffers((PVOID)(m_Output_pbDMA_PAGES[0]));
m_Output_pbDMA_PAGES[0] = NULL;
m_Output_pbDMA_PAGES[1] = NULL;
#ifdef AUDIO_RECORDING_ENABLED
m_Input_pbDMA_PAGES[0] = NULL;
m_Input_pbDMA_PAGES[1] = NULL;
#endif
}
DEBUGMSG(ZONE_FUNCTION,(_T("-HardwareContext::UnmapDMABuffers\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: SetOutputGain
//
// Parameters:
// DWORD dwGain - new gain level
//
// Returns:
// Returns MMSYSERR_NOERROR if successful, otherwise returns
// MMSYSERR_ERROR.
//
//-----------------------------------------------------------------------------
MMRESULT HardwareContext::SetOutputGain (DWORD dwGain)
{
DEBUGMSG(ZONE_FUNCTION,(_T("+HardwareContext::SetOutputGain\n")));
BSPAudioSetOutputGain(AUDIO_BUS_STEREO_OUT, dwGain);
m_dwOutputGain = dwGain;
DEBUGMSG(ZONE_FUNCTION,(_T("-HardwareContext::SetOutputGain\n")));
return MMSYSERR_NOERROR;
}
MMRESULT HardwareContext::SetOutputMute (BOOL fMute)
{
// TODO: Call down to PMIC driver for codec mute configuration
// Save output mute configuration
m_fOutputMute = fMute;
return MMSYSERR_NOERROR;
}
BOOL HardwareContext::GetOutputMute (void)
{
return m_fOutputMute;
}
DWORD HardwareContext::GetOutputGain (void)
{
return m_dwOutputGain;
}
#ifdef AUDIO_RECORDING_ENABLED
BOOL HardwareContext::GetInputMute (void)
{
return m_fInputMute;
}
MMRESULT HardwareContext::SetInputMute (BOOL fMute)
{
// TODO: Call down to PMIC driver for codec mute configuration
// Save input mute configuration
m_fInputMute = fMute;
return m_InputDeviceContext.SetGain(fMute ? 0: m_dwInputGain);
}
DWORD HardwareContext::GetInputGain (void)
{
return m_dwInputGain;
}
//-----------------------------------------------------------------------------
//
// Function: SetInputGain
//
//
// Parameters:
// None.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
MMRESULT HardwareContext::SetInputGain (DWORD dwGain)
{
DEBUGMSG(ZONE_FUNCTION,(_T("+HardwareContext::SetInputGain\n")));
BSPAudioSetInputGain(AUDIO_BUS_VOICE_IN, dwGain);
m_dwInputGain = dwGain;
DEBUGMSG(ZONE_FUNCTION,(_T("-HardwareContext::SetInputGain\n")));
return MMSYSERR_NOERROR;
}
#endif // #ifdef AUDIO_RECORDING_ENABLED
//-----------------------------------------------------------------------------
//
// Function: InitOutputDMA
//
// This function initializes the DMA channel for output.
//
// Parameters:
// None.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL HardwareContext::InitOutputDMA()
{
BOOL rc = FALSE;
DDK_DMA_ACCESS audioDataTXWordSize = DDK_DMA_ACCESS_8BIT;
if (sizeof(HWSAMPLE) == sizeof(INT16))
{
audioDataTXWordSize = DDK_DMA_ACCESS_16BIT;
}
else if (sizeof(HWSAMPLE) == sizeof(INT32))
{
audioDataTXWordSize = DDK_DMA_ACCESS_32BIT;
}
DEBUGMSG(ZONE_FUNCTION,(_T("+HardwareContext::InitOutputDMA\n")));
// Confirm that DMA buffer has been allocated.
if (!g_PhysDMABufferAddr.LowPart)
{
ERRORMSG(ZONE_ERROR, (_T("Invalid DMA buffer physical address.\r\n")));
goto cleanUp;
}
// Configure the platform-specific output DMA channel
if (!BSPAudioInitOutput(AUDIO_BUS_STEREO_OUT))
{
ERRORMSG(ZONE_ERROR, (_T("BSPAudioInitOutput failed.\r\n")));
goto cleanUp;
}
// Allocate a DMA chain for the virtual channel to handle the DMA transfer
// requests.
if (!DDKSdmaAllocChain(m_OutputDMAChan, NUM_DMA_BUFFERS))
{
ERRORMSG(ZONE_ERROR, (_T("DDKSdmaAllocChain failed.\r\n")));
goto cleanUp;
}
// Configure the SDMA buffer descriptors. We currently use 2 contiguous DMA
// pages as a circular queue. Each DMA buffer is AUDIO_DMA_PAGE_SIZE bytes
// in size.
//
// If the audio data stream is not big enough to fill a DMA buffer (i.e., we
// are performing the last transfer), then we will resize the data transfer
// at that time.
if (!DDKSdmaSetBufDesc(m_OutputDMAChan,
0,
DDK_DMA_FLAGS_INTR | DDK_DMA_FLAGS_CONT,
g_PhysDMABufferAddr.LowPart,
0,
audioDataTXWordSize,
AUDIO_DMA_PAGE_SIZE))
{
ERRORMSG(ZONE_ERROR, (_T("DDKSdmaSetBufDesc failed.\r\n")));
goto cleanUp;
}
if (!DDKSdmaSetBufDesc(m_OutputDMAChan,
1,
DDK_DMA_FLAGS_INTR | DDK_DMA_FLAGS_CONT |
DDK_DMA_FLAGS_WRAP,
g_PhysDMABufferAddr.LowPart + AUDIO_DMA_PAGE_SIZE,
0,
audioDataTXWordSize,
AUDIO_DMA_PAGE_SIZE))
{
ERRORMSG(ZONE_ERROR, (_T("DDKSdmaSetBufDesc failed.\r\n")));
goto cleanUp;
}
rc = TRUE;
cleanUp:
if (!rc)
{
DeinitOutputDMA();
}
DEBUGMSG(ZONE_FUNCTION,(_T("-HardwareContext::InitOutputDMA\n")));
return rc;
}
//-----------------------------------------------------------------------------
//
// Function: DeinitOutputDMA
//
// This function deinitializes the DMA channel for output.
//
// Parameters:
// None.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL HardwareContext::DeinitOutputDMA()
{
DEBUGMSG(ZONE_FUNCTION,(_T("+HardwareContext::DeinitOutputDMA\n")));
// Stop the audio output devices
BSPAudioStopOutput(AUDIO_BUS_STEREO_OUT, AUDIO_PATH_HEADSET);
if (m_OutputDMAChan != 0)
{
DDKSdmaCloseChan(m_OutputDMAChan);
m_OutputDMAChan = 0;
}
DEBUGMSG(ZONE_FUNCTION,(_T("-HardwareContext::DeinitOutputDMA\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: StartOutputDMA
//
// This function starts outputting the sound data to the audio codec
// chip via the DMA.
//
// Parameters:
// None.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL HardwareContext::StartOutputDMA()
{
HWSAMPLE ssiFifoPrefill[SSI_TX_FIFO_DEPTH]; // For SSI TX FIFO prefill.
unsigned nSsiFifoPrefill = 0; // Number of words used in ssiFifoPrefill[].
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -