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

📄 hxaudses.cpp

📁 symbian 下的helix player源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            while (!theErr && m_pAuxiliaryAudioBuffers->GetCount() > 0)
            {
                HXAudioData* pAudioData =
                    (HXAudioData*) m_pAuxiliaryAudioBuffers->GetHead();

                // Write session audio data to device.
                theErr = m_pAudioDev->Write(pAudioData);
                if( theErr == HXR_OUTOFMEMORY )
                {
                    goto exit;
                }

                if (!theErr)
                {
                    m_ulBlocksWritten++;
                    m_dNumBytesWritten  += pAudioData->pData->GetSize();

                    m_pAuxiliaryAudioBuffers->RemoveHead();
                    pAudioData->pData->Release();
                    delete pAudioData;
                }
                /*All other error codes are translated into audio driver error*/
                else if (theErr != HXR_OUTOFMEMORY && theErr != HXR_WOULD_BLOCK)
                {
                    theErr = HXR_AUDIO_DRIVER;
                }
            }
        }
    }

    // If we have audio streams then play audio.
    if (!theErr && m_bHasStreams)
    {
        // Push down at least 3 secs of audio.
        UINT16 uPush = uNumBlocks;
        if (m_bFirstPlayAudio)
        {
            uPush = (UINT16) m_ulMinBlocksTobeQueued;
        }

        HXAudioData audioData;
        CHXAudioPlayer* pPlayer = 0;
        CHXAudioStream* pStream = 0;
        CHXSimpleList*  pStreamList = 0;
#if defined(HELIX_FEATURE_VOLUME) || defined(HELIX_FEATURE_MIXER)
        UINT16  uPlayerVolume = HX_INIT_VOLUME;
#endif
        UCHAR*  pMixBuffer = 0;
        UCHAR*  pPlayerBuf = NULL;
        UCHAR*  pSessionBuf = NULL;
        IHXBuffer* pMixIHXBuffer = NULL;
        BufType bufType = BUFFER_NONE;

        for (UINT16 i = 0; !theErr && i < uPush; i++ )
        {
            m_uNumToBePushed = uPush - i;
            m_bSessionBufferDirty = FALSE; // only used for multi-player case

            UINT32  ulNumBytesWritten = m_ulBytesPerGran;
            BOOL    bAtLeastOnePlayerActive = FALSE;

            theErr = m_pSessionBuf->SetSize(m_ulBytesPerGran);
            if( theErr == HXR_OUTOFMEMORY )
            {
                theErr = HXR_OUTOFMEMORY;
                goto exit;
            }

            pSessionBuf = m_pSessionBuf->GetBuffer();

            // Zero session buffer.
            //memset(pSessionBuf, 0, HX_SAFESIZE_T(m_ulBytesPerGran));

            // Get each player
            pPlayer = 0;
            CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
            for (; lIter != m_pPlayerList->End(); ++lIter)
            {
                BOOL bStalled = FALSE;
                pPlayer = (CHXAudioPlayer*) (*lIter);
                if (pPlayer->GetStreamCount() == 0 ||
                    pPlayer->IsDonePlayback() ||
                    pPlayer->GetState() != E_PLAYING)
                {
                    continue;
                }

                bAtLeastOnePlayerActive = TRUE;

                if (m_pPlayerList->GetCount() == 1)
                {
                    pMixIHXBuffer = m_pSessionBuf;
                    bufType = BUFFER_SESSION;
                }
                else
                {
                    if (!m_pPlayerBuf)
                    {
                        m_pPlayerBuf = new CHXBuffer;
                        m_pPlayerBuf->AddRef();
                    }

                    m_pPlayerBuf->SetSize(m_ulBytesPerGran);

                    pPlayerBuf = m_pPlayerBuf->GetBuffer();
                    // Zero play buffer.
//                  memset(pPlayerBuf, 0, HX_SAFESIZE_T(m_ulBytesPerGran));
                    pMixIHXBuffer = m_pPlayerBuf;
                    bufType = BUFFER_PLAYER;
                }

                pMixBuffer = pMixIHXBuffer->GetBuffer();
                BOOL bIsMixBufferDirty = FALSE;
                BOOL bMayNeedToRollbackTimestamp = FALSE;

                if (pPlayer->GetState() == E_PLAYING)
                {
                    UINT32  ulBufTime = 0;
                    // Get each stream associated with this player
                    pStreamList = pPlayer->GetStreamList();
                    if (pStreamList)
                    {
                    CHXSimpleList::Iterator lIter = pStreamList->Begin();
                    for (; lIter != pStreamList->End(); ++lIter)
                    {
                        pStream = (CHXAudioStream*) (*lIter);
                        pStream->m_bMayNeedToRollbackTimestamp = FALSE;

                        // don't mix paused audio streams
                        if (pStream->GetState() != E_PAUSED)
                        {
                            theErr = pStream->MixIntoBuffer( pMixBuffer, m_ulBytesPerGran, ulBufTime, bIsMixBufferDirty);

                            // so as not to trigger ReallyNeedData
                            // since one of the streams internal m_llLastwritetime
                            // has been updated even though this flag is set to FALSE.
#if 0
                            if (!bIsMixBufferDirty &&
                                (theErr == HXR_OK || theErr == HXR_NO_DATA))
                            {
                                bIsMixBufferDirty = TRUE;
                                ::memset(pMixBuffer, 0, HX_SAFESIZE_T(m_ulBytesPerGran));
                            }
#endif

                            if (theErr == HXR_NO_DATA)
                            {
                                pStream->m_bMayNeedToRollbackTimestamp = TRUE;
                                bMayNeedToRollbackTimestamp = TRUE;
                                theErr = HXR_OK;
                                continue;
                            }

                            if (theErr == HXR_FAIL)
                            {
                                theErr = HXR_OK;
                                goto exit;
                            }

                            if (theErr == HXR_OUTOFMEMORY)
                            {
                                goto exit;
                            }

                            if (theErr == HXR_WOULD_BLOCK)
                            {
#ifdef _RAHULDEBUG
                                {
                                    char str[255]; /* Flawfinder: ignore */
                                    ::sprintf(str, "Num to be pushed remaining: %lu\n", m_uNumToBePushed); /* Flawfinder: ignore */
                                    OutputDebugString(str);
                                }
#endif

                                if (bMayNeedToRollbackTimestamp)
                                {
                                    bMayNeedToRollbackTimestamp = FALSE;
                                    lIter = pStreamList->Begin();
                                    for (; lIter != pStreamList->End(); ++lIter)
                                    {
                                        pStream = (CHXAudioStream*) (*lIter);
                                        if (pStream->m_bMayNeedToRollbackTimestamp)
                                        {
                                            pStream->m_bMayNeedToRollbackTimestamp = FALSE;
                                            pStream->RollBackTimestamp();
                                        }
                                    }
                                }

                                goto handlewouldblock;
                            }
                        }

                        if (pPlayer->GetState() != E_PLAYING)
                        {
                            /* We should keep the last buffer around and the last stream
                             * to be mixed again...TBD XXX Rahul
                             */
                            //pPlayer->SetLastMixedBuffer(pMixBuffer, pStream);
                            bStalled = TRUE;
                            break;
                        }
                    }
                    } //if (pStreamList)

                    /* This pause may have happended due to ondrynotification */
                    if (m_bPaused || m_bStoppedDuringPause)
                    {
                        /* This would happen ONLY IF THERE IS ONE AUDIO PLAYER
                         * and that has been paused. So simply break
                         */
                        goto exit;
                        //break;
                    }

                    /* hmmm... looks like there are more than one audio player.
                     * continue with the next one
                     */
                    if (bStalled)
                    {
                        continue;
                    }

                    /* If the mixer buffer was not used, make sure it is initialized
                     * to silence since we pass it to post process hooks
                     */
                    if (!bIsMixBufferDirty)
                    {
//{FILE* f1 = ::fopen("e:\\audioses.txt", "a+"); ::fprintf(f1, "%lu\t%p\tsilence in mix buffer\n", HX_GET_BETTERTICKCOUNT(), this);::fclose(f1);}
                        ::memset(pMixBuffer, 0, HX_SAFESIZE_T(m_ulBytesPerGran));
                    }

#if defined(HELIX_FEATURE_VOLUME) && defined(HELIX_FEATURE_MIXER)
                    // Apply Player volume to buffer; do this before we call
                    // the post mix hooks.
                    uPlayerVolume = pPlayer->GetVolume();

                    if (uPlayerVolume != 100 && bIsMixBufferDirty)
                    {
                        CHXMixer::ApplyVolume(pMixBuffer, m_ulBytesPerGran, uPlayerVolume, m_DeviceFmt.uBitsPerSample);
                    }
#endif /* HELIX_FEATURE_VOLUME && HELIX_FEATURE_MIXER */

                    // Give data to this AudioPlayer's post mix hooks
                    // (do they want 8 or 16 bit?)
                    BOOL bChanged = FALSE;
                    ProcessPostMixHooks(pPlayer, pMixIHXBuffer, &bDisableWrite, ulBufTime, bChanged);

                    /*
                     * If the mixer buffer changed (because of a post mix hook)
                     * make sure to point the player/session buffer to this
                     * modified buffer
                     */
                    if (bChanged)
                    {
                        pMixBuffer = pMixIHXBuffer->GetBuffer();

                        if (bufType == BUFFER_PLAYER)
                        {
                            m_pPlayerBuf = pMixIHXBuffer;
                            pPlayerBuf = pMixIHXBuffer->GetBuffer();
                        }
                        else
                        {
                            m_pSessionBuf = pMixIHXBuffer;
                            pSessionBuf = pMixIHXBuffer->GetBuffer();
                        }
                    }
                }

#if defined(HELIX_FEATURE_MIXER)
                // Don't mix if volume is 0.
                // Don't mix if this player has disabled device write.
                // Don't mix if there is only one player since we would have
                // written data into session buf instead of player buffer
                if (m_pPlayerList->GetCount() > 1 && uPlayerVolume > 0 && !bDisableWrite)
                {
                    /* We always set a volume of 100 since we have already applied volume
                     * to player buffer
                     */
                    CHXMixer::MixBuffer( pPlayerBuf, pSessionBuf,
                                m_ulBytesPerGran, FALSE, 100, m_DeviceFmt.uBitsPerSample, m_bSessionBufferDirty);
                }
#endif /* HELIX_FEATURE_MIXER */

                pPlayer->UpdateLastWriteTime(m_ulGranularity);
            }

            if (!bAtLeastOnePlayerActive)
            {
                goto exit;
            }

            /* did we ever write to the session buffer ? */
            if (m_pPlayerList->GetCount() > 1 && !m_bSessionBufferDirty)
            {
//{FILE* f1 = ::fopen("e:\\audioses.txt", "a+"); ::fprintf(f1, "%lu\t%p\tsilence in session buffer\n", HX_GET_BETTERTICKCOUNT(), this);::fclose(f1);}
                ::memset(pSessionBuf, 0, HX_SAFESIZE_T(m_ulBytesPerGran));
            }

            // This increments with each buffered played.
            m_dBufEndTime   += m_dGranularity;

            // Set the session buffer to the IRMA buffer.
            audioData.pData       = m_pSessionBuf;
            audioData.ulAudioTime = (ULONG32)m_dBufEndTime;

            if (m_pAudioDev && !m_bDisableWrite)
            {
                /* are we dealing with a f*%$'ed up sound card */
                if ((m_BeforeHookDeviceFmt.uChannels == 1 && m_DeviceFmt.uChannels == 2)||
                    m_BeforeHookDeviceFmt.uBitsPerSample == 8)
                {
                    ConvertTo8BitAndOrMono(&audioData);
                }

                if (m_pFinalHook && m_bUseFinalHook)
                {
                    if (HXR_OK == ProcessAudioHook(ACTION_CHECK, m_pFinalHook))
                    {
                        m_pOutDataPtr->pData        = NULL;
                        m_pOutDataPtr->ulAudioTime          = audioData.ulAudioTime;
                        m_pOutDataPtr->uAudioStreamType = audioData.uAudioStreamType;

                        m_pFinalHook->OnBuffer(&audioData, m_pOutDataPtr);

                        HX_ASSERT(m_pOutDataPtr->pData);
                        if (m_pOutDataPtr->pData)
                        {
                            HX_RELEASE(audioData.pData);
                            m_pSessionBuf = audioData.pData = m_pOutDataPtr->pData;
                        }
                        else
                        {
                            /* This is a screwed up Hook. Disable it */
                            m_bUseFinalHook = FALSE;
                        }
                    }
                }

                if (m_pHookList)
                {
                    ProcessHooks(&audioData);
                }

                ulNumBytesWritten    = audioData.pData->GetSize();
                if (HXR_OK == ProcessAudioDevice(ACTION_CHECK, m_pAudioDev))
                {
                    // Write session audio data to device.
                    theErr = m_pAudioDev->Write(&audioData);
                    if( theErr == HXR_OUTOFMEMORY )
                    {
                        goto exit;
                    }
                }

                if (theErr == HXR_WOULD_BLOCK)
                {
                    HXAudioData* pAudioData     = new HXAudioData;
                    pAudioData->pData           = audioData.pData;
                    pAudioData->pData->AddRef();
                    pAudioData->ulAudioTime     = audioData.ulAudioTime;
                    pAudioData->uAudioStreamType= audioData.uAudioStreamType;

                    // Create auxiliary buffer list, if one is not already created
                    if (!m_pAuxiliaryAudioBuffers)
                    {
                        m_pAuxiliaryAudioBuffers = new CHXSimpleList;
                    }
                    if( NULL == m_pAuxiliaryAudioBuffers->AddTail(pAudioData) )
                    {
                        theErr = HXR_OUTOFMEMORY;
                        goto exit;
                    }

                    HX_RELEASE(m_pSessionBuf);
                }
                /* Any error from audio device other than memory error is
                 * returned as HXR_AUDIO_DRIVER
                 */
                if (theErr != HXR_OK && theErr != HXR_WOULD_BLOCK &&
                    theErr != HXR_OUTOFMEMORY)
                {
                    theErr = HXR_AUDIO_DRIVER;
                }
            }

            if (!theErr)
            {
                m_ulBlocksWritten++;
                m_dNumBytesWritten  += ulNumBytesWritten;
            }

            // So this function is good in theory, but in practice we find in
            // heap-optimized mode it is not necessary, and it leads to
            // unnecessary heap fragmentation.
#if !defined(HELIX_CONFIG_MIN_HEAP_FRAG)
            theErr = CheckForBufferReuse();
#endif
        }  // for loop
    }     //  end if we have audio streams

handlewouldblock:

⌨️ 快捷键说明

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