📄 hxaudevds.cpp
字号:
m_ulCurrPlayTime = 0;
m_ulCurrLoopTime = 0;
m_ulLoops = 0;
// Setup converter to convert from samples/sec to milliseconds
m_TSConverter.SetBase(m_WaveFormat.Format.nSamplesPerSec, 1000);
return theErr;
}
HX_RESULT CHXAudioDeviceDS::_Imp_Close()
{
HX_RESULT theErr = HXR_OK;
KillThreadAndEvent();
HX_RELEASE(m_pPrimaryBuffer);
HX_RELEASE(m_pSecondaryBuffer);
HX_RELEASE(m_pDSDev);
m_pAudioPtrStart = NULL;
m_ulLastPlayCursor = 0;
m_ulLastWriteCursor =0;
m_eState = E_DEV_CLOSED;
m_ulLoops = 0;
m_ulLoopTime = 0;
m_nBlocksPerBuffer = 0;
m_ulCurrPlayTime = 0;
m_ulCurrLoopTime = 0;
if (m_hwnd)
{
SetWindowLong(m_hwnd, GWL_USERDATA, NULL);
}
return HXR_OK;
}
HX_RESULT CHXAudioDeviceDS::_Imp_Pause()
{
HX_RESULT theErr = HXR_OK;
m_bPaused = TRUE;
if (m_pSecondaryBuffer)
{
m_pSecondaryBuffer->Stop();
}
m_eState = E_DEV_PAUSED;
return HXR_OK;
}
HX_RESULT CHXAudioDeviceDS::_Imp_Resume()
{
if (m_pSecondaryBuffer && m_pAudioPtrStart)
{
m_pSecondaryBuffer->Play(0, 0, DSBPLAY_LOOPING);
if(m_bPaused)
{
m_bPaused = FALSE;
}
OnTimeSync();
}
m_eState = E_DEV_RESUMED;
return HXR_OK;
}
HX_RESULT CHXAudioDeviceDS::_Imp_Write(const HXAudioData* pAudioHdr)
{
HRESULT res ;
IHXBuffer* pBuffer;
pBuffer = pAudioHdr->pData;
UINT32 ulBufSize = pBuffer->GetSize();
void* pAudioPtr1 = NULL;
void* pAudioPtr2 = NULL;
DWORD ulAudioBytes1 = 0;
DWORD ulAudioBytes2 = 0;
res = m_pSecondaryBuffer->Lock(m_ulLastWriteCursor, ulBufSize, &pAudioPtr1, &ulAudioBytes1,
&pAudioPtr2, &ulAudioBytes2, 0);
if(res != DS_OK)
{
RMDS_LOG(" Lock failed ulBufSize = %ld pAudioPtr1 = %ld ulAudioBytes1 = %ld pAudioPtr2 = %ld ulAudioBytes2 = %ld \n", ulBufSize, pAudioPtr1, ulAudioBytes1, pAudioPtr2, ulAudioBytes2);
return HXR_FAIL ;
}
HX_ASSERT(ulBufSize = ulAudioBytes1+ulAudioBytes2);
m_ulLastWriteCursor += ulBufSize ;
if (m_ulLastWriteCursor >= m_ulTotalBuffer)
m_ulLastWriteCursor -= m_ulTotalBuffer;
if(pAudioPtr1)
{
::memcpy(pAudioPtr1, (void*) pBuffer->GetBuffer(), ulAudioBytes1); /* Flawfinder: ignore */
if(!m_pAudioPtrStart)
{
m_pAudioPtrStart = pAudioPtr1;
m_ulLoops = 0;
m_pSecondaryBuffer->SetCurrentPosition(0);
}
}
if (pAudioPtr2)
::memcpy(pAudioPtr2, ((char*)pBuffer->GetBuffer()) + ulAudioBytes1 , ulAudioBytes2); /* Flawfinder: ignore */
res = m_pSecondaryBuffer->Unlock(pAudioPtr1, ulAudioBytes1, pAudioPtr2, ulAudioBytes2);
if(res != DS_OK)
{
RMDS_LOG(" Unlock failed ulBufSize = %ld pAudioPtr1 = %ld ulAudioBytes1 = %ld pAudioPtr2 = %ld ulAudioBytes2 = %ld \n", ulBufSize, pAudioPtr1, ulAudioBytes1, pAudioPtr2, ulAudioBytes2);
return HXR_FAIL ;
}
return HXR_OK;
}
HX_RESULT CHXAudioDeviceDS::_Imp_SetVolume(const UINT16 uVolume)
{
LONG lVol = 0;
m_uCurVolume = uVolume;
if( m_uCurVolume == 0)
lVol = DSBVOLUME_MIN;
else
{
double dVolFromMin = (double)m_uCurVolume - m_uMinVolume;
double dVolFrac = (dVolFromMin/(m_uMaxVolume - m_uMinVolume));
lVol = (LONG)(1055.0 * log(dVolFrac));
}
if(m_pSecondaryBuffer)
m_pSecondaryBuffer->SetVolume(lVol);
return HXR_OK;
}
UINT16 CHXAudioDeviceDS::_Imp_GetVolume()
{
LONG lVolume;
if (!m_pSecondaryBuffer)
return m_uMaxVolume ;
m_pSecondaryBuffer->GetVolume(&lVolume);
return (UINT16)(exp(lVolume / 1055.0) * (m_uMaxVolume - m_uMinVolume) + m_uMinVolume) ;
}
HX_RESULT CHXAudioDeviceDS::_Imp_Reset()
{
if ( NULL == m_pSecondaryBuffer )
{
return HXR_OK;
}
void* pAudioPtr1 = NULL;
void* pAudioPtr2 = NULL;
DWORD ulAudioBytes1 = 0;
DWORD ulAudioBytes2 = 0;
HRESULT result = m_pSecondaryBuffer->Lock(0, 0, &pAudioPtr1, &ulAudioBytes1,&pAudioPtr2, &ulAudioBytes2, DSBLOCK_ENTIREBUFFER);
if(result == DS_OK)
{
::ZeroMemory(pAudioPtr1, ulAudioBytes1);
::ZeroMemory(pAudioPtr2, ulAudioBytes2);
m_ulLastWriteCursor = 0;
m_pSecondaryBuffer->Unlock(pAudioPtr1, ulAudioBytes1, pAudioPtr2, ulAudioBytes2);
m_ulCurrPlayTime = 0;
m_ulCurrLoopTime = 0;
m_ulLoops = 0;
m_ulLastPlayCursor = 0;
m_pAudioPtrStart = pAudioPtr1;
m_pSecondaryBuffer->SetCurrentPosition(0);
RMDS_LOG("RESET \n \n \n \n");
}
else
{
RMDS_LOG(" Reset - Lock failed \n");
}
return HXR_OK;
}
HX_RESULT CHXAudioDeviceDS::_Imp_Drain()
{
return HXR_OK;
}
HX_RESULT CHXAudioDeviceDS::_Imp_CheckFormat( const HXAudioFormat* pFormat )
{
return HXR_OK;
}
HX_RESULT CHXAudioDeviceDS::_Imp_GetCurrentTime(ULONG32& ulCurrentTime)
{
DWORD dwCurrentPlayCursor = 0;
DWORD dwCurrentWriteCursor = 0;
HRESULT result;
ulCurrentTime = m_ulCurrPlayTime;
if (m_pSecondaryBuffer)
{
result = m_pSecondaryBuffer->GetCurrentPosition(&dwCurrentPlayCursor,
&dwCurrentWriteCursor);
if (result == DS_OK)
{
UINT32 uLast = m_ulCurrPlayTime;
if(dwCurrentPlayCursor != m_ulLastPlayCursor)
{
if( (dwCurrentPlayCursor < m_ulLastPlayCursor) && ((m_ulLastPlayCursor-dwCurrentPlayCursor) > (m_ulTotalBuffer/2)) )
{
RMDS_LOG(" m_ulLastPlayCursor = %ld ; dwCurrentPlayCursor = %ld \n", m_ulLastPlayCursor, dwCurrentPlayCursor);
m_ulLoops++;
m_ulCurrPlayTime = m_ulCurrLoopTime = (UINT32) (m_ulLoopTime * 1000.0 * m_ulLoops);
m_ulLastPlayCursor = 0;
}
// Time can only move forward
if (dwCurrentPlayCursor > m_ulLastPlayCursor)
{
ULONG32 ulSamplesPlayedThisLoop =
dwCurrentPlayCursor / m_WaveFormat.Format.nBlockAlign;
m_ulCurrPlayTime = m_ulCurrLoopTime +
m_TSConverter.ConvertVector(ulSamplesPlayedThisLoop);
m_ulLastPlayCursor = dwCurrentPlayCursor;
}
ulCurrentTime = m_ulCurrPlayTime;
}
RMDS_LOG(" ulCurrentTime = %ld \n", ulCurrentTime);
}
else
{
RMDS_LOG(" GetCurrentPosition failed \n");
}
}
return HXR_OK;
}
UINT32
CHXAudioDeviceDS::CalcMs(UINT32 ulNumBytes)
{
return (ulNumBytes * 1000UL ) / m_WaveFormat.Format.nAvgBytesPerSec ;
}
DWORD
CHXAudioDeviceDS::defaultChannelMapping(UINT32 ulChannels) const
{
switch (ulChannels)
{
case 1:
return SPEAKER_FRONT_CENTER ;
case 2:
return SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT ;
case 5:
return SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_FRONT_CENTER ;
case 6:
return SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_FRONT_CENTER |
SPEAKER_LOW_FREQUENCY;
}
return 0 ;
}
void
CHXAudioDeviceDS::KillThreadAndEvent()
{
DWORD dwThreadWaitResult = WAIT_FAILED;
if(m_hDSNotifyEvent)
{
m_bExitThread = TRUE;
::SetEvent(m_hDSNotifyEvent);
// Wait for thread to exit
if ( m_hWaitThread )
{
dwThreadWaitResult = WaitForSingleObject(m_hWaitThread, kExitThreadWaitTime);
}
CloseHandle(m_hDSNotifyEvent);
m_hDSNotifyEvent = NULL;
}
if(m_hWaitThread)
{
if ( dwThreadWaitResult != WAIT_OBJECT_0 )
{
::TerminateThread(m_hWaitThread, -1 );
}
CloseHandle(m_hWaitThread);
m_hWaitThread = NULL;
}
m_bExitThread = FALSE;
}
void
CHXAudioDeviceDS::PostTimeSyncMessage()
{
::PostMessage(m_hwnd, HXMSG_TIMESYNC, 0, 0);
}
DWORD WINAPI CHXAudioDeviceDS::EventThreadProc(LPVOID pVoid)
{
CHXAudioDeviceDS* pThis = (CHXAudioDeviceDS*)pVoid;
if(!pThis)
return 0;
HANDLE hWaitEvent = pThis->GetEventHandle();
if(!hWaitEvent)
return 0;
while(1)
{
DWORD dwReturn = WaitForMultipleObjects(1, &hWaitEvent, FALSE, INFINITE);
if(pThis->GetExitCode())
{
return 0;
}
if (dwReturn != (WAIT_OBJECT_0 + 1))
{
// Post message to the window so that it can call OnTimeSync on the audio thread( on which the window was created )
// and then reset the event
pThis->PostTimeSyncMessage();
ResetEvent(hWaitEvent);
}
}
return 0;
}
static LRESULT CALLBACK HXDSWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == HXMSG_TIMESYNC)
{
CHXAudioDeviceDS* pThis = (CHXAudioDeviceDS*)GetWindowLong(hWnd, GWL_USERDATA);
if(pThis)
pThis->OnTimeSync();
return 0;
}
else if (message == CHXAudioDeviceDS::zm_uDestroyMessage)
{
LRESULT result = (LRESULT)DestroyWindow(hWnd);
// free the memory used by this class now that our window is destroyed
UnregisterClass(szWindowClass, g_hInstance);
return result;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -