📄 hxaudevds.cpp
字号:
} } pNotify->SetNotificationPositions(m_nBlocksPerBuffer, aPositionNotify); delete[] aPositionNotify; DWORD dwWaitThreadID(0); m_hWaitThread = CreateThread(NULL, 0, EventThreadProc, (LPVOID)this, 0, &dwWaitThreadID); } HX_RELEASE(pNotify); m_pSecondaryBuffer->SetVolume(DSBVOLUME_MAX); m_pSecondaryBuffer->SetCurrentPosition(0); } 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 ;}DWORDCHXAudioDeviceDS::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 + -