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

📄 hxaudses.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
         * fake timeline if the presentation has atleast one media type other         * than audio         */        if (!theErr || theErr == HXR_AUDIO_DRIVER)        {            CreatePlaybackBuffer();        }        // Reset the number of blocks we've written        m_ulBlocksWritten = 0;        // Open the audio device only if DisableWrite is OFF        /* This probably needs to be moved at the top so that         * when second player comes in and we are already intialized,         * we check for new value of disablewrite again         */        CheckDisableWrite();        m_bUseFinalHook         = FALSE;        if (!theErr && !m_bDisableWrite)        {            theErr = OpenDevice();        } /* If disable wirte is ON, release the audio device */        else if (!theErr)        {            m_pAudioDev = 0;        }        /* If the audio device is busy, check if we have         * anything other than audio in the presentation.         * If TRUE, play silence so that the rest of the         * presentation can be played.         */        if (theErr == HXR_AUDIO_DRIVER && !m_bDisableWrite)        {            if (!IsAudioOnlyTrue())            {                m_bDisableWrite = TRUE;                m_pAudioDev         = 0;                theErr      = HXR_OK;            }        }    }    m_bInited = (!theErr) ? TRUE : FALSE;    if (!theErr && m_pAudioDev && m_pHookList)    {        InitHooks();    }    if (!theErr && m_pAudioDev && m_pFinalHook)    {        ProcessAudioHook(ACTION_ADD, m_pFinalHook);    }    if(m_pContext)    {        HX_RELEASE(m_pMPPSupport);        m_pContext->QueryInterface(IID_IHXMultiPlayPauseSupport, (void**)&m_pMPPSupport);    }    return theErr;}HX_RESULTCHXAudioSession::OpenDevice(){    HX_RESULT       theErr = HXR_OK;    HXAudioFormat  audioFormat;    if (m_pFinalHook)    {        m_bUseFinalHook = TRUE;        if (HXR_OK != ProcessAudioHook(ACTION_CHECK, m_pFinalHook))        {            m_bUseFinalHook = FALSE;        }        if (m_bUseFinalHook)        {            memcpy( &audioFormat, &m_ActualDeviceFmt, sizeof(HXAudioFormat));            theErr = m_pFinalHook->OnInit(&audioFormat);        }    }    if (!theErr && m_pFinalHook && m_bUseFinalHook)    {        m_bUseFinalHook = TRUE;        /* Did the hook change the data format? */        if( 0!=memcmp(&audioFormat, &m_ActualDeviceFmt, sizeof(HXAudioFormat)))        {            memcpy( &m_BeforeHookDeviceFmt, &m_ActualDeviceFmt, sizeof(HXAudioFormat));            memcpy( &m_ActualDeviceFmt, &audioFormat, sizeof(HXAudioFormat));        }    }    else    {        m_bUseFinalHook = FALSE;    }    theErr = OpenAudio();    if (theErr && m_pFinalHook && m_bUseFinalHook)    {        /* Looks like the audio device does not support the format         * specified by the final Hook         * Revert back to the original format and try again         */        memcpy( &m_ActualDeviceFmt, &m_BeforeHookDeviceFmt, sizeof(HXAudioFormat));        m_bUseFinalHook         = FALSE;        theErr = OpenAudio();    }    return theErr;}/* *********************************************************************** *  Method: *              CHXAudioSession::GetDeviceFormat *      Purpose: *              Determine the device format for this session. *              The session object needs to resolve the device format *              among multiple players. */HX_RESULT CHXAudioSession::GetDeviceFormat(){    HX_RESULT       theErr          = HXR_OK;    UINT16          uOrigSampleRate = 0;    CHXAudioPlayer* p               = NULL;    UINT16          bAutoUpsampling = FALSE;    HXAudioFormat   audioFmt;    // We no longer force audio device in stereo mode.  However we    // still try to open it in 16-bit mode since all of our processing    // is done in 16 bit.    m_DeviceFmt.uBitsPerSample  = 16;    //Just grab the first players stats to use as maximums.    LISTPOSITION lp = m_pPlayerList->GetHeadPosition();    while(lp)    {        p = (CHXAudioPlayer*) m_pPlayerList->GetNext(lp);        if(0!=p->GetStreamCount())        {            p->GetFormat( &audioFmt );            m_DeviceFmt.uChannels       = audioFmt.uChannels;            m_DeviceFmt.ulSamplesPerSec = audioFmt.ulSamplesPerSec;            m_DeviceFmt.uMaxBlockSize   = audioFmt.uMaxBlockSize;            break;        }    }    //Now loop through the rest of the players and find all the    //maximums.    while(lp)    {        p = (CHXAudioPlayer*) m_pPlayerList->GetNext(lp);        if( 0 != p->GetStreamCount() )        {            p->GetFormat( &audioFmt );            m_DeviceFmt.uChannels       = max(m_DeviceFmt.uChannels,                                              audioFmt.uChannels);            m_DeviceFmt.ulSamplesPerSec = max(m_DeviceFmt.ulSamplesPerSec,                                              audioFmt.ulSamplesPerSec);            m_DeviceFmt.uMaxBlockSize   = max(m_DeviceFmt.uMaxBlockSize,                                              audioFmt.uMaxBlockSize);        }    }    // turn on the default upsampling to 44K only on IX86 platforms    // which support MMX    // XXXgfw this also uses more memory for each block we push down    // XXXgfw to the audio device. You might not want it on MIN_HEAP    // XXXgfw kind of MMX devices, if there are any.#if defined(_M_IX86)    ReadPrefINT16(m_pPreferences, "AutoAudioUpsampling", bAutoUpsampling );#endif    if(bAutoUpsampling)    {        //force 44khz as our first attempt to open audio device        uOrigSampleRate = (UINT16)m_DeviceFmt.ulSamplesPerSec;        m_DeviceFmt.ulSamplesPerSec = 44100;    }#if defined(HELIX_FEATURE_PREFERENCES)    else    {        UINT16 ulSamplesPerSecPreference = 0;        ReadPrefINT16(m_pPreferences, "AudioDeviceSamplesPerSec", ulSamplesPerSecPreference );        if(ulSamplesPerSecPreference)        {            uOrigSampleRate = (UINT16)m_DeviceFmt.ulSamplesPerSec;            m_DeviceFmt.ulSamplesPerSec = ulSamplesPerSecPreference;        }    }#endif /* HELIX_FEATURE_PREFERENCES */    //Start negotiating with the device. Generate a table that will    //drive the different formats we want to try.  Start with the    //native rate (and any mods from the pref stuff above) and go up    //in samplerate. If that fails, go down in sample rate.    const int nNumberOfRates = sizeof(z_anValidSampleRates)/sizeof(z_anValidSampleRates[0]);    //Total number of table entries per sample rate will be:    //nNumberOfRates*4 (mono/16, mono/8, stereo/16, stereo/8) plus    //native format + user defined samplerate entry.    const int      nTmp       = nNumberOfRates*4+2;    unsigned short nTableSize = 0;    tableEntry* table = new tableEntry[nTmp];    HX_ASSERT(table);    if( NULL == table )        return HXR_OUTOFMEMORY;    //First entry is always our native format from above with any    //samplerate changes the user made via prefs.    table[nTableSize++].set( (UINT16)m_DeviceFmt.ulSamplesPerSec,                             (UINT8)m_DeviceFmt.uChannels,                             (UINT8)m_DeviceFmt.uBitsPerSample                             );    //Second entry is always the above with the clip's original    //sample rate, if we changed it.    if( uOrigSampleRate )        table[nTableSize++].set(uOrigSampleRate,                                (UINT8)m_DeviceFmt.uChannels,                                (UINT8)m_DeviceFmt.uBitsPerSample                                );    //Now generate the rest of the format table....    const UINT8 usNativeChannel = (UINT8)m_DeviceFmt.uChannels;    const UINT8 usAltChannel    = (2==m_DeviceFmt.uChannels)?1:2;    const UINT8 usNativeBits    = (UINT8)m_DeviceFmt.uBitsPerSample;    const UINT8 usAltBits       = (8==m_DeviceFmt.uBitsPerSample)?16:8;    //First use all equal or higher sample rates.    short nIdx = 0;    while( nIdx<nNumberOfRates )    {        UINT16 usRate = z_anValidSampleRates[nIdx];        if( usRate >= m_DeviceFmt.ulSamplesPerSec )        {            table[nTableSize++].set(usRate, usNativeChannel, usNativeBits );            table[nTableSize++].set(usRate, usAltChannel,    usNativeBits );            table[nTableSize++].set(usRate, usNativeChannel, usAltBits  );            table[nTableSize++].set(usRate, usAltChannel,    usAltBits  );        }        nIdx++;    }    //Now all the samle rates lower then the native rate.    nIdx = nNumberOfRates-1;    while( nIdx>=0)    {        UINT16 usRate = z_anValidSampleRates[nIdx];        if( usRate < m_DeviceFmt.ulSamplesPerSec )        {            table[nTableSize++].set(usRate, usNativeChannel, usNativeBits );            table[nTableSize++].set(usRate, usAltChannel,    usNativeBits );            table[nTableSize++].set(usRate, usNativeChannel, usAltBits  );            table[nTableSize++].set(usRate, usAltChannel,    usAltBits  );        }        nIdx--;    }    //Now loop through our table and find a supported format.    nIdx = 0;    theErr = HXR_FAIL;    while( FAILED(theErr) && nIdx<nTableSize)    {        m_DeviceFmt.ulSamplesPerSec = table[nIdx].usSampleRate;        m_DeviceFmt.uChannels       = table[nIdx].usChannels;        m_DeviceFmt.uBitsPerSample  = table[nIdx].usBits;        theErr = CheckAudioFormat(&m_DeviceFmt);        nIdx++;    }    //We still need to create playback buffers since we will use the    //fake timeline if the presentation has atleast one media type    //other than audio    //XXXgfw this code below needs to be looked at. I Don't want to    //touch it now for fear of breaking something that will take    //a long time to fix.    if (!theErr || theErr == HXR_AUDIO_DRIVER)    {        m_ActualDeviceFmt = m_DeviceFmt;        //All the calculations are done for 16 bit stereo. There are        //VERY FEW sound cards out there which do not support 16 bit        //stereo. They will incur a high performace hit because of        //possible unnecessary up/down conversion. For now we will        //live with that.        //XXXgfw wrong. lots of handhelds/phones don't do 16bit-2        //channel output.        m_DeviceFmt.uBitsPerSample  = 16;        m_BeforeHookDeviceFmt = m_ActualDeviceFmt;    }    HX_VECTOR_DELETE(table);    return theErr;}/************************************************************************ *  Method: *              CHXAudioSession::CheckAudioFormat *      Purpose: *       The audio player calls this to check its audio format with the *       the audio device. */HX_RESULT CHXAudioSession::CheckAudioFormat(    HXAudioFormat*    pAudioFormat){    HX_RESULT theErr = HXR_OK;    if (!m_pAudioDev)    {        CreateAudioDevice();        m_pAudioDev = m_pCurrentAudioDev;    }    if (m_pAudioDev)    {        theErr = m_pAudioDev->CheckFormat(pAudioFormat);        /* 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;        }    }    return theErr;}/************************************************************************ *  Method: *              CHXAudioSession::PlayAudio *      Purpose: *       The player object call this to play audio. This method is called *       again in the playback response function. */HX_RESULT CHXAudioSession::PlayAudio(UINT16 uNumBlocks){    HX_RESULT theErr        = HXR_OK;    BOOL      bDisableWrite = FALSE;    if ( !m_bInited )        return theErr;    if (m_bInPlayAudio)    {        return HXR_OK;    }    m_pMutex->Lock();    if (m_bToBeRewound)    {        theErr = Rewind();        goto exit;    }    m_bInPlayAudio = TRUE;    if (m_pAuxiliaryAudioBuffers &&        m_pAuxiliaryAudioBuffers->GetCount() > 0 && m_pAudioDev && !m_bDisableWrite)    {        if (HXR_OK == ProcessAudioDevice(ACTION_CHECK, m_pAudioDev))        {            /* Try to stuff in as much backlog as possible */            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;        }

⌨️ 快捷键说明

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