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: , , , , , ,