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

📄 mixer.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
字号:
#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 + -