audunix.cpp

来自「linux下的一款播放器」· C++ 代码 · 共 1,081 行 · 第 1/3 页

CPP
1,081
字号
    //has alread exited.    retCode = _Imp_Reset();        if( retCode != RA_AOE_DEVNOTOPEN )    {        if( _IsSelectable() )        {            IHXAsyncIOSelection* pAsyncIO = NULL;                        if( HXR_OK == m_pContext->QueryInterface( IID_IHXAsyncIOSelection,                                                      (void**)&pAsyncIO)                )            {                pAsyncIO->Remove(_Imp_GetAudioFd() , PNAIO_WRITE);                HX_RELEASE( pAsyncIO );            }        }    }    //Close the audio device.    retCode = _CloseAudio();        //Close the mixer device.    _CloseMixer();    //Set state.    LOCK(m_mtxWriteListPlayStateLock);    m_wState = RA_AOS_CLOSED;    UNLOCK(m_mtxWriteListPlayStateLock);    //Remove callback from scheduler    if (m_bCallbackPending)    {        m_pScheduler->Remove(m_PendingCallbackID);        m_bCallbackPending = FALSE;    }    HX_VECTOR_DELETE(m_pRollbackBuffer);    //return    m_wLastError = retCode;    return m_wLastError;}//So far no UN*X platforms support this.HX_RESULT CAudioOutUNIX::_Imp_Seek(ULONG32 ulSeekTime){    m_wLastError = HXR_OK;    return m_wLastError;}HX_RESULT CAudioOutUNIX::_Imp_Pause(){    //XXXgfw We really should be closing the device instead of keeping it open to be nice to    //other procs.    LOCK(m_mtxWriteListPlayStateLock);    m_wState = RA_AOS_OPEN_PAUSED;    UNLOCK(m_mtxWriteListPlayStateLock);            if( !_HardwarePauseSupported() )    {        // Strategy.        //--Find out how much we have left in the device's buffer.        ULONG32 ulBytesPlayed      = _GetBytesActualyPlayed();        ULONG32 ulNumBytesToRewind = m_ulTotalWritten-ulBytesPlayed;                //Sometimes we can get a value for bytesPlayed that is slightly        //more then the amount we have actually written. This results        //in a huge number.        if( ulBytesPlayed > m_ulTotalWritten )            ulNumBytesToRewind = 0;                //--and reset player and discard all the data in the device's buffer        //We will just ignore an error here. That means the buffer will just drain        //and we will hear it again when they unpause.        LOCK(m_mtxDeviceStateLock);        _Reset();        UNLOCK(m_mtxDeviceStateLock);        //Make sure we only deal with full samples. Bytes-per-sample*num-channels.        int nRem = ulNumBytesToRewind%(m_uSampFrameSize*m_unNumChannels);        ulNumBytesToRewind = ulNumBytesToRewind>nRem ? ulNumBytesToRewind-nRem : 0;        // In heap-optimized mode, we accept that we're going to lose a         // little bit of data after a pause/resume because we are using as        // small a rollback buffer as we can get away with.#ifdef HELIX_CONFIG_MIN_ROLLBACK_BUFFER	if( ulNumBytesToRewind > m_ulDeviceBufferSize )	{	   ulNumBytesToRewind = m_ulDeviceBufferSize;	}#endif // HELIX_CONFIG_MIN_ROLLBACK_BUFFER        //  and add it to the front of the write buffer.        IHXBuffer* pNewBuffer = new CHXBuffer();        pNewBuffer->Set( m_pRollbackBuffer+m_ulDeviceBufferSize-ulNumBytesToRewind,                         ulNumBytesToRewind );        LOCK(m_mtxWriteListPlayStateLock);        m_pWriteList->AddHead(pNewBuffer);                pNewBuffer->AddRef();        UNLOCK(m_mtxWriteListPlayStateLock);        //--Subtract that from m_ulTotalWritten.        m_ulTotalWritten -= ulNumBytesToRewind;                _Pause();    }    else    {        //The hardware device handles the Pause/Resume.        LOCK(m_mtxDeviceStateLock);        _Pause();        UNLOCK(m_mtxDeviceStateLock);    }        m_wLastError = HXR_OK;    return m_wLastError;}HX_RESULT CAudioOutUNIX::_Imp_Resume(){    //XXXgfw We really should be closing and re-opening the device to be nice to other procs.    LOCK(m_mtxWriteListPlayStateLock);    m_wState = RA_AOS_OPEN_PLAYING;    UNLOCK(m_mtxWriteListPlayStateLock);    //XXXgfw If the two branches of the if are the same maybe get rid of one????    if( !_HardwarePauseSupported() )    {        _Resume();        _Imp_Write(NULL);    }    else    {        //The hardware device handles the Pause/Resume.        _Resume();        _Imp_Write(NULL);    }        m_wLastError = HXR_OK;    return m_wLastError;}HX_RESULT CAudioOutUNIX::_Imp_Reset(){    HX_RESULT retCode = RA_AOE_NOERR;        if ( m_wState != RA_AOS_CLOSED )    {        LOCK(m_mtxDeviceStateLock);        retCode = _Reset();        UNLOCK(m_mtxDeviceStateLock);        LOCK(m_mtxWriteListPlayStateLock);        while (m_pWriteList && m_pWriteList->GetCount() > 0)        {            IHXBuffer* pBuffer = (IHXBuffer *)(m_pWriteList->RemoveHead());            HX_RELEASE( pBuffer );        }        UNLOCK(m_mtxWriteListPlayStateLock);        m_ulTotalWritten  = 0;        m_bFirstWrite     = TRUE;        m_ulLastNumBytes  = 0;    }        m_wLastError = retCode;    return m_wLastError;}HX_RESULT CAudioOutUNIX::_Imp_Drain(){    HX_RESULT retCode = RA_AOE_NOERR;    LOCK(m_mtxWriteListPlayStateLock);    if( m_wState != RA_AOS_CLOSED )    {        retCode = _Drain();    }    while( m_pWriteList && !m_pWriteList->IsEmpty() )    {        IHXBuffer* pBuffer = (IHXBuffer *)(m_pWriteList->RemoveHead());        HX_RELEASE( pBuffer );    }    UNLOCK(m_mtxWriteListPlayStateLock);        m_wLastError = retCode;    return m_wLastError;}HX_RESULT CAudioOutUNIX::_Imp_CheckFormat( const HXAudioFormat* pFormat ){    HX_RESULT retCode = RA_AOE_NOERR;    m_wLastError       = HXR_OK;    retCode = _CheckFormat( pFormat );    if( RA_AOE_NOERR != retCode && RA_AOE_DEVBUSY != retCode )    {        m_wLastError = HXR_FAILED;    }    else    {        m_wLastError = HXR_OK;    }        return m_wLastError;}HX_RESULT CAudioOutUNIX::_Imp_GetCurrentTime( ULONG32& ulCurrentTime ){    ULONG32 ulTime   = 0;    UINT64  ulBytes  = 0;    LOCK(m_mtxWriteListPlayStateLock);    ulBytes = _GetBytesActualyPlayed();    UNLOCK(m_mtxWriteListPlayStateLock);        ulTime = (ULONG32)(( ( (double)ulBytes/(double)m_uSampFrameSize)/(double)m_unSampleRate) * 1000.0 / (double)m_unNumChannels);        //Not used anywhere but belongs to CHXAudioDevice so we must set it.    m_ulCurrentTime  = ulTime;    //Set the answer.    ulCurrentTime = ulTime;    m_wLastError = HXR_OK;    return HXR_OK;}void CAudioOutUNIX::DoTimeSyncs(){    ReschedPlaybackCheck();    OnTimeSync();    return;}HX_RESULT CAudioOutUNIX::ReschedPlaybackCheck(){    HX_RESULT retCode = HXR_OK;        if(!m_bCallbackPending)    {        HX_ASSERT( m_pCallback );        if(m_pCallback)        {            *m_pPlaybackCountCBTime += (int)(500*m_ulGranularity);            m_bCallbackPending = TRUE;            m_PendingCallbackID = m_pScheduler->AbsoluteEnter( m_pCallback,*((HXTimeval*)m_pPlaybackCountCBTime));        }        else        {            retCode = HXR_OUTOFMEMORY;        }    }    m_wLastError = retCode;    return m_wLastError;}UINT16 CAudioOutUNIX::_NumberOfBlocksRemainingToPlay(void){    UINT32 bytesBuffered = 0;    //We have to go through all of the buffers and count the size. Even though    //we always write m_wBlockSize buffers, we can get off-sized buffs because    //of the pause/resume code. When we pause we rewind however many bytes have    //not been played yet in the buffer.        LOCK(m_mtxWriteListPlayStateLock);    if( m_pWriteList )    {        LISTPOSITION i = m_pWriteList->GetHeadPosition();                while( i )        {            bytesBuffered += ((IHXBuffer *)m_pWriteList->GetAt(i)) -> GetSize();            m_pWriteList->GetNext(i);        }    }    bytesBuffered += (m_ulTotalWritten - _GetBytesActualyPlayed());        UNLOCK(m_mtxWriteListPlayStateLock);    return bytesBuffered / m_wBlockSize + 1;}CAudioOutUNIX::HXPlaybackCountCB::~HXPlaybackCountCB(){}STDMETHODIMP CAudioOutUNIX::HXPlaybackCountCB::QueryInterface(	REFIID riid, void** ppvObj ){    HX_RESULT retCode = HXR_OK;        if( IsEqualIID(riid, IID_IHXCallback) )    {        AddRef();        *ppvObj = (IHXCallback*)this;    }    else if (IsEqualIID(riid, IID_IUnknown))    {        AddRef();        *ppvObj = this;    }    else    {        *ppvObj = NULL;        retCode = HXR_NOINTERFACE;    }    return retCode;}STDMETHODIMP_(ULONG32) CAudioOutUNIX::HXPlaybackCountCB::AddRef(){    return InterlockedIncrement(&m_lRefCount);}STDMETHODIMP_(ULONG32) CAudioOutUNIX::HXPlaybackCountCB::Release(){        if (InterlockedDecrement(&m_lRefCount) > 0)    {        return m_lRefCount;    }        delete this;    return HXR_OK;}STDMETHODIMP CAudioOutUNIX::HXPlaybackCountCB::Func(void){    if (m_pAudioDeviceObject)    {        if(!m_timed)        {            //m_pAudioDeviceObject->_Imp_Write(NULL);        }        else        {            m_pAudioDeviceObject->m_bCallbackPending  = FALSE;            m_pAudioDeviceObject->_Imp_Write(NULL);            m_pAudioDeviceObject->DoTimeSyncs();        }    }    return HXR_OK;}HX_RESULT CAudioOutUNIX::_Pause(){    return RA_AOE_NOTSUPPORTED;

⌨️ 快捷键说明

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