Jump to content
IGNORED

Doing speech in C using TMS9900-GCC


xahmol

Recommended Posts

Funny ... python_wizard - never heard of it before - actually works quite well, you just have to provide a good voice recording. I did some experiments today; I've always been interested to know whether the speech synthesis is generic enough to work for other languages. I tried three typical German words: ich, ach, and my last name Zapf.

 

"ach" is quite good. "ich" is still good, a bit too much "isch" (or "ish"). Sadly, "Zapf" is not really good, hardly recognizable; the affricates (z="ts" and pf) seem to be hard to analyse.

 

The MERGE files on the disk image were created by Speecoder from the output of python_wizard, each one may be merged to the SPEAK program. The original wave files are in the ZIP file for reference.

 

Edit: Do it yourself - just these steps and you are set to go.

git clone https://github.com/ptwz/python_wizard.git
pip install scipy
cd python_wizard

 

sptests.zip speech.dsk

Edited by mizapf
  • Like 3
Link to comment
Share on other sites

8 hours ago, mizapf said:

Funny ... python_wizard - never heard of it before - actually works quite well, you just have to provide a good voice recording. I did some experiments today; I've always been interested to know whether the speech synthesis is generic enough to work for other languages. I tried three typical German words: ich, ach, and my last name Zapf.

 

"ach" is quite good. "ich" is still good, a bit too much "isch" (or "ish"). Sadly, "Zapf" is not really good, hardly recognizable; the affricates (z="ts" and pf) seem to be hard to analyse.

 

The MERGE files on the disk image were created by Speecoder from the output of python_wizard, each one may be merged to the SPEAK program. The original wave files are in the ZIP file for reference.

 

Edit: Do it yourself - just these steps and you are set to go.


git clone https://github.com/ptwz/python_wizard.git
pip install scipy
cd python_wizard

 

sptests.zip 144.91 kB · 2 downloads speech.dsk 360 kB · 2 downloads

Does python_wizard convert the recordings to Allophones?

 

If so based on the Allophone list here: Standard allophone codes for TI Text to Speech—English - Ninerpedia 

I don't think our favourite machine will ever speak good German or Dutch or French or  Scots or Welsh or anything but American English.  :) 

 

Is there another level below allophones?

 

 

Link to comment
Share on other sites

Did not try to make it speak Dutch yet. Luckily my name is pronounced perfectly. Even though in real live I did not meet a UK or US person pronouncing it correctly. Mostly gets to Xender instead of the correct Xahnder. So the a as in ball.

 

Will try it to feed my sons’ names (Wouter, Reinier) and my wife’s name (Gerda) to put it to the test (and no, do not use those names in my passwords, so you can stop trying to hack me with it now ?).

Ou, ei and the Dutch G are very typical Dutch sounds ( sounds like Wow-ter, Reyneer, and no clue how to describe the guttural Dutch hard G sound)

 

But luckily I was not planning to use it for Dutch anyway, too small of a target group to code for, especially as most Dutch persons and certainly all those into retro computers speak also English anyway (as we learned to use it mostly from English and German magazines).

Edited by xahmol
  • Like 1
Link to comment
Share on other sites

4 hours ago, TheBF said:

I think Gerda will be a challenge. Maybe it can say it with a "soft" G. :) 

Well, it is very easy to irritate Dutch people by pronouncing their name in the German or Flemish (Dutch speaking Belgium) way ;-) As in many places in the world, the worst thing you can do to someone is assuming they are from the neighboring country...... especially if some WorldWarII dynamics kicks in.

Link to comment
Share on other sites

I guess the "soft" G is not particularly difficult for the synthesizer; I was able to make it say "ach" and "ich" fairly well. It failed for my last name Zapf maybe because there are too many phonemes in those 0.5 secs that it takes to utter the word. The letter Z alone is pronounced like [ʦεtʰ] in about 0.4 seconds, so here you would have 80 ms per phoneme on average.

I have a cunning plan ... let's try to find out how far we get in our various languages, Dutch, French, Portuguese, Italian, German ... ! (In a new thread, of course.) The challenge would be to bring the TMS5200 to its limits, using the python_wizard or another tool. We just need to postprocess the python_wizard output to make DATA lines from it.

 

 

 

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

3 hours ago, xahmol said:

Well, it is very easy to irritate Dutch people by pronouncing their name in the German or Flemish (Dutch speaking Belgium) way ;-) As in many places in the world, the worst thing you can do to someone is assuming they are from the neighboring country...... especially if some WorldWarII dynamics kicks in.

I married a Noord Brabant girl so with my accent I am one of those irritators.   ;)

 

  • Haha 1
Link to comment
Share on other sites

I just hacked together a shell script that turns the hex output of python_wizard into DATA lines.

 

From ach.lpc:

00 00 00 06 8b 66 52 4c 6d 94 c4 e4 11 51 13 b5 12 1b bb 48 d5 c4 4a 6c 9c 22 53 93 27 b6 71 92 dc 4c a
e d8 fb 4e 16 09 59 12 9d 52 49 dd 74 2a 8b f1 08 22 8b 01 e8 36 cb e9 45 65 09 92 25 63 14 9b 6d c0 a1
8c 9e 5d 8d 82 98 32 6e d1 91 06 6c 51 39 59 67 09 90 65 65 84 d0 49 e0 61 84 1e 52 3b 82 07 61 89 f7
ad a4 6e 96 a4 2e 94 90 ba 39

 

you get:

 

10000 DATA 96,0,113
10010 DATA 0,0,0,6,139,102
10020 DATA 82,76,109,148,196,228
10030 DATA 17,81,19,181,18,27
10040 DATA 187,72,213,196,74,108
10050 DATA 156,34,83,147,39,182
10060 DATA 113,146,220,76,174,216
10070 DATA 251,78,22,9,89,18
10080 DATA 157,82,73,221,116,42
10090 DATA 139,241,8,34,139,1
10100 DATA 232,54,203,233,69,101
10110 DATA 9,146,37,99,20,155
10120 DATA 109,192,161,140,158,93
10130 DATA 141,130,152,50,110,209
10140 DATA 145,6,108,81,57,89
10150 DATA 103,9,144,101,101,132
10160 DATA 208,73,224,97,132,30
10170 DATA 82,59,130,7,97,137
10180 DATA 247,173,164,110,150,164
10190 DATA 46,148,144,186,57

 

by this script:

 

#!/bin/bash
if [ $# -lt 2 ]
then
  echo "Syntax: createdata start incr"
  exit 1
fi
read -r -a value
length=${#value[@]}
LINE=$1
echo -n $LINE "DATA "
echo 96,$((length/256)),$((length%256))
LINE=$((LINE+$2))
echo -n $LINE "DATA "
for ((i=0; i<$length; i++))
do
  printf "%d" $((16#${value[i]}))
  if [ $((i%6)) -eq 5 ]
  then
    printf "\n"
    LINE=$((LINE+$2))
    echo -n $LINE "DATA "
  else
    if [ $i -ne $((length-1)) ]
    then
       printf ","
    else
       printf "\n"
    fi
  fi
done

 


 

  • Like 3
Link to comment
Share on other sites

2 hours ago, mizapf said:

I just hacked together a shell script that turns the hex output of python_wizard into DATA lines.

 

From ach.lpc:

 


00 00 00 06 8b 66 52 4c 6d 94 c4 e4 11 51 13 b5 12 1b bb 48 d5 c4 4a 6c 9c 22 53 93 27 b6 71 92 dc 4c a
e d8 fb 4e 16 09 59 12 9d 52 49 dd 74 2a 8b f1 08 22 8b 01 e8 36 cb e9 45 65 09 92 25 63 14 9b 6d c0 a1
8c 9e 5d 8d 82 98 32 6e d1 91 06 6c 51 39 59 67 09 90 65 65 84 d0 49 e0 61 84 1e 52 3b 82 07 61 89 f7
ad a4 6e 96 a4 2e 94 90 ba 39

 

 

you get:

 

 


10000 DATA 96,0,113
10010 DATA 0,0,0,6,139,102
10020 DATA 82,76,109,148,196,228
10030 DATA 17,81,19,181,18,27
10040 DATA 187,72,213,196,74,108
10050 DATA 156,34,83,147,39,182
10060 DATA 113,146,220,76,174,216
10070 DATA 251,78,22,9,89,18
10080 DATA 157,82,73,221,116,42
10090 DATA 139,241,8,34,139,1
10100 DATA 232,54,203,233,69,101
10110 DATA 9,146,37,99,20,155
10120 DATA 109,192,161,140,158,93
10130 DATA 141,130,152,50,110,209
10140 DATA 145,6,108,81,57,89
10150 DATA 103,9,144,101,101,132
10160 DATA 208,73,224,97,132,30
10170 DATA 82,59,130,7,97,137
10180 DATA 247,173,164,110,150,164
10190 DATA 46,148,144,186,57

 

 

by this script:

 

 


#!/bin/bash
if [ $# -lt 2 ]
then
  echo "Syntax: createdata start incr"
  exit 1
fi
read -r -a value
length=${#value[@]}
LINE=$1
echo -n $LINE "DATA "
echo 96,$((length/256)),$((length%256))
LINE=$((LINE+$2))
echo -n $LINE "DATA "
for ((i=0; i<$length; i++))
do
  printf "%d" $((16#${value[i]}))
  if [ $((i%6)) -eq 5 ]
  then
    printf "\n"
    LINE=$((LINE+$2))
    echo -n $LINE "DATA "
  else
    if [ $i -ne $((length-1)) ]
    then
       printf ","
    else
       printf "\n"
    fi
  fi
done

 

 


 

What's the leading 96 for? 

Link to comment
Share on other sites

This is for Extended BASIC's CALL SAY; the leading 96 is hex 60, which probably means Speak External (depends on how this is internally implemented). You will also see it when you do a CALL SPGET with vocabulary words.

 

This is the typical main program; you need to save the lines from above as a MERGE file and merge them to it later, or paste them directly behind this program.

 

10 RESTORE
20 READ A,B,C
30 A$=CHR$(A)&CHR$(B)&CHR$(C)
40 FOR I=1 TO C :: READ X :: A$=A$&CHR$(X) :: NEXT I
50 CALL SAY(,A$)
60 END

 

The bash script from above should also work in Windows with Cygwin, or with the Windows Subsystem for Linux.

Edited by mizapf
  • Thanks 2
Link to comment
Share on other sites

On 4/1/2021 at 10:46 AM, mizapf said:

Funny ... python_wizard - never heard of it before - actually works quite well, you just have to provide a good voice recording. I did some experiments today; I've always been interested to know whether the speech synthesis is generic enough to work for other languages. I tried three typical German words: ich, ach, and my last name Zapf.

 

"ach" is quite good. "ich" is still good, a bit too much "isch" (or "ish"). Sadly, "Zapf" is not really good, hardly recognizable; the affricates (z="ts" and pf) seem to be hard to analyse.

 

The MERGE files on the disk image were created by Speecoder from the output of python_wizard, each one may be merged to the SPEAK program. The original wave files are in the ZIP file for reference.

 

Edit: Do it yourself - just these steps and you are set to go.


git clone https://github.com/ptwz/python_wizard.git
pip install scipy
cd python_wizard

 

sptests.zip 144.91 kB · 3 downloads speech.dsk 360 kB · 3 downloads

 

in addition if you ( on a debian system ) : 

apt install portaudio19-dev
pip install pyaudio 

 

You can run the python3 ./python_wizard_gui.py 

It will have a PLAY button in the menu IF pyaudio is installed.

 

  • Like 1
Link to comment
Share on other sites

Sorry, did not have time past few days, but today did a little test. And actually, it is not bad at the Dutch hard G. See attached video with the quick test.

 

Source (coded for C) for the two samples in Dutch:

- the place name Scheveningen: chosen as that place name famously was used to root out German spies during World War II 'Anecdotal evidence exists of the name Scheveningen being used as a shibboleth during World War II to identify German spies: they would pronounce the initial "Sch" differently from Dutch native speakers (https://en.wikipedia.org/wiki/Scheveningen#cite_note-mcnamara-4)'
So thought if it could do that.....

- testing with my wife and sons' names (Ik hou van.... is I love you)

const unsigned char scheveningen[] = {0x08,0x98,0x3A,0x88,0x00,0x33,0x35,0x0B,0x60,0xA5,0x31,0x05,0x6C,0x5F,0xA1,0xE4,0xA8,0x8A,0xC4,0xC2,0xA6,0x18,0x8D,0x76,0x60,0x0D,0xC7,0x02,0x8C,0xC1,0x51,0xD8,0x2B,0xB9,0x50,0x05,0x99,0xB0,0x01,0x15,0x26,0x1E,0x6C,0x9B,0x0B,0x72,0x08,0x79,0xF4,0x4B,0x71,0xC8,0x29,0x10,0xC1,0x2E,0xC3,0x49,0xA5,0x80,0x47,0xDF,0x4E,0x27,0x15,0x02,0x5A,0x72,0xC6,0x14,0x54,0x08,0x45,0xD0,0x5D,0x4F,0x90,0x26,0x62,0x5E,0xFB,0xD4,0x49,0xA9,0x58,0x8B,0xE0,0xC8,0x88,0x24,0x9C,0xA4,0x83,0x8D,0x3D,0xB1,0x70,0xB9,0x74,0x34,0x8B,0xD4,0x46,0x26,0xC9,0xB4,0xC3,0x2C,0xBA,0x14,0x4F,0xCF,0x52,0x22,0x19,0x72,0xD2,0xCB,0x47,0x9C,0xA0,0x29,0x50,0x1B,0x1D,0x14,0x50,0xAC,0x80,0x3D,0x5F,0xA1,0x18,0x8B,0x02,0x8C,0x7C,0x87,0xA0,0xE3,0x0A,0x1C,0x2B,0x87,0x9D,0xB4,0x2B,0x88,0xAF,0x5C,0x4C,0x38,0xAE,0x24,0x21,0x7A,0x44,0x60,0x9B,0x12,0x87,0x98,0x05,0x43,0x26,0x4A,0x30,0xD7,0x0A,0xDC,0x96,0xAA,0xC0,0xA8,0x2E,0x70,0x47,0xA6,0x42,0x39,0xE3,0x40,0xE4,0x84,0x8A,0xA6,0x88,0x25,0x91,0xE8,0x6A,0x5A,0x2C,0x9A,0x9D,0x90,0x69,0x48,0x68,0x59,0x28,0xA2,0xA2,0x01,0x3D,0x56,0x38,0x69,0x8B,0x06,0xD4,0x78,0x96,0x90,0x2D,0x1A,0xD0,0xE2,0x45,0x52,0xB1,0x68,0x40,0x8D,0x63,0x0D,0xD9,0xAC,0x01,0x37,0x8A,0x2D,0xE9,0xA0,0x06,0xBC,0x28,0x96,0x90,0x82,0x1A,0x30,0x3B,0x5C,0xD5,0x0A,0x6A,0x81,0x9D,0x74,0xD7,0x44};

const unsigned char ikhouvan[] = {0x20,0x02,0xE6,0x23,0xD7,0x93,0xA6,0x8B,0x58,0xC8,0x9A,0x74,0x08,0x2E,0x22,0xA5,0x7B,0x54,0x21,0x85,0x98,0x85,0xCA,0x77,0x87,0x64,0x62,0xE1,0xA4,0x5E,0x94,0x14,0x51,0x88,0x69,0x1F,0x63,0x4A,0x42,0x72,0x26,0xA9,0xCA,0x6D,0xA9,0x30,0xE4,0x84,0x88,0x8C,0xEC,0x12,0x56,0xD5,0x16,0x42,0x74,0x4A,0x44,0x35,0x5E,0x74,0xD3,0x29,0x11,0x53,0xAD,0x31,0x4C,0x87,0x58,0x1C,0xE7,0x56,0x33,0x19,0x12,0xBE,0x42,0x52,0x2D,0x84,0x4B,0xD8,0x35,0x29,0x4D,0x03,0x2A,0xA1,0x8F,0xAD,0xB4,0x04,0x8B,0x14,0xA5,0xF2,0x20,0xB3,0xC3,0x78,0x64,0x53,0x5D,0xC3,0x91,0x08,0x95,0x75,0x50,0x12,0xC7,0x6A,0x15,0xA5,0x34,0x4C,0xA2,0x98,0x84,0x3D,0x8E,0xD0,0x32,0xEC,0x32,0xF6,0xD8,0xD2,0x42,0xB0,0xCB,0xD9,0x13,0x4D,0x53,0x33,0xA6,0x20,0x4F,0x34,0xCC,0xCC,0xA8,0x02,0x3D,0x75,0xB1,0x14,0x27,0x0A,0x78,0xBC,0x49,0x5B,0x8A,0x28,0xE0,0x73,0x0B,0x6E,0xD1,0xCA,0xA0,0x3D,0x39,0xC5,0x43,0x87,0x84,0xCF,0xA4,0x52,0x0F,0x9C,0x12,0x39,0x0B,0xCB,0x2C,0x70,0x8A,0xD5,0x4A,0x6C,0xB7,0xC0,0x29,0x92,0x2B,0xA9,0xCC,0x02,0xA7,0x50,0xCE,0xA2,0x72,0x2F,0x1C,0x42,0xD1,0x9A,0xD2,0xAC,0xB0,0x0A,0x49,0x59,0xF4,0x14,0x8B,0xC2,0x21,0xA4,0xCB,0x54,0x15,0x89,0x24,0x81,0x70,0x32,0x97,0xE5,0x02,0xD1,0x38,0xDB,0x52,0x68,0x0A,0x65,0xA5,0x4C,0x2F,0x31,0x29,0x56,0x95,0x32,0xBD,0x24,0x87,0x58,0x37,0xE8,0xF0,0x14,0x65,0x12,0xD9,0xF0,0xC2,0x4B,0x94,0x89,0x55,0xC1,0x4E,0x1F,0xD1,0x26,0xD6,0x05,0x3A,0x7C,0x44,0x87,0xD8,0x54,0xEC,0xB0,0x15,0x13,0x12,0x53,0xA9,0x52,0x57,0x68,0x48,0x54,0xA5,0x4D,0x6F,0xB2,0x29,0x51,0x55,0xAA,0xAD,0x85,0xA4,0x54,0x16,0xC9,0xF1,0x16,0x62,0x52,0x9E,0xCC,0xD6,0x52,0x28,0x4B,0xD1,0xF0,0x67,0x77,0xA4,0x22,0x45,0x23,0x1E,0x2C,0x19,0x85,0x84,0xBA,0xAA,0x45,0xA7,0x17,0x12,0x12,0xBA,0x86,0x8D,0x5E,0x48,0x68,0xA8,0x3C,0x53,0xE8,0x21,0xA6,0xA1,0xF2,0x5C,0xA1,0xB9,0x98,0x14,0xBF,0x11,0x81,0xE3,0x62,0x5E,0xE4,0xDD,0x8D,0x4A,0x88,0x74,0x81,0x8B,0x48,0xD1,0x21,0xB6,0x0D,0x26,0x22,0x2D,0xB9,0x44,0x57,0xD8,0xB2,0x12,0xA9,0x3A,0x59,0x79,0x57,0x9A,0x90,0x60,0x4D,0x96,0x68,0x39,0xD1,0xC2,0x52,0x49,0x62,0x64,0x04,0x9B,0x95,0x17,0xCB,0x63,0x23,0xEA,0x56,0x56,0xC2,0x4F,0x59,0x8C,0x4A,0xF0,0xB2,0x0A,0x0A,0xEA,0x2A,0xC1,0xC3,0x87,0xAC,0xE8,0xAA,0x14,0xB6,0xD2,0x14,0x11,0xAD,0x52,0x6E,0x82,0xB4,0xC2,0xA1,0x50,0xB5,0x76,0xD0,0xB4,0x9A,0x42,0x37,0xD6,0x50,0xC5,0xE2,0x08,0xCD,0x47,0x41,0x03,0x4F,0x1C,0x12,0x9D,0x69,0xB5,0x8A,0x72,0x4A,0x65,0x96,0x4D,0x6B,0x22,0x29,0x93,0x59,0x27,0xB5,0x88,0x84,0x5C,0x14,0xEB,0xE6,0x20,0x16,0x0A,0x51,0xB5,0x46,0x52,0x88,0x2A,0x49,0xF7,0x18,0x72,0xA1,0xA6,0x16,0x3E,0x2D,0xCD,0x62,0x86,0x4A,0x16,0xB7,0xE6,0x32,0x1A,0x6A,0x59,0xCC,0x9A,0x52,0x68,0x68,0x64,0x53,0x2F,0x2A,0x22,0xAE,0x91,0xD5,0x65,0xD0,0x8D,0xB8,0x46,0x74,0xF5,0x82,0x24,0xAA,0x5A,0x36,0xA4,0x15,0x8B,0x0C,0xEB,0xD0,0xA2,0x66,0x6B,0xD8,0xA8,0x07,0xD3,0x3D,0xCC,0x6C,0xA1,0x01,0xF8,0x32,0x73,0xB5,0x8D,0x3A,0xA6,0xCA,0xD5,0xD4,0x36,0x00,0x00,0x00,0xA0,0x4D,0xF9,0x24,0x53,0xA3,0x03};

 

Edited by xahmol
  • Like 3
Link to comment
Share on other sites

  • 2 weeks later...

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...