Text mode AF spectrum analyser.

 
Thread Tools Search this Thread
Operating Systems OS X (Apple) Text mode AF spectrum analyser.
# 1  
Old 04-25-2017
Text mode AF spectrum analyser.

Well guys, this MUST be a first.

This is DEMO code only and has NO error detection or correction, nor out of bounds checking.

I have succumbed to Python and scipy to do the FFT heavy lifting as I have absolutely no idea where to start do such a thing using AWK. This is a taster for me to include into AudioScope.sh. I am thinking of doing each vertical plot in differing colours and juggling the numbers to suit.

This IS a bash script but creates a 250Hz 1 second WAV file and the python script on the fly.

At the moment the plotting takes a few seconds, but I am not bothered about that at this point. The fact that it works has even amazed me!

The two images show the pre-generated 250Hz spectrum and a 1 second burst of me talking into the MBP's mic...

COMMENTS?!

I await the flak...
Code:
#!/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

Text mode AF spectrum analyser.-spec_an_250hzjpeg
Text mode AF spectrum analyser.-spec_an_speechjpeg
This User Gave Thanks to wisecracker For This Post:
# 2  
Old 04-26-2017
Quite an achievement!

Your graticle can be made a lot simpler:

Code:
printf "%s" "\033[2J\033[H" # %s is good enough for this

printf "%s\n" \
    "           +----------------------------[DISPLAY]----------------------------+" \
    "       100 ++-------+-------+-------+-------+-------+-------+-------+-------++" \
    "           |        |       |       |       |       |       |       |        |" \
    "        90 +        |       |       |       |       |       |       |        |" \
    "    R      |        |       |       |       |       |       |       |        |" \
    "    E   80 +        |       |       |       |       |       |       |        |" \
    "    L      |        |       |       |       |       |       |       |        |" \
    "    A   70 +        |       |       |       |       |       |       |        |" \
    "    T      |        |       |       |       |       |       |       |        |" \
    "    I   60 +        |       |       |       |       |       |       |        |" \
    "    V      |        |       |       |       |       |       |       |        |" \
    "    E   50 +        |       |       |       |       |       |       |        |" \
    "           |        |       |       |       |       |       |       |        |" \
    "    L   40 +        |       |       |       |       |       |       |        |" \
    "    E      |        |       |       |       |       |       |       |        |" \
    "    V   30 +        |       |       |       |       |       |       |        |" \
    "    E      |        |       |       |       |       |       |       |        |" \
    "    L   20 +        |       |       |       |       |       |       |        |" \
    " Log10(x)  |        |       |       |       |       |       |       |        |" \
    "        10 +        |       |       |       |       |       |       |        |" \
    "           |        |       |       |       |       |       |       |        |" \
    "          0++-------+-------+-------+-------+-------+-------+-------+-------++" \
    "   FREQ Hz +0------500----1000----1500----2000----2500----3000----3500----4000"

Also that while loop can write to 250Hz.wav once instead of 249 times:

Code:
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"
	CHAR=$(( $CHAR + 1 ))
done >> /tmp/250Hz.wav

This User Gave Thanks to Corona688 For This Post:
# 3  
Old 04-26-2017
I do think Python, Perl, etc is about as good as you can expect for FFT unless we can convince a genuine, credentialed Computer Scientist to build one for us. Smilie It's possible to do it - I've seen it done in Basic - but the mathematics are very subtle and involve complex numbers or ways to cheat around non-complex numbers.
This User Gave Thanks to Corona688 For This Post:
# 4  
Old 04-26-2017
Quote:
Originally Posted by Corona688
I do think Python, Perl, etc is about as good as you can expect for FFT unless we can convince a genuine, credentialed Computer Scientist to build one for us. Smilie It's possible to do it - I've seen it done in Basic - but the mathematics are very subtle and involve complex numbers or ways to cheat around non-complex numbers.
Boy don't I know it now.
It took a couple of days to get my head around how to set about jumping from the python result into a bash array but in the end I decided on saving to disk then using cat to get that result into the bash array. So I took the easy way out.

As for you previous post I don't need the for loop at all as it will get the WAV file from the FREQ command in AudioScope to look at its spectrum. There it little point in looking at the main capture as a few users might just use the internal mic only.
However I will use your method of generating the window although I have already modified it for my requirements.

The image is the new look and colours of the spectrum of a single sung note into the mic from FREQ command in AudioScope...
Text mode AF spectrum analyser.-single_sung_notejpeg
# 5  
Old 04-26-2017
Well isn't that lovely to see Smilie Good job.
# 6  
Old 04-26-2017
Hi Corona688...

Thanks.

Whooda thunk that the humble bash shell, terminal and the plethora of utilities could do something like this eh!
I would love to know if it has been done before.

;o)

---------- Post updated at 08:52 PM ---------- Previous update was at 06:45 PM ----------

Apologies if this reply attaches itself to the previous one.

I have done away with the display window function completely and the code for the window is now generated per file call.
# 7  
Old 04-26-2017
Sometime in the 90's, I made a microphone oscilloscope which operated in DOS 80x25 text mode at 128x128 resolution. It updated the display by changing the font every single frame. This made it fast and flicker-free. I could do 128x256, which was less oddly shaped, but suffered graphical artifacts because of characters the video card blithely assumed were "line drawing" characters which it should extend to meet the neighboring character.

Oscilloscope was the best I could do. I struggled with it for a long time but never managed to port a working FFT algorithm from anywhere. There weren't widely available libraries back then.

Everything was done in Borland Turbo C for DOS, an IDE which students across the globe still use to this day for learning purposes.

Last edited by Corona688; 04-26-2017 at 05:07 PM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. OS X (Apple)

Text mode dual _LED_ VU meter.

Hi guys... Finally decided to release this, I have a python version too but that is unimportant to me. It is a text mode "Dual_VU.sh" meter. It actually calls dash as the interpreter but change the shebang to suit yourselves. It uses the bell character for overload per channel and... (1 Reply)
Discussion started by: wisecracker
1 Replies

2. UNIX for Dummies Questions & Answers

Pseudo-3D effect in text mode...

This is a DEMO only... Someone recently asked about creating a box to make something look nicer on screen. I suggested that with careful colouring a 3D effect could be created... Linux version; this also works on a Macbook Pro but is not as easy to see as the other code below:- ... (0 Replies)
Discussion started by: wisecracker
0 Replies

3. Hardware

How to go to GUI from text mode?

Dear All, i am trying to install the redhat linux using graphical mode...but it stucks while probing video card...i have installed linux using text mode it works fine and whole the installation goes fine. after installation if i give startx command it again stucks....looks like a vga card... (9 Replies)
Discussion started by: zaheer.gr8
9 Replies

4. Red Hat

Fedora booting in text mode (screen messes up)

Hello everyone Had a problem booting Fedora. I installed it as a server without any desktop environment(kde, gnome) except for X. Problem is when i booting system after it loads kernel suddenly screen messes up with parts of fedora graphics(it's not clear but you can see it -... (8 Replies)
Discussion started by: dimamu15
8 Replies

5. SuSE

Convet Linux OS from text mode to graphic mode

Hi All, I used to have my suse linux(VM) server in graphic mode but not anymore since morning. I cant rolback since i loose somuch work. Any idea how to it back to normal. Thanks (6 Replies)
Discussion started by: s_linux
6 Replies

6. Solaris

How to switch from GUI to text mode?

Hi all I have installed solaris 5.10 and it is loading in GUI mode by default. I want to load in text mode by default. How to do this? How to switch from GUI to text mode and vise versa.? Please help.. (2 Replies)
Discussion started by: johnl
2 Replies

7. UNIX for Dummies Questions & Answers

emacs in text mode how to?

hello all I saw somewhere there is some kind of version of emacs in full text mode ? how can I get/download it? if I have ordenry emacs installed can I start it in text mode? thanks (2 Replies)
Discussion started by: umen
2 Replies

8. AIX

Startup AIX in GUI or text mode

Can I know is there anyone know how to statup AIX in GUI and text mode? Thank You..... (2 Replies)
Discussion started by: dwarf007
2 Replies

9. UNIX for Advanced & Expert Users

simulate text mode in X-Windows

Hi. I need to run old full-screen text-mode application under X-Windows. (By the way it is touch-screen calibrator firmware). The screen resolution is to be 1280x1024 exactly. The program expect text-mode geometry 80x25. Running xterm (no window manager) I have adjusted the font pararameters to... (3 Replies)
Discussion started by: shestero
3 Replies

10. IP Networking

how to get online in text mode with redhat 7.1 ?

Hi people... Is there any way to configure the conection i text mode ? I need to know how to make the modem work and how to configure a dial up conection in text mode by redhat 7.1 and if possible how to configure the email... I use the workstation installation...any help will be welcome...... (2 Replies)
Discussion started by: furioso
2 Replies
Login or Register to Ask a Question