2007-05-24

ScanSoft RealSpeak 3.51 for Linux - problem with Debian ETCH (ext3 ?)

hi,


I updated my (quick-and-dirty) post originally called "Text To Speech (ScanSoft RealSpeak)". Hoping it would become less obscure.


Today I encountered some problems with another installation (being Debian ETCH, kernel 2.6.18-4, with root ext3)... for which I found a workaround.


It seems that ScanSoft RealSpeak 3.5.1 does not function (anymore) in this distribution. The standard application (as used in aforementioned Posting), "hangs" just after outputting "Initialize".


When using strace it looks like one of the internal functions of RealSpeak looses itself in a loop... always continuing looking into (digging deeper and reaallly deeper!!!) into directory "." (so actually it's not digging deeper, ... but it's not comming back anyway).


This is probably caused by the (erroneous ? obsolete ?) assumption of the (a) programmer that a readdir(3) (or but probably not getdents(1)) will return its first two items being "." and "..". Thus not needing to "check" them out, and jumping to number three.

The code seems to go down into all directories of the given engine directory.

But if the result is not ordered with these . and .. upfront, but on some other position 3 (or 4), these special directory entries seem to be treated like any regular directory and descended into... And if - like all good stories - the story repeats itself (very probable if e.g. we're examining . as a regular directory, thus descending into it, actually staying put), this could take a while...

Here some logging:

open("/opt/scansoft/tts/engine/../api/server"...
...
open("/opt/scansoft/tts/engine/../api/./server"...
...
open("/opt/scansoft/tts/engine/../api/././server"...
...
open("/opt/scansoft/tts/engine/../api/./././././././././server"...
...


This snippet can be explained thus:

First when examining engine directory, getdir returns .. on some later-than-second place. This directory is treated as any other directory and since the code is - probably - descending recursively into all directories, looking for all languages available for instance (?), the code examines that directory.

Then Apparently getdir of that directory .. directory (actually the directory /opt/scansoft/tts) returns directory api (being absolutely /opt/scansoft/tts/api, but by the faulty procedure now considered part of the engine-tree.

Then second Murphy: the directory api apparently ahs it's . reference as first directory entry, (later-than-second place), so the anxious procedure is going there,... . But now we arrive absolutely again in the same spot (directory api, which again gives . as directory.... return the same result, and we're off for a nice long trip into ././././././././././... and so on


Proof for(or making understandable/acceptable of) this assumption ?

Well, dir -f returns the list of files in order of the filesystem, so I executed that:
and got:
$ ls -af /opt/scansoft/tts/engine
libicudata.so.22 tts4sml.so libicuuc.so.22 dec_encrypt.so ttsengine.so ..
dub . headers libxml4c.so.50 xlit_1252.so


On other distributions/versions/systems (where the ScanSoft software does work), this instruction returns:
$ ls -af /opt/scansoft/tts/engine
. dec_encrypt.so headers dub libxml4c.so.50 xlit_1252.so
.. libicudata.so.22 tts4sml.so libicuuc.so.22 ttsengine.so


P.S.

Thanks to my collegue Erik Devriendt for helping me finding the origin of the failure.


Solution


A clean solution to the problem would be a bugfix by ScanSoft (Nuance now) seems to be in its place...


A workaround has been composed:


In the process of finding a workaround, I mounted (using sshfs) the engine-directory of a working system over the engine directory of a non-working, and the system functioned...
More fine-tuning of this discovered that especially the header directory of the working system was important. The other files and directories could be used within the local system (using symlinks).


Anyway... In that process, I tried to compose an image-file and mounting it through loopback. Then I discovered that when an ext2 image was extended with a journal (tune2fs -j /dev/loop123) to ext3, and subsequently mounted, the directory got scrambled again. Mounting as ext2 did not solve this.


But when using an (ext2) image mounted on the engine directory, the Initialization procedure indeed continued (did not loose itself in that nasty recursion), but apparently the system then did not find the required files..., because the Initialization returned with Error 23 (in api/inc/lh_err.h, we find TTS_E_NO_MATCH_FOUND 23 . This is the same behaviour as when you request an unknown language-code...


In a last desperate attempt, I created an ext2-image (205M), mounted it as the /opt/scansoft and reinstalled all (rs-api and rs-<lang> packages).


This worked !!!


Although this system now works, I think it more safe just to use another distribution, c.q. version that does not have this problem.

Procedure for workaround:


In this procedure, we assume it being executed by a user with sudo privileges on dd, losetup, mkfs.ext2, mount, mkdir, dpkg, OR execute it in the unsafe way: as superuser.

  1. Create the image-filesystem (first on arbitrary location)

    $ img=/opt/scansoft.img;
    $ dev=$(/sbin/losetup -f);
    $ sudo dd if=/dev/zero of=${img} bs=$(( 1024*1024 )) count=205;
    $ sudo /sbin/losetup ${dev} ${img};
    $ sudo /sbin/mkfs.ext2 ${dev};
  2. mount it and install the software:
    $ mnt=/opt/scansoft;
    $ sudo mkdir -p ${mnt};
    $ sudo mount ${dev} ${mnt} -t ext2;
    $ sudo dpkg -i rs-*.deb;
  3. test the directory-order in the image:
    $ ls -af ${mnt}/tts/engine/headers
    and (at least I did) revel at the result:
    .   dec_encrypt.so    headers     dub             libxml4c.so.50  xlit_1252.so
    .. libicudata.so.22 tts4sml.so libicuuc.so.22 ttsengine.so
  4. Now finaly, test the standard test-program:
    cd /tmp;
    echo "This is a simple test">test.txt;
    /opt/scansoft/tts/api/demos/standard/standard 0 0 /opt/scansoft/tts/engine test.txt;

    You should now see
    Initialize
    Process
    Uninitialize
    after which the current directory should hold a standard.pcm file (of filesize > 0).

To allow automatically (and user-requested) mounting (c.q. unmounting) of the ScanSoft system, we added a line to /etc/fstab:
/opt/scansoft.img /opt/scansoft ext2 loop,ro,users,exec 0 2

Labels: , , , , , ,

2006-03-24

ScanSoft RealSpeak 3.51 for Linux

hi,


A small description about the procedure how I installed it (and use it) on my
Debian Sarge system.


I have been demonstrated that the same procedure worked for Ubuntu 6.06.


Here we go.


Install


The scansoft realspeak host 3.51 provides two .rpm files:

  • rs-api-<version-stuff>.rpm (for developpers)
  • rs-<lang>-<version-stuff>.rpm (the language data).

The indication <lang> is different for every language-package. Belgian Dutch for instance gives us "dub".


For ease of use (especially installation) on a .deb based system (like debian, ubuntu,...), we convert these packages using alien:


fakeroot alien rs-api-3.51.00.02-1.i386.rpm
fakeroot alien rs-dub-3.51.00.02-1.i386.rpm



Then follows installation:


sudo dpkg -i rs-api_3.51.00.02-2_i386.deb
sudo dpkg -i rs-dub_3.51.00.02-2_i386.deb



By this, the ScanSoft (RealSpeak) files are put into /opt/scansoft.


To allow applications to reach the libraries, I added to /etc/ld.so.conf a line:


/opt/scansoft/engine


Followed by execution of sudo /sbin/ldconfig to apply these changes.

Test/Usage


ScanSoft RealSpeak comes with a couple of demos, which can be used to test the functioning. One of them, standard just converts a text into a raw file.

cd /tmp
echo "This is the text I want to be converted to speech by Scansoft." >> text.txt
/opt/scansoft/tts/api/demos/standard 0 0 /opt/scansoft/tts/engine /tmp/text.txt


The values 0 and 0 in the example, select American English (first zero) and a Female voice (second zero). The value(s) corresponding to your language-package might differ.


My system having female flemish (belgian dutch) speaker, uses 14 resp. 0. In the code-directory of rs-api, you'll find the correct values. Read /opt/scansoft/tts/api/inc/lh_ttsso.h to find the corresponding values.

Look for a line like:

#define TTS_LANG_<YOURLANGUAGE> <number>

that will give you the language number.


Above code snippet will write in the /tmp directory a file called standard.pcm. This file can be auditioned using:


play --type=raw --channels=1 --rate=8000 -s -2 --endian=little standard.pcm

play is provided by the sox package.
I used a version d.d. 2007-01-31. (version 13.0.0-1).

For an older version (Debian ETCH uses sox 12.17.9-1), you could try:

play -t raw -c 1 -r 8000 -f s -s w standard.pcm


or you could install the alsa-utils-package, and use aplay:

aplay --type=raw --channels=1 --rate=8000 --format=S16_LE standard.pcm

You even might want to convert the audio-file to an mp3-file:

lame -r -m m -s 8 -x standard.pcm standard.mp3



Note that the last 3 seconds of the audio might not be played. This seems to have something to do with the rudimentary way of playing them. Use another player and it might work as expected.

Labels: , , ,