示例#1
0
int gcep(double *xw, const int flng, double *gc, const int m, const double g,
         const int itr1, const int itr2, const double d, const double e,
         const double f, const int itype)
{
   int i, j, flag = 0;
   double t, s, dd = 0.0;
   static double *x = NULL, *y, *cr, *ci, *rr, *hr, *hi, *er, *ei;
   static int size;

   if (x == NULL) {
      x = dgetmem(9 * flng);
      size = flng;

      y = x + flng;
      cr = y + flng;
      ci = cr + flng;
      rr = ci + flng;
      hr = rr + flng;
      hi = hr + flng;
      er = hi + flng;
      ei = er + flng;
   }

   if (flng > size) {
      free(x);
      x = dgetmem(9 * flng);
      size = flng;

      y = x + flng;
      cr = y + flng;
      ci = cr + flng;
      rr = ci + flng;
      hr = rr + flng;
      hi = hr + flng;
      er = hi + flng;
      ei = er + flng;
   }

   movem(xw, x, sizeof(*x), flng);

   switch (itype) {
   case 0:                     /* windowed data sequence */
      fftr(x, y, flng);
      for (i = 0; i < flng; i++) {
         x[i] = x[i] * x[i] + y[i] * y[i] + e;  /*  periodegram  */
      }
      break;
   case 1:                     /* dB */
      for (i = 0; i <= flng / 2; i++) {
         x[i] /= 20.0 / log(10.0);      /* dB -> amplitude spectrum */
         x[i] = x[i] * x[i] + e;        /* amplitude -> periodgram */
      }
      break;
   case 2:                     /* log */
      for (i = 0; i <= flng / 2; i++) {
         x[i] = exp(x[i]);      /* log -> amplitude spectrum */
         x[i] = x[i] * x[i] + e;        /* amplitude -> periodgram */
      }
      break;
   case 3:                     /* amplitude */
      for (i = 0; i <= flng / 2; i++) {
         x[i] = x[i] * x[i] + e;        /* amplitude -> periodgram */
      }
      break;
   case 4:                     /* periodgram */
      for (i = 0; i <= flng / 2; i++) {
         x[i] = x[i] + e;
      }
      break;
   default:
      fprintf(stderr, "mgcep : Input type %d is not supported!\n", itype);
      exit(1);
   }
   if (itype > 0) {
      for (i = 1; i < flng / 2; i++)
         x[flng - i] = x[i];
   }
   for (i = 0; i < flng; i++)
      cr[i] = log(x[i]);

   /*  initial value of generalized cepstrum  */
   ifftr(cr, y, flng);          /*  x : IFFT[x]  */
   cr[0] = exp(cr[0] / 2);
   gc2gc(cr, m, 0.0, gc, m, g); /*  gc : generalized cepstrum  */

   /*  Newton-Raphson method  */
   for (j = 1; j <= itr2; j++) {
      fillz(cr, sizeof(*cr), flng);
      movem(&gc[1], &cr[1], sizeof(*cr), m);
      fftr(cr, ci, flng);       /*  cr+jci : FFT[gc]  */

      for (i = 0; i < flng; i++) {
         t = x[i] / agexp(g, cr[i], ci[i]);
         cr[i] = 1 + g * cr[i];
         ci[i] = g * ci[i];
         s = cr[i] * cr[i] + ci[i] * ci[i];
         rr[i] = t / s;
         hr[i] = (cr[i] * cr[i] - ci[i] * ci[i]) * t / (s * s);
         hi[i] = 2 * cr[i] * ci[i] * t / (s * s);
         er[i] = cr[i] * t / s;
         ei[i] = ci[i] * t / s;
      }

      ifftr(rr, y, flng);       /*  rr : r(k)  */
      ifft(hr, hi, flng);       /*  hr : h(k)  */
      ifft(er, ei, flng);       /*  er : e(k)  */
      s = gc[0];                /*  gc[0] : gain  */

      for (i = 1, t = 0.0; i <= m; i++)
         t += er[i] * gc[i];

      t = er[0] + g * t;
      t = sqrt(fabs(t));

      if (j >= itr1) {
         if (fabs((t - dd) / t) < d) {
            flag = 1;
            break;
         }
         dd = t;
      }

      for (i = 2; i <= m + m; i++)
         hr[i] *= 1 + g;

      if (theq(rr, &hr[2], &y[1], &er[1], m, f)) {
         fprintf(stderr, "gcep : Error in theq() at %dth iteration!\n", j);
         exit(1);
      }

      gc[0] = t;

      for (i = 1; i <= m; i++)
         gc[i] += y[i];
   }

   if (flag)
      return (0);
   else
      return (-1);
}
示例#2
0
文件: _smcep.c 项目: rhdunn/sptk
int smcep(double *xw, const int flng, double *mc, const int m, const int fftsz,
          const double a, const double t, const int itr1, const int itr2,
          const double dd, const int etype, const double e, const double f,
          const int itype)
{
   int i, j;
   int flag = 0, f2, m2;
   double u, s, eps = 0.0, min, max;
   static double *x = NULL, *y, *c, *d, *al, *b;
   static int size_x, size_d;

   if (etype == 1 && e < 0.0) {
      fprintf(stderr, "smcep : value of e must be e>=0!\n");
      exit(1);
   }

   if (etype == 2 && e >= 0.0) {
      fprintf(stderr, "smcep : value of E must be E<0!\n");
      exit(1);
   }

   if (etype == 1) {
      eps = e;
   }


   if (x == NULL) {
      x = dgetmem(3 * flng);
      y = x + flng;
      c = y + flng;
      size_x = flng;

      d = dgetmem(3 * m + 3);
      al = d + (m + 1);
      b = al + (m + 1);
      size_d = m;
   }
   if (flng > size_x) {
      free(x);
      x = dgetmem(3 * flng);
      y = x + flng;
      c = y + flng;
      size_x = flng;
   }
   if (m > size_d) {
      free(d);
      d = dgetmem(3 * m + 3);
      al = d + (m + 1);
      b = al + (m + 1);
      size_d = m;
   }

   f2 = flng / 2.;
   m2 = m + m;

   movem(xw, x, sizeof(*x), flng);

   switch (itype) {
   case 0:                     /* windowed data sequence */
      fftr(x, y, flng);
      for (i = 0; i < flng; i++) {
         x[i] = x[i] * x[i] + y[i] * y[i] + eps;        /*  periodogram  */
      }
      break;
   case 1:                     /* dB */
      for (i = 0; i <= flng / 2; i++) {
         x[i] = exp((x[i] / 20.0) * log(10.0)); /* dB -> amplitude spectrum */
         x[i] = x[i] * x[i] + eps;      /* amplitude -> periodogram */
      }
      break;
   case 2:                     /* log */
      for (i = 0; i <= flng / 2; i++) {
         x[i] = exp(x[i]);      /* log -> amplitude spectrum */
         x[i] = x[i] * x[i] + eps;      /* amplitude -> periodogram */
      }
      break;
   case 3:                     /* amplitude */
      for (i = 0; i <= flng / 2; i++) {
         x[i] = x[i] * x[i] + eps;      /* amplitude -> periodogram */
      }
      break;
   case 4:                     /* periodogram */
      for (i = 0; i <= flng / 2; i++) {
         x[i] = x[i] + eps;
      }
      break;
   default:
      fprintf(stderr, "smcep : Input type %d is not supported!\n", itype);
      exit(1);
   }
   if (itype > 0) {
      for (i = 1; i < flng / 2; i++)
         x[flng - i] = x[i];
   }

   if (etype == 2 && e < 0.0) {
      max = x[0];
      for (i = 1; i < flng; i++) {
         if (max < x[i])
            max = x[i];
      }
      max = sqrt(max);
      min = max * pow(10.0, e / 20.0);  /* floor is 20*log10(min/max) */
      min = min * min;
      for (i = 0; i < flng; i++) {
         if (x[i] < min)
            x[i] = min;
      }
   }

   for (i = 0; i < flng; i++)
      c[i] = log(x[i]);

   /*  1, (-a), (-a)^2, ..., (-a)^M  */

   al[0] = 1.0;
   for (i = 1; i <= m; i++)
      al[i] = 0.0;

   frqt_a(al, m, fftsz, a, t);


   /*  initial value of cepstrum  */
   ifftr(c, y, flng);           /*  c : IFFT[x]  */

   c[0] /= 2.0;
   c[flng / 2] /= 2.0;
   freqt2(c, f2, mc, m, fftsz, a, t);   /*  mc : mel cep.  */

   s = c[0];

   /*  Newton Raphson method  */
   for (j = 1; j <= itr2; j++) {
      fillz(c, sizeof(*c), flng);
      ifreqt2(mc, m, c, f2, fftsz, a, t);       /*  mc : mel cep.  */

      fftr(c, y, flng);         /*  c, y : FFT[mc]  */
      for (i = 0; i < flng; i++)
         c[i] = x[i] / exp(c[i] + c[i]);
      ifftr(c, y, flng);
      frqtr2(c, f2, c, m2, fftsz, a, t);        /*  c : r(k)  */

      u = c[0];
      if (j >= itr1) {
         if (fabs((u - s) / u) < dd) {
            flag = 1;
            break;
         }
         s = u;
      }

      for (i = 0; i <= m; i++)
         b[i] = c[i] - al[i];
      for (i = 0; i <= m2; i++)
         y[i] = c[i];
      for (i = 0; i <= m2; i += 2)
         y[i] -= c[0];
      for (i = 2; i <= m; i += 2)
         c[i] += c[0];
      c[0] += c[0];

      if (theq(c, y, d, b, m + 1, f)) {
         fprintf(stderr, "smcep : Error in theq() at %dth iteration!\n", j);
         exit(1);
      }

      for (i = 0; i <= m; i++)
         mc[i] += d[i];
   }

   if (flag)
      return (0);
   else
      return (-1);
}