예제 #1
0
파일: process.c 프로젝트: rtdsp/dsk6713
void cc(float *y,float *H)
{
    // Complete el código 

	fftr(y, NFFT, 1);		//  FFT directa
    // Complete el código 

    fftr(y, NFFT, -1);		//  FFT inversa

}
예제 #2
0
파일: _fftcep.c 프로젝트: rhdunn/sptk
void fftcep(double *sp, const int flng, double *c, const int m, int itr,
            double ac)
{
   double temp;
   static double *x = NULL, *y;
   static double size;
   int k;

   if (x == NULL) {
      x = dgetmem(flng + flng);
      y = x + flng;
   }
   if (flng > size) {
      free(x);
      x = dgetmem(flng + flng);
      y = x + flng;
      size = flng;
   }

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

   fftr(x, y, flng);
   for (k = 0; k < flng; k++)
      x[k] /= flng;
   for (k = 0; k <= m; k++) {
      c[k] = x[k];
      x[k] = 0;
   }

   ac += 1.0;
   while (--itr > 0) {
      for (k = 1; k <= m; k++)
         x[flng - k] = x[k];

      fftr(x, y, flng);

      for (k = 0; k < flng; k++)
         if (x[k] < 0.0)
            x[k] = 0.0;
         else
            x[k] /= flng;

      fftr(x, y, flng);

      for (k = 0; k <= m; k++) {
         temp = x[k] * ac;
         c[k] += temp;
         x[k] -= temp;
      }
   }
   c[0] *= 0.5;

   if (m == flng / 2)
      c[m] *= 0.5;
}
예제 #3
0
void phase(double *p, const int mp, double *z, const int mz, double *ph,
           const int flng, const int unlap)
{
   static double *x;
   static int fsize = 0;
   double *y, *xx, *yy, *py;
   int no, i, offset;
   double pi;

   pi = atan(1.) * 4.;

   no = flng / 2 + 1;

   if (flng > fsize) {
      if (x != NULL)
         free(x);
      fsize = flng;
      x = dgetmem(4 * flng + no);
   }
   y = &x[flng];
   xx = &y[flng];
   yy = &xx[flng];
   py = &yy[flng];

   fillz(x, sizeof(*x), flng);
   fillz(xx, sizeof(*xx), flng);
   movem(z, x, mz + 1, sizeof(*z));
   movem(p, xx, mp + 1, sizeof(*p));

   fftr(x, y, flng);
   xx[0] = 1;
   fftr(xx, yy, flng);
   for (i = 0; i < no; i++) {
      ph[i] = x[i] * xx[i] + y[i] * yy[i];
      py[i] = y[i] * xx[i] - x[i] * yy[i];
   }
   offset = 0;
   i = 0;
   ph[i] = atan2(py[i], ph[i]) / pi;
   i++;
   for (; i < no; i++) {
      ph[i] = atan2(py[i], ph[i]) / pi;
      if (unlap) {
         if (ph[i - 1] - ph[i] - offset > 1)
            offset += 2;
         else if (ph[i] + offset - ph[i - 1] > 1)
            offset -= 2;
         ph[i] += offset;
      }
   }

   return;
}
예제 #4
0
파일: _c2sp.c 프로젝트: delfvad/speech-apps
void c2sp(double *c, const int m, double *x, double *y, const int l)
{
   int m1;

   m1 = m + 1;

   movem(c, x, sizeof(*c), m1);
   fillz(x + m1, sizeof(*x), l - m1);

   fftr(x, y, l);
}
예제 #5
0
void grpdelay(double *x, double *gd, const int size, const int is_arma)
{
   static double *y;
   static int fsize;

   double *u, *v;
   int k, size_2;

   if (fsize < size) {
      if (y != NULL)
         free(y);
      fsize = size;
      y = dgetmem(3 * size);
   }
   movem(x, gd, sizeof(*x), size);
   u = y + size;
   v = u + size;

   size_2 = size / 2;

   if (is_arma)
      gd[0] = 1;
   for (k = 0; k < size; ++k)
      u[k] = gd[k] * k;

   fftr(gd, y, size);
   fftr(u, v, size);

   for (k = 0; k <= size_2; k++) {
      gd[k] = (gd[k] * u[k] + y[k] * v[k]) / (gd[k] * gd[k] + y[k] * y[k]);
      if (is_arma)
         gd[k] *= -1;
   }

   return;
}
예제 #6
0
파일: process.c 프로젝트: rtdsp/dsk6713
void init_process()		// Filtrado FIR con coeficientes obtenidos en MATLAB
{

// Pegue entre corchetes en la definición de hh la lista de los coeficientes 
//obtenidos con MATLAB

	float hh[]={0};
    int n;

    for (n=0; n<L_FIR; n++)
		h[n] = hh[n];
	for (; n<NFFT; n++)
		h[n] = 0.0;
	fftr(h, NFFT, 1);

}
예제 #7
0
int ifftr(double *x, double *y, const int l)
{
   int i;
   double *xp, *yp;

   fftr(x, y, l);

   xp = x;
   yp = y;
   i = l;
   while (i--) {
      *xp++ /= l;
      *yp++ /= -l;
   }

   return (0);
}
예제 #8
0
파일: _c2ndps.c 프로젝트: rhdunn/sptk
void c2ndps(double *c, const int m, double *n, const int l)
{
   int i;
   double *tmp;

   fillz(n, sizeof(*n), l);
   tmp = dgetmem(l);

   // generate mc(m)
   for (i = 1; i < m + 1; i++) {
      n[i] = c[i] * i / 2.0;
      n[l - i] = n[i];
   }

   fftr(n, tmp, l);

   free(tmp);
}
예제 #9
0
파일: analisint.c 프로젝트: rtdsp/dsk6713
void analisi(float *io_data, float *blockIn, float *x, NRstruct *nr)
{

// Suposa que cada bloc de processament (tram) conté dos blocs de dades.
// Usa el vector auxiliar blockIn.
// Posa a x la transformada de Fourier del tram de senyal.

  int n;
  
  for(n=0;n<IO_N;n++)
  	blockIn[n+IO_N] = io_data[n]; // Posa el bloc actual al final de blockIn
  
  for(n=0;n<N;n++)
	x[n] = blockIn[n]*(nr->w[n]); // Multiplica el tram que s'analitza per la finestra

  fftr(x,N,1);		//  FFT directa
 
  for(n=0;n<IO_N;n++)
	blockIn[n] = blockIn[n+IO_N]; // Posa el bloc actual al principi de blockIn per a la iteració següent
}
예제 #10
0
파일: analisint.c 프로젝트: rtdsp/dsk6713
void sintesi(float *io_data, float *blockOut, float *x)
{

// Suposa que cada bloc de processament (tram) conté dos blocs de dades. 
// Usa el vector auxiliar blockOut.
// Rep a través de x la transformada de Fourier del tram de senyal modificat.

  int n;

  fftr(x, N, -1);		//  FFT inversa

  for(n=0;n<N;n++)
  	blockOut[n]+=x[n]; // Acumula el tram actual amb la part solapada de l'anterior
  
  for (n=0;n<IO_N;n++) 
  	io_data[n] = blockOut[n]; // Passa a la sortida D/A el bloc resultant de l'acumulació

//Prepara blockOut per a la iteració següent

/*************************************************************************/
/*** ESCRIURE CODI ***/
/*************************************************************************/

}
예제 #11
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);
}
예제 #12
0
파일: fftr.c 프로젝트: delfvad/speech-apps
int main(int argc, char *argv[])
{
   FILE *fp;
   char *s, *infile = NULL, c;
   int size = SIZE, nout = 0, k, nd = -1, out = ' ';
   double *x, *y;

   if ((cmnd = strrchr(argv[0], '/')) == NULL)
      cmnd = argv[0];
   else
      cmnd++;
   while (--argc) {
      if (*(s = *++argv) == '-') {
         c = *++s;
         if ((c == 'l' || c == 'm') && (*++s == '\0')) {
            s = *++argv;
            --argc;
         }
         switch (c) {
         case 'l':
            size = atoi(s);
            break;
         case 'm':
            nd = atoi(s) + 1;
            break;
         case 'H':
            nout = 1;
            break;
         case 'i':
         case 'p':
         case 'r':
            c -= ('a' - 'A');
         case 'A':
         case 'I':
         case 'P':
         case 'R':
            out = c;
            break;
         case 'h':
            usage(0);
         default:
            fprintf(stderr, "%s : Invalid option '%c'!\n", cmnd, c);
            usage(1);
         }
      } else
         infile = s;
   }

   if (nd == -1)
      nd = size;
   if (nd > size) {
      fprintf(stderr,
              "%s : Order of sequence %d should be less than the FFT size %d!\n",
              cmnd, nd, size);
      return (1);
   }

   nout = (nout) ? size / 2 + 1 : size;

   fp = stdin;

   if (infile) {
      fp = getfp(infile, "rb");
   }

   x = dgetmem(size + size);
   y = x + size;

   while (!feof(fp)) {
      fillz(x, size, sizeof(*x));
      if (freadf(x, sizeof(*x), nd, fp) == 0)
         break;
      fftr(x, y, size);
      if (out == 'P')
         for (k = 0; k < size; k++)
            x[k] = x[k] * x[k] + y[k] * y[k];
      else if (out == 'A')
         for (k = 0; k < size; k++)
            x[k] = sqrt(x[k] * x[k] + y[k] * y[k]);
      if (out != 'I')
         fwritef(x, sizeof(*x), nout, stdout);
      if (out == ' ' || out == 'I')
         fwritef(y, sizeof(*y), nout, stdout);
   }

   if (infile) {
      fclose(fp);
   }

   return (0);
}
예제 #13
0
double mlsacheck(double *in, double *out, int m, int fftlen,
                 double a, double r, int c)
{
   int i;
   double gain, *x, *y, *mag = NULL, max = 0.0;

   x = dgetmem(fftlen);
   y = dgetmem(fftlen);

   fillz(x, sizeof(*x), fftlen);
   fillz(y, sizeof(*y), fftlen);

   /* calculate gain factor */
   for (i = 0, gain = 0.0; i <= m; i++) {
      x[i] = in[i];
      gain += x[i] * pow(-a, i);
   }

   /* gain normalization */
   x[0] -= gain;

   /* check stability */
   if (c != 1 && c != 4) {      /* usual mode */
      mag = dgetmem(fftlen);
      fillz(mag, sizeof(*mag), fftlen);
      fftr(x, y, fftlen);
      for (i = 0; i < fftlen; i++) {
         mag[i] = sqrt(x[i] * x[i] + y[i] * y[i]);
         if (mag[i] > max)
            max = mag[i];
      }
   } else {                     /* fast mode */
      for (i = 0; i <= m; i++)
         max += x[i];
   }

   /* modify MLSA filter coefficients */
   if (c == 0 || c == 1 || max <= r) {
      memcpy(out, in, sizeof(*out) * (m + 1));
   } else {
      if (c == 2) {             /* clipping */
         for (i = 0; i < fftlen; i++) {
            if (mag[i] > r) {
               x[i] *= r / mag[i];
               y[i] *= r / mag[i];
            }
         }
         ifft(x, y, fftlen);
         x[0] += gain;
         memcpy(out, x, sizeof(*out) * (m + 1));
      } else if (c == 3) {      /* scaling */
         for (i = 0; i < fftlen; i++) {
            x[i] *= r / max;
            y[i] *= r / max;
         }
         ifft(x, y, fftlen);
         x[0] += gain;
         memcpy(out, x, sizeof(*out) * (m + 1));
      } else if (c == 4) {      /* fast mode */
         for (i = 0; i <= m; i++)
            x[i] *= r / max;
         x[0] += gain;
         memcpy(out, x, sizeof(*out) * (m + 1));
      }
   }

   free(x);
   free(y);
   if (c != 1 && c != 4) {
      free(mag);
   }

   return max;
}
예제 #14
0
double * mlsacheck(double *mcep, int m, int fftlen, int frame,
               double a, double R1, double R2,
               int modify_filter, int stable_condition)
{
	int i;
	double K, r, *x, *y, *mag;
	
	x = dgetmem(fftlen);
	y = dgetmem(fftlen);
	mag = dgetmem(fftlen / 2);
	
	for (i = 0; i < fftlen; i++) 
	{
		x[i] = 0;
		y[i] = 0;
	}
	
	for (i = 0; i < m + 1; i++) 
		x[i] = mcep[i];
	
	/* calculate gain factor */
	for (i = 0, K = 0.0; i < m + 1; i++) 
		K += x[i] * pow(a, i);
	
	/* gain normalization */
	x[0] -= K;
	
	fftr(x, y, fftlen);
	
	/* check stability */
	for (i = 0; i < fftlen / 2; i++) 
	{
		mag[i] = x[i] * x[i] + y[i] * y[i];
		mag[i] = sqrt(mag[i]);
		
		if (mag[i] > R1 || mag[i] > R2)  /* unstable */
		{
			/* output ascii report */
		//	fprintf(stderr, "[ unstable frame number : %d ]\n", frame);
		
		//	for (i = 0; i < m + 1; i++) 
		//		fprintf(stderr, "%f\n", mcep[i]);
			
			if (modify_filter == TR)    /* -c option */
			{
				switch (stable_condition)  /* -r option */
				{
					case STABLE1:
						
						if (mag[i] > R1) 
						{
							r = R1 / mag[i];
							x[i] *= r;
							y[i] *= r;
							x[fftlen - 1 - i] *= r;
							y[fftlen - 1 - i] *= r;
						}
						break;
						
					case STABLE2:
						
						if (mag[i] > R2) 
						{
							r = R2 / mag[i];
							x[i] *= r;
							y[i] *= r;
							x[fftlen - 1 - i] *= r;
							y[fftlen - 1 - i] *= r;
						}
				}
			}
		}
	}
	
	ifft(x, y, fftlen);
	
	/* revert gain factor */
	x[0] += K;
	
	for (i = 0; i < m + 1; i++) 
		mcep[i] = x[i];

	// fwrite(x, sizeof(*x), m + 1, stdout);
	
	//free(x);
	free(y);
	free(mag);
	
	return( x );
}
예제 #15
0
파일: LMS.c 프로젝트: Climberirw/audiotools
void WaveInData(WPARAM wParam, LPARAM lParam)
{
    enum
    {FREQ_TIME    = 64,
     DISPLAY_TIME = 16,
     SPECTRUM_TIME = 4};

    // Create buffers for processing the audio data

    static double buffer[SAMPLES];
    static complex x[SAMPLES];

    static double xa[RANGE];
    static double xp[RANGE];
    static double xf[RANGE];

    static double fps = (double)SAMPLE_RATE / (double)SAMPLES;
    static double expect = 2.0 * M_PI * (double)STEP / (double)SAMPLES;

    // Initialise data structs

    if (spectrum.data == NULL)
    {
	spectrum.data = xa;
	spectrum.length = RANGE;
    }

    // Copy the input data

    memmove(buffer, buffer + STEP, (SAMPLES - STEP) * sizeof(double));

    short *data = (short *)((WAVEHDR *)lParam)->lpData;

    for (int i = 0; i < STEP; i++)
	buffer[SAMPLES - STEP + i] = (double)data[i];

    // Give the buffer back

    waveInAddBuffer(audio.hwi, (WAVEHDR *)lParam, sizeof(WAVEHDR));

    // Maximum data value

    static double dmax;

    if (dmax < 4096.0)
	dmax = 4096.0;

    // Calculate normalising value

    double norm = dmax;
    dmax = 0.0;

    // Copy data to FFT input arrays

    for (int i = 0; i < SAMPLES; i++)
    {
	// Find the magnitude

	if (dmax < fabs(buffer[i]))
	    dmax = fabs(buffer[i]);

	// Calculate the window

	double window =
	    0.5 - 0.5 * cos(2.0 * M_PI *
			    i / SAMPLES);

	// Normalise and window the input data

	x[i].r = (double)buffer[i] / norm * window;
    }

    // do FFT

    fftr(x, SAMPLES);

    // Process FFT output

    for (int i = 1; i < RANGE; i++)
    {
	double real = x[i].r;
	double imag = x[i].i;

	xa[i] = hypot(real, imag);

	// Do frequency calculation

	double p = atan2(imag, real);
	double dp = xp[i] - p;
	xp[i] = p;

	// Calculate phase difference

	dp -= (double)i * expect;

	int qpd = dp / M_PI;

	if (qpd >= 0)
	    qpd += qpd & 1;

	else
	    qpd -= qpd & 1;

	dp -=  M_PI * (double)qpd;

	// Calculate frequency difference

	double df = OVERSAMPLE * dp / (2.0 * M_PI);

	// Calculate actual frequency from slot frequency plus
	// frequency difference

	xf[i] = (i * fps + df * fps);
    }

    // Maximum FFT output

    double max = 0.0;
    double f = 0.0;

    // Find maximum value

    for (int i = 1; i < RANGE - 1; i++)
    {
	if (xa[i] > max)
	{
	    max = xa[i];
	    f = xf[i];
	}
    }

    static long freqTimer;

    if (max > MIN)
    {
	display.f = f;
	freqTimer = 0;
    }

    else
    {
	if (freqTimer == 64)
	    display.f = 0.0;
    }

    freqTimer++;

    double level = 0.0;

    for (int i = 0; i < STEP; i++)
	level += ((double)data[i] / 32768.0) *
	    ((double)data[i] / 32768.0);

    level = sqrt(level / STEP) * 2.0;

    double dB = log10(level) * 20.0;

    if (dB < -80.0)
	dB = -80.0;

    display.l = dB;

    meter.l = level / pow(10.0, 0.15);

    static long displayTimer;

    // Update display

    if ((displayTimer % SPECTRUM_TIME) == 0)
	InvalidateRgn(spectrum.hwnd, NULL, TRUE);

    if ((displayTimer % DISPLAY_TIME) == 0)
	InvalidateRgn(display.hwnd, NULL, TRUE);

    displayTimer++;
}
예제 #16
0
파일: mlsacheck.c 프로젝트: rhdunn/sptk
void mlsacheck(double *mcep, int m, int fftlen, int frame,
               double a, double r, int c)
{
   int i;
   double gain, *x, *y, *mag = NULL, max = 0.0;

   x = dgetmem(fftlen);
   y = dgetmem(fftlen);

   fillz(x, sizeof(*x), fftlen);
   fillz(y, sizeof(*y), fftlen);

   /* calculate gain factor */
   for (i = 0, gain = 0.0; i <= m; i++) {
      x[i] = mcep[i];
      gain += x[i] * pow(-a, i);
   }

   /* gain normalization */
   x[0] -= gain;

   /* check stability */
   if (c == 0 || c == 2 || c == 3) {    /* usual mode */
      mag = dgetmem(fftlen);
      fillz(mag, sizeof(*mag), fftlen);
      fftr(x, y, fftlen);
      for (i = 0; i < fftlen; i++) {
         mag[i] = sqrt(x[i] * x[i] + y[i] * y[i]);
         if (mag[i] > max)
            max = mag[i];
      }
   } else {                     /* fast mode */
      for (i = 0; i <= m; i++)
         max += x[i];
   }

   /* modification MLSA filter coefficients */
   if (max > r) {
      /* output ascii report */
      fprintf(stderr,
              "[No. %d] is unstable frame (maximum = %f, threshold = %f)\n",
              frame, max, r);

      /* modification */
      if (c == 2) {             /* clipping */
         for (i = 0; i < fftlen; i++) {
            if (mag[i] > r) {
               x[i] *= r / mag[i];
               y[i] *= r / mag[i];
            }
         }
      } else if (c == 3) {      /* scaling */
         for (i = 0; i < fftlen; i++) {
            x[i] *= r / max;
            y[i] *= r / max;
         }
      } else if (c == 4) {      /* fast mode */
         for (i = 0; i <= m; i++)
            x[i] *= r / max;
      }
   }

   /* output MLSA filter coefficients */
   if (c == 0 || c == 1 || max <= r) {  /* no modification */
      fwritef(mcep, sizeof(*mcep), m + 1, stdout);
   } else {
      if (c == 2 || c == 3)
         ifft(x, y, fftlen);
      x[0] += gain;
      fwritef(x, sizeof(*x), m + 1, stdout);
   }

   free(x);
   free(y);
   if (c == 0 || c == 2 || c == 3)
      free(mag);
}
예제 #17
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);
}
예제 #18
0
void WaveInData(WPARAM wParam, LPARAM lParam)
{
    // Create buffers for processing the audio data

    static double buffer[SAMPLES];
    static complex x[STEP];
    static double xa[RANGE];

    static double K = 2.0 * M_PI / (double)SAMPLE_RATE;

    // Initialise data structs

    if (spectrum.data == NULL)
    {
	spectrum.data = xa;
	spectrum.length = RANGE;
    }

    // Copy the input data

    memmove(buffer, buffer + STEP, (SAMPLES - STEP) * sizeof(double));

    short *data = (short *)((WAVEHDR *)lParam)->lpData;

    for (int i = 0; i < STEP; i++)
	buffer[SAMPLES - STEP + i] = (double)data[i];

    // Give the buffer back

    waveInAddBuffer(audio.hwi, (WAVEHDR *)lParam, sizeof(WAVEHDR));

    // Maximum data value

    static double dmax;

    if (dmax < 4096.0)
	dmax = 4096.0;

    // Calculate normalising value

    double norm = dmax;
    dmax = 0.0;

    // Copy data to FFT input arrays

    for (int i = 0; i < STEP; i++)
    {
	// Find the magnitude

	if (dmax < fabs(buffer[i]))
	    dmax = fabs(buffer[i]);

	// Calculate the window

	double window =
	    0.5 - 0.5 * cos(2.0 * M_PI *
			    i / STEP);

	// Normalise and window the input data

	x[i].r = (double)buffer[i] / norm * window;
    }

    // do FFT

    fftr(x, STEP);

    // Process FFT output

    for (int i = 1; i < RANGE; i++)
    {
	double real = x[i].r;
	double imag = x[i].i;

	xa[i] = hypot(real, imag);
    }

    // Do cross correlation

    double imag = 0.0;
    double real = 0.0;

    for (int i = 0; i < SAMPLES; i++)
    {
	double window =
	    (0.5 - 0.5 * cos(2.0 * M_PI * i / SAMPLES));

	imag += (buffer[i] / 32768.0) * window * sin(i * display.f * K);

	real += (buffer[i] / 32768.0) * window * cos(i * display.f * K);
    }

    double level = hypot(real, imag);

    level = level / (SAMPLES / (4.0 * sqrt(2.0)));

    meter.l = level / pow(10.0, 0.15);

    double dB = log10(level) * 20.0;

    if (dB < -80.0)
	dB = -80.0;

    static long timer;

    // Update display

    if ((timer % 4) == 0)
	InvalidateRgn(spectrum.hwnd, NULL, TRUE);

    if ((timer % 16) == 0)
    {
	    display.l = dB;
	    InvalidateRgn(display.hwnd, NULL, TRUE);
    }

    timer++;
}