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

📄 hxaudstr.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
HX_RESULT CHXAudioStream::Setup(        HXAudioFormat*  pFormat,       ULONG32         ulGranularity){    HX_RESULT theErr = HXR_OK;    m_DeviceFmt.uChannels       = pFormat->uChannels;    m_DeviceFmt.uBitsPerSample  = pFormat->uBitsPerSample;    m_DeviceFmt.ulSamplesPerSec = pFormat->ulSamplesPerSec;    m_DeviceFmt.uMaxBlockSize   = pFormat->uMaxBlockSize;    m_ulGranularity = ulGranularity;    m_bSetupDone = TRUE;        /* we have all the info now.. so setup the resampler */    if (m_bAudioFormatKnown && !m_bInited)    {        theErr = ProcessInfo();    }    return theErr;}/************************************************************************ *  Method: *              IHXAudioStream::ResetStream *      Purpose: */void CHXAudioStream::ResetStream(){    m_bInited           = FALSE;    m_bCanBeRewound     = FALSE;    m_bSetupDone        = FALSE;    m_bAudioFormatKnown = FALSE;    m_bIsResumed        = FALSE;        UnRegister();    while (m_pAvailableBuffers && m_pAvailableBuffers->GetCount() > 0)    {        IHXBuffer* pBuffer = (IHXBuffer*) m_pAvailableBuffers->RemoveHead();        HX_RELEASE(pBuffer);    }    HX_DELETE(m_pAvailableBuffers);    // Delete all entries in the audio data list    FlushBuffers();    HX_DELETE(m_pDataList);    HX_DELETE(m_pInstantaneousList);    CleanupRAByToTs();    HX_DELETE(m_pRAByToTsInList);    HX_DELETE(m_pRAByToTsAdjustedList);        // Delete resample buffer    HX_VECTOR_DELETE(m_pResampleBuf);    // Delete tmp resample buffer    HX_VECTOR_DELETE(m_pTmpResBuf);    HX_VECTOR_DELETE(m_pCrossFadeBuffer);    HX_VECTOR_DELETE(m_pExcessInterpBuffer);    HX_VECTOR_DELETE(m_pTempInterpBuffer);    m_ulExcessInterpBufferSize = m_ulPreviousExcessInterpBufferSize = 0;    #if defined(HELIX_FEATURE_CROSSFADE)    HX_DELETE(m_pCrossFader);#endif /* HELIX_FEATURE_CROSSFADE */    // Free the resampler    HX_RELEASE(m_pResampler);    m_bGotHooks = FALSE;    m_llLastWriteTime = 0;    m_ulTSRollOver = 0;#ifdef _TESTING    if ( g_log > 0 )        close(g_log);    g_log = -1;#endif    HX_RELEASE(m_pValues);#if defined(HELIX_FEATURE_AUDIO_PREMIXHOOK)    // Delete all entries in the pre-mix hook list.    if ( m_PreMixHookMap.GetCount() > 0)    {        HXAudioHookInfo* h = 0;        CHXMapPtrToPtr::Iterator lIter = m_PreMixHookMap.Begin();        for (; lIter != m_PreMixHookMap.End(); ++lIter)        {            h = (HXAudioHookInfo*) (*lIter);            ProcessAudioHook(ACTION_REMOVE, h->pHook);            h->pHook->Release();            delete h;        }                m_PreMixHookMap.RemoveAll();    }#endif /* HELIX_FEATURE_AUDIO_PREMIXHOOK */#if defined(HELIX_FEATURE_VOLUME)    // Delete IRMA volume object.    if (m_pStreamVolume && m_pVolumeAdviseSink)    {        m_pStreamVolume->RemoveAdviseSink(m_pVolumeAdviseSink);        m_pVolumeAdviseSink->m_pCHXAudioStream = 0;    }    HX_RELEASE(m_pVolumeAdviseSink);#endif /* HELIX_FEATURE_VOLUME */    HX_RELEASE(m_pStreamVolume);    HX_DELETE(m_pInDataPtr);    HX_DELETE(m_pOutDataPtr);    if (m_DryNotificationMap.GetCount() > 0)    {        IHXDryNotification* pDryNotification = 0;        CHXMapPtrToPtr::Iterator lIter = m_DryNotificationMap.Begin();        for (; lIter != m_DryNotificationMap.End(); ++lIter)        {            pDryNotification = (IHXDryNotification*) (*lIter);            pDryNotification->Release();        }                m_DryNotificationMap.RemoveAll();    }    HX_RELEASE(m_pCrossFadeStream);    HX_RELEASE(m_pCommonClassFactory);#if defined(HELIX_FEATURE_PREFERENCES)    HX_RELEASE(m_pPreferences);#endif /* HELIX_FEATURE_PREFERENCES */    HX_RELEASE(m_Owner);    return;}HX_RESULTCHXAudioStream::ProcessAudioHook(PROCESS_ACTION action,                                  IHXAudioHook* pAudioHook){    return HXR_OK;}// Dummy version of this method - real version would be in hxaudstr_new.cppBOOL CHXAudioStream::ConvertIntoBuffer(tAudioSample* buffer, UINT32 nSamples, INT64 llStartTimeInSamples){    return FALSE;}/************************************************************************ *  Method: *              IHXAudioStream::InitHooks *      Purpose: *      Init any pre-mix hooks. Return TRUE if hooks exist else return *      FALSE. */void CHXAudioStream::InitHooks(){#if defined(HELIX_FEATURE_AUDIO_PREMIXHOOK)    /* Iterate thru the hook list and call the hook's OnInit().     * If any of the hooks have disabled write set to TRUE, then     * we will let this override any set to FALSE.     */    if ( m_PreMixHookMap.GetCount() > 0 )    {        HXAudioHookInfo* h = 0;        CHXMapPtrToPtr::Iterator lIter = m_PreMixHookMap.Begin();        for (; lIter != m_PreMixHookMap.End(); ++lIter)        {            h = (HXAudioHookInfo*) (*lIter);            if (h->bIgnoreAudioData ||                HXR_OK == ProcessAudioHook(ACTION_CHECK, h->pHook))            {                h->pHook->OnInit( &m_AudioFmt );            }        }    }#endif /* HELIX_FEATURE_AUDIO_PREMIXHOOK */    m_bHooksInitialized = TRUE;}/************************************************************************ *  Method: *              IHXAudioStream::ProcessHooks *      Purpose: */HX_RESULT CHXAudioStream::ProcessHooks(     HXAudioData*        pInData,    HXAudioData*        pOutData){    HX_RESULT theErr = HXR_OK;#if defined(HELIX_FEATURE_AUDIO_PREMIXHOOK)    m_pInDataPtr->pData         = pInData->pData;    m_pInDataPtr->pData->AddRef();    m_pInDataPtr->ulAudioTime   = pInData->ulAudioTime;        m_pOutDataPtr->pData        = NULL;    m_pOutDataPtr->ulAudioTime  = pInData->ulAudioTime;    m_pInDataPtr->uAudioStreamType    = pInData->uAudioStreamType;    m_pOutDataPtr->uAudioStreamType   = pInData->uAudioStreamType;    if ( m_PreMixHookMap.GetCount() > 0 )    {        HXAudioHookInfo* pPreMixHookInfo = 0;        CHXMapPtrToPtr::Iterator lIter = m_PreMixHookMap.Begin();        for (; !theErr && lIter != m_PreMixHookMap.End(); ++lIter)        {            pPreMixHookInfo = (HXAudioHookInfo*) (*lIter);            if (HXR_OK == ProcessAudioHook(ACTION_CHECK, pPreMixHookInfo->pHook))            {                theErr = pPreMixHookInfo->pHook->OnBuffer( m_pInDataPtr, m_pOutDataPtr);                /* Check to see if renderer changed the buffer. If so, then                 * make this output as input to the next Hook.                 */                if (!theErr && m_pOutDataPtr->pData)                {                    m_pInDataPtr->pData->Release();                    m_pInDataPtr->pData     = m_pOutDataPtr->pData;                    m_pInDataPtr->ulAudioTime   = m_pOutDataPtr->ulAudioTime;                    m_pOutDataPtr->pData        = 0;                }            }            else if (pPreMixHookInfo->bIgnoreAudioData)            {                IHXBuffer* pTempBuf = m_pInDataPtr->pData;                m_pInDataPtr->pData = NULL;                theErr = pPreMixHookInfo->pHook->OnBuffer( m_pInDataPtr, m_pOutDataPtr);                m_pInDataPtr->pData = pTempBuf;            }        }    }    /* Final output is always in InDataPtr*/    pOutData->pData             = m_pInDataPtr->pData;    pOutData->ulAudioTime       = m_pInDataPtr->ulAudioTime;    pOutData->uAudioStreamType  = m_pInDataPtr->uAudioStreamType;#endif /* HELIX_FEATURE_AUDIO_PREMIXHOOK */    return theErr;}/************************************************************************ *  Method: *      CHXAudioStream::MixIntoBuffer *  Purpose: *      Mix stream data into this pPlayerBuf. *  Note: *       *      Resampler always works on 16 bit PCM. If the input is *      8 bit, it converts it first to 16 bit before making *      any resampling calculations.  *      We always try to open audio device in 16 bit stereo mode. *      This is because a new player/stream may be instantiated in the *      midst of a presentation and this new stream may be stereo. If we  *      earlier opened the device as mono, we will have to force this stereo *      stream to be played as mono! Not a good idea. Also any mono-streo *      conversion almost comes for free (some extra memory usage and  *      an extra assignment) since it can be done in the mixing loop in *      MixBuffer(). * *      Any 8-16 and stereo-mono conversion, if required, SHOULD be done *      before resampling. *      Any mono-stereo conversion should be done after resampling. * *      Stereo-Mono conversion code resides in the resampler.  *      Mono-Stereo conversion code resides in the mixer.  * */HX_RESULT CHXAudioStream::MixIntoBuffer(    UCHAR*   pPlayerBuf,    ULONG32  ulBufSize,    ULONG32& ulBufTime,    BOOL&    bIsMixBufferDirty,    BOOL     bGetCrossFadeData){    BOOL    bCrossFadeThisTime  = FALSE;    UINT32  ulTimeActuallyFaded = m_ulGranularity;    if (!m_bInited)    {        return HXR_NOT_INITIALIZED;    }//{FILE* f1 = ::fopen("c:\\temp\\rasync.txt", "a+"); ::fprintf(f1, "Call MixIntoBuffer: %lu\n", m_ulLastWriteTime);::fclose(f1);}    /* If this is a *FROM* stream, we may have already mixed     * data during cross-fade with *TO* stream     */    if (m_bFadeAlreadyDone && !m_bFadeToThisStream)    {        m_bFadeAlreadyDone = FALSE;        return HXR_OK;    }    HX_ASSERT(!bGetCrossFadeData || !m_bFadeToThisStream);    /* If we need to mix cross fade data from the *from* stream,     * it better be available      */    HX_ASSERT(!bGetCrossFadeData || m_pDataList->GetCount() > 0);    /* If this stream needs to be cross-faded and is a     * NOT a fade-to stream, it would have been already taken     * care of by the fade-to stream in an earlier call to      * MixIntoBuffer()     */    if (m_bCrossFadingToBeDone && m_pDataList->GetCount() > 0)    {        HXAudioInfo* pInfo = (HXAudioInfo*) m_pDataList->GetHead();        INT64 llActualStartTime  = 0;        if (pInfo)        {            llActualStartTime   = CAST_TO_INT64 (pInfo->ulStartTime) +                                   CAST_TO_INT64 (CalcMs(pInfo->pBuffer->GetSize() - pInfo->ulBytesLeft)) +                                  CAST_TO_INT64 m_ulTSRollOver * CAST_TO_INT64 MAX_UINT32;            if (m_bFadeToThisStream)            {                /* Cool! It is time for cross-fading */                if ((m_llLastWriteTime <= m_llCrossFadeStartTime                            &&                     m_llCrossFadeStartTime - m_llLastWriteTime <= CAST_TO_INT64 m_ulGranularity)  ||                    (m_llLastWriteTime > m_llCrossFadeStartTime                             &&                     m_llLastWriteTime - m_llCrossFadeStartTime <= CAST_TO_INT64 m_ulFudge))                {                    bCrossFadeThisTime = TRUE;                    if (m_llLastWriteTime <= m_llCrossFadeStartTime)                    {                        ulTimeActuallyFaded = m_ulGranularity -                                               INT64_TO_UINT32(m_llCrossFadeStartTime - m_llLastWriteTime);                    }//{FILE* f1 = ::fopen("c:\\raroot\\racross.txt", "a+"); ::fprintf(f1, "m_ulLastWriteTime: %lu ulStartTime: %lu m_ulCrossFadeStartTime: %lu pInfo->ulStartTime: %lu pInfo->pBuffer->GetSize(): %lu pInfo->ulBytesLeft: %lu\n", m_ulLastWriteTime, ulStartTime, m_ulCrossFadeStartTime, pInfo->ulStartTime, pInfo->pBuffer->GetSize(), pInfo->ulBytesLeft);::fclose(f1);}                    HX_ASSERT(                        (llActualStartTime >= m_llCrossFadeStartTime &&                        (llActualStartTime <= m_llCrossFadeStartTime +                                               m_ulCrossFadeDuration)) ||                        (llActualStartTime < m_llCrossFadeStartTime &&                         (m_llCrossFadeStartTime - llActualStartTime <= CAST_TO_INT64 m_ulFudge)));                }            }        }    }    UINT32  ulLastWriteTime = INT64_TO_UINT32(m_llLastWriteTime - CAST_TO_INT64 m_ulTSRollOver * CAST_TO_INT64 MAX_UINT32);    if (!bGetCrossFadeData && ulBufTime < ulLastWriteTime)    {        ulBufTime = ulLastWriteTime;    }    /* If there are any DryNotifications and the data list is empty     * we need to notify them so that they can write more data.     */    if (m_DryNotificationMap.GetCount() > 0 || m_Owner->GetAudioStreamCount() == 1)    {        UINT32 ulNumMsRequired = m_ulGranularity;        if (m_pDataList->IsEmpty() || !EnoughDataAvailable(ulLastWriteTime, ulNumMsRequired))        {            if (!bIsMixBufferDirty && !bGetCrossFadeData && !m_Owner->m_Owner->ReallyNeedData())            {                return HXR_WOULD_BLOCK;            }            if (m_DryNotificationMap.GetCount() > 0)            {                IHXDryNotification* pDryNotification = 0;                CHXMapPtrToPtr::Iterator lIter = m_DryNotificationMap.Begin();                for (; lIter != m_DryNotificationMap.End(); ++lIter)                {                    pDryNotification = (IHXDryNotification*) (*lIter);                    pDryNotification->OnDryNotification(ulLastWriteTime, ulNumMsRequired);                }                if (m_Owner->GetState() != E_PLAYING)                {                    return HXR_OK;                }            }        }    }    m_Owner->DataInAudioDevice(TRUE);    // /////////////////////////////////////////////////////////////    // There may be no buffers in the list. No packets? Play silence.    // Still need to increment time.    if ( m_pDataList->IsEmpty() && m_pInstantaneousList->IsEmpty() )    {        m_llLastWriteTime += CAST_TO_INT64 m_ulGranularity;//{FILE* f1 = ::fopen("e:\\MixIntoBuffer.txt", "a+"); ::fprintf(f1, "%lu\t%p\t%lu\n", HX_GET_BETTERTICKCOUNT(), this, (UINT32)m_llLastWriteTime);::fclose(f1);}        return HXR_NO_DATA;    }    UCHAR*      pSourceBuffer = 0;    ULONG32     ulMaxBytes = 0;    ULONG32     ulMaxFramesIn = 0;    ULONG32     ulMaxFramesOut = 0;    ULONG32     ulNumBytesMixed = 0;    BOOL        bMonoToStereoMayBeConverted = TRUE;    BOOL        bResampleBufferDirty        = FALSE;

⌨️ 快捷键说明

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