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

📄 mixer.cpp.svn-base

📁 ffshow源码
💻 SVN-BASE
字号:
#include "stdafx.h"#include "mixer.h"const double TmixerMatrix::LEVEL_PLUS6DB=2.0;const double TmixerMatrix::LEVEL_PLUS3DB=1.4142135623730951;const double TmixerMatrix::LEVEL_3DB    =0.7071067811865476;const double TmixerMatrix::LEVEL_45DB   =0.5946035575013605;const double TmixerMatrix::LEVEL_6DB    =0.5;TmixerMatrix::TmixerMatrix(void){ for (int i=0;i<NCHANNELS;i++)  for (int j=0;j<NCHANNELS;j++)    matrix[i][j]=0;}TsampleFormat TmixerMatrix::calc_matrix(const TsampleFormat &infmt,const TmixerSettings *cfg){ TsampleFormat outfmt=infmt; cfg->setFormatOut(outfmt,infmt); int in_ch      = infmt.makeChannelMask(); int out_ch     = outfmt.makeChannelMask(); int in_nfront  = infmt.nfront(); int in_nrear   = infmt.nrear(); int out_nfront = outfmt.nfront(); int out_nrear  = outfmt.nrear(); double clev=cfg->clev/100.0;             // central mix level double slev=cfg->slev/100.0;             // surround mix level double lfelev=cfg->lfelev/100.0;         // lfe mix level if (cfg->customMatrix)  for (int i=0;i<6;i++)   for (int j=0;j<6;j++)    matrix[i][j]=((int (*)[6])&cfg->matrix00)[i][j]/100000.0; else  {   memset(&matrix, 0, sizeof(mixer_matrix_t));   if (infmt.dolby & outfmt.dolby) // Dolby modes are backwards-compatible    {     matrix[CH_L][CH_L] = 1;     matrix[CH_R][CH_R] = 1;    }   else if (outfmt.dolby) // Downmix to Dolby Surround/ProLogic/ProLogicII    {     if (in_nfront >= 2)      {       matrix[CH_L][CH_L] = 1;       matrix[CH_R][CH_R] = 1;      }     if (in_nfront != 2)      {       matrix[CH_C][CH_L] = 0.7071 * clev;       matrix[CH_C][CH_R] = 0.7071 * clev;      }     if (in_nrear == 1)      {       matrix[CH_S][CH_L] = -0.7071 * slev;       matrix[CH_S][CH_R] = +0.7071 * slev;      }     else if (in_nrear == 2)      {       switch (outfmt.dolby)        {          case TsampleFormat::DOLBY_PROLOGICII:          matrix[CH_SL][CH_L] = -0.8660*slev;          matrix[CH_SR][CH_L] = -0.5000*slev;          matrix[CH_SL][CH_R] = +0.5000*slev;          matrix[CH_SR][CH_R] = +0.8660*slev;          break;         case TsampleFormat::DOLBY_SURROUND:         case TsampleFormat::DOLBY_PROLOGIC:         default:          matrix[CH_SL][CH_L] = -slev;          matrix[CH_SR][CH_L] = -slev;          matrix[CH_SL][CH_R] = +slev;          matrix[CH_SR][CH_R] = +slev;          break;        }      }    }   else // A/52 standart mixes    {     // direct route equal channels     if (in_ch & out_ch & SPEAKER_FRONT_LEFT)   matrix[CH_L ][CH_L ]=1.0;     if (in_ch & out_ch & SPEAKER_FRONT_RIGHT)  matrix[CH_R ][CH_R ]=1.0;     if (in_ch & out_ch & SPEAKER_FRONT_CENTER) matrix[CH_C ][CH_C ]=clev;     if (in_ch & out_ch & SPEAKER_BACK_LEFT)    matrix[CH_SL][CH_SL]=slev;     if (in_ch & out_ch & SPEAKER_BACK_RIGHT)   matrix[CH_SR][CH_SR]=slev;     // calc matrix for fbw channels     if (out_nfront == 1)      {       if (in_nfront != 1)        {         matrix[CH_L][CH_M]=LEVEL_3DB;         matrix[CH_R][CH_M]=LEVEL_3DB;        }       if (in_nfront == 3)        {         matrix[CH_C][CH_M] = clev * LEVEL_PLUS3DB;        }       if (in_nrear == 1)        {         matrix[CH_S][CH_M] = slev * LEVEL_3DB;        }       else        {         matrix[CH_SL][CH_M] = slev * LEVEL_3DB;         matrix[CH_SR][CH_M] = slev * LEVEL_3DB;        }      }     else // not mono modes      {       if (out_nfront == 2)        {         if (in_nfront == 1)          {           matrix[CH_M][CH_L] = LEVEL_3DB;           matrix[CH_M][CH_R] = LEVEL_3DB;          }         else if (in_nfront == 3)          {           matrix[CH_C][CH_L] = clev;           matrix[CH_C][CH_R] = clev;          }        }       if (in_nrear == 1)        {         if (out_nrear == 0)          {           matrix[CH_S][CH_L] = slev * LEVEL_3DB;           matrix[CH_S][CH_R] = slev * LEVEL_3DB;          }         else if (out_nrear == 2)          {           matrix[CH_S][CH_SL] = slev * LEVEL_3DB;           matrix[CH_S][CH_SR] = slev * LEVEL_3DB;          }        }       else if (in_nrear == 2)        {         if (out_nrear == 0)          {           matrix[CH_SL][CH_L] = slev;           matrix[CH_SR][CH_R] = slev;          }                  else if (out_nrear == 1)          {           matrix[CH_SL][CH_S] = slev * LEVEL_3DB;           matrix[CH_SR][CH_S] = slev * LEVEL_3DB;          }        }      }    }   // Expand stereo & Voice control   bool expand_stereo_allowed = cfg->expandStereo && !in_nrear;   bool voice_control_allowed = cfg->voiceControl && (in_nfront == 2);   if ((voice_control_allowed || expand_stereo_allowed) && !outfmt.dolby)    {     if (voice_control_allowed && out_nfront != 2)      {       // C' = clev * (L + R) * LEVEL_3DB       matrix[CH_L][CH_M] = clev * LEVEL_3DB;       matrix[CH_R][CH_M] = clev * LEVEL_3DB;      }          if (expand_stereo_allowed && in_nfront == 2 && out_nrear)      {       if (out_nrear == 1)        {         // S' = slev * (L - R)         matrix[CH_L][CH_S] = + slev;         matrix[CH_R][CH_S] = - slev;        }       if (out_nrear == 2)        {         // SL' = slev * 1/2 (L - R)         // SR' = slev * 1/2 (R - L)         matrix[CH_L][CH_SL] = + 0.5 * slev;         matrix[CH_R][CH_SL] = - 0.5 * slev;         matrix[CH_L][CH_SR] = - 0.5 * slev;         matrix[CH_R][CH_SR] = + 0.5 * slev;        }      }     if (in_nfront != 1)      {       if (expand_stereo_allowed && voice_control_allowed)        {         // L' = L * 1/2 (slev + clev) - R * 1/2 (slev - clev)         // R' = R * 1/2 (slev + clev) - L * 1/2 (slev - clev)         matrix[CH_L][CH_L] = + 0.5 * (slev + clev);         matrix[CH_R][CH_L] = - 0.5 * (slev - clev);         matrix[CH_L][CH_R] = - 0.5 * (slev - clev);         matrix[CH_R][CH_R] = + 0.5 * (slev + clev);        }       else if (expand_stereo_allowed)        {         matrix[CH_L][CH_L] = + 0.5 * (slev + 1);         matrix[CH_R][CH_L] = - 0.5 * (slev - 1);         matrix[CH_L][CH_R] = - 0.5 * (slev - 1);         matrix[CH_R][CH_R] = + 0.5 * (slev + 1);        }       else // if (voice_control_allowed)        {         matrix[CH_L][CH_L] = + 0.5 * (1 + clev);         matrix[CH_R][CH_L] = - 0.5 * (1 - clev);         matrix[CH_L][CH_R] = - 0.5 * (1 - clev);         matrix[CH_R][CH_R] = + 0.5 * (1 + clev);        }      }    }   // LFE mixing   if (in_ch & out_ch & SPEAKER_LOW_FREQUENCY)     matrix[CH_LFE][CH_LFE] = lfelev;   // mix LFE into front channels if exists in input   // and absent in output   if (in_ch & ~out_ch & SPEAKER_LOW_FREQUENCY)    {     if (out_nfront > 1)      {       matrix[CH_LFE][CH_L]  = lfelev;       matrix[CH_LFE][CH_R]  = lfelev;      }     else      matrix[CH_LFE][CH_C]  = lfelev;    }  }    if (cfg->normalizeMatrix)  {   double levels[NCHANNELS] = { 0, 0, 0, 0, 0, 0 };   double max_level;   double norm;   int i, j;   for (i = 0; i < NCHANNELS; i++)    for (j = 0; j < NCHANNELS; j++)     levels[i] += matrix[j][i];   max_level = levels[0];   for (i = 1; i < NCHANNELS; i++)    if (levels[i] > max_level)      max_level = levels[i];   if (max_level > 0)    norm = 1.0/max_level;   else    norm = 1.0;   for (i = 0; i < NCHANNELS; i++)    for (j = 0; j < NCHANNELS; j++)     matrix[j][i] *= norm;  }   for (int i = 0; i < NCHANNELS; i++)  for (int j = 0; j < NCHANNELS; j++)   matrix[j][i] = limit(matrix[j][i],-4.0,4.0); return outfmt;}

⌨️ 快捷键说明

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