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

📄 hxaudses.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            {
            m_pSessionBuf->AddRef();
        }
            else
            {
                return HXR_OUTOFMEMORY;
            }
        }
    }
    else
    {
        /* create this buffer */
        m_pSessionBuf = (IHXBuffer*) new CHXBuffer;
        if( m_pSessionBuf )
        {
        m_pSessionBuf->AddRef();
    }
        else
        {
            return HXR_OUTOFMEMORY;
        }
    }

    if (m_pPlayerBuf)
    {
        m_pPlayerBuf->AddRef();
        if (m_pPlayerBuf->Release() > 1)
        {
            /*
             * Cannot use this buffer the next time
             * release our reference and  create a new one
             */
            m_pPlayerBuf->Release();

            m_pPlayerBuf = (IHXBuffer*) new CHXBuffer;
            if( m_pSessionBuf )
            {
            m_pPlayerBuf->AddRef();
        }
            else
            {
                return HXR_OUTOFMEMORY;
            }
    }
    }
    return HXR_OK;
}

void CHXAudioSession::ConvertTo8BitAndOrMono(HXAudioData* pAudioData)
{
    BOOL bChannelConversion = (m_BeforeHookDeviceFmt.uChannels == 1) &&
                              (m_DeviceFmt.uChannels == 2);
    BOOL bBitConversion     = m_BeforeHookDeviceFmt.uBitsPerSample == 8;

    /* Atleast one of them should be true to be in this function */
    HX_ASSERT(bChannelConversion || bBitConversion);

    ULONG32     ulLen           = pAudioData->pData->GetSize();
    short int*  pShortBuf       = (short int*) pAudioData->pData->GetBuffer();
    UCHAR*      pOutUCharBuf    = pAudioData->pData->GetBuffer();
    short int*  pOutShortBuf    = (short int*) pAudioData->pData->GetBuffer();
    ULONG32     ulLoopCount     = ulLen;

    if (bBitConversion && bChannelConversion)
    {
        ulLen       =  pAudioData->pData->GetSize() / 4;
        ulLoopCount = pAudioData->pData->GetSize() / 4;
    }
    else if (bBitConversion && !bChannelConversion)
    {
        ulLen       = pAudioData->pData->GetSize() / 2;
        ulLoopCount = pAudioData->pData->GetSize() / 2;
    }
    else /*if (!bBitConversion && bChannelConversion) */
    {
        ulLen       = pAudioData->pData->GetSize() / 2;
        ulLoopCount = pAudioData->pData->GetSize() / 4;
    }

    for(ULONG32 j = 0; j < ulLoopCount; j++)
    {
        if (bBitConversion && bChannelConversion)
        {
            *pOutUCharBuf++ = (UCHAR)   (
                                ((LONG32) ((*pShortBuf++  + 32768L) >> 8) +
                                 (LONG32) ((*pShortBuf++  + 32768L) >> 8))/2
                                        );
        }
        else if (bBitConversion && !bChannelConversion)
        {
            *pOutUCharBuf++ = (UCHAR)((*pShortBuf++  + 32768L) >> 8);
        }
        else /*if (!bBitConversion && bChannelConversion) */
        {
            *pOutShortBuf++ = (short int) (((LONG32) *pShortBuf++  + (LONG32) *pShortBuf++)/2);
        }
    }

    pAudioData->pData->SetSize(ulLen);
}

/************************************************************************
 *  Method:
 *              CHXAudioSession::ConvertToEight
 *      Purpose:
 */
void CHXAudioSession::ConvertToEight()
{
    UCHAR* pSessionBuf = m_pSessionBuf->GetBuffer();
    ULONG32 ulLen = m_ulBytesPerGran / sizeof(short);
    short int* iTmp = (short int*) pSessionBuf;

    for(ULONG32 j = 0; j < ulLen; j++ )
    {
        pSessionBuf[j] = (UCHAR) ((*iTmp++  + 32768L) >> 8);
    }
}

/************************************************************************
 *  Method:
 *              CHXAudioSession::TryOpenAudio
 *      Purpose:
 *       Try to open the audio device.
 */
HX_RESULT CHXAudioSession::TryOpenAudio()
{
    HX_RESULT theErr = HXR_OK;
    BOOL bDeviceOpened = FALSE;

    // Free the audio device if it is ours so that we can create it on the core thread!
    if ((!m_bReplacedDev || !m_bUsingReplacedDevice) && m_pCurrentAudioDev)
    {

        ReleaseAudioDevice();
        RestoreReplacedDevice();
        m_pAudioDev = NULL;
    }

    theErr = CreateAudioDevice();

    if (!theErr && m_pCurrentAudioDev)
    {
        m_pAudioDev = m_pCurrentAudioDev;

        if (!m_bReplacedDev || !m_bUsingReplacedDevice)
        {
            ((CHXAudioDevice*)m_pAudioDev)->SetGranularity( m_ulGranularity, m_ulBytesPerGran);
        }
        theErr = m_pAudioDev->Open( &m_ActualDeviceFmt, this );
        bDeviceOpened = TRUE;
        m_ulBlocksWritten = 0;

        /* we always open in a PAUSED state */
        if (!theErr)
        {
            theErr = m_pAudioDev->Pause();
        }

        if (theErr != HXR_OK)
        {
            m_pAudioDev = NULL;
        }

        if (!theErr && m_pAudioDev)
        {
            /* Set the initial device volume */
            m_pAudioDev->SetVolume(m_bMute ? 0 : m_uVolume);
        }
    }

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

#ifndef _CARBON
    if (!theErr && bDeviceOpened && m_bShouldOpenOnCoreThread &&
        m_pInterruptState && !m_pInterruptState->AtInterruptTime())
    {
        // we should re-open on the core thread!!!
        m_bToBeReOpened = TRUE;
        if( !m_pDeviceCallback )
	{
	    m_pDeviceCallback = new HXDeviceSetupCallback(this);
	    m_pDeviceCallback->AddRef();
	}
        if (!m_pDeviceCallback->PendingID())
	{
            m_pDeviceCallback->PendingID( m_pScheduler->RelativeEnter(m_pDeviceCallback, 0));
	}

    }
    else
#endif
    {
        m_bToBeReOpened = FALSE;
    }

    return theErr;
}

HX_RESULT
CHXAudioSession::CreateAudioDevice()
{
    HX_RESULT theErr = HXR_OK;

    if (!m_pCurrentAudioDev)
    {
        // create the audioout object
        CHXAudioDevice* pAudioDev = CHXAudioDevice::Create(m_pPreferences);
        if (pAudioDev)
        {
            pAudioDev->AddRef();
            pAudioDev->Init(m_pContext);
            if (pAudioDev->InitVolume(0, 100) == TRUE)
            {
                m_bAudioDeviceSupportsVolume = TRUE;
            }
            else
            {
                m_bAudioDeviceSupportsVolume = FALSE;
            }

            m_pCurrentAudioDev = (IHXAudioDevice*) pAudioDev;
        }
        else
        {
            theErr = HXR_OUTOFMEMORY;
        }
    }

    return theErr;
}

void
CHXAudioSession::ReleaseAudioDevice()
{
    if (m_pCurrentAudioDev)
    {
        ProcessAudioDevice(ACTION_REMOVE, m_pCurrentAudioDev);
    }

    m_pCurrentAudioDev->Close(FALSE);
    HX_RELEASE(m_pCurrentAudioDev);

    m_bToBeReOpened = FALSE;
    if (m_pDeviceCallback && m_pDeviceCallback->PendingID())
    {
	m_pScheduler->Remove(m_pDeviceCallback->PendingID());
	m_pDeviceCallback->PendingID(0);
    }
}

void
CHXAudioSession::RestoreReplacedDevice()
{
    if (m_bReplacedDev && !m_bUsingReplacedDevice && !m_pCurrentAudioDev)
    {
        m_pCurrentAudioDev = m_pReplacedAudioDev;
        m_pCurrentAudioDev->AddRef();
        m_bUsingReplacedDevice = TRUE;
    }
}

/************************************************************************
 *  Method:
 *              CHXAudioSession::OpenAudio
 *      Purpose:
 *       Open the audio device.
 */
HX_RESULT CHXAudioSession::OpenAudio()
{
    HX_RESULT theErr = TryOpenAudio();

    if (theErr == HXR_AUDIO_DRIVER)
    {
        StopAllOtherPlayers();
        theErr = TryOpenAudio();
    }

    return theErr;
}

/************************************************************************
 *  Method:
 *              CHXAudioSession::CreatePlaybackBuffer
 *      Purpose:
 *              This is the buffer that we mix all player buffers into
 *              and the one we write to the audio device.
 */
HX_RESULT CHXAudioSession::CreatePlaybackBuffer()
{
    // Calculate the number of bytes per granularity.
    m_ulBytesPerGran = (ULONG32)
            (((m_DeviceFmt.uChannels * ((m_DeviceFmt.uBitsPerSample==8)?1:2) *  m_DeviceFmt.ulSamplesPerSec)
                            / 1000.0) * m_ulGranularity);

    /* Number of samples required at output should be a multiple of 8 if
     * sampling rate is 8K/16K/32K...or a multiple of 11 for 11K/22K...
     * This is needed since the resamplerequires works reliably ONLY if
     * this condition is true. Ken is working on this problem. This is
     * an interim fix
     */
    ULONG32 ulExtraGranularity = 1;
    if (m_DeviceFmt.ulSamplesPerSec % 8 == 0)
    {
        ulExtraGranularity = 8;
    }
    else
    {
        ulExtraGranularity = 11;
    }


    if (m_ulBytesPerGran % (2*m_DeviceFmt.uChannels*ulExtraGranularity) != 0)
    {
        m_ulBytesPerGran -= m_ulBytesPerGran % (2*m_DeviceFmt.uChannels*ulExtraGranularity);

        m_dGranularity = (double) m_ulBytesPerGran / (double) ((double) (m_DeviceFmt.uChannels * ((m_DeviceFmt.uBitsPerSample==8)?1:2) *  m_DeviceFmt.ulSamplesPerSec)
                                / 1000.0);
    }

    // Readjust the max size of the block
    m_ActualDeviceFmt.uMaxBlockSize = (UINT16) m_ulBytesPerGran;

    HX_RELEASE(m_pSessionBuf);
    HX_RELEASE(m_pPlayerBuf);

    m_pSessionBuf = new CHXBuffer;
    m_pSessionBuf->AddRef();
    m_pSessionBuf->SetSize(m_ulBytesPerGran);

    m_DeviceFmt.uMaxBlockSize   = (UINT16) m_ulBytesPerGran;
    m_ActualDeviceFmt.uMaxBlockSize = m_DeviceFmt.uMaxBlockSize;

    return HXR_OK;
}

/************************************************************************
 *  Method:
 *              CHXAudioSession::Pause
 *      Purpose:
 *       Pause playback of this Player's audio.
 */
HX_RESULT CHXAudioSession::Pause( CHXAudioPlayer* p)
{
    m_pMutex->Lock();

    BOOL bUseStopInPause = FALSE;

#if defined _DEBUG && defined HELIX_FEATURE_AUDIO_MULTIPLAYER_PAUSE
    bUseStopInPause = HXDebugOptionEnabled("zUseStopInPause");
#endif

    if (!bUseStopInPause && NumberOfResumedPlayers() == 0)
    {
        m_bPaused = TRUE;

        if(m_ulCallbackID)
        {
            m_pScheduler->Remove(m_ulCallbackID);
            m_ulCallbackID = 0;
        }

        // Check to see if all audio players are paused, then and only
        // then will we pause the device
        if ( m_pAudioDev )
        {
            m_pAudioDev->Pause();
        }

        m_bAtLeastOneTimeReceived = FALSE;
        m_pLastPausedPlayer = p;
    }
    /*
     * more than one audio player is currently active.
     * We need to do the following:
     * 1. get the current time from the device
     * 2. get the time for data we have already pushed down to the device
     * 3. flush the audio device
     * 4. instruct all streams to "rewind" by the "written but not played" duration
     */
#ifdef HELIX_FEATURE_AUDIO_MULTIPLAYER_PAUSE
    else if (!GetDisableMultiPlayPauseSupport() && m_pAudioDev && p->HasDataInAudioDevice())
    {
        HX_ASSERT(!m_bPaused && !m_bStoppedDuringPause);
        RewindSession();

        // this if is temporary
        if (NumberOfResumedPlayers() > 0)
        {
            ActualResume();
        }
    }
#endif

    m_pMutex->Unlock();
    return HXR_OK;
}

/************************************************************************
 *  Method:
 *              CHXAudioSession::Resume
 *      Purpose:
 *       Resume playback of this Player's audio.
 */
HX_RES

⌨️ 快捷键说明

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