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

📄 hxaudply.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    if ( m_eState == E_PLAYING )    {	return HXR_OK;    }    m_bIsDonePlayback = FALSE;    m_eState          = E_PLAYING;    m_bCanBeRewound   = TRUE;    /* Use Audio Session Object ONLY if there are any audio streams     * in the presentation     */    if (m_bHasStreams)    {	CHXAudioStream* s = 0;	CHXSimpleList::Iterator lIter = m_pStreamList->Begin();	for (; lIter != m_pStreamList->End(); ++lIter)	{	    s = (CHXAudioStream*) (*lIter);	    if ( s )		s->Resume(TRUE);	}	// This is the audio device playback time that corresponds to	// when this audio player resumed.	m_ulADresumeTime = m_Owner->GetCurrentPlayBackTime();	// This is this player's start time within its timeline. This is	// modified when the player is seeked or resumed.	m_ulAPstartTime = m_ulAPplaybackTime;	UpdateStreamLastWriteTime();	// Resume the audio device playback	if ( !theErr )	    theErr = m_Owner->Resume(this);    }    else    {	theErr = ResumeFakeTimeline();	/* Send time 0 at first Resume */	if (!theErr && m_bIsFirstResume)	{	    m_bIsFirstResume = FALSE;	    OnTimeSync(m_ulIncreasingTimer);	}    }    m_bIsResumed = TRUE;    return ( !theErr ) ? HXR_OK : HXR_FAILED;}/************************************************************************ *  Method: *		CHXAudioPlayer::Pause *	Purpose: *		The player object calls this function to pause audio playback. */HX_RESULT CHXAudioPlayer::Pause(){    if (m_eState == E_PAUSED)    {	return HXR_OK;    }    m_eState = E_PAUSED;    if (m_bHasStreams)    {	CHXAudioStream* s = 0;	CHXSimpleList::Iterator lIter = m_pStreamList->Begin();	for (; lIter != m_pStreamList->End(); ++lIter)	{	    s = (CHXAudioStream*) (*lIter);	    if ( s )		s->Pause(TRUE);	}	m_Owner->Pause(this);    }    else    {	StopFakeTimeline();    }    m_bCanBeRewound = FALSE;    return HXR_OK;}/************************************************************************ *  Method: *		CHXAudioPlay::Stop *	Purpose: *      The player object calls this function to stop audio playback. *		If bFlush is TRUE, flush any data in the audio device. */HX_RESULT CHXAudioPlayer::Stop(    const BOOL bFlush){    m_eState = E_STOPPED;    m_ulAPstartTime 	= 0;    if (m_bHasStreams)    {	CHXAudioStream* s = 0;	CHXSimpleList::Iterator lIter = m_pStreamList->Begin();	for (; lIter != m_pStreamList->End(); ++lIter)	{	    s = (CHXAudioStream*) (*lIter);	    if ( s )		s->Stop();	}	m_Owner->Stop(this, bFlush);    }    else    {	StopFakeTimeline();    }    ResetPlayer();    return HXR_OK;}/************************************************************************ *  Method: *		CHXAudioPlayer::Seek *	Purpose: *		The player object calls this function to seek audio playback to *		the time (in milliseconds) given. */HX_RESULT CHXAudioPlayer::Seek(const 	UINT32			ulSeekTime){    /* always remember this seek time.. even though there may not be any streams     * yet for this player. This is because the streams may be created later and     * we need to correctly apply the seek time to get the accurate time.     */    m_ulAPstartTime = m_ulAPplaybackTime = ulSeekTime;	// current start time for this player    m_llLastWriteTime = (INT64) ulSeekTime;    if (m_bHasStreams)    {	// Make each stream seek, too, since they own the resampling buffers.	CHXAudioStream* s = 0;	CHXSimpleList::Iterator lIter = m_pStreamList->Begin();	for (; lIter != m_pStreamList->End(); ++lIter)	{	    s = (CHXAudioStream*) (*lIter);	    if ( s )		s->Seek(ulSeekTime);	}	m_Owner->Seek( this, ulSeekTime );	m_ulADresumeTime = m_Owner->GetCurrentPlayBackTime();    }    else    {	StopFakeTimeline();	m_bIsFirstResume    = TRUE;    }    m_ulCurrentTime	    = ulSeekTime;    m_ulLastCurrentTimeReturned	= m_ulCurrentTime;    m_bTimeReturned	    = FALSE;    m_bHasDataInAudioDevice = FALSE;    return HXR_OK;}void CHXAudioPlayer::ResetPlayer(void){    m_bInited		= FALSE;    m_bHasStreams	= FALSE;    m_bIsFirstResume	= TRUE;    m_ulAPstartTime	= 0;    m_ulAPplaybackTime	= 0;    m_ulADresumeTime	= 0;    m_ulCurrentTime	= 0;    m_ulLastCurrentTimeReturned	= 0;    m_ulLastDeviceTimeAdjusted = 0;    m_bTimeReturned	= FALSE;    m_bIsLive		= FALSE;    m_bIsResumed	= FALSE;    m_bIsDonePlayback	= TRUE;    m_llLastWriteTime	= 0;    m_bCanBeRewound	= FALSE;    m_bHasDataInAudioDevice = FALSE;    // Delete all streams.  Remove all list items.    if ( m_pStreamList )    {	CHXAudioStream* pAudioStream = 0;	while(!m_pStreamList->IsEmpty())	{	    pAudioStream = (CHXAudioStream*) m_pStreamList->RemoveHead();	    pAudioStream->ResetStream();	    pAudioStream->Release();	}    }    /* We do not remove post mix hooks any more */    /* We do not remove Stream Response Objects any more */    /* Default value of Player format */    m_PlayerFmt.uChannels	= 2;    m_PlayerFmt.uBitsPerSample	= 16;    m_PlayerFmt.ulSamplesPerSec	= 16000;    m_PlayerFmt.uMaxBlockSize	= 64000;    m_ulLastFakeCallbackTime = 0;    StopFakeTimeline();}/************************************************************************ *  Method: *		CHXAudioPlayer::SetupStreams *	Purpose: *		Tell each stream about the audio device format so *		they can setup their resamplers and buffer. */void CHXAudioPlayer::SetupStreams(void){    // Get audio device format    m_Owner->GetFormat(&m_DeviceFmt);    // Calculate bytes per gran    m_ulBytesPerGran = (ULONG32)                (((m_DeviceFmt.uChannels * ((m_DeviceFmt.uBitsPerSample==8)?1:2) *  m_DeviceFmt.ulSamplesPerSec)                                / 1000.0) * m_ulGranularity);    // Make sure that number of bytes per granularity is an even number.    if ( (m_ulBytesPerGran % 2) != 0 )        m_ulBytesPerGran++;    /* Don't we have to calculate granularity again if we adjust     * for even byte boundary - XXX Rahul 06/15/97     */    // Notify each stream    CHXAudioStream* s = 0;    CHXSimpleList::Iterator lIter = m_pStreamList->Begin();    for (; lIter != m_pStreamList->End(); ++lIter)    {	s = (CHXAudioStream*) (*lIter);	if ( s )	{	    s->Setup( &m_DeviceFmt, m_ulGranularity );	}    }}/************************************************************************ *  Method: *		CHXAudioPlayer::OnTimeSync *	Purpose: */HX_RESULT	CHXAudioPlayer::OnTimeSync(ULONG32 ulCurrentTime){    HX_RESULT theErr = HXR_OK;#ifdef _MACINTOSH    if (InterlockedIncrement(&gTIMELINE_MUTEX) > 1)    {       InterlockedDecrement(&gTIMELINE_MUTEX);       return;    }    InterlockedDecrement(&gTIMELINE_MUTEX);#endif    if (m_bHasStreams)    {	ULONG32 ulADplaybackTime;	ulADplaybackTime = m_Owner->GetCurrentPlayBackTime();	m_ulAPplaybackTime = (ulADplaybackTime - m_ulADresumeTime) +			      m_ulAPstartTime;    }    else    {	m_ulAPplaybackTime  = ulCurrentTime;    }    m_ulCurrentTime = m_ulAPplaybackTime ;    AdjustForRealAudio();    // Here we need to fudge the actual time for this player    // For now we support only one player/timeline    if (m_pPlayerResponse)    {	// The current playback time of any player is the difference	// of the current audio device playback time minus the audio	// device time when this player started (resumed) playback	// plus the initial start time of playback within this player's	// timeline (usually 0 but can be something else esp. after a	// seek).	theErr = m_pPlayerResponse->OnTimeSync(m_ulCurrentTime);    }    return theErr;}/************************************************************************ *  Method: *		CHXAudioPlayer::Setup *	Purpose: *		This is called after AS receives format and stream info *		from the renderers AND before packets are received from *		the renderer. */HX_RESULT CHXAudioPlayer::Setup( ULONG32 ulGranularity){    HX_RESULT theErr = HXR_OK;    if (m_bInited)	return HXR_OK;    /* Always write 100ms audio blocks for now. */    m_ulGranularity = MAXIMUM_AUDIO_GRANULARITY;	//ulGranularity;    /* We do not go below MINIMUM_AUDIO_GRANULARITY. This will not affect     * sending timesyncs at this lower granularity since HXPlayer object     * uses the scheduler to send individual timesyncs anyway     */    if (m_ulGranularity < MINIMUM_AUDIO_GRANULARITY)    {	m_ulGranularity = MINIMUM_AUDIO_GRANULARITY;    }    else if (m_ulGranularity > MAXIMUM_AUDIO_GRANULARITY)    {	m_ulGranularity = MAXIMUM_AUDIO_GRANULARITY;    }    if (!m_bHasStreams)    {	m_bInited = TRUE;	return HXR_OK;    }    /* If this is the second player, session object may overide     * the granularity value.     */    m_ulGranularity = m_Owner->SetGranularity(m_ulGranularity);    // Determine this player's audio format parameters based on    // the mixer channels attributes supplied in RegisterRenderer.    //    // 1. Spin thru the list of registered streams and    //    determine the desired audio device parameters.    // 2. Check the audio format with the audio device.    //    CHXAudioStream* pAudioStream = 0;    ULONG32 maxSamplesPerSec = 8000;    ULONG32 minSamplesPerSec = 44100;    BOOL    bFirst = TRUE;    UINT16  maxChannels = 1;    UINT16  maxBlocksize = 0;    UINT16  maxBitsPerSample = 0;    HXAudioFormat audioFmt;    theErr = GetAudioPrefs();    if (!theErr && m_pStreamList->GetCount() > 0)    {	CHXSimpleList::Iterator lIter = m_pStreamList->Begin();	for (;lIter != m_pStreamList->End(); ++lIter)	{	    pAudioStream = (CHXAudioStream*) (*lIter); //m_pStreamList->GetNext(lp);	    if (!pAudioStream->IsAudioFormatKnown())	    {		continue;	    }	    pAudioStream->GetFormat( &audioFmt );	    if (bFirst)	    {		bFirst = FALSE;		maxSamplesPerSec    = audioFmt.ulSamplesPerSec;		minSamplesPerSec    = audioFmt.ulSamplesPerSec;		maxChannels	    = audioFmt.uChannels;		maxBlocksize	    = audioFmt.uMaxBlockSize;		maxBitsPerSample    = audioFmt.uBitsPerSample;	    }	    else	    {		//		// NOTE: upsampling typically costs more CPU than downsampling		if ( audioFmt.ulSamplesPerSec > maxSamplesPerSec )		    maxSamplesPerSec = audioFmt.ulSamplesPerSec;		if ( audioFmt.ulSamplesPerSec < minSamplesPerSec)		    minSamplesPerSec = audioFmt.ulSamplesPerSec;		//		// NOTE: converting mono to stereo and vice versa cost about the		// same in CPU usage.		if ( audioFmt.uChannels > maxChannels)		    maxChannels = audioFmt.uChannels;		// Get max block size.		if ( audioFmt.uMaxBlockSize > maxBlocksize )		    maxBlocksize = audioFmt.uMaxBlockSize;		// Get max sample width.		if ( audioFmt.uBitsPerSample > maxBitsPerSample )		    maxBitsPerSample = audioFmt.uBitsPerSample;	    }	}	// Set the audio format for this Player.	m_PlayerFmt.uMaxBlockSize 	= maxBlocksize;	m_PlayerFmt.uChannels		= maxChannels;	m_PlayerFmt.uBitsPerSample 	= maxBitsPerSample;	// If user wants upsampling	if ( m_uPrefAudioQuality > 2 )	    m_PlayerFmt.ulSamplesPerSec = maxSamplesPerSec;	else	    m_PlayerFmt.ulSamplesPerSec = minSamplesPerSec;    }    if (m_bPrefUse11khz)    {	m_PlayerFmt.ulSamplesPerSec = 11025;    }    // Do audio session setup. (e.g., determine device audio    // format, etc.    if ( !theErr )	theErr = m_Owner->Setup( m_bHasStreams );    // Now let all streams know the final audio format so they    // can resample to this format.    if ( !theErr )    {	SetupStreams();    }    // if audio device is failed to initialized, we    // will keep the video playing if this is not audio only source    else if (!IsAudioOnlyTrue())    {	m_bHasStreams = FALSE;	m_bInited = TRUE;	return HXR_OK;    }    // Let all stream response know total number of streams.    if (!theErr && m_pStreamRespList)    {	IHXAudioStreamInfoResponse* pAudioStreamInfoResponse = 0;	CHXSimpleList::Iterator lIter = m_pStreamRespList->Begin();	for (; lIter != m_pStreamRespList->End(); ++lIter) 	{	    pAudioStreamInfoResponse = (IHXAudioStreamInfoResponse*) (*lIter);	    CHXSimpleList::Iterator lIter2 = m_pStreamList->Begin();	    for (; lIter2 != m_pStreamList->End(); ++lIter2) 	    {		CHXAudioStream* pStream = (CHXAudioStream*) (*lIter2);		/* Only if a stream is initialized, send it to		 * Response object. If not, we will send it when it		 * gets initialized (in StreamInitialized() call)		 */		if (pStream->IsInitialized())		{		    pAudioStreamInfoResponse->OnStream(pStream);		}	    }	}    }    // All renderers should have checked in by now!    // Call post mix process hooks in list and provide the audio format.    if (!theErr && m_pPMixHookList)    {	HXAudioFormat audioFmt;	m_Owner->GetFormat( &audioFmt );	HXAudioHookInfo* pPMixHookInfo = 0;	CHXSimpleList::Iterator lIter = m_pPMixHookList->Begin();	for (; lIter != m_pPMixHookList->End(); ++lIter)	{	    pPMixHookInfo = (HXAudioHookInfo*) (*lIter);	    if (pPMixHookInfo->bIgnoreAudioData ||		HXR_OK == ProcessAudioHook(ACTION_CHECK, pPMixHookInfo->pHook))	    {		pPMixHookInfo->pHook->OnInit( &audioFmt );	    }	}    }    if (!theErr)    {    	m_bInited = TRUE;	/* Only change the state to initialized if we were in a stopped	 * state earlier. It is possible to be in Playing state and be still	 * in this function. This will happen if we have started the	 * timeline as a fake timeline and later an audio stream joins the	 * presentation thereby converting fake to audio timeline	 * (delayed audio source in SMIL playback)	 */	if (m_eState == E_STOPPED)	{	    m_eState = E_INITIALIZED;	}    }    return theErr;}ULONG32	CHXAudioPlayer::GetCurrentPlayBackTime(void){    if (m_eState != E_PLAYING)    {	return m_ulCurrentTime;    }    // The current playback time of any player is the difference    // of the current audio device playback time minus the audio    // device time when this player started (resumed) playback    // plus the initial start time of playback within this player's    // timeline (usually 0 but can be something else esp. after a    // seek).    if (!m_bHasStreams)    {	ULONG32 ulCurrentTime	= HX_GET_TICKCOUNT();	m_ulIncreasingTimer	    += CALCULATE_ELAPSED_TICKS(m_ulLastFakeCallbackTime, ulCurrentTime);	m_ulLastFakeCallbackTime    = ulCurrentTime;	m_ulCurrentTime		    = m_ulIncreasingTimer;    }    else    {	m_ulCurrentTime	= (m_Owner->GetCurrentPlayBackTime() -		    m_ulADresumeTime) + m_ulAPstartTime;    }    m_ulAPplaybackTime = m_ulCurrentTime;    AdjustForRealAudio();    return m_ulCurrentTime;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -