Files
MicroslopSam/docs/NOTES.md
T

5.3 KiB

Notes

Registry facts

From spchapi/SPCHAPI.INF (%49000% = %25%\speech = C:\windows\speech):

  • CLSID_TTSEnumerator {D67C0280-C743-11cd-80E5-00AA003E4B50} -> Speech.dll
  • "Audio Destination to File Object" {D4623720-E4B9-11cf-8D56-00A0C9034A7E} -> Speech.dll
  • "Audio Destination Object" {CB96B400-C743-11cd-80E5-00AA003E4B50} -> Speech.dll
  • Lexicon dialog {92655FB1-ADF9-11d1-BEB9-006008317CE8} -> Speech.dll
  • Phoneme converter {B9F11A96-90E3-11d0-8D77-00A0C9034A7E} -> Speech.dll

From msttsl/mstts.inf ([TTSReg]):

  • Engine MSTTSSyn = {E0725551-286F-11d0-8E73-00A0C9083363} -> MSTTSSYN.dll
  • Engine install dir: Common Files\microsoft shared\SpeechEngines\TTS.
  • Enumerates voices by scanning *.vce in its own directory.

Flextalk registration (from the installer's setup.ins)

  • Engine value: HKLM\Software\Voice\TextToSpeech\Engine "AT&T FlexTalk" = "{FFE78E00-C69C-11CE-AEC1-0000C0E9CB87}"
  • Engine subkey (forces mode enumeration): ...\Engine\{FFE78E00-...} with Dirty = 1 (REG_DWORD). The runtime rewrites Count + Mode0..N and clears Dirty after enumerating.
  • HKCR\CLSID\{FFE78E00-C69C-11CE-AEC1-0000C0E9CB87}\InprocServer32 = <root>\EngineDLLs\FlexTalk.dll, ThreadingModel = Apartment. Also registered: {778EAAE2-499F-11CF-B0BA-444553540000} -> same DLL.
  • Directories: HKLM\Software\AT&T\Watson\2.0\FlexTalk\2.0\Directories RootDirectory = C:\FlexTalk\.
  • Dictionaries: ...\FlexTalk\2.0\Dictionaries: StandardDictionary="2 ft_sdict.dll", ExceptionDictionary="0 ft_udict.dll", HomographDictionary="1 ft_hgrap.dll", ProperNameDictionary="3 ft_namsa.dll", LetterToSoundDictionary="4 ft_l2s.dll".
  • Options: ...\FlexTalk\2.0\Options Gender=Male, SampleRate=11025.
  • Speakers (per-voice settings; names come from these values). All numeric values must be REG_DWORD: with REG_SZ the engine reads garbage and synthesizes a monotone buzz (pitch fixed at max, pitch control dead).
    • {11260610-C84A-11ce-AEC4-0000C0E9CB87}: Mode Name / Speaker Name "Keith Bell", Pitch 27, Speaking Rate 33, Head Size 46, Expression 59, Lowering 40, Prominences 17, Age 30, Volume 100.
    • {000031CB-3699-551F-AED0-6B4893382D57}: "Kerry Watson", Pitch 65, Speaking Rate 32, Head Size 45, Expression 100, Lowering 40, Prominences 17, Age 30, Volume 100. Measured effects per value and the change procedure are in docs/TTS-DESIGN.md ("Flextalk profile parameters").
  • Voice data: EngineData\AE1M08LC.*, AE1M11LC.* (male, 8/11 kHz) and AE2F08LC.*, AE2F11LC.* (female); .INV inventory, .NDX index, .COD codebook, plus shared DICT_CI.*, phondef, AMPRULES, ENDINGS.

Extraction: unshield -O -d extracted x installer/flextalk/data1.cab (-O = old compression; the archive.org package has no data2.cab, so the final file WatsonUNInstall.dll is incomplete).

SAPI4 runtime engine discovery (speech.dll)

  • FUN_635747a4 reads HKLM\Software\Voice\TextToSpeech\Engine values (value name = engine name, data = CLSID string), validates the GUID with FUN_635712e4, then opens a subkey named by the CLSID string.
  • FUN_635758b1 (TTS mode-list ctor) reads Dirty; when non-zero/missing it calls CoCreateInstance(CLSID, ..., IID @635791c0) and pulls modes via vtable+0xC into 0xaf0-byte records, writes Mode%d (REG_BINARY), Count, then clears Dirty. When Dirty=0 it reads the cached Mode%d blobs.
  • Practical rule: to add an engine, register the Engine value + the CLSID InprocServer32 + an engine subkey with Dirty=1 (a missing subkey also triggers enumeration).

Environment gotchas

  • Wine needs a working X display (the runtime creates windows). xvfb-run -a proved flaky here; setup/run.sh starts a persistent Xvfb :77 instead.
  • Wine reports err:ole:apartment_add_dll couldn't load in-process dll when the InprocServer32 path does not exist. Check the file copy first (this bit us: a bad unshield run created empty directories).
  • 32-bit engines require a 32-bit prefix (WINEARCH=win32).
  • sudo on this machine requires a password; installs are manual.

Engine units (measured)

  • speed: MSTTS range 30-450, Flextalk 50-390; the natural rate is about 150 for every voice (duration at 100/200/300 fits a natural value near 140-150).
  • pitch: engine units, roughly linear in F0 near the natural point (~1.1 Hz per unit). Natural values: about 100 (MSTTS), 106 (Keith Bell), 186 (Kerry Watson); Flextalk max 250. Verified with the corrected DWORD registry: Kerry 0 st = 209 Hz, -6 st = 148 Hz, +6 st = 250 Hz (clamped at max); Keith 0 st = 119 Hz, +6 st = 170 Hz.
  • The wrapper maps semitones as natural * 2^(st/12) and clamps to the range.
  • volume: available through ITTSAttributes (host flag -V). Flextalk is linear (0-65535, default 65535; half is about -6 dB). MSTTS is non-linear (0 = silence, 4096 about -24 dB, 65535+ full scale); treat it as on/off.
  • Flextalk per-speaker profile values are applied at voice load; Expression was verified audible (0/59/100 produce different waveforms at equal duration). Changing them requires a registry edit and re-selecting the voice.

Decompiled corpora (Ghidra)

  • /mnt/ghidra/decomp/msttssyn.dll/ (786 functions, engine)
  • /mnt/ghidra/decomp/speech.dll/ (1030 functions, SAPI4 runtime)