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