Jump to content
IGNORED

Speech in fbForth 2.x


Recommended Posts

The following questions in another topic prompted this post dedicated to speech in fbForth 2.x:

  

On 2/22/2023 at 4:02 PM, Asmusr said:

I also wonder why they didn't add a speech player to the ISR?

 

On 2/22/2023 at 8:37 PM, Retrospect said:

Hi Lee.  So with your fbForth, speech can play without halting the CPU? 

 

Both speech and sound are serviced by the fbForth 2.x ISR (Interrupt Service Routine) via an up-to-three-address branch stack that is populated when the ISR is called by the console ISR through the ISR hook at >83C4. [fbForth sound words do not use the console ISR’s sound player.] The branch stack will have entries only if speech and/or sound table #1 (immediate or sequential sounds) and/or sound table #2 (immediate playing over muted sound table #1) are awaiting service. Though sound processing is not part of this topic, for the sake of completeness, I will mention that multiple sound tables can be added to the sound stack to be processed sequentially. I mention this here because I did not provide for a speech stack, which could be a useful addition to a future version of fbForth. Currently, if you want more than one block of speech to be spoken sequentially, you must use TALKING? to check whether the Speech Synthesizer is idle. Otherwise, the second block of speech will immediately cancel what is being spoken of the previous block.

 

Because the ISR services speech, further program processing is interrupted only very briefly to process the next bit of speech. The speech synthesizer itself does not suspend processing while it is actually speaking. Here is some example code that illustrates what actually happens:

HEX 
\ Speech Synthesizer strings--- 
\ "Hello"
: HELLO  ( -- addr n )
   HERE 351A , 1  ;
\ "Do not be so negative"
: NONEG  ( -- addr n )
   DATA[ 2480 4AAB 1A42 6153 48DC ]DATA  ;

DECIMAL
: RUN
   HELLO SAY
   BEGIN TALKING? 0= UNTIL    \ wait until done saying "hello"
   NONEG SAY      \ start saying, "do not be so negative"
   \ print 200 numbers
   200 0 DO 
      I . 
   LOOP  ;

RUN

 

You will notice that you do not hear speech until nearly 100 numbers have been displayed, even though speech was started before the number-printing loop. What is clear, however, is that processing continues during speech synthesizer processing. Obviously, the loop containing TALKING? does suspend further speech processing until “hello” is spoken. This was done to prevent the next phrase from stepping on “hello”. Just remove that loop to see what I mean. What is interesting (read, “I don’t have a clue why”) is that printing starts before even the start of “hello” is heard, which means that the TALKING? loop already finished and that hearing what the speech synthesizer sends to the audio channel has a significant delay. This was done with Classic99 QI399.063, so I do not know whether this also obtains on real iron because I did not bring a TI-99/4A with me to Florida, but I would expect it to perform similarly.

 

...lee

  • Like 6
Link to comment
Share on other sites

This is neat.  I had read somewhere that the code to drive speech synth had to be in scratchpad RAM.

But you seem to be using Forth.

 

Makes me wonder if I could do it with a background task that polls TALKING? and pushes data to the speech synth from a queue.

Do you see any impediment(s) to that approach?

 

  • Like 1
Link to comment
Share on other sites

On 2/28/2023 at 5:18 PM, TheBF said:

This is neat.  I had read somewhere that the code to drive speech synth had to be in scratchpad RAM.

But you seem to be using Forth.

 

The code to read the SS does, indeed, need to be on the 16-bit bus, but it is a simple matter to save the small area you need, load read and timing code, run it, and restore said small area.

 

On 2/28/2023 at 5:18 PM, TheBF said:

Makes me wonder if I could do it with a background task that polls TALKING? and pushes data to the speech synth from a queue.

Do you see any impediment(s) to that approach?

 

None at all except for the above read stuff.

 

You probably have my code, but it may be rough deciphering it. I will post it later tonight or tomorrow.

 

...lee

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

5 hours ago, Lee Stewart said:

This was done with Classic99 QI399.063, so I do not know whether this also obtains on real iron because I did not bring a TI-99/4A with me to Florida, but I would expect it to perform similarly.

Lee, try Parsec with speech enabled , on Classic99 063.   You'll see that there is a slight delay in the speech.  The voice tells you about the incoming enemy after it has arrived.  Tursi mentioned something about this a while back, but I can't remember where it was mentioned or the exact words used.

  • Thanks 1
Link to comment
Share on other sites

Here is my ROM2 code for Speech and Sound: 

 

fbForth205_Speech&Sound.a99

 

You can see that the block of code that is used to read the speech synthesizer's (SS) status is only 12 bytes, so the copying to and fro is pretty fast. And...reading the SS status is the only read done in the speech words and that is all that requires execution from 16-bit space (scratchpad RAM in this case).

 

...lee

  • Like 2
Link to comment
Share on other sites

* 
* 42us delay required before another command can be issued to the SS.
* See Editor/Assembler manual, Section 22.1.1, page 349.
*
       SRC  R1,13          delay 14us\
       SRC  R1,13          delay 14us > delay 42us
       SRC  R1,13          delay 14us/

 

Could this 42uS delay be met by NEXT at around ~56uS or is it a tight requirement.

Link to comment
Share on other sites

17 hours ago, TheBF said:

Could this 42uS delay be met by NEXT at around ~56uS or is it a tight requirement.

 

I should think so. The times I used are the absolute minima before the next access. I should think the worst that could happen with longer times would be speech hesitation, but times measured in microseconds probably won’t be noticed.

 

In looking over the execution times of the delay code (SRCs), it looks like the “42”-µs delay on the 8-bit bus is actually 50 µs. I am pretty sure I padded the times a little to accommodate clock variation, but that seems more than necessary. At any rate, your 56-µs time is not that much more than it turns out I am using.

 

...lee

  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...

Nice demo of Forth/fbForth.

 

The thing that makes Forth (IMO) isn't so much the use of words/subroutines. We can do similar stuff in XB with SUBs. For example, you can define multiple SUBs and they can call each other, myuch like your PAY word calls BREAD and BUTTER etc. We can also do it in XB with GOSUBs. Each GOSUB calls a subroutine at a specific line number, and you can nest them, and when a subroutine sees a RETURN command it returns to the line that called it. This is the same as Forth. Each word is effectively a GOSUB, and each ; (semi-colon) is a RETURN:

 

: TOM CR ." I AM TOM" ;

: DICK CR ." I AM DICK" ;

: HARRY CR ." I AM HARRY" ;

: SAY-HELLO TOM DICK HARRY ;

 

10 GOSUB 100

20 GOSUB 200

30 GOSUB 300

40 END

100 PRINT "I AM TOM"

110 RETURN

200 PRINT "I AM DICK"

210 RETURN

300 PRINT "I AM HARRY"

310 RETURN

 

These two programs do the same thing, in the same way. Lines 10 to 30 are the equivalent of the word SAY-HELLO. The RETURN statements in lines 110, 210, and 310 are the equivalent of the semi-colons at the end of the words TOM DICK and HARRY.

 

So, in this respect, the two languages are conceptually very similar, despite having totally different syntaxes.

 

What makes Forth REALLY different is that fact that you have to manage the data stack in addition to program flow. In most 'traditional' languages, we only manage the flow of our program. We say "goto this line, run that, then go here, and if this condition happens then do this" type of stuff. Our program state is stored in variables.

 

In Forth, in addition to managing our program flow, we also have to manage our stack. The stack is the interface between words. Words can take data from the stack (parameters), do something, and leave something on the stack for the next word in the sequence to use. It's this aspect that makes Forth very different to pretty much any other programming language, and it does take a lot of getting used to. Keep at it!

Edited by Willsy
  • Like 4
  • Thanks 1
Link to comment
Share on other sites

8 hours ago, Willsy said:

Keep at it!

I will try me best.  It's a lot to take on though .   In a way , my video , as simple as it is, is an encouragement for others to join in and try it.

I'm that shit karaoke singer down the pub that makes others stand up and join in 'cos they know they can do better :P

  • Haha 1
Link to comment
Share on other sites

Forth also does things quicker. So a "sub" may perform faster than expected sometimes, depending on things, but I'm just pointing out that timing is something to watch and use properly so you don't waste it at the same time.. you'll know more about that as you use it.

  • Like 2
Link to comment
Share on other sites

On 2/28/2023 at 5:16 PM, Retrospect said:

Lee, try Parsec with speech enabled , on Classic99 063.   You'll see that there is a slight delay in the speech.  The voice tells you about the incoming enemy after it has arrived.  Tursi mentioned something about this a while back, but I can't remember where it was mentioned or the exact words used.

Late speech is a Classic99 issue, not a hardware issue. ;) I've noticed it myself. Likely there's just too much buffering on the audio stream for that channel.
 

  • Like 5
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...