Advertisement
Guest User

Untitled

a guest
Aug 30th, 2015
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.86 KB | None | 0 0
  1.  
  2. static void MatrixDecode(const float *in, const int k, const int il,
  3.     const int ir, bool decode_rear,
  4.     const int _dlbuflen,
  5.     float _l_fwr, float _r_fwr,
  6.     float _lpr_fwr, float _lmr_fwr,
  7.     float *_adapt_l_gain, float *_adapt_r_gain,
  8.     float *_adapt_lpr_gain, float *_adapt_lmr_gain,
  9.     float *_lf, float *_rf, float *_lr,
  10.     float *_rr, float *_cf)
  11. {
  12.     static const float M9_03DB = 0.3535533906f;
  13.     static const float MATAGCTRIG = 8.0f;   /* (Fuzzy) AGC trigger */
  14.     static const float MATAGCDECAY = 1.0f;  /* AGC baseline decay rate (1/samp.) */
  15.     static const float MATCOMPGAIN = 0.37f; /* Cross talk compensation gain,  0.50 - 0.55 is full cancellation. */
  16.  
  17.     const int kr = (k + olddelay) % _dlbuflen;
  18.     float l_gain = (_l_fwr + _r_fwr) / (1 + _l_fwr + _l_fwr);
  19.     float r_gain = (_l_fwr + _r_fwr) / (1 + _r_fwr + _r_fwr);
  20.     // The 2nd axis has strong gain fluctuations, and therefore require
  21.     // limits.  The factor corresponds to the 1 / amplification of (Lt
  22.     // - Rt) when (Lt, Rt) is strongly correlated. (e.g. during
  23.     // dialogues).  It should be bigger than -12 dB to prevent
  24.     // distortion.
  25.     float lmr_lim_fwr = _lmr_fwr > M9_03DB * _lpr_fwr ? _lmr_fwr : M9_03DB * _lpr_fwr;
  26.     float lpr_gain = (_lpr_fwr + lmr_lim_fwr) / (1 + _lpr_fwr + _lpr_fwr);
  27.     float lmr_gain = (_lpr_fwr + lmr_lim_fwr) / (1 + lmr_lim_fwr + lmr_lim_fwr);
  28.     float lmr_unlim_gain = (_lpr_fwr + _lmr_fwr) / (1 + _lmr_fwr + _lmr_fwr);
  29.     float lpr, lmr;
  30.     float l_agc, r_agc, lpr_agc, lmr_agc;
  31.     float f, d_gain, c_gain, c_agc_cfk;
  32.  
  33.     /*** AXIS NO. 1: (Lt, Rt) -> (C, Ls, Rs) ***/
  34.     /* AGC adaption */
  35.     d_gain = (fabs(l_gain - *_adapt_l_gain) + fabs(r_gain - *_adapt_r_gain)) * 0.5f;
  36.     f = d_gain * (1.0f / MATAGCTRIG);
  37.     f = MATAGCDECAY - MATAGCDECAY / (1 + f * f);
  38.     *_adapt_l_gain = (1 - f) * *_adapt_l_gain + f * l_gain;
  39.     *_adapt_r_gain = (1 - f) * *_adapt_r_gain + f * r_gain;
  40.     /* Matrix */
  41.     l_agc = in[il] * PassiveLock(*_adapt_l_gain);
  42.     r_agc = in[ir] * PassiveLock(*_adapt_r_gain);
  43.     _cf[k] = (l_agc + r_agc) * (float)M_SQRT1_2;
  44.     if (decode_rear)
  45.     {
  46.         _lr[kr] = _rr[kr] = (l_agc - r_agc) * (float)M_SQRT1_2;
  47.         // Stereo rear channel is steered with the same AGC steering as
  48.         // the decoding matrix. Note this requires a fast updating AGC
  49.         // at the order of 20 ms (which is the case here).
  50.         _lr[kr] *= (_l_fwr + _l_fwr) / (1 + _l_fwr + _r_fwr);
  51.         _rr[kr] *= (_r_fwr + _r_fwr) / (1 + _l_fwr + _r_fwr);
  52.     }
  53.  
  54.     /*** AXIS NO. 2: (Lt + Rt, Lt - Rt) -> (L, R) ***/
  55.     lpr = (in[il] + in[ir]) * (float)M_SQRT1_2;
  56.     lmr = (in[il] - in[ir]) * (float)M_SQRT1_2;
  57.     /* AGC adaption */
  58.     d_gain = fabs(lmr_unlim_gain - *_adapt_lmr_gain);
  59.     f = d_gain * (1.0f / MATAGCTRIG);
  60.     f = MATAGCDECAY - MATAGCDECAY / (1 + f * f);
  61.     *_adapt_lpr_gain = (1 - f) * *_adapt_lpr_gain + f * lpr_gain;
  62.     *_adapt_lmr_gain = (1 - f) * *_adapt_lmr_gain + f * lmr_gain;
  63.     /* Matrix */
  64.     lpr_agc = lpr * PassiveLock(*_adapt_lpr_gain);
  65.     lmr_agc = lmr * PassiveLock(*_adapt_lmr_gain);
  66.     _lf[k] = (lpr_agc + lmr_agc) * (float)M_SQRT1_2;
  67.     _rf[k] = (lpr_agc - lmr_agc) * (float)M_SQRT1_2;
  68.  
  69.     /*** CENTER FRONT CANCELLATION ***/
  70.     // A heuristic approach exploits that Lt + Rt gain contains the
  71.     // information about Lt, Rt correlation.  This effectively reshapes
  72.     // the front and rear "cones" to concentrate Lt + Rt to C and
  73.     // introduce Lt - Rt in L, R.
  74.     /* 0.67677 is the empirical lower bound for lpr_gain. */
  75.     c_gain = 8 * (*_adapt_lpr_gain - 0.67677f);
  76.     c_gain = c_gain > 0 ? c_gain : 0;
  77.     // c_gain should not be too high, not even reaching full
  78.     // cancellation (~ 0.50 - 0.55 at current AGC implementation), or
  79.     // the center will sound too narrow. */
  80.     c_gain = MATCOMPGAIN / (1 + c_gain * c_gain);
  81.     c_agc_cfk = c_gain * _cf[k];
  82.     _lf[k] -= c_agc_cfk;
  83.     _rf[k] -= c_agc_cfk;
  84.     _cf[k] += c_agc_cfk + c_agc_cfk;
  85. }
  86.  
  87. void DPL2Decode(float *samples, int numsamples, float *out)
  88. {
  89.     static const unsigned int FWRDURATION = 240; // FWR average duration (samples)
  90.     static const int cfg_delay = 0;
  91.     static const unsigned int fmt_freq = 48000;
  92.     static const unsigned int fmt_nchannels = 2; // input channels
  93.  
  94.     int cur = 0;
  95.  
  96.     if (olddelay != cfg_delay || oldfreq != fmt_freq)
  97.     {
  98.         Done();
  99.         olddelay = cfg_delay;
  100.         oldfreq = fmt_freq;
  101.         dlbuflen = std::max(FWRDURATION, (fmt_freq * cfg_delay / 1000)); //+(len7000-1);
  102.         cyc_pos = dlbuflen - 1;
  103.         fwrbuf_l.resize(dlbuflen);
  104.         fwrbuf_r.resize(dlbuflen);
  105.         lf.resize(dlbuflen);
  106.         rf.resize(dlbuflen);
  107.         lr.resize(dlbuflen);
  108.         rr.resize(dlbuflen);
  109.         cf.resize(dlbuflen);
  110.         cr.resize(dlbuflen);
  111.         filter_coefs_lfe = CalculateCoefficients125HzLowpass(fmt_freq);
  112.         lfe_pos = 0;
  113.         memset(LFE_buf, 0, sizeof(LFE_buf));
  114.     }
  115.  
  116.     float *in = samples; // Input audio data
  117.     float *end = in + numsamples * fmt_nchannels; // Loop end
  118.  
  119.     while (in < end)
  120.     {
  121.         const int k = cyc_pos;
  122.  
  123.         const int fwr_pos = (k + FWRDURATION) % dlbuflen;
  124.         /* Update the full wave rectified total amplitude */
  125.         /* Input matrix decoder */
  126.         l_fwr += fabs(in[0]) - fabs(fwrbuf_l[fwr_pos]);
  127.         r_fwr += fabs(in[1]) - fabs(fwrbuf_r[fwr_pos]);
  128.         lpr_fwr += fabs(in[0] + in[1]) - fabs(fwrbuf_l[fwr_pos] + fwrbuf_r[fwr_pos]);
  129.         lmr_fwr += fabs(in[0] - in[1]) - fabs(fwrbuf_l[fwr_pos] - fwrbuf_r[fwr_pos]);
  130.  
  131.         /* Matrix encoded 2 channel sources */
  132.         fwrbuf_l[k] = in[0];
  133.         fwrbuf_r[k] = in[1];
  134.         MatrixDecode(in, k, 0, 1, true, dlbuflen,
  135.             l_fwr, r_fwr,
  136.             lpr_fwr, lmr_fwr,
  137.             &adapt_l_gain, &adapt_r_gain,
  138.             &adapt_lpr_gain, &adapt_lmr_gain,
  139.             &lf[0], &rf[0], &lr[0], &rr[0], &cf[0]);
  140.  
  141.         out[cur + 0] = lf[k];
  142.         out[cur + 1] = rf[k];
  143.         out[cur + 2] = cf[k];
  144.         LFE_buf[lfe_pos] = (lf[k] + rf[k] + 2.0f * cf[k] + lr[k] + rr[k]) / 2.0f;
  145.         out[cur + 3] = FIRFilter(LFE_buf, lfe_pos, len125, len125, filter_coefs_lfe);
  146.         lfe_pos++;
  147.         if (lfe_pos == len125)
  148.         {
  149.             lfe_pos = 0;
  150.         }
  151.         out[cur + 4] = lr[k];
  152.         out[cur + 5] = rr[k];
  153.         // Next sample...
  154.         in += 2;
  155.         cur += 6;
  156.         cyc_pos--;
  157.         if (cyc_pos < 0)
  158.         {
  159.             cyc_pos += dlbuflen;
  160.         }
  161.     }
  162. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement