Jump to content
IGNORED

TI 99/4A Speech Synth Browser/Editor Thingy


pixelpedant

Recommended Posts

Hey folks. I've been toying around with TI 99/4A speech synth lately, and decided it would be fun to write a TI LPC speech pattern exploration and editing app in the spirit of the venerable Speecoder, but for use on modern PC, and with some more comprehensive and user friendly spreadsheet-style editing options. At this point, I figure it's worth sharing, in case anyone else wants to poke around a few speech patterns, or mess around with modifying/editing/combining them, using this tool. It's a quick way to, e.g., get your TI 99/4A talking like Max Headroom, if you feel like it. Or to subsample a pattern to make new words. Or to combine portions of two patterns. You can see what the app looks like here:

 

FVl3tbN.png

 

The app is a Windows executable and comes packaged with the standard speech synth vocabulary listed in the Extended BASIC manual (consisting of 370 words, it appears to me). Use on Linux will be achievable via included source on your Python installation of choice, provided necessary module dependencies.

 

Included patterns were fetched via XB CALL SPGET on real iron, and transferred via Ti99Hdx. As a consequence, they're in individual V9T9 format files, and the program will save in this format as well. Sound patterns are saved in 255 byte fixed length records. This does impose a (255 byte) limitation on output. However, no built-in vocabulary (not even "THAT IS INCORRECT") exceeds this limit, as the pattern duration itself must be recorded as a one byte value. So this is in keeping with normal (and unavoidable) parameters.

 

The program does not in all respects enforce the entry of, or modifications resulting in, valid pattern data. Warnings are provided for values which are out of bounds for a field (e.g., "16" would be an invalid value for a frame's "Energy" nibble), but the user is not, for example, prevented from failing to terminate a pattern with the value '15' (i.e., 1111) as will be found in all provided patterns.
Note that simple Copy/Paste functionality is implemented using the clipboard, so patterns can be copied and pasted between two separate instances of the program, when combining patterns (or within a single instance, of course). This is particularly important when creating new sounds from phonetic components.
BE ADVISED: Results when feeding these patterns to emulators are likely to be inconsistent. But you should have good luck (as I have) on real iron.
UPDATES:
06/24/2018 - Many bugfixes, cleaned up source somewhat, added source to package,
07/02/2018 - More bugfixes, overhaul of decoding process and cleanup of source.
07/05/2018 - Ported to QT5. Packaging moved to cx_Freeze. High-DPI scaling implemented.
TO DO:
- GUI pitch adjustment control for selected ranges?
- GUI energy adjustment control for selected ranges?
The app may be found here:
Current Version: v1.3:
Previous Version: v1.2:
Previous Version: v1.1:

Edited by pixelpedant
  • Like 13
Link to comment
Share on other sites

Yeah, I would have included the code, but it's still a complete bloody mess as a result of the project just kind of having begun as "hey, I bet it'd be fun to decode a speech pattern" and grown willy-nilly from there in all sorts of random directions until it ended up as this. Now that all the basic problems are solved, I'll likely clean it up - maybe do a full rewrite - and release the code once there's something sufficiently readable that it might be of use to someone.

Link to comment
Share on other sites

Can your software find where (what addresses) exactly in a module the individual words or phrases are located. Do you know a simple method to accomplish this?

 

Nah, but you could certainly do a probabilistic analysis which returns likely candidates I figure, based on the fairly consistent structure of the speech samples. Always must begin with "01100000 00000000 ????????? ???0????" for example (where the first unknown byte is pattern length, and in the next byte, energy is unknown, but the repeat bit must be zero).

  • Like 1
Link to comment
Share on other sites

UPDATES:

 

The package linked in the initial post has now been updated to include source. Source has been cleaned up somewhat. A lot of bugfixes have been implemented.

 

If anyone would like to see an example of what custom speech made by phonetic recombination and pitch/energy editing using this tool looks like, you can see an example in this video here.

 

If you'd prefer not to watch the whole video, a demo of the TI speaking an invented phrase with custom intonation created using the tool ("Hehehehe...wipeout!") can be seen precisely here.

Edited by pixelpedant
  • Like 4
Link to comment
Share on other sites

  • 4 weeks later...
  • 4 years later...

How do i take the file this program outputs (shows up as INT/FIX 255 in TI99DIR) and read the data into a string to feed to CALL SAY() from XB?

I know i can do CALL SAY("",STRING$) where string is data from CALL SPGET("WORD",STRING$), and i can store the string to disk and read it back:

1396526970_writedata.thumb.png.c7910048cb43fab7c4c4dddf2158c4ce.png90451867_readdata.png.e05c5c7d4fa67fca9b06259476baa928.png

But i can not seem to do that with the files made by this program.

An example of how to use these output files in XB with CALL SAY would be appreciated.

(attached dsk has both of the above pictured programs on it)

spget testing.dsk

  • Like 1
Link to comment
Share on other sites

Haha! That was fun...

 

Your program works as expected!

 

..."DATA", is not a RESERVED WORD in the RESIDENT VOCABULARY.:lol:

 

EDIT: Haha! Another joke on me. "DATA" is in the E/A, BOOK. Seeing the LETTERS for each group, LEFT JUSTIFIED, naturally, I thought I was at the end of the LIST when I reached the next LETTER, never noticing the RIGHT JUSTIFIED column.:roll:

 

Tested:

Still works!

 

image.thumb.jpeg.ab4b09de85254b2f91aec0b9c713f6e8.jpeg

>New

  *READY*

image.thumb.jpeg.aecd33e6084ab9d43c790b866fd305fe.jpeg

Edited by HOME AUTOMATION
  • Like 2
Link to comment
Share on other sites

So having reminded myself and tested, this is indeed the correct means of opening then playing the INT/FIX 255 files output by the synth editor, in this case for a file called "PLNO" located on DSK1:

 

10 OPEN #1:"DSK1.PLNO",INTERNAL,INPUT,FIXED 255
20 INPUT #1:WRD$
30 CALL SAY(,WRD$)

 

Note that quotation marks are not required to provide for an initial empty argument for CALL SAY.  A comma is fine.

 

With the output (of the mashed up speech) in this case being:

 

 

 

  • Like 3
Link to comment
Share on other sites

1 hour ago, pixelpedant said:

So having reminded myself and tested, this is indeed the correct means of opening then playing the INT/FIX 255 files output by the synth editor, in this case for a file called "PLNO" located on DSK1:

 

10 OPEN #1:"DSK1.MYFILE",INTERNAL,INPUT,FIXED 255
20 INPUT #1:WRD$
30 CALL SAY(,WRD$)

That's what i was missing, the ",INTERNAL,INPUT,FIXED 255" part.

Thanks again!

  • Like 1
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...