real time /dev/audio 3-D spectrum analyser for PI
Christopher Hull
hull at griffin.uvm.edu
Sun Jun 10 13:10:41 AEST 1990
Here is an interesting program we developed for fun to explore the
world of signal processing (on a limited basis :-). It should work on
any PI with the audio jack hooked up to a sound source. The program
will read from stdin unless the -a flag is given to specifically
another file. One caveat here however; since read() is used to grab
the data as fast as possible the program will probably not work well
with pipes. Also no synchronizing is done in this version between the
reading and graphing process so a prerecorded file will probably get
eaten up in a matter of seconds. Moral: this program works best with
/dev/audio as its input.
We've included a uuencoded noise sample from
our system, but you'll probably want to creat your own. (#define
SAVENOISE and run).
If you find it useful or make any improvements
please forward them to us. Also if any one else has used /dev/audio
for any purpose we'd like to know. We have a few more nifty programs
that we've written so if there's enough interest we may post.
Steve Chappelow
Christopher Hull EMBA-CF Univserity of Vermont
---------------------------------------------------------------------
hull at uvm.edu swc at uvm.edu
%<-------------------- cut here -------------------->%
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: makefile fft4.c freq3d.c freq3d.h
# Wrapped by swc at emily on Sat Jun 9 23:29:47 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile'\"
else
echo shar: Extracting \"'makefile'\" \(271 characters\)
sed "s/^X//" >'makefile' <<'END_OF_FILE'
X#DEFS=-DQUICKGRAPHICS -DSKIPFFT
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: makefile fft4.c freq3d.c freq3d.h noise.dat.uu
# Wrapped by swc at emily on Sat Jun 9 23:42:24 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile'\"
else
echo shar: Extracting \"'makefile'\" \(271 characters\)
sed "s/^X//" >'makefile' <<'END_OF_FILE'
X#DEFS=-DQUICKGRAPHICS -DSKIPFFT
CFLAGS= -O -float
LIBS= -lgl_s -lm
X
freq3d: freq3d.o fft4.o
X cc $(DEFS) $(CFLAGS) freq3d.o fft4.o $(LIBS) -o freq3d
X
freq3d.o: freq3d.c freq3d.h
X cc $(DEFS) freq3d.c -c -o freq3d.o
X
fft4.o: fft4.c freq3d.h
X cc $(DEFS) fft4.c -c -o fft4.o
END_OF_FILE
if test 271 -ne `wc -c <'makefile'`; then
echo shar: \"'makefile'\" unpacked with wrong size!
fi
# end of 'makefile'
fi
if test -f 'fft4.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'fft4.c'\"
else
echo shar: Extracting \"'fft4.c'\" \(5141 characters\)
sed "s/^X//" >'fft4.c' <<'END_OF_FILE'
X/** Very Fast Fourier Transform routines
X *
X * (C) Copyright 1990, Christopher Hull, Steve Chappelow
X * The University of Vermont, EMBA-CF.
X *
X * This program may be redistributed in accordance with the
X * GNU GENERAL PUBLIC LICENSE.
X *
X */
X
X
X#include <stdio.h>
X#include <malloc.h>
X#include <math.h>
X#include <memory.h>
X#include "freq3d.h"
X
X
int fft (unsigned int samples,
X float *timedata,
X float *freqdist);
static void computefft (unsigned int samples,
X float *real,
X float *imaginary);
void buildtables (unsigned int lowidx,
X unsigned int idxrange);
X
extern float sine[], cosine[], eq[];
extern unsigned int butterfly[];
X
X
X/*********************************************************************
X * Last edit: swc at newton (Steve Chappelow)
X * Wed Jun 6 00:57:35 1990
X *
X * fft() --- Performs the Fourier transform on a real-valued function.
X *
X * Requires: samples --- Number of data points in the input
X * function, real part only. Must be a power of two.
X *
X * timedata --- Array containing real-part of raw
X * input function. This should be normalized.
X *
X * freqdist --- Coeffecients in the frequency
X * domain. Half as many frequencies as input points are stored
X * here, since the 2nd half of the coeffiecents are identical
X * because we don't use the imaginary part of the time signal.
X *
X * Returns: 0 if all ok, -1 otherwise.
X */
int fft (unsigned int samples,
X float *timedata,
X float *freqdist)
X{
float imaginary[FFTSIZE]; /* create the imaginary part */
unsigned int loop;
X#ifdef SKIPFFT
X return (1);
X#endif SKIPFFT
X /* test to see if length is a power of two greater than zero */
X for (loop = samples; 0 == (loop & 1); loop >>= 1)
X ;
X if (0x1 != loop)
X return (-1);
X
X /* zero imaginary */
X (void) memset ((char *) imaginary, 0, (int) samples * sizeof (float));
X computefft (samples, timedata, imaginary);
X
X /*
X * Reorder only half of coeffecients into the outgoing array since
X * 2nd half is identical.
X */
X for (loop = 0; loop < samples / 2; loop++)
X {
X unsigned int r = butterfly[loop];
X *freqdist++ = sqrt (timedata[r] * timedata[r] + imaginary[r] * imaginary[r]);
X }
X return (0);
X}
X
X
X
X/*********************************************************************
X * Last edit: swc at midnight (Steve Chappelow)
X * Wed Jun 6 20:29:14 1990
X *
X * computefft() ---Does the Descrete Fourier Transform.
X *
X * Requires: samples --- Number of complex valued samples of
X * the function in the parallel arrays.
X *
X * real --- Real valued part of complex numbers.
X *
X * imaginary --- Imaginary part of complex
X * numbers.
X *
X * Returns: nothing
X */
static void computefft (unsigned int samples,
X float *real,
X float *imaginary)
X{
X register unsigned int loop0, loop1, loop2;
X register unsigned int i = samples >> 1, j = 1, k, l, y,
X power = log10 ((float) samples) / log10 (2.0);
X
X for (loop0 = 0; loop0 < power; loop0++)
X {
X k = 0;
X l = i;
X for (loop1 = 0; loop1 < j; loop1++)
X {
X register float *rp = real, *ip = imaginary;
X register float w1, w2;
X y = butterfly[k / i];
X w1 = cosine[y];
X w2 = sine[y]; /* save a neg here */
X for (rp += k, ip += k, loop2 = k; loop2 < l; loop2++, rp++, ip++) /* 8 */
X {
X register float b1 = w1 * *(rp + i) + w2 * *(ip + i); /* 7 */
X register float b2 = w1 * *(ip + i) - w2 * *(rp + i); /* 3 */
X *(rp + i) = *rp - b1; /* 3 */
X *(ip + i) = *ip - b2; /* 3 */
X *rp = *rp + b1; /* 3 */
X *ip = *ip + b2; /* 3 */
X } /* 4 */
X k += (i << 1);
X l += (i << 1);
X }
X i >>= 1;
X j <<= 1;
X }
X}
X
X
X/*********************************************************************
X * Last edit: swc at newton (Steve Chappelow)
X * Thu Jun 9 20:01:44 1990
X *
X * reverse() --- Reverses a string of bits.
X *
X * Requires: bitpattern --- Bit string to reverse
X * length --- Number of bits starting at bit zero
X * for reverse.
X *
X * Returns: The reverse bit string.
X */
void buildtables (unsigned int lowidx,
X unsigned int idxrange)
X{
X register unsigned int result = 0;
X register unsigned int bitpattern;
X register unsigned int loop;
X register unsigned int length;
X for (loop = 0; loop < FFTSIZE; loop += 1)
X {
X length = (int) (log10 ((float) FFTSIZE) / log10 (2.0));
X bitpattern = loop;
X result = 0;
X do
X { /* 58 cycles */
X result <<= 1;
X result |= (bitpattern & 1);
X bitpattern >>= 1;
X }
X while (--length);
X butterfly[loop] = result;
X }
X
X /* pre-compute trig tables [0,2PI] */
X for (length = 0; length < FFTSIZE; length++)
X {
X sine[length] = sin (TWO_PI * length / (float) FFTSIZE);
X cosine[length] = cos (TWO_PI * length / (float) FFTSIZE);
X }
X
X /* compute the equalization on frequencies */
X for (length = 0; length < idxrange; length++)
X eq[length] = log10 ((length + lowidx + 7.0) / 5.0);
X}
END_OF_FILE
if test 5141 -ne `wc -c <'fft4.c'`; then
echo shar: \"'fft4.c'\" unpacked with wrong size!
fi
# end of 'fft4.c'
fi
if test -f 'freq3d.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'freq3d.c'\"
else
echo shar: Extracting \"'freq3d.c'\" \(13415 characters\)
sed "s/^X//" >'freq3d.c' <<'END_OF_FILE'
X/** Spectral Decomposition Display Driver
X *
X * (C) Copyright 1990, Christopher Hull, Steve Chappelow
X * The University of Vermont, EMBA-CF.
X *
X * This program may be redistributed in accordance with the
X * GNU GENERAL PUBLIC LICENSE.
X *
X */
X
X#include <stdio.h>
X#include <math.h>
X#include <gl.h>
X#include <device.h>
X#include <sys/types.h>
X#include <sys/file.h>
X#include <fcntl.h>
X#include <sys/time.h>
X#include <sys/audio.h>
X#include <signal.h>
X#include <sys/prctl.h>
X#include <ulocks.h>
X#include <sys/schedctl.h>
X
X#include "freq3d.h"
X
X
void sighup (void);
void sigterm (void);
void drawaxes (int low,
X int high,
X struct timeval lowtime,
X struct timeval hightime,
X struct timeval starttime);
void graphproc (void);
void readproc (void);
static void parseargs (int argc,
X char **argv);
void printsemastats (void);
void makemap (void);
void updatetickers (float,
X unsigned int,
X unsigned int,
X struct timeval);
int main (int argc,
X char **argv);
X
X
extern void buildtables ();
X
X/* global since fft() uses these too */
float sine[FFTSIZE];
float cosine[FFTSIZE];
float eq[FFTSIZE / 2]; /* eq on frequencies */
unsigned int butterfly[FFTSIZE]; /* lookup reversed bits */
signed char buf[BUFSIZE];
static unsigned int readcount = 0;
X
int graphpid;
int readpid;
X
char *noisesfilename = "noise.dat";
int audiofd = 0; /* stdin by default */
float highfrequency = DIGITIZERATE / 2.0 - 1,
X lowfrequency = 0.0;
X
float blankrect[] = {
X TMIN, 0, 0,
X TMIN, FFTSIZE, 0,
X TMIN, FFTSIZE, 10000,
X TMIN, 0, 10000
X};
X
X
X
int main (int argc, char **argv)
X{
X
X parseargs (argc, argv);
X
X if (-1 == ioctl (audiofd, AUDIOCSETRATE, 1))
X perror ("ioctl: AUDIOCDURATION:"), exit (1);
X if (-1 == ioctl (audiofd, AUDIOCDURATION, 200))
X perror ("ioctl: AUDIOCDURATION:"), exit (1);
X
X
X if ((graphpid = sproc (graphproc, PR_SALL, NULL)) < 0)
X {
X perror ("sproc");
X exit (1);
X }
X if ((readpid = sproc (readproc, PR_SALL, NULL)) < 0)
X {
X perror ("sproc");
X exit (1);
X }
X return (0); /* parent dies */
X}
X
X
X
void updatetickers (float running_t,
X unsigned int idxrange,
X unsigned int frame,
X struct timeval starttime)
X{ /* so we have realtimestr each time past
X * here */
X struct timeval realtime;
X static char realtimestr[20] = "00.00",
X virtualtimestr[20] = "00.00",
X framenumstr[20] = "0",
X readcountstr[20] = "00.00";
X
X color (BACKGROUNDCOLOR);
X cmov (TMAX, -150.0 * ((float) idxrange / FFTSIZE), -BOXHEIGHT);
X charstr (realtimestr); /* erase previous time */
X cmov (TMAX * .85, -150.0 * ((float) idxrange / FFTSIZE), -BOXHEIGHT);
X charstr (virtualtimestr);
X cmov (TMAX * .7, -150.0 * ((float) idxrange / FFTSIZE), -BOXHEIGHT);
X charstr (framenumstr);
X cmov (TMAX * 0.55, -150.0 * ((float) idxrange / FFTSIZE), -BOXHEIGHT);
X charstr (readcountstr);
X gettimeofday (&realtime, (struct timezone *) NULL);
X sprintf (realtimestr, "Real: %.2f",
X ((realtime.tv_sec * 1000000.0 + realtime.tv_usec)
X - (starttime.tv_sec * 1000000.0 + starttime.tv_usec))
X / 1000000.0);
X sprintf (virtualtimestr, "Virtual: %.2f", ((running_t - TMIN) / (TMAX - TMIN)
X + frame) * SLICES * NSEC);
X sprintf (framenumstr, "Frame: %0d", frame);
X sprintf (readcountstr, "Reads: %.2f", (float) readcount * NSEC);
X color (7);
X cmov (TMAX, -150.0 * ((float) idxrange / FFTSIZE), -BOXHEIGHT);
X charstr (realtimestr);
X cmov (TMAX * 0.85, -150.0 * ((float) idxrange / FFTSIZE), -BOXHEIGHT);
X charstr (virtualtimestr);
X cmov (TMAX * 0.7, -150.0 * ((float) idxrange / FFTSIZE), -BOXHEIGHT);
X charstr (framenumstr);
X cmov (TMAX * 0.55, -150.0 * ((float) idxrange / FFTSIZE), -BOXHEIGHT);
X charstr (readcountstr);
X}
X
X
void drawaxes (int lowindex,
X int highindex,
X struct timeval lowtime,
X struct timeval hightime,
X struct timeval starttime)
X{
char tmp[25];
float numpoints;
int loop;
X
X numpoints = highindex - lowindex;
X drawmode (OVERDRAW);
X mapcolor (1, 0, 0, 255);
X mapcolor (2, 255, 255, 255);
X mapcolor (3, 0, 255, 0);
X color (0);
X clear ();
X color (2);
X setlinestyle (1);
X for (loop = 0; loop <= 6; loop++)
X {
X float freq = loop * numpoints / 6.0;
X sprintf (tmp, "%.0f Hz", ((6.0 * lowindex + numpoints * loop)
X * (float) MAXFREQUENCY) / (6.0 * (FFTSIZE / 2.0)));
X cmov (TMAX * 1.2, freq - 10.0 * (numpoints / FFTSIZE), 0.0);
X color (2);
X charstr (tmp);
X color (1);
X move (TMAX * 1.1, freq, 0.0);
X draw (TMAX, freq, 0.0);
X }
X
X color (3);
X move (TMAX, 0.0, 0.0);
X
X draw (TMAX, numpoints, 0.0);
X move (TMIN, 0.0, 0.0);
X draw (TMAX, 0.0, 0.0);
X
X#define sec(x) ((x.tv_sec*1000000.0 + x.tv_usec)/1000000.0)
X
X for (loop = 0; loop <= 8; loop++)
X {
X sprintf (tmp, "%7.1fs",
X (sec (lowtime) - sec (starttime)) +
X (loop / 8.0) * (sec (hightime) - sec (lowtime)));
X
X cmov (loop * (TMAX - TMIN) / 8 - TMAX, -80.0 * (numpoints / FFTSIZE), 0.0);
X color (2);
X charstr (tmp);
X }
X cmov (TMIN - 150, numpoints / 2 - 20 * (numpoints / FFTSIZE), 800.0);
X charstr ("Real-Time Spectral Analysis");
X move (TMAX, 0.0, -BOXHEIGHT);
X draw (TMAX, (float) numpoints, -BOXHEIGHT);
X draw (TMAX, (float) numpoints, BOXHEIGHT);
X draw (TMAX, (float) numpoints, -BOXHEIGHT);
X
X setlinestyle (2);
X draw (TMIN, numpoints, -BOXHEIGHT);
X draw (TMIN, numpoints, BOXHEIGHT);
X move (TMIN, numpoints, -BOXHEIGHT);
X draw (TMIN, 0.0, -BOXHEIGHT);
X
X setlinestyle (1);
X draw (TMIN, 0.0, BOXHEIGHT);
X draw (TMIN, 0.0, -BOXHEIGHT);
X draw (TMAX, 0.0, -BOXHEIGHT);
X draw (TMAX, 0.0, BOXHEIGHT);
X move (TMAX, 0.0, BOXHEIGHT);
X
X draw (TMAX, numpoints, BOXHEIGHT);
X draw (TMIN, numpoints, BOXHEIGHT);
X draw (TMIN, 0.0, BOXHEIGHT);
X draw (TMAX, 0.0, BOXHEIGHT);
X drawmode (NORMALDRAW);
X setlinestyle (0);
X}
X
X
void graphproc (void)
X{
struct timeval starttime, lowtime, hightime;
unsigned int idxrange, lowidx, highidx, x;
int i1, i2;
float v[3];
float running_time;
unsigned int frame = 0;
long sx, sy;
float timedata[FFTSIZE];
X /* these are all half as big since the frequency domain is courser */
float freqdist[FFTSIZE / 2]; /* ignore mirror side */
float avg[FFTSIZE / 2];
float noises[FFTSIZE / 2];
X
X
X signal (SIGHUP, sighup);
X signal (SIGTERM, sighup);
X gettimeofday (&starttime, (struct timezone *) NULL);
X lowtime = starttime;
X hightime = starttime;
X bzero (noises, sizeof (noises));
X bzero (avg, sizeof (avg)); /* reset averages */
X bzero (eq, sizeof (eq)); /* reset eq */
X bzero (freqdist, sizeof (freqdist)); /* reset freqs */
X
X#ifndef SAVENOISE
X if ((i1 = open (noisesfilename, O_RDONLY)) < 0)
X fprintf (stderr, "can't find noise reduction\n"), exit (1);
X
X if (read (i1, (char *) noises, sizeof (noises)) != sizeof (noises))
X fprintf (stderr, "version mismatch in noise data file\n"), exit (1);
X#endif
X
X lowidx = (int) ((lowfrequency / MAXFREQUENCY) * (FFTSIZE >> 1));
X highidx = (int) ((highfrequency / MAXFREQUENCY) * (FFTSIZE >> 1));
X idxrange = highidx - lowidx;
X
X prefposition (0, 1280, 0, 1023);
X foreground ();
X winopen ("Fequency display ");
X makemap ();
X overlay (2);
X gconfig ();
X getsize (&sx, &sy);
X
X concave (TRUE);
X
X ortho (TMIN, TMAX, -FFTSIZE, FFTSIZE, -1000, 1000);
X
X polarview (300, 850, 600, 0);
X translate (0, -FFTSIZE / 2, 0);
X
X scale (1.3, FFTSIZE / (float) idxrange, 0.2); /* time, frequency,
X * voltage */
X deflinestyle (1, 0xFFFF);
X deflinestyle (2, 0x0001);
X color (BACKGROUNDCOLOR);
X clear ();
X
X qdevice (REDRAW);
X qdevice (ESCKEY);
X qdevice (WINQUIT);
X qdevice (DEPTHCHANGE);
X drawaxes (lowidx, highidx, lowtime, hightime, starttime);
X
X buildtables (lowidx, idxrange);
X
X running_time = TMIN;
X while (1)
X {
X#ifdef SAVENOISE
static int count = 0;
X#endif
X for (i1 = 0; i1 < FFTSPERBUF; i1++)
X {
X register float *ft, *ft2, *ft3;
X signed char *ch;
X ft = timedata;
X ch = buf;
X for (i2 = 0; i2 < FFTSIZE; i2++)
X *ft++ = *ch++ * sine[i2 >> 1]; /* apply Hanning window */
X /* if FFT is too fast we may apply twice on 1 window */
X
X if (-1 == fft ((unsigned) FFTSIZE, timedata, freqdist))
X fprintf (stderr, "fft failed\n"), exit (1);
X#ifdef SAVENOISE
X if (count++ == 200)
X {
X write (1, avg, sizeof (avg));
X kill (readpid, 9);
X sleep (9);
X exit (0);
X }
X#endif SAVENOISE
X ft = avg;
X ft2 = freqdist + lowidx;
X ft3 = noises + lowidx;
X for (i2 = 0; i2 < idxrange; i2++, ft++) /* put into [0,idxrange] */
X *ft = *ft * (1 - ATTACKFACTOR) /* decaying average */
X + (fabs (*ft2++) - *ft3++) * ATTACKFACTOR;
X#ifndef QUICKGRAPHICS
X color (0);
X bgnpolygon ();
X v[0] = running_time;
X v[1] = 0;
X v[2] = -10;
X v3f (v); /* first point */
X
X for (x = 0; x < idxrange - 1; x += FREQSTEP)
X {
X v[1] = x; /* 3-way smoothing */
X v[2] = (avg[x] + avg[x + 1] + avg[x + 2]) * eq[x];
X if (v[2] < 0)
X v[2] = 0;
X v3f (v);
X if (!(x & 127))
X {
X float tmp;
X tmp = v[2];
X v[2] = -10.0;
X v3f (v);
X endpolygon ();
X bgnpolygon ();
X v3f (v);
X v[2] = tmp;
X v3f (v);
X }
X }
X v[2] = -10.0;
X v3f (v);
X endpolygon ();
X#endif
X
X bgnline ();
X for (x = 0; x < idxrange - 1; x++)
X {
X color (((x * 256) / idxrange) + 512); /* 256 COLOR RAMP */
X v[0] = running_time;
X v[1] = x;
X v[2] = (avg[x] + avg[x + 1] + avg[x + 2]) * eq[x];
X if (v[2] < 0)
X v[2] = 0;
X v3f (v);
X }
X endline ();
X
X updatetickers ((float) running_time, idxrange, frame, starttime);
X running_time += TIMESTEP;
X if (running_time > TMAX)
X {
X struct timeval lasttimerange;
X /* newhightime = newlowtime + lastrange; */
X gettimeofday (&hightime, (struct timezone *) NULL);
X lasttimerange.tv_sec = hightime.tv_sec - lowtime.tv_sec;
X lasttimerange.tv_usec = hightime.tv_usec - lowtime.tv_usec;
X gettimeofday (&lowtime, (struct timezone *) NULL);
X hightime.tv_sec = lasttimerange.tv_sec + lowtime.tv_sec;
X hightime.tv_usec = lasttimerange.tv_usec + lowtime.tv_usec;
X drawaxes (lowidx, highidx, lowtime, hightime, starttime);
X frame += 1;
X color (BACKGROUNDCOLOR);
X polf (4, blankrect);
X running_time = TMIN;
X#ifdef QUICKGRAPHICS
X color (BACKGROUNDCOLOR);
X clear ();
X#endif
X }
X if (qtest ())
X switch (qread (&i2))
X {
X case REDRAW:
X case DEPTHCHANGE:
X pushmatrix ();
X pushviewport ();
X fullscrn ();
X drawmode (OVERDRAW);
X color (BACKGROUNDCOLOR);
X clear ();
X drawmode (NORMALDRAW);
X endfullscrn ();
X popviewport ();
X popmatrix ();
X reshapeviewport ();
X color (BACKGROUNDCOLOR);
X clear ();
X drawaxes (lowidx, highidx, lowtime, hightime, starttime);
X getsize (&sx, &sy);
X break;
X case ESCKEY:
X case WINQUIT:
X fullscrn ();
X drawmode (OVERDRAW);
X color (0);
X clear ();
X kill (readpid, SIGKILL);
X gexit ();
X exit (0);
X }
X }
X }
X}
X
void sigterm ()
X{
X kill (graphpid, SIGHUP); /* tell him to clear the screen */
X exit (0);
X}
X
void sighup ()
X{
X drawmode (OVERDRAW);
X fullscrn ();
X color (0);
X clear ();
X exit (0);
X}
X
void readproc (void)
X{
X signal (SIGTERM, sigterm);
X for (;;)
X {
X /* stdio always read stdio BUFSIZ == 8192 on mips */
X if (-1 == read (audiofd, (char *) buf, (unsigned) BUFSIZE))
X kill (graphpid, SIGHUP), kill (getpid (), SIGHUP);
X readcount += 1;
X }
X}
X
X
static void parseargs (int argc, char **argv)
X{
extern float highfrequency, lowfrequency;
extern char *noisesfilename;
extern char *optarg;
int c;
X
X while ((c = getopt (argc, argv, "a:h:l:n:")) != -1)
X switch (c)
X {
X case 'a':
X printf ("using %s for input\n", optarg);
X if (NULL == (audiofd = open (optarg, O_RDONLY)))
X perror (optarg), exit (1);
X break;
X case 'h':
X highfrequency = atof (optarg);
X printf ("highest frequency is %f\n", highfrequency);
X break;
X case 'l':
X lowfrequency = atof (optarg);
X printf ("lowest frequency is %f\n", lowfrequency);
X break;
X case 'n':
X noisesfilename = optarg;
X printf ("Using noise sample from %s\n", noisesfilename);
X break;
X default:
X fprintf (stderr, "Usage: %s [-a audiofile] [-h highfreq] [-l lowfreq] [-n noisefile]\n", argv[0]), exit (1);
X }
X}
X
X
void makemap (void)
X{
int i, r, g, b, inc;
X
X inc = 6;
X r = 255;
X g = 0;
X b = 0;
X for (i = 0; i <= 60; i++)
X {
X mapcolor (512 + i, r, g, b);
X g += inc;
X if (g > 255)
X g = 255;
X }
X g = 255;
X for (i = 61; i <= 105; i++)
X {
X r -= inc;
X if (r < 0)
X r = 0;
X mapcolor (512 + i, r, g, b);
X }
X
X r = 0;
X for (i = 106; i <= 165; i++)
X {
X b += inc;
X if (b > 255)
X b = 255;
X mapcolor (512 + i, r, g, b);
X }
X
X b = 255;
X for (i = 166; i <= 210; i++)
X {
X g -= inc;
X if (g < 0)
X g = 0;
X mapcolor (512 + i, r, g, b);
X }
X
X g = 0;
X for (i = 211; i <= 258; i++)
X {
X r += inc;
X if (r > 255)
X r = 255;
X mapcolor (512 + i, r, g, b);
X }
X}
END_OF_FILE
if test 13415 -ne `wc -c <'freq3d.c'`; then
echo shar: \"'freq3d.c'\" unpacked with wrong size!
fi
# end of 'freq3d.c'
fi
if test -f 'freq3d.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'freq3d.h'\"
else
echo shar: Extracting \"'freq3d.h'\" \(1229 characters\)
sed "s/^X//" >'freq3d.h' <<'END_OF_FILE'
X/** Spectral Decomposition Display Header
X *
X * (C) Copyright 1990, Christopher Hull, Steve Chappelow
X * The University of Vermont, EMBA-CF.
X *
X * This program may be redistributed in accordance with the
X * GNU GENERAL PUBLIC LICENSE.
X *
X */
X
X/* universal constants */
X#define PI ((float)3.141592653589793232)
X#define TWO_PI ((float)2.0 * PI)
X
X/* semi-tunable parameters */
X#define DIGITIZERATE (32*1024)
X#define MAXFREQUENCY (DIGITIZERATE/2)
X
X/* tunable parameters */
X#define NSEC (1.0/64)
X#define BUFSIZE ((int)(DIGITIZERATE*NSEC))
X
X#define DUMB_CC
X#ifdef DUMB_CC
X#define FFTSIZE 512
X#define FFTSPERBUF (BUFSIZE/FFTSIZE)
X#else
X#define FFTSPERBUF 1
X#define FFTSIZE (BUFSIZE/FFTSPERBUF)
X#endif
X/* above needed since cc may barf on arrays dimensioned with FFTSIZE */
X
X/* weight for frequencies from each new fft */
X#define ATTACKFACTOR 0.25
X
X/* skip over this many frequency bands in ploting */
X#define FREQSTEP 1
X
X/* time axis ranges and number of slices graphed */
X#define TMIN (-384.0)
X#define TMAX (384.0)
X#define SLICES (128.0)
X#define TIMESTEP ((TMAX - TMIN)/SLICES)
X
X/* experimental visual switches */
X#define BOXHEIGHT 800.0
X#undef SKIPFFT
X#define BACKGROUNDCOLOR 40
END_OF_FILE
if test 1229 -ne `wc -c <'freq3d.h'`; then
echo shar: \"'freq3d.h'\" unpacked with wrong size!
fi
# end of 'freq3d.h'
fi
if test -f 'noise.dat.uu' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'noise.dat.uu'\"
else
echo shar: Extracting \"'noise.dat.uu'\" \(1440 characters\)
sed "s/^X//" >'noise.dat.uu' <<'END_OF_FILE'
begin 664 noise.dat
M1:Z.$T3I1>-#M]$"0R`L>D*PM\1"B7$G0C:']T'N<NE!J?^*08TS9$&3])!!
M.DD-01@^^D$<B9Q`X>5S014RFT"X_T%`Y).+0/RN<D#W':9`U?:?0,UZOT#@
MP&5`GMA90-4#/$#_J/)`N<2G0+O04T"+S0-`DXN,0$6`/$#`3.)`2]&E0(:X
M>D"3B&I`>S>Z0'OH$4"5A[1`H7EI0(,MWD";589`OV:Y0)O'94!7*,U`>N+@
M0*GB-T#0F1U`I=1H0'?;5$"3E+!`L+F10)VU!D"_/6Q`>RKH0+<`T$#(!81`
MO53304MYDD%@;&Q`D%870/;(>D#6[*Q`T;=F0*_4\$"V8*%`N;`,0)2"ET">
MZ:I`FDAV0-`OUD"/A3]`QZW90)]K<$!WI/Q`;'Y60!(#+4!'\5)`7V2A0+\G
MND#`R<)`H_'$0+6,I4"%Q^!`BA2V0)IAAT"/7,I`BG^@0#6$=D"M/1)`?_LO
M0(HQ$T"C at HI`OO6N0(SSST!D]JQ`AK+O0)>$G4"=3Y)`@64>0*MQS$"CE[9`
MHR2%0*5M14"G_/M`EAO*0(4JST!Z41Y`BS-L0(JN:$"&34]`;Z&00&'LC4",
MLU!`H(J70*Y484#S]V)`V<KF0)6@?T"@CIA`X>3`0*G4J$"JNI)`L3B$0*P1
M:D"B[@I`BW;60-]%ZT"S]YY`E.V*0(4S0T""`+Y`;8*`0(WA.T"B)%1`8:=E
M0)=.0$"S$OQ`L^2#0,]+\D!6L49`FI[`0)3.>D##!-%`B2NZ0$Y.YD!:BOQ`
MI]2T0(`C+$!I&KY`<1R^0*XI.$";4S=`TZRH0&7L9T">XZY`H#8<0)P/K$"T
M$81`X3.V0.&$#D#, at J5`VK*&0,:Z+$"U\(Y!$/6>00#M*T"`T\1`IZCU0*96
M^$#*V79`N6E%0)GK<$!?%6!`HF-,0),TQ4!2".1`O_A10/=L*D"M(EI`E?^W
M0%DIF$#'>(Y`F!2:0*4C^$"OS25`JO6=0(D;&T"!5*I`I.M"0*FO)D!RX+9`
M=-U&0.1(4T"@8B9`VA2;0-3&"4#VHT!`H-+&0)WPQD#G8ZA`QAR+0*%F-$!B
MLCA`J1O:0)\2_T#5P<E`U,6D0(NOH$"\WI=`LO:40+G4E$#N]>A`H=D10)$A
MNT"PA'1`Z\U801[&ZD$Z]#I`U/UC0--HVD#G,[Y!?S*4091;MT$0I*Y`ZWRR
M0.\4G$%;7LE!F+AT05M$_4"QO.Y`_\#`0,>*<$#^#?Q`R4"*0/#6 at D#)K4A`
M^>U.0,X(A$$V^&A!(R100,QW]4$5FR]`O%D=0.QB;D#?7>=`V9Q,0,*VLT"B
BB$M`GL:M0/\Z%4#:ME=`:LOL0//\7T#I=J5`Y.,C03_:".=`
X`
end
END_OF_FILE
if test 1440 -ne `wc -c <'noise.dat.uu'`; then
echo shar: \"'noise.dat.uu'\" unpacked with wrong size!
fi
# end of 'noise.dat.uu'
fi
echo shar: End of shell archive.
exit 0
More information about the Comp.sys.sgi
mailing list