SRS2000 Speech Recognition System

SRS2000 is a speech recognition system that uses machine code routines loaded from a separate file (“spmc”) to create, store, and compare voiceprints. The system supports up to eight labeled voice samples stored in a string array `v$(8,15)` and uses POKE instructions to pass parameters such as file position, recognition accuracy threshold, and a four-byte sample timing value directly into machine code at address 61440 and above. Voiceprint data is stored as raw CODE blocks at address 62080 (512 bytes) alongside the BASIC string array, allowing save and load of complete recognition sessions by filename. A frequency-spectrum plot routine reads 64 bytes from address 61888 and renders a bar graph scaled to fit a bordered display region. The setup menu includes a conversion routine that decomposes a sample time in seconds into four separate byte-sized countdown components POKEd into consecutive addresses for the machine code timing loop.


Program Analysis

Program Structure

The program is organized as a menu-driven shell with nine options, each handled by a block of code at a line number equal to the menu selection multiplied by 100. The dispatch is performed at line 70 with the idiom GO TO (s*100), routing directly to lines 100, 200, 300, 400, 500, 600, 700, 800, and 900. All menu blocks return to the main menu at line 12 via GO TO 12 rather than through a structured loop. A shared display subroutine at line 1000 centers a string s$ on the screen and is called extensively throughout.

Machine Code Interface

The heavy lifting is delegated to a machine code file loaded via LOAD "spmc" CODE at line 3. Three distinct entry points are used:

  • RANDOMIZE USR 61440 — creates a voiceprint from live audio input
  • LET w=USR 61443 — recognition routine; returns 0 on failure or a slot index (1–8) on match
  • RANDOMIZE USR 61446 — clears all stored voiceprints
  • RANDOMIZE USR 61459 — captures a sample for the spectrum plot

Parameters are passed to the machine code entirely through POKEs into fixed addresses: POKE 61449,r sets the file slot, POKE 61450,ac sets the accuracy threshold, and POKEs to 61451–61454 set the four-byte sample timing decomposition. The raw voiceprint data block lives at 62080 (512 bytes) and is saved and loaded independently of the BASIC data.

Timing Decomposition

The setup option for sample speech time (lines 870–890) converts a floating-point duration in seconds into four separate byte values representing successively finer time quanta, presumably matching a nested countdown loop structure in the machine code. The constants used are:

ByteAddressQuantum (seconds)
p161454285.21
p2614531.1141
p3614524.352e-3
p46145117e-6 (residual fraction)

Each byte is computed by integer division of the remaining time by the quantum, with the remainder passed to the next stage. Note that p4 stores the raw floating-point residual rather than an integer, which may cause unexpected behavior if the machine code expects a byte value.

Voiceprint Storage

Up to eight voiceprint records are maintained. Each has a corresponding label stored in the string array v$(8,15), which holds word names up to 15 characters long. The raw acoustic data is stored as a 512-byte CODE block at address 62080. On save (lines 400–420), two files are written: one with the suffix "v" for the CODE block and one with the suffix "d" for the DATA array, allowing a complete voice dataset to be archived under a single base filename.

Spectrum Plot Routine

Option 7 (lines 700–780) plots a bar graph of 64 frequency bins read from addresses 61888–61951. Each bin value is scaled by 3 and offset by 50 to fit within a bordered plot area spanning x=32 to x=224 and y=50 to y=150. Each bar is three pixels wide. Values exceeding 150 are clamped. Axis labels (“High”, “Low”, “FREQUENCY”) and a vertical title (“No. of Counts”) are printed using PRINT AT with individual characters to achieve vertical text.

Error Handling

The program uses ON ERR in two distinct ways. At line 2, ON ERR GO TO 10 is used as a startup guard so that if the machine code load fails, execution continues at the main initialization block. At line 11, ON ERR RESET establishes a global fallback. During the load sequence (lines 507–517), error handling is temporarily overridden to GO TO 515 so that a missing voiceprint CODE file does not abort the load of the DATA array; the global handler is restored at line 517.

Key BASIC Idioms

  • Computed GO TO via GO TO (s*100) replaces a long IF-THEN chain for menu dispatch.
  • The keypress-wait pattern LET b$=INKEY$: IF b$="" THEN GO TO … is used consistently before audio capture.
  • String concatenation builds filenames dynamically: LET h$=d$+"v" and LET h$=d$+"d".
  • The centering formula TAB ((32-LEN (s$))/2) is used throughout for display.
  • The SAVE "speech" LINE 2 at line 1 causes the program to auto-run at line 2 when loaded.

Potential Anomalies

  • The CLEAR 61439 at line 2 sets RAMTOP just below the machine code area, protecting it from BASIC. However, if the program is restarted without reloading, the machine code remains in place but is not reloaded, which could cause issues if memory has been disturbed.
  • p4 at line 888 stores the floating-point residual after all integer divisions rather than an integer byte; if the machine code expects a clean integer at address 61451, this could produce incorrect timing.
  • The recognition return value w from USR 61443 is used directly as an index into v$(w) at line 217. If the machine code returns a value outside 1–8, this would cause a subscript error.

Content

Appears On

Related Products

Train your computer to obey your voice commands. Recognizes up to eight spoken words. Used a microphone and amplifier connected...

Related Articles

Related Content

Image Gallery

SRS2000 Speech Recognition System

Source Code

    1 SAVE "speech" LINE 2
    2 CLEAR 61439: ON ERR GO TO 10
    3 LOAD "spmc"CODE 
   10 DIM v$(8,15)
   11 ON ERR RESET 
   12 CLS : PRINT : PRINT : PRINT : PRINT : PRINT 
   15 PRINT "              MENU"
   20 PRINT : PRINT 
   25 LET t=5
   30 PRINT TAB (t);"1.  Create Voiceprint"
   35 PRINT TAB (t);"2.  Recognize Word"
   40 PRINT TAB (t);"3.  Clear Files"
   45 PRINT TAB (t);"4.  Save Voiceprints"
   50 PRINT TAB (t);"5.  Load Voiceprints"
   55 PRINT TAB (t);"6.  Display Word File"
   57 PRINT TAB (t);"7.  Plot Voiceprint"
   58 PRINT TAB (t);"8.  Setup"
   60 PRINT TAB (t);"9.  Stop"
   65 PRINT : PRINT : PRINT "       Input Selection": INPUT s
   70 GO TO (s*100)
  100 CLS : LET s$="Input File Position": GO SUB 1000: INPUT r
  105 POKE 61449,r: REM *** file number**********
  110 CLS : LET s$="Input Word": GO SUB 1000: INPUT v$(r)
  115 CLS : LET s$="Press Any Key to Start": GO SUB 1000
  120 LET b$=INKEY$: IF b$="" THEN GO TO 120
  122 CLS 
  125 RANDOMIZE USR 61440: REM ******* create voiceprint*******
  130 CLS : LET s$="Again? (Y/N)": GO SUB 1000: INPUT g$
  135 IF g$="y" THEN GO TO 100
  140 GO TO 12
  200 CLS : LET s$="Press Any Key to Continue": GO SUB 1000
  205 LET b$=INKEY$: IF b$="" THEN GO TO 205
  207 LET s$="Say a Word": GO SUB 1000
  210 LET w=USR 61443: REM ********recognition routine call***
  211 IF w<>0 THEN GO TO 215
  212 LET s$="I Didn't Recognize That": GO SUB 1000
  213 PAUSE 180: GO TO 207
  215 LET s$="The Word You Said Was:": GO SUB 1000: PRINT 
  217 PRINT TAB ((32-LEN v$(w))/2);v$(w)
  220 PRINT : PRINT : PRINT : PRINT "          Again? (Y/N)"
  225 INPUT g$: IF g$="y" THEN GO TO 207
  230 GO TO 12
  300 RANDOMIZE USR 61446: REM ***clear voiceprints**********
  305 FOR i=1 TO 8: LET v$(i)="": NEXT i
  310 GO TO 12
  400 CLS : LET s$="Input File Name": GO SUB 1000: INPUT d$
  405 CLS : LET s$="Saving File "+d$+"...": GO SUB 1000
  410 LET h$=d$+"v": SAVE h$CODE 62080,512 
  415 LET h$=d$+"d": SAVE h$ DATA v$()
  420 GO TO 12
  500 CLS : LET s$="Input File Name": GO SUB 1000: INPUT d$
  505 CLS : LET s$="Loading File "+d$+"...": GO SUB 1000
  507 ON ERR GO TO 515
  510 LET h$=d$+"v": LOAD h$CODE 62080
  515 LET h$=d$+"d": LOAD h$ DATA v$()
  517 ON ERR RESET 
  520 GO TO 12
  600 CLS : PRINT : PRINT : PRINT : PRINT 
  605 FOR i=1 TO 8
  610 PRINT TAB (t);i;".  ";v$(i): NEXT i
  615 PRINT "  Press Enter to Continue": INPUT i$
  620 GO TO 12
  700 CLS : LET s$="Press Any Key to Start": GO SUB 1000
  702 LET b$=INKEY$: IF b$="" THEN GO TO 702
  703 RANDOMIZE USR 61459
  704 CLS 
  705 FOR i=32 TO 224: PLOT i,50: PLOT i,150: NEXT i
  710 FOR i=50 TO 150: PLOT 32,i: PLOT 224,i: NEXT i
  715 LET s$="No. of Counts"
  720 FOR i=1 TO LEN s$: PRINT AT 2+i,2;s$(i): NEXT i
  725 PRINT AT 16,3;"High": PRINT AT 16,27;"Low"
  730 PRINT AT 17,12;"FREQUENCY"
  735 LET i=32
  740 FOR j=0 TO 63
  745 LET a=PEEK (61888+j)*3+50
  750 IF a>150 THEN LET a=150
  755 FOR k=50 TO a: PLOT i,k: PLOT i+1,k: PLOT i+2,k: NEXT k
  760 LET i=i+3
  765 NEXT j
  770 PRINT AT 21,10;"Again? (y/n)": INPUT b$
  775 IF b$="y" THEN GO TO 700
  780 GO TO 12
  800 LET s$="SETUP": GO SUB 1000
  805 PRINT : PRINT TAB (t);"1.  Recognition Accuracy"
  810 PRINT : PRINT TAB (t);"2.  Sample Speech Time"
  812 PRINT : PRINT TAB (t);"3.  Return to Main Menu"
  815 PRINT : PRINT : PRINT "        Input Selection"
  820 INPUT g$
  825 IF g$="3" THEN GO TO 12
  830 IF g$="1" THEN GO TO 840
  835 IF g$="2" THEN GO TO 870
  837 GO TO 800
  840 LET s$="Input Accuracy Value (0-255)": GO SUB 1000
  845 PRINT : PRINT TAB (t);"0 = Most Accurate"
  850 PRINT : PRINT TAB (t);"255 = Least Accurate"
  855 INPUT ac: POKE 61450,ac: GO TO 800
  870 LET s$="Input Sample Time in Seconds": GO SUB 1000
  875 INPUT sp
  880 LET h1=285.21: LET l1=1.1141: LET h2=4.352e-3
  881 LET l2=17e-6
  885 LET p1=INT (sp/h1): LET sp=sp-h1*p1
  886 LET p2=INT (sp/l1): LET sp=sp-l1*p2
  887 LET p3=INT (sp/h2): LET sp=sp-h2*p3
  888 LET p4=sp
  890 POKE 61451,p4: POKE 61452,p3: POKE 61453,p2: POKE 61454,p1
  895 GO TO 800
  900 STOP 
 1000 CLS : PRINT AT 10,0: PRINT TAB ((32-LEN (s$))/2);s$: RETURN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top