ftp.nice.ch/pub/next/unix/audio/cmusic.bs.N.tar.gz#/src/sig/envelope.c

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.