This is envelope.c in view mode; [Download] [Up]
#include <math.h> #include <stdio.h> #include <carl/sndio.h> #include <carl/carl.h> /*------------------------------------------------------- envelope.c This program takes floatsams on stdin and outputs a high resolution envelope on stdout. The envelope is actually the magnitude of the analytic signal z(n) = x(n) + j x^(n) where x(n) is the input signal and x^(n) is the hilbert transform of the input signal. To compile: cc envelope.c -lieee -lI77 -lF77 -lcarl -lm -------------------------------------------------------*/ main(argc, argv) int argc; char **argv; { float *sbuf, /* array for real part of FFT */ *tbuf; /* array for imaginary part of FFT */ float a, /* temporary */ b; /* temporary */ long icnt, /* counts input samples */ ocnt = 0; /* counts output samples */ int i, nor = 0, /* specifies forward FFT */ inv = 1, /* specifies inverse FFT */ N = 1024, /* FFT size */ N2 = 512; /* N / 2 */ char ch; /* Interpret commandline by calling dgl's subroutine crack. */ if (isatty(0)) usage(1); while ((ch = crack(argc, argv, "h", 0)) != NULL) { switch (ch) { case 'h': usage(0); default: usage(1); /* this exits with error */ } } /* Set up buffers. */ if ((sbuf = (float *) calloc(N, sizeof(float))) == NULL) malerr("envelope: insufficient memory", 1); if ((tbuf = (float *) calloc(N, sizeof(float))) == NULL) malerr("envelope: insufficient memory", 1); sbuf = (float *) calloc(N,sizeof(float)); tbuf = (float *) calloc(N,sizeof(float)); /* Fill up input buffer. */ for (i=0; i<N; i++) if (getfloat(sbuf+i) <= 0) break; icnt = i; for (; i<N; i++) *(sbuf+i) = 0.; for (i=0; i<N; i++) *(tbuf+i) = 0.; if (icnt == 0){ fprintf(stderr,"envelope: no valid input\n"); exit(1); } /* Main loop: Take N-point FFT of next N input samples and calculate FFT of the analytic signal z(n) according to the formula Z(f) = 0 if f <= 0 2*X(f) if f > 0. Then take inverse FFT to get z(n), and calculate magnitude of z(n) as sqrt(real*real + imag*imag). */ while(ocnt < icnt){ fft842_(&nor,&N,sbuf,tbuf); *sbuf = 0.; *tbuf = 0.; for (i=N2; i<N; i++){ *(sbuf+i) = 0.; *(tbuf+i) = 0.; } fft842_(&inv,&N,sbuf,tbuf); for (i=0; i<N; i++){ a = *(sbuf+i); b = *(tbuf+i); *(sbuf+i) = 2. * sqrt(a*a + b*b); } for (i=0; i<N; i++) putfloat(sbuf+i); ocnt += N; for (i=0; i<N; i++) if (getfloat(sbuf+i) <= 0) break; icnt += i; for (; i<N; i++) *(sbuf+i) = 0.; for (i=0; i<N; i++) *(tbuf+i) = 0.; } flushfloat(); exit(0); } usage(exitcode) int exitcode; { fprintf(stderr,"usage: envelope < floatsams > floatsams \n"); exit(exitcode); } malerr(str, ex) char *str; int ex; { fprintf(stderr, "%s\n", str); exit(ex); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.