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

📄 hxaudstr_new.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}/************************************************************************ *  Method: *              CHXAudioStream::Bytes2Samples *      Purpose: *		Translate from units of bytes to samples. */UINT32 CHXAudioStream::Bytes2Samples (    UINT64	ulNumBytes,    const HXAudioFormat *fmt ){    ASSERT(ulNumBytes % (fmt->uBitsPerSample >> 3) == 0) ;    return INT64_TO_UINT32(ulNumBytes / (fmt->uBitsPerSample >> 3)) ;}/************************************************************************ *  Method: *              CHXAudioStream::Samples2Ms *      Purpose: *		Calculate the duration in millisecs for this number of samples. */UINT64 CHXAudioStream::Samples2Ms(    INT64 nSamples,    const HXAudioFormat *fmt){    UINT32 ulDenom = fmt->uChannels * fmt->ulSamplesPerSec;    UINT64 q = nSamples / ulDenom;    UINT64 r = nSamples - q * ulDenom;    return q * 1000 + (r * 1000) / ulDenom;}/************************************************************************ *  Method: *              CHXAudioStream::CalcMs *      Purpose: *		Calculate the duration in millisecs for this number of *              bytes in input format. */ULONG32 CHXAudioStream::CalcMs(    ULONG32	ulNumBytes){    return INT64_TO_ULONG32(Samples2Ms(Bytes2Samples(ulNumBytes, &m_AudioFmt), &m_AudioFmt));}/************************************************************************ *  Method: *              CHXAudioStream::CalcDeviceMs *      Purpose: *		Calculate the duration in millisecs for this number of  *		bytes in Device format. */ULONG32 CHXAudioStream::CalcDeviceMs(    ULONG32	ulNumBytes){    return INT64_TO_ULONG32(Samples2Ms(Bytes2Samples(ulNumBytes, &m_DeviceFmt), &m_DeviceFmt));}/************************************************************************ *  Method: *              CHXAudioStream::CalcOffset *      Purpose: *		Calculate the offset in bytes given time. */UINT32 CHXAudioStream::CalcOffset(    INT64 llStartTime,   INT64 llEndTime){    /* Using m_ulBytesPerMs may introduce cumulative error due      * to decimal cutoff      */    HX_ASSERT(llEndTime - llStartTime < MAX_TIMESTAMP_GAP);    return m_ulGranularity ?        INT64_TO_UINT32((llEndTime - llStartTime) * m_ulInputBytesPerGran / m_ulGranularity) :        0 ;}void CHXAudioStream::FlushBuffers(BOOL bInstantaneousAlso){    while (m_pDataList && m_pDataList->GetCount() > 0)    {	HXAudioInfo* pInfo = (HXAudioInfo*) m_pDataList->RemoveHead();	FreeInfo(pInfo);    }    while (bInstantaneousAlso && m_pInstantaneousList && m_pInstantaneousList->GetCount() > 0)    {	CHXSimpleList* pList = (CHXSimpleList*) m_pInstantaneousList->RemoveHead();	while (pList->GetCount() > 0)	{	    HXAudioInfo* pInfo = (HXAudioInfo*) pList->RemoveHead();	    FreeInfo(pInfo, TRUE);	}	HX_DELETE(pList);    }    // reset m_bLastNMilliSecsToBeSaved so that we actually     // delete buffers in FreeInfo    BOOL bLastNMilliSecsToBeSaved = m_bLastNMilliSecsToBeSaved;    m_bLastNMilliSecsToBeSaved = FALSE;    while (m_pLastNMilliSecsList && m_pLastNMilliSecsList->GetCount() > 0)    {	HXAudioInfo* pInfo = (HXAudioInfo*) m_pLastNMilliSecsList->RemoveHead();	FreeInfo(pInfo);    }    m_bLastNMilliSecsToBeSaved = bLastNMilliSecsToBeSaved;    HX_DELETE(m_pLastNMilliSecsList);}/*    this routine checks if there are enough packets waiting in the queue    to be mixed. It will return FALSE if not, or if there are packets missing    in the middle of the queue.*/BOOLCHXAudioStream::EnoughDataAvailable(INT64& llStartTimeInSamples, UINT32& nSamplesRequired){    INT64           llEndTimeInSamples   = llStartTimeInSamples + nSamplesRequired ;    HXAudioInfo*    pInfoOld        = 0 ;    HXAudioInfo*    pInfo           = 0;    LISTPOSITION    lp              = 0;    // if the list is completely empty, report the whole data range as missing    if (m_pDataList->IsEmpty())	return FALSE ;    nSamplesRequired = 0 ;    /* skip over old packets. Old packets are packets that have an end time that is before       our current mix time. */    lp = m_pDataList->GetHeadPosition();    while( lp )    {	pInfoOld = (HXAudioInfo*) m_pDataList->GetNext(lp);	if (pInfoOld->llEndTimeInSamples >= llStartTimeInSamples)            break ;    }#if 0 // disabled missing packet detection    // pInfoOld is the first packet to be mixed. To make sure it overlaps with the start    // of the mix buffer, do this (disabled for now):        if (pInfoOld->llStartTimeInSamples > llStartTimeInSamples)        return FALSE ;#endif        // now go through the rest of packets, and make sure they are contiguous until    // the end of our mix time    // If packets overlap, one packet will then take precedence over another -- not    // much we can do about that.    while( lp )    {	pInfo    = (HXAudioInfo*) m_pDataList->GetNext(lp);        // if we see a packet with a timestamp after the mix time ("future packet")        // or one that does not abut with the previous one ("discontinuity"), stop.        if (pInfo->llStartTimeInSamples >= llEndTimeInSamples)         // future packet//            pInfo->llStartTimeInSamples != pInfoOld->llEndTimeInSamples) // discontinuity        {            break ;        }        pInfoOld = pInfo ;    }    // pInfoOld is the last packet to be mixed (or the last before a discontinuity).    // Make sure it overlaps with the end of the mix buffer.    if (pInfoOld->llEndTimeInSamples < llEndTimeInSamples)    {        llStartTimeInSamples = pInfoOld->llEndTimeInSamples ;        nSamplesRequired = INT64_TO_UINT32(llEndTimeInSamples - llStartTimeInSamples) ;        return FALSE ;    }    return TRUE ; // Data available!}HX_RESULT    CHXAudioStream::StartCrossFade(CHXAudioStream*  pFromStream, 			       UINT32		ulCrossFadeStartTime,			       UINT32		ulCrossFadeDuration, 			       BOOL		bToStream){#if defined(HELIX_FEATURE_CROSSFADE)    // XXX wschildbach need to account for rollover.    INT64 llStartTimeInSamples = CAST_TO_INT64(ulCrossFadeStartTime) * m_DeviceFmt.ulSamplesPerSec / 1000 * m_DeviceFmt.uChannels ;    INT64 llEndTimeInSamples = (CAST_TO_INT64(ulCrossFadeStartTime)+ulCrossFadeDuration) * m_DeviceFmt.ulSamplesPerSec / 1000 * m_DeviceFmt.uChannels ;    m_pMixEngine->SetCrossFade(bToStream ? HXAudioSvcMixEngine::FADE_IN : HXAudioSvcMixEngine::FADE_OUT,        llStartTimeInSamples, llEndTimeInSamples) ;/*    {        FILE *f2 = fopen("c:\\temp\\mix.txt","a+");        fprintf(f2,"** StartCrossFade(%I64d, %I64d, len=%ld, to=%s\n",            llStartTimeInSamples,            llEndTimeInSamples,            (INT32)(-llStartTimeInSamples+llEndTimeInSamples),            bToStream?"yes":"no");        fclose(f2);    }*/    return HXR_OK;#else    return HXR_NOTIMPL;#endif /* HELIX_FEATURE_CROSSFADE */}/* *  IHXRealAudioSync methods *//************************************************************************ *  Method: *      IHXRealAudioSync::Register *  Purpose: */STDMETHODIMPCHXAudioStream::Register(void) {#if defined _DEBUG && defined HELIX_FEATURE_AUDIO_MULTIPLAYER_PAUSE     if (HXDebugOptionEnabled("zDoNotUseFudge"))    {        return HXR_OK;    }#endif    if (m_bRealAudioStream)    {	return HXR_UNEXPECTED;    }    m_bRealAudioStream = TRUE;    m_Owner->RegisterRealAudioStream(this);#if defined(HELIX_FEATURE_AUDIO_INACCURATESAMPLING)    if (!m_pRAByToTsInList)    {	m_pRAByToTsInList	= new CHXSimpleList;	m_pRAByToTsAdjustedList	= new CHXSimpleList;    }#endif /* HELIX_FEATURE_AUDIO_INACCURATESAMPLING */    return HXR_OK;}/************************************************************************ *  Method: *      IHXRealAudioSync::UnRegister *  Purpose: */STDMETHODIMPCHXAudioStream::UnRegister(void){#if defined _DEBUG && defined HELIX_FEATURE_AUDIO_MULTIPLAYER_PAUSE     if (HXDebugOptionEnabled("zDoNotUseFudge"))    {        return HXR_OK;    }#endif    if (!m_bRealAudioStream)    {	return HXR_UNEXPECTED;    }    m_bRealAudioStream = FALSE;    m_Owner->UnRegisterRealAudioStream(this);    CleanupRAByToTs();    return HXR_OK;}/************************************************************************ *  Method: *      IHXRealAudioSync::FudgeTimestamp *  Purpose: *	Tell the audio stream about the relationship between the number  *	of bytes written to the actual timestamp. *	     */STDMETHODIMPCHXAudioStream::FudgeTimestamp(UINT32 /*IN*/ ulNumberofBytes,			       UINT32 /*IN*/ ulTimestamp){#if defined(HELIX_FEATURE_AUDIO_INACCURATESAMPLING)#if defined _DEBUG && defined HELIX_FEATURE_AUDIO_MULTIPLAYER_PAUSE     if (HXDebugOptionEnabled("zDoNotUseFudge"))    {        return HXR_OK;    }#endif    RealAudioBytesToTimeStamp* pByToTs = 	new RealAudioBytesToTimeStamp;    pByToTs->m_ulTimestamp	= ulTimestamp;    pByToTs->m_ulInTimestamp	= m_ulLastInputStartTime;    pByToTs->m_ulInEndTime	= m_ulLastInputEndTime;    if (m_bIsLive && m_ulBaseTime > 0)    {	pByToTs->m_ulTimestamp	+= m_ulLiveDelay;	if (pByToTs->m_ulTimestamp > m_ulBaseTime)	{	    pByToTs->m_ulTimestamp -= m_ulBaseTime;	}	else	{	    pByToTs->m_ulTimestamp  = 0;	}    }    pByToTs->m_ulOrigTimestamp	= pByToTs->m_ulTimestamp;    m_pRAByToTsInList->AddTail((void*) pByToTs);#endif /* HELIX_FEATURE_AUDIO_INACCURATESAMPLING *///{FILE* f1 = ::fopen("d:\\temp\\audio.txt", "a+"); ::fprintf(f1, "Fudge:\t%lu\t%lu\n", ulTimestamp, m_ulLastInputStartTime);::fclose(f1);}    return HXR_OK;}voidCHXAudioStream::CleanupRAByToTs(void){#if defined(HELIX_FEATURE_AUDIO_INACCURATESAMPLING)    if (!m_pRAByToTsInList)    {	return;    }    CHXSimpleList::Iterator ndx = m_pRAByToTsInList->Begin();    for (; ndx != m_pRAByToTsInList->End(); ++ndx)    {	RealAudioBytesToTimeStamp* pByToTs = 	    (RealAudioBytesToTimeStamp*) (*ndx);	delete pByToTs;    }    m_pRAByToTsInList->RemoveAll();    ndx = m_pRAByToTsAdjustedList->Begin();    for (; ndx != m_pRAByToTsAdjustedList->End(); ++ndx)    {	RealAudioBytesToTimeStamp* pByToTs = 	    (RealAudioBytesToTimeStamp*) (*ndx);	delete pByToTs;    }    m_pRAByToTsAdjustedList->RemoveAll();#endif /* HELIX_FEATURE_AUDIO_INACCURATESAMPLING */} HX_RESULTCHXAudioStream::ConvertCurrentTime(double dBytesPlayed, 				   UINT32 ulCurrentTime, 				   UINT32& ulAdjustedTime){#if defined(HELIX_FEATURE_AUDIO_INACCURATESAMPLING)    HX_ASSERT(m_bRealAudioStream);    ulAdjustedTime  = ulCurrentTime;    LISTPOSITION posRABytes = m_pRAByToTsAdjustedList->GetHeadPosition();    RealAudioBytesToTimeStamp* pByToTsLower = NULL;    RealAudioBytesToTimeStamp* pByToTsHigher = NULL;    INT64   llActualByToTsHigherTimestamp = 0;    INT64   llActualByToTsLowerTimestamp =0;    while(posRABytes)    {	RealAudioBytesToTimeStamp* pByToTs = (RealAudioBytesToTimeStamp*) 			    m_pRAByToTsAdjustedList->GetAt(posRABytes);	if (dBytesPlayed >= pByToTs->m_ulOutNumBytes)	{	    pByToTsLower = pByToTs;	}	else	{	    if (pByToTsLower)	    {		pByToTsHigher = pByToTs; 	    }	    else	    {		/* It means that this stream was added mid-presentation and we have not yet 		 * played any bits from this stream. Maintain the current time and do not		 * fudge it.		 */ 		return HXR_OK;	    }	}	if (pByToTsLower && pByToTsHigher)	{	    break;	}	m_pRAByToTsAdjustedList->GetNext(posRABytes);    }    /* We got a range, interpolate */    if (pByToTsLower && pByToTsHigher)    {//{FILE* f1 = ::fopen("d:\\temp\\rasync.txt", "a+"); ::fprintf(f1, "ConvertLowHigh: dBytesPlayed: %f LowTS: %lu HighTS: %lu LowBytes: %f HighBytes: %f\n", dBytesPlayed,pByToTsLower->m_ulTimestamp,pByToTsHigher->m_ulTimestamp, pByToTsLower->m_ulOutNumBytes,pByToTsHigher->m_ulOutNumBytes);::fclose(f1);}	/* Need to re-visit this ASSERT. A check will do for now */#if 0	HX_ASSERT((pByToTsHigher->m_ulTimestamp >= 		   pByToTsLower->m_ulTimestamp) &&		  (pByToTsHigher->m_ulOutNumBytes >= 		   pByToTsLower->m_ulOutNumBytes));#endif	llActualByToTsHigherTimestamp = CAST_TO_INT64 (pByToTsHigher->m_ulTimestamp) + CAST_TO_INT64 m_ulTSRollOver * CAST_TO_INT64 MAX_UINT32;	llActualByToTsLowerTimestamp = CAST_TO_INT64 (pByToTsLower->m_u

⌨️ 快捷键说明

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