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

📄 mixengine.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        200, 170, 152, 140, 130, 122, 115, 110, 105, 100, 96, 92,        89, 85, 82, 80, 77, 74, 72, 70, 68, 66, 64, 62,        60, 59, 57, 55, 54, 52, 51, 49, 48, 47, 46, 44,        43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32,        31, 30, 29, 28, 28, 27, 26, 25, 24, 24, 23, 22,        21, 21, 20, 19, 19, 18, 17, 17, 16, 15, 15, 14,        14, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8,        7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2,        1, 1, 0, 0    } ;    if (vol > HX_MAX_VOLUME)      return 0 ;    else if (vol <= 0)      return VOLUME_SILENT ;    else      return -(INT32)vol2TenthOfDb[vol] ;}#endifHX_RESULT HXAudioSvcMixEngine::MixIntoBuffer(void* pPlayerbuf0, UINT32 ulBufSizeInBytes_4, BOOL &bIsMixBufferDirty){    // our caller's sense of "dirty" is inverted    bIsMixBufferDirty = !bIsMixBufferDirty ;    char *pPlayerbuf = (char*)pPlayerbuf0 ; // keep the original around    BOOL bHadInput = FALSE ;    // optimization lazy-init of buffers.    // We only allocate the sample buffers when we really need them (the first    // time MixIntoBuffer() is called)    if (!m_pBuffer_1)    {        // allocate both buffers        m_pBuffer_1 = new tAudioSample[m_ulChunkSize_1] ;        if (!m_pBuffer_1)            return HXR_OUTOFMEMORY ;        if (m_pResampler)        {            m_pBuffer_3 = new tAudioSample[m_ulBufferSize_3] ;            if (!m_pBuffer_3)                return HXR_OUTOFMEMORY ;        }    }    UINT32 nSamplesOutput_4 = ulBufSizeInBytes_4 / m_ulBytesPerSample ;    // make sure we are being handed right-sized buffers.    if (nSamplesOutput_4 / m_nChannels_4 * (m_ulBytesPerSample * m_nChannels_4) != ulBufSizeInBytes_4)    {        HX_ASSERT(0) ;        return HXR_FAIL ;    }    // tile output into chunks    while (nSamplesOutput_4)    {        // Figure out how many samples we need on the resampler output.        // If we have left-overs from last time, adjust the tile size        UINT32 nSamples_3 = MIN(nSamplesOutput_4 / m_nChannels_4 * m_nChannels_2_3, m_ulChunkSize_3) ;        // how many samples in do we need on input?        UINT32 nSamples_2 ;#ifdef HELIX_FEATURE_RESAMPLER        if (m_pResampler)            nSamples_2 = m_pResampler->GetMinInput(nSamples_3 - m_nOutputSamplesLeft_3) ;        else#endif        nSamples_2 = (nSamples_3 - m_nOutputSamplesLeft_3) ;        UINT32 nSamples_1 = nSamples_2 * m_nChannels_1 / m_nChannels_2_3 ;        // make sure that we don't overflow the input buffer (if we did, that would        // be a design error)        HX_ASSERT(nSamples_1 <= m_ulChunkSize_1) ;        //        // Phase 1: Get the input        //        // get input        BOOL bHaveInput = m_pCvt->ConvertIntoBuffer(m_pBuffer_1, nSamples_1, m_llTimestamp_1);        // update the time stamp.        m_llTimestamp_1 += nSamples_1 ;        //        // Phase 2: Downmix if necessary. This might need headroom and create overgain        // (not implemented yet)        //        // downmix if necessary (creates nSamples_2 samples)        if (bHaveInput && m_nChannels_2_3 != m_nChannels_1)            (*this.*m_pfDownmix)(m_pBuffer_1, nSamples_1) ;        //        // apply any volume changes        //#ifdef HELIX_FEATURE_GAINTOOL        if (bHaveInput)            gainFeed(m_pBuffer_1, nSamples_2, m_pGaintool) ;#endif        //        // Phase 3: Resample        //        // resample, but only if we have data. This is a hack -- it ignores        // the buffers in the resamplers, and thus looses some data, and time-        // shifts other data. This needs to be worked out.        tAudioSample *pResampOutput_3 ;        if (m_pResampler && bHaveInput)        {#ifdef HELIX_FEATURE_RESAMPLER            // compiler should optimize one of these branches away.            if (NBITS_PER_AUDIOSAMPLE == 32)                m_nOutputSamplesLeft_3 += m_pResampler->Resample(m_pBuffer_1, nSamples_2, (signed int*)(m_pBuffer_3 + m_nOutputSamplesLeft_3) ) ;            else                m_nOutputSamplesLeft_3 += m_pResampler->Resample(m_pBuffer_1, nSamples_2, (signed short*)(m_pBuffer_3 + m_nOutputSamplesLeft_3) ) ;            // assert that the resampler did not write out-of-bounds            HX_ASSERT(m_nOutputSamplesLeft_3 <= m_ulBufferSize_3) ;            // assert that we got at least nSamples_3 samples            HX_ASSERT(m_nOutputSamplesLeft_3 >= nSamples_3) ;            pResampOutput_3 = m_pBuffer_3 ;#endif        }        else // estimate the resampler output.        {            m_ulResamplerPhase += (nSamples_2 / m_nChannels_2_3) * m_ulSampleRate_3_4 ;            int sampleFramesOut = m_ulResamplerPhase / m_ulSampleRate_1_2 ;            m_ulResamplerPhase -= sampleFramesOut * m_ulSampleRate_1_2 ;            m_nOutputSamplesLeft_3 += sampleFramesOut * m_nChannels_2_3 ;            pResampOutput_3 = m_pResampler ? m_pBuffer_3 : m_pBuffer_1 ; // pass-through        }        // m_nOutputSamplesLeft_3 is the total number of resampled samples (including leftovers        // from the last time around). Do all further DSP only on nSamples_3 samples, leaving        // any leftovers for the next time.#ifdef HELIX_FEATURE_CROSSFADE        // We apply the crossfade even if we won't use the data, in order to        // kick its timestamp keeping forward.        // The performance impact should be negligible, though, since we won't be        // in crossfades most of the time.        //        // if we are at the start of a fade, notify the xfader        //        //        // m_llTimestamp                         ts+nsamples        // +-------------------------------------+ incoming        //                  XFade        //                   |        // nSamplesBeforeFade nSamplesInFade        //        //       m_llTimestamp                         ts+nsamples        //       +-------------------------------------+ incoming        // XFade        //   |------V----------------------------------|        //       nSamplesInFade        //  nSamplesBeforeFade  < 0        INT64 nSamplesBeforeFade = m_llFadeStart - m_llTimestamp_3 ;        INT64 nSamplesInFade     = nSamples_3 - nSamplesBeforeFade ;        if (nSamplesBeforeFade >= 0 // fade starts after this segment start            && nSamplesInFade > 0) // fade starts before this segment end        {            // time to start an XFade            m_bPastXFade = TRUE ;            XFader_start(m_ulXFadeSamples, m_pXFader) ;        }        // if we have passed the X-Fade point, we always run the signal through        // the XFader. Since it has a fast path when the XFade is done, this is        // not a resource drain.        if (m_bPastXFade)        {            if (nSamplesBeforeFade < 0) // fade was started earlier            {                nSamplesInFade += nSamplesBeforeFade ; // == nSamples_3                nSamplesBeforeFade = 0 ;            }            HX_ASSERT( nSamplesInFade > 0 );            if (XFader_active(m_pXFader))                Fader_feed(pResampOutput_3 + nSamplesBeforeFade, (INT32)nSamplesInFade, m_eCrossFadeDirection == FADE_OUT, m_pXFader) ;        }#endif        //        // Phase 3.5: Run the limiter if needed        //#ifdef HELIX_FEATURE_LIMITER        if (m_pLimiter && NBITS_PER_AUDIOSAMPLE == 32)        {            LimiterProcess((int*)pResampOutput_3, nSamples_3, m_pLimiter);        }        else#endif        {            // TODO: insert clipping code        }        //        // Phase 4: Mix into the output buffer.        //        UINT32 nSamples_4 = nSamples_3 / m_nChannels_2_3 * m_nChannels_4 ;        if (bHaveInput)        {            if (!bHadInput && bIsMixBufferDirty)            {                // if we did not have input earlier, but we now receive data, we need to clean out                // the parts that have not been touched so far.                memset(pPlayerbuf0,0,pPlayerbuf - (char*)pPlayerbuf0) ;            }            // and mix into output (mix) buffer            switch (m_ulBytesPerSample)            {            case 2:                upmix(pResampOutput_3, (INT16*)pPlayerbuf, m_upmixMachine, nSamples_3, bIsMixBufferDirty) ;                break ;            case 4:                upmix(pResampOutput_3, (INT32*)pPlayerbuf, m_upmixMachine, nSamples_3, bIsMixBufferDirty) ;                break ;            }            // if we have input anywhere, the buffer is not "dirty" anymore.            bHadInput = TRUE ;        }        else        {            if (bHadInput && bIsMixBufferDirty)            {                // if we did have input earlier, but do not now, we need to clean the output                // buffer (because it will not be marked "dirty" anymore).                memset(pPlayerbuf, 0, nSamples_4 * m_ulBytesPerSample) ;            }        }        // save left-over samples        m_nOutputSamplesLeft_3 -= nSamples_3 ;        m_llTimestamp_3        += nSamples_3 ;        // if there is no resampler, there should be no left-over samples        if (!m_pResampler) HX_ASSERT(m_nOutputSamplesLeft_3 == 0) ;        // if left-over samples        if (m_nOutputSamplesLeft_3)            memcpy(m_pBuffer_3, m_pBuffer_3 + nSamples_3, m_nOutputSamplesLeft_3 * sizeof(*m_pBuffer_3)) ;        nSamplesOutput_4 -= nSamples_4 ;        pPlayerbuf += nSamples_4 * m_ulBytesPerSample ;    }    // if we had input anywhere within this function, the buffer is not dirty anymore.    bIsMixBufferDirty &= !bHadInput ;    bIsMixBufferDirty = !bIsMixBufferDirty ;    return HXR_OK ;}HX_RESULT HXAudioSvcMixEngine::SetCrossFade(    enum eCrossfadeDirection inOut, // FADE_IN and FADE_OUT    INT64 llStarttimeInSamples, // output side!    INT64 llEndtimeInSamples){#if defined(HELIX_FEATURE_CROSSFADE)    m_eCrossFadeDirection = inOut ;    HX_ASSERT(llStarttimeInSamples % m_nChannels_4 == 0 &&              llEndtimeInSamples   % m_nChannels_4 == 0 ) ;    m_llFadeStart = llStarttimeInSamples ; // both are pre-resampler    if (llEndtimeInSamples - llStarttimeInSamples > INT_MAX ||        llEndtimeInSamples - llStarttimeInSamples < 0)    {        // we don't support such long fades        return HXR_FAIL ;    }    // duration is in part 3 samples    m_ulXFadeSamples = (INT32)(llEndtimeInSamples - llStarttimeInSamples) / m_nChannels_4 * m_nChannels_2_3 ;    m_bPastXFade = FALSE ;    return HXR_OK ;#else    return HXR_NOTIMPL ;#endif}

⌨️ 快捷键说明

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