This code is the latest as of 19-06-2013. It is an AudioScope designed around a Macbook Pro 13" of which only has ONE microphone input. It works under Linux variants too. Read the code for much more info.
It was my way of learning Bash scripting.
It is resident here at this site:-
http://www.unix.com/shell-programming-scripting/212939-start-simple-audio-scope-shell-script.html
It started off as a fun idea and is now becoming a very serious project.
As it stands this is fully working but it is uncalibrated and this is where it will stay on this site.
As the above site is the host then all future uploads will be there...
To do list...
DC input. [1] DC polarity. [1] 2 more Internal sync modes. External triggering. Zoom facility - if possible in text mode. Vertical calibration. [2] Frequency measurement. {3] (Others.)
[1] I have simple HW built as an idea but yet to prove it... [2] Preliminary HW built but not yet used. Calibration SW and circuit(s) to be built into script as it progresses. [3] I already have a working script but not completely satisfied at it at this point...
I am noing to say much else except that it has already been given a 5 star rating on the above UNIX site...
As it stands this code is entirely Public Domian and you may do with it as you please...
Enjoy something completely different using Bash scripting...
Finally the code defaults to a DEMO mode which requires no HW access at all but everything is still functional...
__Thoroughly__ read the code for more information...
As a circuit is inside the script then it is best viewed in plan text mode.
Bazza, G0LCU.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 | #!/bin/bash
#
# AudioScope.sh
#
# At this point I will include and say thank you to "Corona688", a member of http://www.unix.com for his input...
# Also to others on the same site for their input too.
# Many thanks also go to the guys who have helped with this on http://www.linuxformat.com for all your input too...
#
# Tested in SOX mode on this Macbook Pro 13 inch, OSX 10.7.5 with the SOX sinewave generator enabled.
# Tested in /dev/dsp mode on an aging HP notebook running Debian 6.0.x with the /dev/dsp sinewave generator enabled.
# Tested in /dev/dsp mode on an Acer Aspire One netbook booting from a USB stick running PCLinuxOS 2009; also with
# the /dev/dsp sinewave generator enabled.
# Tested on all three in DEMO mode.
#
# Added the first simple circuit at the end of this script.
#
# Relevant pointers to help:-
# http://wisecracker.host22.com/public/AudioScope_Manual.readme
# http://wisecracker.host22.com/public/cal_draw.jpg
# http://wisecracker.host22.com/public/cal_plot.jpg
# http://wisecracker.host22.com/public/mic_ear1.jpg
# http://wisecracker.host22.com/public/mic_ear2.jpg
# http://wisecracker.host22.com/public/mic_ear3.jpg
# http://wisecracker.host22.com/public/mic_ear4.jpg
#
# The latest vesrion will always be here:-
# http://www.unix.com/shell-programming-scripting/212939-start-simple-audio-scope-shell-script.html
#
# NOTE TO SELF:- Remove "/tmp" and replace with "~" when ready, AND, "/tmp" is automatically cleared on this machine per reboot.
# #########################################################
# FOR SOund eXchance USERS ONLY!!! TESTED!!!
# The lines below, from ">" to "xterm", will generate a new shell script and execute it in a new xterm terminal...
# Just EDIT out the comments and then EDIT the line pointing to the correct </full/path/to/sox/> to use it.
# It assumes that you have SoX installed. When this script is run it generates a 1KHz sinewave in a separate window
# that lasts for 8 seconds. Just press ENTER when this window is active and it will repeat again. To quit this script
# and close the window just press Ctrl-C. This generator will be needed for the calibration of some timebase ranges.
#> /tmp/1KHz-Test.sh
#chmod 744 /tmp/1KHz-Test.sh
#printf '#!/bin/bash\n' >> /tmp/1KHz-Test.sh
#printf '> /tmp/sinewave.raw\n' >> /tmp/1KHz-Test.sh
#printf 'data="\\\\x80\\\\x26\\\\x00\\\\x26\\\\x7F\\\\xD9\\\\xFF\\\\xD9"\n' >> /tmp/1KHz-Test.sh
#printf 'for waveform in {0..8191}\n' >> /tmp/1KHz-Test.sh
#printf 'do\n' >> /tmp/1KHz-Test.sh
#printf ' printf "$data" >> /tmp/sinewave.raw\n' >> /tmp/1KHz-Test.sh
#printf 'done\n' >> /tmp/1KHz-Test.sh
#printf 'while true\n' >> /tmp/1KHz-Test.sh
#printf 'do\n' >> /tmp/1KHz-Test.sh
#printf ' /full/path/to/sox/play -b 8 -r 8000 -e unsigned-integer /tmp/sinewave.raw\n' >> /tmp/1KHz-Test.sh
#printf ' read -p "Press ENTER to rerun OR Ctrl-C to quit:- " -e kbinput\n' >> /tmp/1KHz-Test.sh
#printf 'done\n' >> /tmp/1KHz-Test.sh
#sleep 1
#xterm -e /tmp/1KHz-Test.sh &
# #########################################################
# FOR /dev/dsp USERS ONLY!!! TESTED!!!
# The lines below, from ">" to "xterm", will generate a new shell script and execute it in a new xterm terminal...
# Just EDIT out the comments to use it.
# It assumes that you have /dev/dsp _installed_. When this script is run it generates a 1KHz sinewave in a separate window
# that lasts for 8 seconds. Just press ENTER when this window is active and it will repeat again. To quit this script
# and close the window just press Ctrl-C. This generator will be needed for the calibration of some timebase ranges.
#> /tmp/1KHz-Test.sh
#chmod 744 /tmp/1KHz-Test.sh
#printf '#!/bin/bash\n' >> /tmp/1KHz-Test.sh
#printf '> /tmp/sinewave.raw\n' >> /tmp/1KHz-Test.sh
#printf 'data="\\\\x80\\\\x26\\\\x00\\\\x26\\\\x7F\\\\xD9\\\\xFF\\\\xD9"\n' >> /tmp/1KHz-Test.sh
#printf 'for waveform in {0..8191}\n' >> /tmp/1KHz-Test.sh
#printf 'do\n' >> /tmp/1KHz-Test.sh
#printf ' printf "$data" >> /tmp/sinewave.raw\n' >> /tmp/1KHz-Test.sh
#printf 'done\n' >> /tmp/1KHz-Test.sh
#printf 'while true\n' >> /tmp/1KHz-Test.sh
#printf 'do\n' >> /tmp/1KHz-Test.sh
#printf ' cat /tmp/sinewave.raw > /dev/dsp\n' >> /tmp/1KHz-Test.sh
#printf ' read -p "Press ENTER to rerun OR Ctrl-C to quit:- " -e kbinput\n' >> /tmp/1KHz-Test.sh
#printf 'done\n' >> /tmp/1KHz-Test.sh
#sleep 1
#xterm -e /tmp/1KHz-Test.sh &
# #########################################################
# Variables in use.
ifs_str=$IFS
version=" \$VER: AudioScope.sh_Version_0.00.70_PD_B.Walker_G0LCU. "
setup=" Please wait while the very first scan and configuration file is generated. "
# Default first time run capture mode, 0 = DEMO.
demo=0
# Draw proceedure mode, 0 = OFF
drawline=0
# Pseudo-continuous data file saving.
savefile="0000000000"
save_string="OFF"
# "hold" and "status" will always be reset to "1" on program exit.
hold=1
status=1
# "count", "number" and "char" are reusable variables...
count=0
number=0
char="?"
# Vertical components...
# vert_one and vert_two are the vertical plotting points for the draw() function...
vert_one=2
vert_two=2
vert=12
vert_shift=2
vshift="?"
vert_array=""
vert_draw=9
# Display setup...
graticule="Public Domain, 2013, B.Walker, G0LCU."
# Keyboard components...
kbinput="?"
tbinput=1
# "str_len" is a reusable variable IF required...
str_len=1
# "grab" is used for internal pseudo-synchronisation...
grab=0
# "zero_offset" can only be manually changed in the AudioScope.config file, OR, here...
zero_offset=-2
# Horizontal components...
horiz=9
# Scan retraces...
scan=1
scanloops=1
# Timebase variable components...
subscript=0
# "scan_start" is from 0 to ( length of file - 64 )...
scan_start=0
# "scan_jump" is from 1 to ( ( ( scan_end - scan_start ) / 64) + 1 )...
scan_jump=1
# "scan_end" is at least 64 bytes in from the absolute file end...
scan_end=47935
# Synchronisation variables...
# synchronise switches the syncchroisation ON or OFF...
synchronise="OFF"
# sync_point is any value between 15 and 240 of the REAL grab(s)...
sync_point=128
sync_input="?"
# #########################################################
# Add the program tilte to the Terminal title bar...
# This may NOT work in every Terminal so just comment it out if it doesn't.
printf "\x1B]0;Shell AudioScope.\x07"
# #########################################################
# Generate a config file and temporarily store inside /tmp
if [ -f /tmp/AudioScope.config ]
then
. /tmp/AudioScope.config
else
user_config
fi
user_config()
{
> /tmp/AudioScope.config
chmod 644 /tmp/AudioScope.config
printf "demo=$demo\n" >> /tmp/AudioScope.config
printf "drawline=$drawline\n" >> /tmp/AudioScope.config
printf "hold=1\n" >> /tmp/AudioScope.config
printf "status=1\n" >> /tmp/AudioScope.config
printf "zero_offset=$zero_offset\n" >> /tmp/AudioScope.config
printf "scanloops=$scanloops\n" >> /tmp/AudioScope.config
printf "scan_start=$scan_start\n" >> /tmp/AudioScope.config
printf "scan_jump=$scan_jump\n" >> /tmp/AudioScope.config
printf "scan_end=$scan_end\n" >> /tmp/AudioScope.config
printf "vert_shift=$vert_shift\n" >> /tmp/AudioScope.config
printf "setup='$setup'\n" >> /tmp/AudioScope.config
printf "save_string='$save_string'\n" >> /tmp/AudioScope.config
}
# #########################################################
# Screen display setup function.
display()
{
# Set foregound and background graticule colours and foreground and background other window colours.
printf "\x1B[0;36;44m"
clear
graticule=" +-------+-------+-------+---[\x1B[0;37;44mDISPLAY\x1B[0;36;44m]---+-------+-------+--------+ \n"
graticule=$graticule" | | | | + | | | | \n"
graticule=$graticule" | | | | + | | | | \n"
graticule=$graticule" | | | | + | | | | \n"
graticule=$graticule" +-------+-------+-------+-------+-------+-------+-------+--------+ < \n"
graticule=$graticule" | | | | + | | | | \n"
graticule=$graticule" | | | | + | | | | \n"
graticule=$graticule" | | | | + | | | | \n"
graticule=$graticule" 0 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+ < \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" \x1B[0;37;40m+-----------------------------[COMMAND WINDOW]------------------------------+\x1B[0;37;44m \n"
graticule=$graticule" \x1B[0;37;40m| COMMAND:- |\x1B[0;37;44m \n"
graticule=$graticule" \x1B[0;37;40m+------------------------------[STATUS WINDOW]-------------------------------+\x1B[0;37;44m \n"
graticule=$graticule" \x1B[0;37;40m| Stopped... |\x1B[0;37;44m \n"
graticule=$graticule" \x1B[0;37;40m|$setup|\x1B[0;37;44m \n"
graticule=$graticule" \x1B[0;37;40m+----------------------------------------------------------------------------+\x1B[0;37;44m "
printf "$graticule"
# Set the colours for plotting.
printf "\x1B[1;37;44m"
}
# #########################################################
# Pick which method to capture, (and store), the waveform on the fly.
waveform()
{
> /tmp/waveform.raw
chmod 644 /tmp/waveform.raw
# Demo mode, generate 48000 bytes of random data.
if [ $demo -eq 0 ]
then
# Use "sleep" to simulate a 1 second burst.
sleep 1
# "/dev/urandom is now used instead of RANDOM as it is MUCH faster.
dd if=/dev/urandom of=/tmp/waveform.raw bs=48000 count=1
fi
# Using the aging(/old) /dev/dsp device, mono, 8 bits per sample and 8KHz sampling rate, 8000 unsigned-integer bytes of data...
# Now tested on PCLinuxOS 2009 and Debian 6.0.x.
if [ $demo -eq 1 ]
then
# This uses the oss-compat installation from your distro's repository...
dd if=/dev/dsp of=/tmp/waveform.raw bs=8000 count=1
fi
# The main means of obtaining the unsigned-integer data, using SoX, (Sound eXcahnge) from http://sox.sourceforge.net ...
if [ $demo -eq 2 ]
then
# Change the absolute address for your location of "sox"...
/Users/barrywalker/Downloads/sox-14.4.0/sox -q -V0 -d -t raw -r 48000 -b 8 -c 1 -e unsigned-integer -> /tmp/waveform.raw trim 0 00:01
fi
}
# #########################################################
# Plot the points inside the window...
plot()
{
subscript=$scan_start
vert_array=""
for horiz in {9..72}
do
vert=`hexdump -n1 -s$subscript -v -e '1/1 "%u"' /tmp/waveform.raw`
# Add a small offset to give a straight line with zero input allowing for mid-point sound card bit error.
vert=$[ ( $vert + $zero_offset ) ]
if [ $vert -le 0 ]
then
vert=0
fi
if [ $vert -ge 255 ]
then
vert=255
fi
# Pseudo-vertical shift of + or - 1 vertical division maximum.
vert=$[ ( ( $vert / 16 ) + $vert_shift ) ]
# Ensure the plot is NOT out of bounds after moving the shift position.
if [ $vert -le 2 ]
then
vert=2
fi
if [ $vert -ge 17 ]
then
vert=17
fi
subscript=$[ ( $subscript + $scan_jump ) ]
# Generate a smple space delimited 64 sample array.
vert_array="$vert_array$vert "
printf "\x1B[1;37;44m\x1B["$vert";"$horiz"f*"
done
# Set end of plot to COMMAND window.
printf "\x1B[0;37;40m\x1B[20;14f"
}
# #########################################################
# This function connects up the plotted points.
# Defaults to OFF on the very first time run and must be manually enabled if needed.
draw()
{
statusline
IFS=" "
subscript=0
number=0
vert_one=2
vert_two=2
vert_draw=( $vert_array )
for horiz in {9..71}
do
# Obtain the two vertical components.
vert_one=${vert_draw[ $subscript ]}
subscript=$[ ( $subscript + 1 ) ]
vert_two=${vert_draw[ $subscript ]}
# Now subtract them and obtain an absolute value - ALWAYS 0 to positive...
number=$[ ( $vert_two - $vert_one ) ]
number=${number#-}
# This decision section _is_ needed.
if [ $number -le 1 ]
then
: # NOP. Do nothing...
fi
# This section does the drawing...
if [ $number -ge 2 ]
then
if [ $vert_one -gt $vert_two ]
then
vert_one=$[ ( $vert_one - 1 ) ]
while [ $vert_one -gt $vert_two ]
do
printf "\x1B[1;37;44m\x1B["$vert_one";"$horiz"f*"
vert_one=$[ $vert_one - 1 ]
done
fi
if [ $vert_two -gt $vert_one ]
then
vert_one=$[ ( $vert_one + 1 ) ]
while [ $vert_one -lt $vert_two ]
do
printf "\x1B[1;37;44m\x1B["$vert_one";"$horiz"f*"
vert_one=$[ $vert_one + 1 ]
done
fi
fi
IFS=$ifs_str
done
# Set end of plot to COMMAND window.
printf "\x1B[0;37;40m\x1B[20;14f"
}
# #########################################################
# This is the information line _parser_...
statusline()
{
printf "\x1B[0;37;40m\x1B[22;3f \x1B[22;4f"
if [ $status -eq 0 ]
then
printf "Stopped..."
fi
if [ $status -eq 1 ]
then
printf "Running $scan of $scanloops scans..."
fi
if [ $status -eq 2 ]
then
printf "Running in single shot storage mode..."
fi
if [ $status -eq 3 ]
then
printf "Drawing the scan..."
fi
if [ $status -eq 4 ]
then
printf "Synchroniastion set to $sync_point$synchronise..."
fi
if [ $status -eq 5 ]
then
printf "CAUTION, AUTO-SAVING FACILITY ENABLED!!!"
fi
if [ $status -eq 254 ]
then
status=1
setup=$version
printf "\x1B[23;3f$setup"
fi
# Set end of plot to COMMAND window.
printf "\x1B[0;37;40m\x1B[20;14f"
}
# #########################################################
# All keyboard commands appear here when the scanning stops; there will be lots of them to make subtle changes...
kbcommands()
{
IFS=$ifs_str
status=1
scan=1
read -p "Press <CR> to (re)run, HELP or QUIT<CR> " -e kbinput
printf "\x1B[0;37;40m\x1B[20;14f "
# Rerun scans captured or stored.
if [ "$kbinput" == "" ]
then
status=1
statusline
fi
# Run scans in captured, (REAL scan), mode only.
if [ "$kbinput" == "RUN" ]
then
status=1
hold=1
statusline
fi
# Swtich off capture mode and rerun one storage shot only, this disables the DRAW command.
# Use DRAW to re-enable again. This is deliberate for slow machines...
if [ "$kbinput" == "HOLD" ]
then
drawline=0
status=2
hold=0
scanloops=1
statusline
sleep 1
fi
# Quit the program.
if [ "$kbinput" == "QUIT" ]
then
status=255
break
fi
# Display the _online_ HELP file in default terminal colours.
if [ "$kbinput" == "HELP" ]
then
status=0
scanloops=1
hold=0
commandhelp
fi
# Enable DEMO pseudo-capture mode, default, but with 10 sweeps...
if [ "$kbinput" == "DEMO" ]
then
status=1
scan_start=0
scan_jump=1
scanloops=10
scan_end=47935
demo=0
hold=1
statusline
sleep 1
fi
# Enable /dev/dsp capture mode, if your Linux flavour does NOT have it, install oss-compat from the distro's repository.
# This is the mode used to test on Debian 6.0.x and now PCLinuxOS 2009...
if [ "$kbinput" == "DSP" ]
then
status=1
scan_start=0
scan_jump=1
scanloops=1
scan_end=7935
hold=1
demo=1
statusline
sleep 1
fi
# Eable SOX capture mode, this code is designed around this application on a Macbook Pro 13 inch OSX 10.7.5...
if [ "$kbinput" == "SOX" ]
then
status=1
scan_start=0
scan_jump=1
scanloops=1
scan_end=47935
hold=1
demo=2
statusline
sleep 1
fi
# The next three commands set the timebase scans; 1, 10 or 100 before COMMAND mode is re-enabled and can be used.
if [ "$kbinput" == "ONE" ]
then
status=1
scanloops=1
hold=1
fi
if [ "$kbinput" == "TEN" ]
then
status=1
scanloops=10
hold=1
fi
if [ "$kbinput" == "HUNDRED" ]
then
status=1
scanloops=100
hold=1
fi
if [ "$kbinput" == "VER" ]
then
status=254
fi
# ************ Horizontal components. *************
# ************ User timebase section. *************
# Written longhand for kids to understand.
if [ "$kbinput" == "TBVAR" ]
then
# Ensure capture mode is turned off.
# RUN<CR> will re-enable it if required.
scanloops=1
status=1
hold=0
printf "\x1B[0;37;40m\x1B[20;14f"
read -p "Set timebase starting point. From 0 to $scan_end<CR> " -e tbinput
printf "\x1B[0;37;40m\x1B[20;14f \x1B[0;37;40m\x1B[20;14f"
# Ensure the timebase values are set to default before changing.
scan_start=0
scan_jump=1
# Eliminate any keyboard error longhand...
# Ensure a NULL string does NOT exist.
if [ "$tbinput" == "" ]
then
scan_start=0
tbinput=0
fi
# Find the length of the inputted string.
str_len=`printf "${#tbinput}"`
# Set the string to the correct last position for the _subscript_ point.
str_len=$[ ( $str_len - 1 ) ]
# Now check for continuous numerical charaters ONLY.
for count in $( seq 0 $str_len )
do
# Reuse variable _number_ to obtain each character per loop.
number=`printf "${tbinput:$count:1}"`
# Now convert the character to a decimal number.
number=`printf "%d" \'$number`
# IF ANY ASCII character exists that is not numerical then reset the scan start point.
if [ $number -le 47 ]
then
scan_start=0
tbinput=0
fi
if [ $number -ge 58 ]
then
scan_start=0
tbinput=0
fi
done
# If all is OK pass the "tbinput" value into the "scan_start" variable.
scan_start=$tbinput
# Do a final check that the number is not out of bounds.
if [ $scan_start -le 0 ]
then
scan_start=0
fi
if [ $scan_start -ge $scan_end ]
then
scan_start=$scan_end
fi
# Use exactly the same method as above to determine the jump interval.
# Now set the jump interval, this is the scan speed...
printf "\x1B[0;37;40m\x1B[20;14f"
read -p "Set timebase user speed. From 1 to $[ ( ( ( ( $scan_end - $scan_start ) / 64 ) + 1 ) ) ]<CR> " -e tbinput
printf "\x1B[0;37;40m\x1B[20;14f \x1B[0;37;40m\x1B[20;14f"
# Eliminate any keyboard error longhand...
# Ensure a NULL string does NOT exist.
if [ "$tbinput" == "" ]
then
scan_jump=1
tbinput=1
fi
# Find the length of the inputted string.
str_len=`printf "${#tbinput}"`
# Set the string to the correct last position for the _subscript_ point.
str_len=$[ ( $str_len - 1 ) ]
# Now check for continuous numerical charaters ONLY.
for count in $( seq 0 $str_len )
do
# Reuse variable _number_ to obtain each character per loop.
number=`printf "${tbinput:$count:1}"`
# Now convert the character to a decimal number.
number=`printf "%d" \'$number`
# IF ANY ASCII character exists that is not numerical then reset the scan jump value.
if [ $number -le 47 ]
then
scan_jump=1
tbinput=1
fi
if [ $number -ge 58 ]
then
scan_jump=1
tbinput=1
fi
done
# If all is OK pass the "tbinput" value into the "scan_jump" variable.
scan_jump=$tbinput
# Do a final check that the number is not out of bounds.
if [ $scan_jump -le 1 ]
then
scan_jump=1
fi
# Reuse number for upper limit...
number=$[ ( ( ( $scan_end - $scan_start ) / 64 ) + 1 ) ]
if [ $scan_jump -ge $number ]
then
scan_jump=$number
fi
printf "\x1B[0;37;40m\x1B[22;4fScan start at offset $scan_start, with a jump rate of $scan_jump."
sleep 1
setup=" Uncalibrated horizontal scan, vertical and storage modes, AC coupled only. "
fi
# ********** User timebase section end. ***********
# ********* Calibrated timebase section. **********
if [ "$kbinput" == "FASTEST" ]
then
scan_start=0
scan_jump=1
setup=" Uncalibrated horizontal scan, vertical and storage modes, AC coupled only. "
fi
if [ "$kbinput" == "1mS" ]
then
scan_start=0
setup=" 1mS/DIV, uncalibrated vertical and storage modes, AC coupled only. "
if [ $demo -eq 0 ]
then
scan_jump=6
fi
if [ $demo -eq 1 ]
then
scan_jump=1
fi
if [ $demo -eq 2 ]
then
scan_jump=6
fi
fi
if [ "$kbinput" == "10mS" ]
then
scan_start=0
setup=" 10mS/DIV, uncalibrated vertical and storage modes, AC coupled only. "
if [ $demo -eq 0 ]
then
scan_jump=60
fi
if [ $demo -eq 1 ]
then
scan_jump=10
fi
if [ $demo -eq 2 ]
then
scan_jump=60
fi
fi
if [ "$kbinput" == "100mS" ]
then
scan_start=0
setup=" 100mS/DIV, uncalibrated vertical and storage modes, AC coupled only. "
if [ $demo -eq 0 ]
then
scan_jump=600
fi
if [ $demo -eq 1 ]
then
scan_jump=100
fi
if [ $demo -eq 2 ]
then
scan_jump=600
fi
fi
# *********** Calibrated timebase end. ************
#
# ************* Vertical components. **************
# ******** Pseudo-vertical shift control. *********
if [ "$kbinput" == "SHIFT" ]
then
while true
do
scanloops=1
status=1
hold=0
printf "\x1B[0;37;40m\x1B[20;14f"
# This input method is something akin to BASIC's INKEY$...
read -p "Vertical shift:- U for up 1, D for down 1, <CR> to RETURN:- " -n 1 -s vshift
printf "\x1B[0;37;40m\x1B[20;14f \x1B[0;37;40m\x1B[20;14f"
if [ "$vshift" == "" ]
then
break
fi
if [ "$vshift" == "D" ]
then
vert_shift=$[ ( $vert_shift + 1 ) ]
fi
if [ "$vshift" == "U" ]
then
vert_shift=$[ ( $vert_shift - 1 ) ]
# Ensure the shift psoition is NOT out of bounds.
fi
if [ $vert_shift -ge 6 ]
then
vert_shift=6
fi
if [ $vert_shift -le -2 ]
then
vert_shift=-2
fi
printf "\x1B[23;3f Vertical shift is $[ ( 2 - $vert_shift ) ] from the mid-point position... "
done
fi
# ****** Pseudo-vertical shift control end. *******
# ********** Connect all plotted points. **********
if [ "$kbinput" == "DRAW" ]
then
drawline=1
status=3
hold=0
scanloops=1
statusline
sleep 1
fi
# ************* Connected plots done. *************
#
# **** PSEUDO synchronisation and triggering. ****
if [ "$kbinput" == "TRIG" ]
then
synchronise=" and OFF"
sync_point=128
status=0
hold=0
scan_start=$[ ( $scan_start + 1 ) ]
scan_jump=1
scanloops=1
subscript=$scan_start
grab=0
if [ $scan_start -ge $scan_end ]
then
scan_start=0
break
fi
printf "\x1B[0;37;40m\x1B[20;14f"
read -p "Set trigger type, <CR> to disable:- " -e kbinput
printf "\x1B[0;37;40m\x1B[20;14f \x1B[0;37;40m\x1B[20;14f"
if [ "$kbinput" == "SYNCEQ" ]
then
synchronise=", ON and fixed"
trigger
for subscript in $( seq $scan_start $scan_end )
do
grab=`hexdump -n1 -s$subscript -v -e '1/1 "%u"' /tmp/waveform.raw`
if [ $grab -eq $sync_point ]
then
scan_start=$subscript
break
fi
done
fi
if [ "$kbinput" == "SYNCGT" ]
then
synchronise=", ON and positive going"
trigger
: # NOP... Place holder only.
fi
if [ "$kbinput" == "SYNCLT" ]
then
synchronise=", ON and negative going"
trigger
: # NOP... Place holder only...
fi
if [ "$kbinput" == "EXT" ]
then
# Remember Corona688's code from the early stages of this thread...
synchronise=", EXTERNAL and waiting"
: # NOP... Place holder only,
fi
status=4
statusline
sleep 1
fi
# ** PSEUDO synchronisation and triggering end. ***
#
# ************* Auto-saving facility. *************
if [ "$kbinput" == "SAVEON" ]
then
status=5
save_string="ON"
statusline
sleep 2
fi
if [ "$kbinput" == "SAVEOFF" ]
then
status=1
save_string="OFF"
statusline
fi
# *********** Auto-saving facility end. ***********
statusline
}
# #########################################################
# Help clears the screen to the startup defaults and prints command line help...
commandhelp()
{
status=2
hold=0
printf "\x1B[0m"
clear
printf "CURRENT COMMANDS AVAILABLE:-\n\n"
printf "<CR> ................................................. Reruns the scan(s) again.\n"
printf "RUN<CR> ......................... Reruns the scan(s), always with real captures.\n"
printf "QUIT<CR> .................................................... Quits the program.\n"
printf "HELP<CR> ................................................ This help as required.\n"
printf "HOLD<CR> ........................................ Switch to pseudo-storage mode.\n"
printf "DEMO<CR> .......... Switch capture to default DEMO mode and 10 continuous scans.\n"
printf "DSP<CR> ...................... Switch capture to Linux /dev/dsp mode and 1 scan.\n"
printf "SOX<CR> ....... Switch capture to multi-platform SOund eXchange mode and 1 scan.\n"
printf "ONE<CR> ......................................... Sets the number of scans to 1.\n"
printf "TEN<CR> ........................................ Sets the number of scans to 10.\n"
printf "HUNDRED<CR> ............. Sets the number of scans to 100, (not very practical).\n"
printf "VER<CR> .................. Displays the version number inside the status window.\n"
printf "TBVAR<CR> ............ Set up uncalibrated user timebase offset and jump points.\n"
printf " SubCommands: ............................. Follow the on screen prompts.\n"
printf "FASTEST<CR> .................. Set all modes to the fastest possible scan speed.\n"
printf "1mS<CR> .......................................... Set scanning rate to 1mS/DIV.\n"
printf "10mS<CR> ........................................ Set scanning rate to 10mS/DIV.\n"
printf "100mS<CR> ...................................... Set scanning rate to 100mS/DIV.\n"
printf "SHIFT<CR> ............ Set the vertical position from -4 to +4 to the mid-point.\n"
printf " SubCommands: ............ Press U or D then <CR> when value is obtained.\n"
printf "\n"
read -p "Press <CR> to continue:- " -e kbinput
clear
printf "CURRENT COMMANDS AVAILABLE:-\n\n"
printf "DRAW<CR> .......... Connect up each vertical plot to give a fully lined display.\n"
printf "TRIG<CR> ........... Sets the synchronisation methods for storage mode retraces.\n"
printf " SubCommand: SYNCEQ ........ Set the internal SYNC to a fixed value only.\n"
printf " SubCommand: SYNCGT ......................................... Unfinished.\n"
printf " SubCommand: SYNCLT ......................................... Unfinished.\n"
printf " SubCommand: EXT ............................................ Unfinished.\n"
printf "SAVEON<CR> .................... Auto-saves EVERY scan with a numerical filename.\n"
printf "SAVEOFF<CR> ....................................... Disables auto-save facility.\n"
printf "\n"
printf "Manual here: < http://wisecracker.host22.com/public/AudioScope_Manual.readme >\n"
printf "\n"
read -p "Press <CR> to continue:- " -e kbinput
display
statusline
}
# #########################################################
# This is the active part of the pseudo-synchroisation section.
trigger()
{
while true
do
printf "\x1B[0;37;40m\x1B[20;14f"
# This input method is something akin to BASIC's INKEY$...
read -p "Sync point:- U for up 1, D for down 1, <CR> to RETURN:- " -n 1 -s sync_input
printf "\x1B[0;37;40m\x1B[20;14f \x1B[0;37;40m\x1B[20;14f"
if [ "$sync_input" == "" ]
then
break
fi
if [ "$sync_input" == "U" ]
then
sync_point=$[ ( $sync_point + 1 ) ]
fi
if [ "$sync_input" == "D" ]
then
sync_point=$[ ( $sync_point - 1 ) ]
# Ensure the synchronisation point is NOT out of bounds.
fi
if [ $sync_point -ge 240 ]
then
sync_point=240
fi
if [ $sync_point -le 15 ]
then
sync_point=15
fi
printf "\x1B[23;3f Synchronisation point set to $sync_point... "
done
}
# #########################################################
# Do an initial screen set up...
display
statusline
setup=$version
# #########################################################
# This is the main loop...
while true
do
for scan in $( seq 1 $scanloops )
do
# "hold" determines a new captured scan or retrace of an existing scan...
if [ $hold -eq 1 ]
then
waveform
fi
display
statusline
plot
if [ $drawline -eq 1 ]
then
draw
fi
if [ "$save_string" == "ON" ]
then
savefile=`date +%s`
cp /tmp/waveform.raw /tmp/$savefile
fi
done
status=0
statusline
kbcommands
done
# #########################################################
# Getout, autosave AudioScope.config, cleanup and quit...
if [ $status -eq 255 ]
then
# Save the user configuration file.
user_config
# Remove "Shell AudioScope" from the title bar.
printf "\x1B]0;\x07"
sleep 0.1
# Reset back to normal...
printf "\x1B[0m"
clear
reset
fi
printf "\nProgram terminated...\n\nTerminal reset back to startup defaults...\n\n"
# #########################################################
# The FIRST extremely simple construction part.
# This is a simple I/O board for testing for the Macbook Pro 13 inch...
# It is just as easy to replace the 4 pole 3.5mm Jack Plug with 2 x 3.5mm Stereo Jack
# Plugs for machines with separate I/O sockets.
# Orange. White flylead.
# Tip -----> O <------------------------------------+---------O <----------+--------+
# Ring 1 --> H <-------------------------+-----------)--------O <- Blue. | |
# Ring 2 --> H <--------------+-----+-----)----------)--------O <- Yellow. | |
# _Gnd_ ---> H <----+ | C1 | + | | O <- Green. | |
# +===+ | \ ===== \ \ | \ |
# | | | / --+-- / / | / |
# P1 | | | \ | \ \ | \ |
# | | | R1 / | R2 / R3 / | R4 / |
# \ / | \ | \ \ | \ |
# H | / | / / | / |
# ~~~ | | | | | | | |
# +---------+------)---+----------+---------+------------+ |
# Pseudo-Ground. -> __|__ | |
# ///// +-----------------------------------------------+
# P1 ......... 3.5mm, 4 pole jack plug.
# R1 ......... 2K2, 1/8W, 5% tolerence resistor.
# R2, R3 ..... 33R, 1/8W, 5% tolerence resistor.
# R4 ......... 1M, 1/8W, 5% tolerence resistor.
# C1 ......... 47uF, 16V electrolytic.
# 4 way terminal block.
# Stripboard, (Verobaord), as required.
# Green, yellow, orange, blue and white wire as required.
# Small cable ties, optional.
# Stick on cable clip, optional.
# Crimp terminal, 1 off, optional.
# #########################################################
|
This might seem like a full edition but there is so much yet to be added that I have relaesed this one and only version here as a learning tool.
Any further relaeses will be metioned occasionally in the comments section...
Enjoy finding simple solutions to often very difficult problems...
Finally EVERYTHING that is required for this project will always be inside the single script...
Upon reading the script you will see what I mean...
Bazza, G0LCU.
As of 28-11-2013 the latest version is here:-
Version 0.20.03...
http://wisecracker.host22.com/public/AudioScope.sh
Latest public version here:-
Version 0.20.00...
http://www.unix.com/showthread.php?t=212939&page=6
As of 12-01-2014 the latest version 0.20.58 is on both URLs above...
As of 07-03-2015 the latest official version is 03120. It is now 135072 bytes in size so far.
It can be found here:-
http://wisecracker.host22.com/public/AudioScope.sh
And the UNIX URL above...
Enjoy...