I started to work on this, it doesn't
quite work, but I'll post it in case anyone wants to work on it, I don't know if I'll have time.
This simplifies the sound into a series of points, forming sort of a curve that defines the sound, then checks to see if those points are close to those in a pre-recorded sample.
After you record the sound, use the left and right keys and the return key to define where the part of the sound you're actually interested in (the words you speak) actually is. The first time you run it, it won't have anything to compare to, so it will probably match all the blank space on the recording. On subsequent runs it will use the data from the previous run.
set display mode desktop width(),desktop height(),32
`Record initial sound
print "2"
wait 1000
print "1"
wait 1000
print "Recording"
record sound 1,1500
wait 1500
stop recording sound
print "Done recording"
print
sync
make memblock from sound 1,1
memsize#=get memblock size(1)
print "Size: "; get memblock size(1)
print "Format: PCM Audio"
print "Channels: Mono"
`Draw basic sound graph
for c=28 to get memblock size(1)-2
line (c-28)*(screen width()/memsize#),500+memblock byte(1,c)-128,(c-27)*(screen width()/memsize#),500+memblock byte(1,c+1)-128
next c
`Simplify graph into line segments for analysis (turquoise display)
DIM points(0) as byte
stepval=400 `Number of bytes in each segment
avgrange=20 `Number of bytes to average together to get each point
for c=28+avgrange to get memblock size(1)-1-stepval step stepval
pointval=0
for d=c-avgrange to c+avgrange
inc pointval,abs(memblock byte(1,d)-128)
next d
pointval=pointval/(avgrange*2)
array insert at bottom points(0)
points(array count(points(0)))=pointval
next c
`Display segments generated above
ink rgb(0,255,255)
for c=1 to array count(points(0))-1
line (c*stepval-28)*(screen width()/memsize#),500-points(c),((c+1)*stepval-28)*(screen width()/memsize#),500-points(c+1)
next c
ink rgb(255,255,255)
`Clip blank space at beginning and end (manual for now)
startend=1
endstart=array count(points(0))
`Beginning
repeat
if leftkey() and startend>1 and pressed=0
pressed=1
dec startend
endif
if rightkey() and startend<array count(points(0)) and pressed=0
pressed=1
inc startend
endif
if scancode()=0 then pressed=0
line (startend*stepval)*(screen width()/memsize#),500,(startend*stepval)*(screen width()/memsize#),300
until returnkey() and pressed=0
pressed=1
`End
repeat
if leftkey() and endstart>1 and pressed=0
pressed=1
dec endstart
endif
if rightkey() and endstart<array count(points(0)) and pressed=0
pressed=1
inc endstart
endif
if scancode()=0 then pressed=0
line (endstart*stepval)*(screen width()/memsize#),500,(endstart*stepval)*(screen width()/memsize#),300
until returnkey() and pressed=0
`Load previous samples from file and display (shades of purple)
`Scaled on x and y axis to best match the current recording
`Find max value
maxval=0
for c=startend to endstart
maxval=max(points(c),maxval)
next c
counter2=1
`Load
while file exist(str$(counter2)+".snp")
open to read 1,str$(counter2)+".snp"
ink rgb(min(counter2*40,255),0,255)
DIM temppoints(0) as byte
read long 1,size `Number of points
adjstepval=(stepval*(endstart-startend))/(1.0*size)
repeat
array insert at bottom temppoints(0)
read byte 1,temppoints(array count(temppoints(0)))
until file end(1)
`Find max for temp array
tempmax=0
for d=1 to array count(temppoints(0))
tempmax=max(temppoints(d),tempmax)
next d
`Scale temp array
for d=1 to array count(temppoints(0))
temppoints(d)=temppoints(d)*(maxval/(1.0*tempmax))
next d
`Draw
for d=1 to array count(temppoints(0))-1
line (startend*stepval+(d-1)*adjstepval)*(screen width()/memsize#),500-temppoints(d),(startend*stepval+(d)*adjstepval)*(screen width()/memsize#),500-temppoints(d+1)
next d
close file 1
inc counter2
endwhile
ink rgb(255,255,255)
`Make the match determination
`Relies on some stuff from display above
`Uses pointflex to see if each point is close enough, then uses
`the percentage to allow a certain number of points to be wrong
pointflex=5 `Plus-or-minus for an individual point
percentagereq#=0.90 `Proportion of points that must match
ink rgb(255,0,0)
for c=1 to array count(points(0))-1-(array count(temppoints(0))*adjstepval)/stepval
counter=0
for d=1 to array count(temppoints(0))
curpos=(c-1)*stepval+(d-1)*adjstepval
prevelem=curpos/stepval
slope#=(points(prevelem+1)-points(prevelem))/(stepval*1.0)
curval=points(prevelem)+slope#*(curpos-prevelem*stepval)
line curpos*(screen width()/memsize#)-1,500-curval,curpos*(screen width()/memsize#)+1,500-curval
line curpos*(screen width()/memsize#),500-curval+1,curpos*(screen width()/memsize#),500-curval-1
if curval-pointflex>=points(c) or curval+pointflex<=points(c) then inc counter
next d
if counter>=array count(temppoints(0))*percentagereq#
text c*stepval*(screen width()/memsize#),470,"Match"
endif
next c
ink rgb(255,255,255)
`Draw axes and range
ink rgb(0,255,0)
line 0,500,screen width(),500
ink rgb(255,0,0)
line 0,628,screen width(),628
line 0,372,screen width(),372
ink rgb(255,255,255)
`Save segment data, clipped
`remstart
temp=0
repeat
inc temp
until file exist(str$(temp)+".snp")=0
open to write 1,str$(temp)+".snp"
write long 1,endstart-startend+1
for c=startend to endstart
write byte 1,points(c)
next c
close file 1
`remend
wait key
