⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hxaudevds.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    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 + -