The shell code for the AF Spectrum Analyser.

Code junkies hangout here

Moderators: ChriThor, LXF moderators

The shell code for the AF Spectrum Analyser.

Postby Bazza » Mon May 01, 2017 11:48 am

This is the test code for the AudioScope's AF Spec An.
It creates a Python script to do the heavy FFT lifting and the rest is done via the bash shell and terminal.
It is primarily for OSX 10.12.4, (Sierra) which has Python 2.7.x, but should work on most *NIX style platforms so long as python is part of the shell utilities. If not you will have to install Python 2.7.x....

The image shows the harmonics to 3750Hz inside the limit of this incarnation.
The shell code is primitive as it is working code for proof of concept, and the display very basic.
Code: Select all
#!/bin/bash
# AF_Spec_An.sh

# Generate a 250Hz square wave, WAV file, for testing. Mono, 8KHz sample, unsigned integer, 8 bit depth.
CHAR=0
: > /tmp/250Hz.wav
: > /tmp/bash_array
: > /tmp/FFT_WAV.py
printf "\122\111\106\106\144\037\000\000\127\101\126\105\146\155\164\040\020\000\000\000\001\000\001\000\100\037\000\000\100\037\000\000\001\000\010\000\144\141\164\141\100\037\000\000" >> /tmp/250Hz.wav
while [ $CHAR -le 249 ]
do
   printf "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" >> /tmp/250Hz.wav
   CHAR=$(( $CHAR + 1 ))
done

# A test display only, active area x = 64, y = 21.
display()
{
   printf "%b" "\033[2J\033[H"
   graticule="           +----------------------------[DISPLAY]----------------------------+\n"
   graticule=$graticule"       100 ++-------+-------+-------+-------+-------+-------+-------+-------++\n"
   graticule=$graticule"           |        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"        90 +        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"    R      |        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"    E   80 +        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"    L      |        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"    A   70 +        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"    T      |        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"    I   60 +        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"    V      |        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"    E   50 +        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"           |        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"    L   40 +        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"    E      |        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"    V   30 +        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"    E      |        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"    L   20 +        |       |       |       |       |       |       |        |\n"
   graticule=$graticule" Log10(x)  |        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"        10 +        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"           |        |       |       |       |       |       |       |        |\n"
   graticule=$graticule"          0++-------+-------+-------+-------+-------+-------+-------+-------++\n"
   graticule=$graticule"   FREQ Hz +0------500----1000----1500----2000----2500----3000----3500----4000\n"
   printf "$graticule"
}

# Pythoin code to do the heavy FFT lifting.
cat << PYTHON_CODE > /tmp/FFT_WAV.py
# Python 2.7.10 (default, Feb  6 2017, 23:53:20)
# [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)] on darwin
# Type "help", "copyright", "credits" or "license" for more information.

import sys
import scipy
from scipy.io import wavfile

global ARRAY_STRING
ARRAY_STRING = ""

# The inbuilt tester.
RATE, WAVEDATA = wavfile.read('/tmp/250Hz.wav')
# A 1 second speech burst.
# RATE, WAVEDATA = wavfile.read('/Users/amiga/Desktop/Sound/test.wav')
DATA = WAVEDATA.T
ELEMENTS = [(ELEMENT/2**8.0)*2-1 for ELEMENT in DATA]
COMPLEX = scipy.fft(ELEMENTS)

LIST = scipy.ndarray.tolist(abs(COMPLEX))

for SUBSCRIPT in range(7999, 3999, -1):
   FFT = int(LIST[SUBSCRIPT])
   if FFT < 1.0: FFT = 1
   FFT = int(5*scipy.log10(FFT))
   ARRAY_STRING = ARRAY_STRING + str(FFT) + " "
filename = open('/tmp/bash_array', 'w+')
filename.write(ARRAY_STRING)
filename.close()
sys.exit()
PYTHON_CODE

# Now run the Python code.
python /tmp/FFT_WAV.py

# Place the space delimited string into a bash array.
bash_array=( $( cat /tmp/bash_array ) )

# Setup the display.
display

# Finally plot the audio spectrum.
COUNT=0
HORIZ=13
VERT=${bash_array[$COUNT]}
# Display window...
# HORIZ, 13 minimum, 77 maximum.
# VERT, 2 minimum, 22 maximum.
# VERT MUST be inverted.
while [ $COUNT -le 3999 ]
do
   VERT=$(( 22 - $VERT ))
   if [ $HORIZ -gt 77 ]
   then
      break
   fi
   for DRAW in $( seq $VERT 1 22 )
   do
      # Bending the rules a little for printf, but this is only a proof of principle demo.
      printf "%b" "\033["$DRAW";"$HORIZ"f\033[1;31m*\033[0m\n\n"
   done
   if [ $(( $COUNT % 63 )) -eq 0 ]
   then
      HORIZ=$(( $HORIZ + 1 ))
   fi
   COUNT=$(( $COUNT + 1 ))
   VERT=${bash_array[$COUNT]}
done

Enjoy...

Bazza.
Attachments
Spec_An_250Hz.jpeg
Spec_An_250Hz.jpeg (79.99 KiB) Viewed 204 times
73...

Bazza, G0LCU...

Team AMIGA...

The less that I speak, the smarter I sound.
User avatar
Bazza
LXF regular
 
Posts: 1594
Joined: Sat Mar 21, 2009 11:16 am
Location: Loughborough

Return to Programming

Who is online

Users browsing this forum: No registered users and 0 guests

cron