The Start Of A Simple Audio Scope Shell Script

This is a DEMO shell script to generate a simple graticule and plot inside it...

Apologies for any typos...

it is another building block along with my other two shell uploads recently to start a semi_serious project of an Terminal_AudioScope...

The fist upload I posted recently was to show how to animate colours, the second was to be able to manipulate a known bainary file to become a timebase and now this simple display...

The next upload will be a simple working unit using "/dev/dsp" for Linux through either the internal micrphone or the external mic input... The limitations of this device is that by default it samples at 8KHz, to 8 bit depth, mono, so don't expect anything wondrous...

There is a FLAW in this DEMO. It is NOT a bug! What is it? ;o)

You need to know how the console or terminal works to find it... <big wink>

Be aware of wordwrapping, etc...

#!/bin/bash
#
# AudioScopeDisplay.sh
# 
# This method can also be used for a simple kids level Analogue Data_logger/Transient_Recorder
# Cannot use "setterm -cursor off" as Mac OSX 10.7.5 has not got "setterm", thought of another way for the Macbook Pro... ;o)
#
# $VER: AudioScopeDisplay.sh_Version_0.00.01_Public_Domain_B.Walker_G0LCU.

display()
{
	clear
	graticule="+-------+-------+-------+-------+-------+-------+-------+--------+\n"
	graticule=$graticule"|       |       |       |       +       |       |       |        |\n"
	graticule=$graticule"|       |       |       |       +       |       |       |        |\n"
	graticule=$graticule"|       |       |       |       +       |       |       |        |\n"
	graticule=$graticule"+-------+-------+-------+-------+-------+-------+-------+--------+\n"
	graticule=$graticule"|       |       |       |       +       |       |       |        |\n"
	graticule=$graticule"|       |       |       |       +       |       |       |        |\n"
	graticule=$graticule"|       |       |       |       +       |       |       |        |\n"
	graticule=$graticule"+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+\n"
	graticule=$graticule"|       |       |       |       +       |       |       |        |\n"
	graticule=$graticule"|       |       |       |       +       |       |       |        |\n"
	graticule=$graticule"|       |       |       |       +       |       |       |        |\n"
	graticule=$graticule"+-------+-------+-------+-------+-------+-------+-------+--------+\n"
	graticule=$graticule"|       |       |       |       +       |       |       |        |\n"
	graticule=$graticule"|       |       |       |       +       |       |       |        |\n"
	graticule=$graticule"|       |       |       |       +       |       |       |        |\n"
	graticule=$graticule"|       |       |       |       +       |       |       |        |\n"
	graticule=$graticule"+-------+-------+-------+-------+-------+-------+-------+--------+\n"
	printf "$graticule"
}

while true
do
	display
	for horiz in {2..65}
	do
		# Simulate an 8 bit grab and divide by 16 to give 4 bit depth. Add offset of 2 to allow
		# for mssing the top graticule line...
		vert=$[ ( $RANDOM % ( 256 / 16 ) + 2 ) ]
		# There IS a FLAW here at _printf_, NOTE, not a bug! What is it? ;o)
		printf "\x1B["$vert";"$horiz"fo"
		# Slow it down so you can see it working...
		sleep 0.05
	done
	printf "\x1B[20;1f"
	sleep 1
done

Enjoy finding simple solutions to often very difficult problems... ;o)

Bazza, G0LCU...

EDIT: Changed the shebang line; many thanks to Scrutinizer...

One little problem with the script is that the shebang on line 1 is not correct in two ways:

# !/bin/sh

There is a space between # and ! so it does not function as a shebang, but as a comment.

And also the script is clearly a bash script, not a sh script, so the shebang should be

#!/bin/bash

for example..

Hi Scrutinizer...

Thanks for the info...

I hadn't noticed the space. Will correct next time. And I check the code on DEFAULT terminals/shells on many Linux flavours as well is this Macbook Pro, (which just happens to be bash)...

If it did not work for you then I would gladly have a description of the error and I will correct if possible accordingly...

If it did work then your shell/terminal would be of interest too...

Again thanks for the info...

Bazza, G0LCU...

EDIT: BTW That was not the flaw... ;o)

Simple example. If the interactive shell is ksh for example, then your script will not run correctly:

$ ksh
$ ./AudioScopeDisplay.sh
./AudioScopeDisplay.sh: line 10: syntax error at line 41: `(' unexpected
$

If you use the correct shebang, then it will run.

Also if you use #!/bin/sh on Ubuntu for example, it will not work...
On other linux distributions #!/bin/sh calls bash --posix which also will not always work like bash.
If you use a shebang then it should call the shell that the script is supposed to work with..

1 Like

Hi Scrutinizer...

I went offline and tried various shells from this Macbook Pro and found the "ksh" error...

Thanks for pointing it out, and edited the code...

I like being corrected and log it down in the old grey matter... ;o)

"sh" worked OK, as did "csh"...

Although an amateur, and old, I learn very quickly... ;o)

Cheers...

Bazza, G0LCU...

This is the next stage...

It alters the size of the Terminal window down in size from 80 x 24 to 66 x 24...

Now in colour and has pseudo-windows for a status line and a command line...

The plotting delay is now removed...

/dev/dsp will be accessed next to give e pseudo-realtime scan...

Any takers want to try it out and pass on any constructive tips...

TIA...

(Watch for wordwrapping, etc.)

Bazza, G0LCU...

Hi all...

A real sample can now be displayed using SoX and the internal microphone of a netbook, laptop, etc...

Just download and install "SoX" command line _sound_(exchange)_system_...

There is also a line using /dev/dsp in default 8000KHz sampling speed but I haven't tested it yet...

You will have to change the "demo" variable from 0 to 1 for /dev/dsp or -1 for SoX. If you use SoX then change the pointer to the correct absolute address of your install...

Colours changed and decided on going back to the default 80 x 24 Terminal size...

Are you running sox once per loop? Why not run it once and just read from it as long as you need?

sox | while true
do
        DATA=$(dd bs=8192 count=1) # Get 8K bytes from the stream
done

That might solve some timing too, since you'd only get data as fast as sox captures it...

This is a new updated version of the AudioScope with limited scans which can be from single shot storage to pseudo-continuous.

Beware when altering any values as there is NO error detection as yet.

Now starting to create _functions_ as this becomes more mature...

Corona688, just eyeballed your upload and will see if it fits my requirements...

Well this script code is now taking shape...

Apologies for any typos...

It has some _command_line_ stuff to alter certain parameters and a few status line updates.

The _commands_ are not case sensitive and there is a starter help window built in also.

HELP and some other commands will auto switch from capture mode to rerun mode displaying the last capture taken. READ THE CODE for more information...

There is a commented out section that would, if edited according to the instructions in the code, generate another shell script and run it in a separate terminal. This will generate an 8 second burst of 1KHz sinewave and as long as the window is the active one just press ENTER to keep rerunning or Ctrl-C to quit the script and close down the terminal...

Connecting the output of the signal to the mic input and adjusting the audio system's gain controls will display a nice sinewave within the limits of standard text mode...

If you edit and run the generator script then SOX must be installed...

I hope this will become a practical kids learning tool along with some simple HW construction in the not too distant future...

As you will see almost EVERYTHING that is needed for testing, calibration running and the like will be generated from this one script only...

Enjoy...

Changes made so that the start position of any timebase scan can be altered. The effective speed is not yet done. This will be the next upload. After that timebase calibration, then a means of saving the settings and being able to start the script with "your" user settings...

Minor changes made including removal of UPPERCASE conversion mode as this could still create a user error.

I hope you guys and gals taking a look at this are enjoying what you are seeing...

What started as a fun upload is evolving into something serious that 10 year olds could understand. I have tried to write the code in such a way as to make it as visaully noise free as possible to youngsters.

Watch for wordwrapping, etc...

To the Admins; thanks for allowing me to do this...

Bazza...

User variable timebase is now complete.

The command is TBVAR then follow the prompts...

It is _in_theory_ error free when typing in wrong characters and/or values... ;o)

The "scan_jump" variable sets the timebase speed, number 1 is the fastest and the maximium allowable number is the slowest and varies according to the "scan_start" position.

The next upload will be the _calibrated_ timebase ranges...

The oscillator commented out of the code will probably be used for checking this...

These will probably be FASTEST, 1mS, 10mS, 100mS and SLOW...

DEMO will not be able to have FASTEST and 1mS.

/dev/dsp will not be able to have FASTEST...

This is slowly evolving into fully working tool...

Watch for wordwrapping, etc...

I think case statements could shrink your kbinput and status checks a lot:

case "$kbinput" in
TEN)  echo "got TEN"
        ;;
HUNDRED) echo "got HUNDRED"
        ;;
...
*) echo "Unknown kbinput"
    ;;
esac

For tiny if-statements with only one thing in them, you can use && shortcuts:

[ $hold -eq 1 ] && waveform

Hi Corona688...

Apologies for any typos...

Thanks for the heads up, you are a real pal...

I will fork the existing code and shorten it in your style but upload the longhand version for the foreseeable future.

I have done it this way so that a 10 year old can see the progression.

Does it show that much that I am an amateur... ;o)

BTW, calibrated timebase ranges are finished and coupling the earphone output to the mic input and setting the levels accordingly works a treat. Also added a small offset to ensure that the trace is linear when there is zero input. This removes the sound card's mid point bit error...

Working on a config file now so that user parameters can be saved and auto-restarted. This will take a while...

Bazza...

1 Like

Before you get too carried away with that, you can use the shell's ability to source files to do that simply. If you can print a file like this:

VAR1="value"
VAR2="value"
VAR3="value"
SOMEOTHERVAR="value"

then you can directly load it like . /path/to/configfile

1 Like

Oh, and you can dump a lot of variables at once in a loop in BASH shell:

for VAR in A B C D E
do
        echo "$VAR=\"${!VAR}\""
done > ~/.scoperc

$VAR is the variable name, for example A. ${!VAR} is interpreted by the shell's name to mean the contents of variable A, as if you'd done ${A}.

Hi Corona688...

Thanks a mill' I will certainly take your advice.

FTTB here is the last of the timebase uploads, less _trigger_ modes, and including the first ultra-simple circuit for the MacBook Pro 13 inch as a comment right at the end of the script.

It includes an offset to allow for sound card midpoint bit error...

I intend to have eveything for basic calibration as part of the script, incuding ultra simple circuits, and matching code if required...

There is now a commented out sinewave generator for Linux machines with /dev/dsp to experiment with...

Although the circuit remains the same the people experimenting will have to work out the dual Stereo I/O plugs wiring for themselves...

Best viewed in plain text mode and watch for wordwrapping, etc...

Hi Corona688...

That small snippet that saves and loads a config file seems to work an absolute dream.
Simplicity at its best, _noise_ free to kids that might view it.

Test code "config.sh"; only tested on this Macbook Pro, assuming my Debian works too.

scan_start=0
scan_jump=1
zero_offset=0
speed="FASTEST"
> /tmp/AudioScope.config
chmod 777 /tmp/AudioScope.config
printf "scan_jump=12\n" >> /tmp/AudioScope.config
printf "scan_start=6\n" >> /tmp/AudioScope.config
printf "speed='10mS'\n" >> /tmp/AudioScope.config
printf "zero_offset=0\n" >> /tmp/AudioScope.config
. /tmp/AudioScope.config
sleep 1
printf "$scan_start $scan_jump $zero_offset $speed\n"

(Just shows how little I know compared to the big guns.)

I am a very quick learner...

I sure am glad you are _on_my_side_... ;o)

Thanks a lot matey...

WIll now see how it works in the main script...

777 is not the magic sledgehammer to fix all permissions problems. It's certainly not a habit I want to teach to kids. 660, or even 600, should do(executable permission is not needed for a script you source). Or just leave it alone.

The traditional location for user config files is ${HOME}, aka ~/, more appropriate than /tmp/

Hi Corona688...

Point taken, except I always do this whilst testing and back down when proven or leave if I want things _global_...

Again I always tend to use the default /tmp/; C:\Windows\Temp; T: and so on as these are usually definitive on any particular platform invovled and you can clear them out as you like.
I've no idea if WIndows 8 (TM) has the ability to allow any/all users to R/W globally to C:\Windows\Temp as I haven't got it, nor do I want it...

My methods may not be the done practice but my motto is "get it working first then improve on it" using the KISS method...

LBNL if anything looks like _noise_ to a kid then I do it longhand for them to understand.

I don't deny that I know little compared to professionals code wise but I sure know how to get things like this project working to give kids a chance to do, and experiment with, for themselves... :slight_smile:

Your input has been a great asset and saved me searching for things I don't know about, however, KISS is also extremely important to me...

HTH, G'Night...