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

📄 mixer.h.svn-base

📁 ffshow源码
💻 SVN-BASE
字号:
/*  Mixer  Mixer and gain control class. Smooth gain control based on ac3 time window,   so delayed samples are also required for operation.  Usage.     Create instance of a mixer, set input and output modes, set matrix     directly or call calc_matrix() function, then call mix() function.    'level' - desired output level. It is guaranteed that Samples will not       exceed it.    'clev', 'slev', 'lfelev' are params for matrix calculation calc_matrix().    'master', 'gain', 'dynrng' are used in gain control and matrix-independent.    'normalize' flag controls gain control behavior. True means one-pass      normalization. So at at the beginning mixing use 'gain' = 'master'.      When overflow occur gain is decreased and so on. When 'normalize' = false      then after overflow gain begins to increase bit by bit until it      reaches 'master' again or other overflow occur.    'auto_gain' - automatic gain control. It will automatically lower gain       level on overload and restore it back then.    'voice_control' - (only when stereo input) enables voice control when      stereo input. Amplifies in-phase signal and route it to center       speaker if present. Only when auto_matrix = true.    'expand_stereo' - (only when stereo input) enables surround control when      stereo input. Amplifies out-of-phase signal and route it to surround       speakers if present. Only when auto_matrix = true.    calc_matrix() - calc mixing matrix complied with ac3 standart (not normalized)    normalize() - normalizes matrix so no overflow at output if no overflow at input.    reset() - reset time window, reset to 'master' to 'gain' and 'dynrng' to 1.0.*/#ifndef MIXER_H#define MIXER_H#include "TsampleFormat.h"#include "TmixerSettings.h"#include "TaudioFilter.h"#include "IffdshowDecAudio.h"class TmixerMatrix{private: static const double LEVEL_PLUS6DB,LEVEL_PLUS3DB,LEVEL_3DB,LEVEL_45DB,LEVEL_6DB; // channel numbers // used as index in arrays enum  {   CH_L        =0, // Left channel   CH_R        =1, // Right channel   CH_C        =2, // Center channel   CH_LFE      =3, // LFE channel   CH_SL       =4, // Surround left channel   CH_SR       =5, // Surround right channel   CH_NONE     =6, // indicates that channel is not used in channel order   CH_M        =2, // Mono channel = center channel   CH_S        =4  // Surround channel for x/1 modes  };protected: static const int NCHANNELS=6; // mixing matrix 6-to-6 channels TsampleFormat calc_matrix(const TsampleFormat &insf,const TmixerSettings *cfg);public:  typedef double mixer_matrix_t[NCHANNELS][NCHANNELS]; mixer_matrix_t matrix; TmixerMatrix(void);};template<class sample_t,class div_t,div_t div,div_t div2> class Mixer :public TmixerMatrix{private: typedef typename TsampleFormatInfo<sample_t>::helper_t helper_t; typedef helper_t mixer_matrix_t[NCHANNELS][NCHANNELS]; mixer_matrix_t matrix; unsigned int rows,cols; template<unsigned int colsT,unsigned int rowsT> static void mix(size_t nsamples,const sample_t *insamples,sample_t *outsamples,const mixer_matrix_t &matrix)  {   for (unsigned int nsample=0;nsample<nsamples;insamples+=rowsT,outsamples+=colsT,nsample++)    for (unsigned int i=0;i<colsT;i++)     {      helper_t sum=0;      for (unsigned int j=0;j<rowsT;j++)       sum+=(insamples[j]*matrix[j][i])/helper_t(div/div2);      outsamples[i]=TsampleFormatInfo<sample_t>::limit(sum);     }  } typedef void (*TmixFn)(size_t nsamples,const sample_t *insamples,sample_t *outsamples,const mixer_matrix_t &matrix); TmixFn mixFn; TsampleFormat calc_matrix(const TsampleFormat &insf,const TmixerSettings *cfg,const TmixerMatrix::mixer_matrix_t* *matrixPtr)  {   TsampleFormat outsf=TmixerMatrix::calc_matrix(insf,cfg);   *matrixPtr=&this->TmixerMatrix::matrix;   static const int mspeakers[]={SPEAKER_FRONT_LEFT,SPEAKER_FRONT_RIGHT,SPEAKER_FRONT_CENTER,SPEAKER_LOW_FREQUENCY,SPEAKER_BACK_LEFT|SPEAKER_BACK_CENTER,SPEAKER_BACK_RIGHT};   rows=0;   int inmask=insf.makeChannelMask(),outmask=outsf.makeChannelMask();   for (int i=0;i<NCHANNELS;i++)    if (inmask&mspeakers[i])     {      cols=0;      for (int j=0;j<NCHANNELS;j++)       if (outmask&mspeakers[j])        {         matrix[rows][cols]=helper_t(TmixerMatrix::matrix[i][j]*div/div2);         cols++;        }      rows++;     }   static const TmixFn mixFns[6][6]=    {     mix<1,1>,mix<1,2>,mix<1,3>,mix<1,4>,mix<1,5>,mix<1,6>,     mix<2,1>,mix<2,2>,mix<2,3>,mix<2,4>,mix<2,5>,mix<2,6>,     mix<3,1>,mix<3,2>,mix<3,3>,mix<3,4>,mix<3,5>,mix<3,6>,     mix<4,1>,mix<4,2>,mix<4,3>,mix<4,4>,mix<4,5>,mix<4,6>,     mix<5,1>,mix<5,2>,mix<5,3>,mix<5,4>,mix<5,5>,mix<5,6>,     mix<6,1>,mix<6,2>,mix<6,3>,mix<6,4>,mix<6,5>,mix<6,6>,    };   mixFn=mixFns[cols-1][rows-1];   return outsf;  } unsigned int oldnchannels,oldchannelmask;int oldsf; TmixerSettings oldcfg; Tbuffer buf; TsampleFormat outfmt;public: IffdshowDecAudio *deciA; Mixer(void)  {   oldnchannels=0;oldchannelmask=0xffffffff;oldsf=TsampleFormat::SF_NULL;   oldcfg.out=-1;  } void process(TsampleFormat &fmt,sample_t* &samples1,size_t &numsamples,const TmixerSettings *cfg,const TmixerMatrix::mixer_matrix_t* *matrixPtr)  {   if (oldnchannels!=fmt.nchannels || oldchannelmask!=fmt.channelmask || oldsf!=fmt.sf || !cfg->equal(oldcfg))    {     oldnchannels=fmt.nchannels;oldchannelmask=fmt.channelmask;oldsf=fmt.sf;oldcfg=*cfg;     outfmt=calc_matrix(fmt,cfg,matrixPtr);    }   TsampleFormat fmt2=fmt;   fmt2.setChannels(outfmt.nchannels,outfmt.channelmask);   sample_t *samples2=(sample_t*)TaudioFilter::alloc_buffer(fmt2,numsamples,buf);   mixFn(numsamples,samples1,samples2,matrix);   fmt=fmt2;   samples1=samples2;  }};#endif

⌨️ 快捷键说明

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