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

📄 rvorbis.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                                                            // convert floats to 16bit signed ints (host order) and interleave            for (i = 0; i < m_vi.channels; i++) {                ogg_int16_t *ptr = ((ogg_int16_t*)audioData.pData->GetBuffer()) + i;                float *mono = pcm[i];                                                                        for (j = 0; j < bout; j++) {                    int val = (int)(mono[j] * 32767.f);                    // guard against clipping                    if (val > 32767) {                        val = 32767;                        clipflag = 1;                    }                    if (val < -32768) {                        val = -32768;                        clipflag = 1;                    }                    *ptr = val;                    ptr += m_vi.channels;                }            }            BOOL bWrite = AdjustAudioData(audioData);            if (m_bIsGapInStreaming) {                audioData.uAudioStreamType = TIMED_AUDIO;                m_bIsGapInStreaming = FALSE;            } else {                audioData.uAudioStreamType = STREAMING_AUDIO;            }            if (bWrite)            {                ulLastWriteTime = audioData.ulAudioTime;                HX_RESULT err = m_pCurrentStream->Write(&audioData);                DPRINTF(D_VORBIS,                        ("write err 0x%08x samples %d audioTime %u\n",                          err, bout, audioData.ulAudioTime));            }        }        else        {            /* We failed to create a buffer so make it             * look like there was a gap in the audio             */            m_bIsGapInStreaming = TRUE;        }        HX_RELEASE(audioData.pData);        m_totalSamples += bout;                    // tell vorbis how many samples we consumed        vorbis_synthesis_read(&m_vd, bout);    }    return ulLastWriteTime;}void CVorbisRenderer::Shutdown(){    vorbis_comment_clear(&m_vc);    vorbis_info_clear(&m_vi);    HX_RELEASE(m_pContext);    HX_RELEASE(m_pClassFactory);    HX_RELEASE(m_pStream);    HX_RELEASE(m_pPlayer);    HX_RELEASE(m_pAudioPlayer);    HX_RELEASE(m_pStreamHeaderObj);    HX_RELEASE(m_pCurrentStream);    while(!m_audioStreams.IsEmpty())    {        COggAudioStreamHelper* pHlpr =             (COggAudioStreamHelper*)m_audioStreams.RemoveHead();        pHlpr->Close();        HX_RELEASE(pHlpr);    }    HX_DELETE(m_pDepack);}void CVorbisRenderer::StartRebuffer(){    /* Only start a rebuffer if we have a stream     * and we haven't had OnEndofPackets() called     */    if (m_pStream && !m_bEndOfPackets)    {        DPRINTF(D_VORBIS,("Starting rebuffer\n"));        m_bRebuffering = TRUE;        m_pStream->ReportRebufferStatus(1, 0);    }}void CVorbisRenderer::EndRebuffer(){    m_bRebuffering = FALSE;    if (m_pStream)    {        DPRINTF(D_VORBIS,("Ending rebuffer\n"));        m_pStream->ReportRebufferStatus(1, 1);    }}int CVorbisRenderer::DepackInfoCount(){    return sizeof(zm_depackInfo) / sizeof(VorbisDepackInfo);}BOOL CVorbisRenderer::AdjustAudioData(REF(HXAudioData) audioData){    BOOL	bResult = TRUE;    UINT32	ulDuration = 0;    UINT32	ulSize = 0;    UINT32	ulExtraInMs = 0;    UINT32	ulExtraInBytes = 0;    IHXBuffer* pBuffer = NULL;    ulSize = (audioData.pData)->GetSize();    // calculate the worth of this data in ms    ulDuration = BytesToMs(ulSize);    // trim off any extra bytes    if (audioData.ulAudioTime < m_ulTrackStartTime)    {	if ((audioData.ulAudioTime + ulDuration) <= m_ulTrackStartTime)	{	 	    	    bResult = FALSE;	}	else	{	    // trim off partial data	    ulExtraInMs = m_ulTrackStartTime - audioData.ulAudioTime;	    // convert to bytes	    ulExtraInBytes = MsToBytes(ulExtraInMs);	    // align in sample boundary	    ulExtraInBytes -= (ulExtraInBytes % (m_audioFmt.uBitsPerSample * 			       m_audioFmt.uChannels / 8));	    if (!m_pClassFactory  ||                HXR_OK != m_pClassFactory->CreateInstance(		    CLSID_IHXBuffer, (void**)&pBuffer))	    {		bResult = FALSE;	    }            else            {                pBuffer->Set((audioData.pData)->GetBuffer() + ulExtraInBytes,                              ulSize - ulExtraInBytes);                //Release and replace with new buffer:                HX_RELEASE(audioData.pData);                audioData.pData = pBuffer;	 	                 audioData.ulAudioTime = m_ulTrackStartTime;            }	}    }        if (bResult && (m_ulTrackEndTime != NO_TIME_SET) &&        (audioData.ulAudioTime + ulDuration) > m_ulTrackEndTime)    {	if (audioData.ulAudioTime >= m_ulTrackEndTime)	{	    // drop this one	    bResult = FALSE;	}	else	{	    // trim off the extra ones	    ulExtraInMs = (audioData.ulAudioTime + ulDuration) - m_ulTrackEndTime;	    // convert to bytes	    ulExtraInBytes = MsToBytes(ulExtraInMs);	    // align in sample boundary	    ulExtraInBytes -= (ulExtraInBytes % (m_audioFmt.uBitsPerSample * 			       m_audioFmt.uChannels / 8));	    if (!m_pClassFactory  ||		    HXR_OK != m_pClassFactory->CreateInstance(		    CLSID_IHXBuffer, (void**)&pBuffer))	    {		bResult = FALSE;	    }            else            {                pBuffer->Set((audioData.pData)->GetBuffer(),                              ulSize - ulExtraInBytes);                //Release and replace with new buffer:                HX_RELEASE(audioData.pData);                audioData.pData = pBuffer;            }	}    }    if (bResult)    {        if (m_lTimeOffset < 0)        {            audioData.ulAudioTime  += (UINT32) (-m_lTimeOffset);        }        else        {            //HX_ASSERT(audioData.ulAudioTime >= (UINT32)m_lTimeOffset);            audioData.ulAudioTime -= (UINT32)m_lTimeOffset;        }    }    return bResult;}void CVorbisRenderer::updateBitrateInfo(vorbis_info* vi){    if (vi && m_pStream && m_pContext)    {        INT32 clipBitrate = 0;        if (vi->bitrate_nominal > 0)        {            clipBitrate = vi->bitrate_nominal;        }        else if (vi->bitrate_upper > 0)        {            clipBitrate = vi->bitrate_upper;        }        UINT32 uStreamRegID;        IHXRegistry* pReg = NULL;        if ((HXR_OK == getRegistryID(m_pStream, uStreamRegID)) &&            (HXR_OK == m_pContext->QueryInterface(IID_IHXRegistry,                                                  (void**)&pReg)))        {            CHXString propName;            if ((clipBitrate > 0) &&                (HXR_OK == getPropName(uStreamRegID, "ClipBandwidth",                                       propName)))            {                pReg->SetIntByName(propName, clipBitrate);            }        }        HX_RELEASE(pReg);    }}void CVorbisRenderer::updateTACInfo(vorbis_comment* vc){    if (vc && m_pStream && m_pContext)    {        IHXStreamSource* pStreamSrc = NULL;        IHXRegistry* pReg = NULL;        UINT32 uSourceRegID;        if ((HXR_OK == m_pStream->GetSource(pStreamSrc)) &&            (HXR_OK == getRegistryID(pStreamSrc, uSourceRegID)) &&            (HXR_OK == m_pContext->QueryInterface(IID_IHXRegistry,                                                  (void**)&pReg)))        {            int tagInfoCount = sizeof(zm_tagInfo) / sizeof(VorbisTagMapping);            for (int i = 0; i < tagInfoCount; i++)            {                char* pVorbisTag = zm_tagInfo[i].m_pVorbisTag;                const char* pPropName = zm_tagInfo[i].m_pPropName;                int commentCount = vorbis_comment_query_count(vc, pVorbisTag);                                if (commentCount > 0)                {                    CHXString value = vorbis_comment_query(vc, pVorbisTag, 0);                    for (int j = 1; j < commentCount; j++)                    {                        value += ", ";                        value += vorbis_comment_query(vc, pVorbisTag, j);                    }                    IHXBuffer* pPropValBuf = NULL;                                        if (HXR_OK == CreateStringBuffer(pPropValBuf,                                                      value,                                                     m_pContext))                    {                                                CHXString propName;                        if (HXR_OK == getPropName(uSourceRegID, pPropName,                                                  propName))                        {                            pReg->SetStrByName(propName, pPropValBuf);                        }                    }                    HX_RELEASE(pPropValBuf);                }            }        }        HX_RELEASE(pStreamSrc);        HX_RELEASE(pReg);    }}HX_RESULT CVorbisRenderer::getPropName(UINT32 uBaseID, const char* pChildPropName,                             CHXString& propName){    HX_RESULT res = HXR_INVALID_PARAMETER;    if (!m_pContext)    {        res = HXR_UNEXPECTED;    }    else if (pChildPropName && strlen(pChildPropName))    {        IHXRegistry* pReg = NULL;        IHXBuffer* pBasePropName = NULL;        res = m_pContext->QueryInterface(IID_IHXRegistry, (void**)&pReg);                if (HXR_OK == res)        {            res = pReg->GetPropName(uBaseID, pBasePropName);        }        if (HXR_OK == res)        {            propName = (const char*)pBasePropName->GetBuffer();            propName += '.';            propName += pChildPropName;        }        HX_RELEASE(pReg);        HX_RELEASE(pBasePropName);    }    return res;}HX_RESULT CVorbisRenderer::getRegistryID(IUnknown* pUnk, REF(UINT32) uRegID){    HX_RESULT res = HXR_INVALID_PARAMETER;    if (pUnk)    {        IHXRegistryID* pRegID = NULL;        res = pUnk->QueryInterface(IID_IHXRegistryID, (void**)&pRegID);        if (HXR_OK == res)        {            res = pRegID->GetID(uRegID);        }        HX_RELEASE(pRegID);    }    return res;}void CVorbisRenderer::gotoInitialHeaderState(){    vorbis_comment_clear(&m_vc);    vorbis_info_clear(&m_vi);        vorbis_info_init(&m_vi);    vorbis_comment_init(&m_vc);        m_VorbisState = VorbisInitialHeader;}HX_RESULT CVorbisRenderer::handleInitialHeader(ogg_packet* pOp){    HX_RESULT res = HXR_FAILED;    if (vorbis_synthesis_headerin(&m_vi, &m_vc, pOp) >= 0)     {        DPRINTF(D_VORBIS,("Got Initial Header\n"));                updateBitrateInfo(&m_vi);                /* check to see if the audio format is different         * from the default values          */        if ((m_audioFmt.uChannels != m_vi.channels) ||            (m_audioFmt.ulSamplesPerSec != (UINT32)m_vi.rate))        {            /* The parameters are different.              * Release our handle on the current stream             * and create a new audio stream object.             */            res = InitAudioStream(m_vi.rate,                                   m_vi.channels);                        m_bIsGapInStreaming = TRUE;        }        else        {            m_pCurrentStream->SetDryNotification(this);            res = HXR_OK;        }                m_VorbisState = VorbisCommentHeader;    }     else    {        HX_ASSERT(FALSE);    }    return res;}

⌨️ 快捷键说明

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