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

📄 taudiofilterlfecrossover.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
字号:
/*
 * Copyright (c) 2004-2006 Milan Cutka
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "stdafx.h"
#include "TaudioFilterLFEcrossover.h"
#include "TlfeCrossoverSettings.h"
#include "firfilter.h"
#include "TfirSettings.h"

TaudioFilterLFEcrossover::TaudioFilterLFEcrossover(IffdshowBase *Ideci,Tfilters *Iparent):TaudioFilter(Ideci,Iparent)
{
 oldfmt.freq=0;oldfreq=0;
 filter_coefs_lfe=filter_coefs_lfeLR=NULL;
}

void TaudioFilterLFEcrossover::done(void)
{
 if (filter_coefs_lfe) aligned_free(filter_coefs_lfe);filter_coefs_lfe=NULL;
 if (filter_coefs_lfeLR) aligned_free(filter_coefs_lfeLR);filter_coefs_lfeLR=NULL;
 buf.clear();
}

HRESULT TaudioFilterLFEcrossover::process(TfilterQueue::iterator it,TsampleFormat &fmt,void *samples0,size_t numsamples,const TfilterSettingsAudio *cfg0)
{
 const TlfeCrossoverSettings *cfg=(const TlfeCrossoverSettings*)cfg0;

 if (oldfmt!=fmt || oldfreq!=cfg->freq)
  {
   oldfmt=fmt;oldfreq=cfg->freq;
   done();
   li=ri=-1;
   for (unsigned int i=0;i<fmt.nchannels;i++)
    {
     if (fmt.speakers[i]&SPEAKER_FRONT_LEFT)
      li=i;
     else if (fmt.speakers[i]&SPEAKER_FRONT_RIGHT)
      ri=i;
     else if (fmt.speakers[i]&SPEAKER_FRONT_CENTER)
      li=ri=i;
    }
   TfirFilter::_ftype_t f=cfg->freq/TfirFilter::_ftype_t(fmt.freq/2);
   lenLFE=256;
   filter_coefs_lfe=TfirFilter::design_fir(&lenLFE,&f,TfirSettings::LOWPASS,TfirSettings::WINDOW_HAMMING,0);
   lenLFElr=256;
   filter_coefs_lfeLR=TfirFilter::design_fir(&lenLFElr,&f,TfirSettings::HIGHPASS,TfirSettings::WINDOW_HAMMING,0);
   outfmt=fmt;
   if ((outfmt.channelmask&SPEAKER_LOW_FREQUENCY)==0)
    {
     outfmt.setChannels(outfmt.nchannels+1,outfmt.makeChannelMask()|SPEAKER_LOW_FREQUENCY);
     for (unsigned int i=0;i<outfmt.nchannels;i++)
      map[i]=oldfmt.findSpeaker(outfmt.speakers[i]);
    }
   lfei=outfmt.findSpeaker(SPEAKER_LOW_FREQUENCY);
   lfe_pos=0;memset(LFE_buf,0,sizeof(LFE_buf));
   lfe_posL=0;memset(LFE_bufL,0,sizeof(LFE_bufL));
   lfe_posR=0;memset(LFE_bufR,0,sizeof(LFE_bufR));
  }

 float *in=(float*)init(cfg,fmt,samples0,numsamples);outfmt.sf=fmt.sf;
 float gain=(float)db2value(cfg->gain/100.0f);
 if ((fmt.channelmask&SPEAKER_LOW_FREQUENCY)==0)
  {
   float *out=(float*)(samples0=alloc_buffer(fmt=outfmt,numsamples,buf));
   for (size_t i=0;i<numsamples;i++)
    {
     for (unsigned int ch=0;ch<fmt.nchannels;ch++)
      if (ch==(unsigned int)lfei)
       {
        LFE_buf[lfe_pos]=(in[li]+in[ri])/2;
        out[ch]=gain*TfirFilter::firfilter(LFE_buf,lfe_pos,lenLFE,lenLFE,filter_coefs_lfe);
        lfe_pos++;if (lfe_pos==lenLFE) lfe_pos=0;
       }
      else
       if (cfg->cutLR)
        if (li==map[ch])
         {
          LFE_bufL[lfe_posL]=in[li];
          out[ch]=TfirFilter::firfilter(LFE_bufL,lfe_posL,lenLFElr,lenLFElr,filter_coefs_lfeLR);
          lfe_posL++;if (lfe_posL==lenLFElr) lfe_posL=0;
         }
        else if (ri==map[ch])
         {
          LFE_bufR[lfe_posR]=in[ri];
          out[ch]=TfirFilter::firfilter(LFE_bufR,lfe_posR,lenLFElr,lenLFElr,filter_coefs_lfeLR);
          lfe_posR++;if (lfe_posR==lenLFElr) lfe_posR=0;
         }
        else
         out[ch]=in[map[ch]];
       else
        out[ch]=in[map[ch]];
     in+=oldfmt.nchannels;out+=fmt.nchannels;
    }
  }
 else
  {
   float *out=(float*)(samples0=in);
   for (size_t i=0;i<numsamples;i++)
    {
     LFE_buf[lfe_pos]=(in[li]+in[ri])/2;
     out[lfei]=gain*TfirFilter::firfilter(LFE_buf,lfe_pos,lenLFE,lenLFE,filter_coefs_lfe);
     if (cfg->cutLR)
      {
       LFE_bufL[lfe_posL]=in[li];
       out[li]=TfirFilter::firfilter(LFE_bufL,lfe_posL,lenLFElr,lenLFElr,filter_coefs_lfeLR);
       lfe_posL++;if (lfe_posL==lenLFElr) lfe_posL=0;
       if (li!=ri)
        {
         LFE_bufR[lfe_posR]=in[ri];
         out[ri]=TfirFilter::firfilter(LFE_bufR,lfe_posR,lenLFElr,lenLFElr,filter_coefs_lfeLR);
         lfe_posR++;if (lfe_posR==lenLFElr) lfe_posR=0;
        }
      }
     lfe_pos++;if (lfe_pos==lenLFE) lfe_pos=0;
     in+=oldfmt.nchannels;out+=fmt.nchannels;
    }
  }

 return parent->deliverSamples(++it,fmt,samples0,numsamples);
}

void TaudioFilterLFEcrossover::onSeek(void)
{
 lfe_pos=0;memset(LFE_buf,0,sizeof(LFE_buf));
 lfe_posL=0;memset(LFE_bufL,0,sizeof(LFE_bufL));
 lfe_posR=0;memset(LFE_bufR,0,sizeof(LFE_bufR));
}

⌨️ 快捷键说明

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