1. Installation Instructions on Win32

Table of Contents

Prerequisites
How does Emacspeak communicate with the speech server?
Installing Emacs for NT
Compiling Tcl/Tk and TCLX
Compiling TCL
Compiling TK
Compiling TCLX
Compiling TCLECI
Using Visual C++ 5.0
Using Visual C++ 6.0
Testing the Outloud server
Modifying Emacspeak
Switching between languages
Entries for .emacs
Auditory Icons
Configuring and Installing Emacspeak on Win32

This chapter tries to provide sufficiently detailed instructions for configuring and installing Emacspeak on Win32 systems like for example Windows 95, Windows 98 and Windows NT using NTemacs and ViaVoice TTS using different languages. However, it is worth mentioning that making Emacspeak for Win32 is not a trivial task ...

Please note, that this chapter is not complete yet and will be completed as time permits.

Emacspeak starts a Tcl program, outloud in our case. The Tcl program relies on the Tcl extension TCLX. outloud receives text via stdin and sends it to the speech synthesizer, in our case using tcleci.dll, which controls ibmeci50.dll, the actual interface to ViaVoice TTS. Making emacspeak work under WIN32 therefore requires the following steps:

  1. Install NT Emacs

  2. Compile TCL/TK and TCLX

  3. Compile tcleci.dll

  4. Modifying and testing outloud

  5. Installing and modifying emacspeak

  6. Because ViaVoice TTS is available for several languages on WIN32, it is also possible to switch between languages

Follow the instructions from http://www.gnu.org/software/emacs/windows/faq3.html#install.

ActiveTCL comes precompiled .. so assuming it works, the following compiles could be skipped.

Follow the instructions in <tcldir>\win\readme

Follow the instructions in <tkdir>\win\readme

Although it is probably not absolutely necessary to compile and install TK in order to use emacspeak, it makes compiling TCLX easier.

Follow the instructions in <tclxdir>\win\install.txt

Because ibmeci50.dll was compiled with VC++ 6.0, it is necessary to install the latest Servive Pack for VC++ 5.0, otherwise the linking fails. The service pack (Visual Studio 97 Service Pack 3) is available from Microsoft (http://www.microsoft.com).

Import this file into Visual C++ 5.0 or use nmake -f tcleci.mak


# Microsoft Developer Studio Generated NMAKE File, Based on TCLECI.DSP
!IF "$(CFG)" == ""
CFG=TCLECI - Win32 Debug
!MESSAGE No configuration specified. Defaulting to TCLECI - Win32 Debug.
!ENDIF 

!IF "$(CFG)" != "TCLECI - Win32 Release" && "$(CFG)" != "TCLECI - Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE 
!MESSAGE NMAKE /f "TCLECI.MAK" CFG="TCLECI - Win32 Debug"
!MESSAGE 
!MESSAGE Possible choices for configuration are:
!MESSAGE 
!MESSAGE "TCLECI - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "TCLECI - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE 
!ERROR An invalid configuration is specified.
!ENDIF 

!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE 
NULL=nul
!ENDIF 

!IF  "$(CFG)" == "TCLECI - Win32 Release"

OUTDIR=.\Release
INTDIR=.\Release
# Begin Custom Macros
OutDir=.\Release
# End Custom Macros

!IF "$(RECURSE)" == "0" 

ALL : "$(OUTDIR)\TCLECI.dll"

!ELSE 

ALL : "$(OUTDIR)\TCLECI.dll"

!ENDIF 

CLEAN :
	-@erase "$(INTDIR)\tcleci.obj"
	-@erase "$(INTDIR)\vc50.idb"
	-@erase "$(OUTDIR)\TCLECI.dll"
	-@erase "$(OUTDIR)\TCLECI.exp"
	-@erase "$(OUTDIR)\TCLECI.lib"

"$(OUTDIR)" :
    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"

CPP=cl.exe
CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\
 /Fp"$(INTDIR)\TCLECI.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c 
CPP_OBJS=.\Release/
CPP_SBRS=.

.c{$(CPP_OBJS)}.obj::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

.cpp{$(CPP_OBJS)}.obj::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

.cxx{$(CPP_OBJS)}.obj::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

.c{$(CPP_SBRS)}.sbr::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

.cpp{$(CPP_SBRS)}.sbr::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

.cxx{$(CPP_SBRS)}.sbr::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

MTL=midl.exe
MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 
RSC=rc.exe
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\TCLECI.bsc" 
BSC32_SBRS= \
	
LINK32=link.exe
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
 advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib tcl82.lib ibmeci50.lib\
 /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\TCLECI.pdb"\
 /machine:I386 /out:"$(OUTDIR)\TCLECI.dll" /implib:"$(OUTDIR)\TCLECI.lib" 
LINK32_OBJS= \
	"$(INTDIR)\tcleci.obj"

"$(OUTDIR)\TCLECI.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
    $(LINK32) @<<
  $(LINK32_FLAGS) $(LINK32_OBJS)
<<

!ELSEIF  "$(CFG)" == "TCLECI - Win32 Debug"

OUTDIR=.\Debug
INTDIR=.\Debug
# Begin Custom Macros
OutDir=.\Debug
# End Custom Macros

!IF "$(RECURSE)" == "0" 

ALL : "$(OUTDIR)\TCLECI.dll"

!ELSE 

ALL : "$(OUTDIR)\TCLECI.dll"

!ENDIF 

CLEAN :
	-@erase "$(INTDIR)\tcleci.obj"
	-@erase "$(INTDIR)\vc50.idb"
	-@erase "$(INTDIR)\vc50.pdb"
	-@erase "$(OUTDIR)\TCLECI.dll"
	-@erase "$(OUTDIR)\TCLECI.exp"
	-@erase "$(OUTDIR)\TCLECI.ilk"
	-@erase "$(OUTDIR)\TCLECI.lib"
	-@erase "$(OUTDIR)\TCLECI.pdb"

"$(OUTDIR)" :
    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"

CPP=cl.exe
CPP_PROJ=/nologo /MD /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\
 /Fp"$(INTDIR)\TCLECI.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c 
CPP_OBJS=.\Debug/
CPP_SBRS=.

.c{$(CPP_OBJS)}.obj::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

.cpp{$(CPP_OBJS)}.obj::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

.cxx{$(CPP_OBJS)}.obj::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

.c{$(CPP_SBRS)}.sbr::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

.cpp{$(CPP_SBRS)}.sbr::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

.cxx{$(CPP_SBRS)}.sbr::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

MTL=midl.exe
MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 
RSC=rc.exe
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\TCLECI.bsc" 
BSC32_SBRS= \
	
LINK32=link.exe
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
 advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib tcl82.lib ibmeci50.lib\
 /nologo /subsystem:windows /dll /incremental:yes /pdb:"$(OUTDIR)\TCLECI.pdb"\
 /debug /machine:I386 /out:"$(OUTDIR)\TCLECI.dll" /implib:"$(OUTDIR)\TCLECI.lib"\
 /pdbtype:sept 
LINK32_OBJS= \
	"$(INTDIR)\tcleci.obj"

"$(OUTDIR)\TCLECI.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
    $(LINK32) @<<
  $(LINK32_FLAGS) $(LINK32_OBJS)
<<

!ENDIF 


!IF "$(CFG)" == "TCLECI - Win32 Release" || "$(CFG)" == "TCLECI - Win32 Debug"
SOURCE=.\tcleci.cpp

!IF  "$(CFG)" == "TCLECI - Win32 Release"

DEP_CPP_TCLEC=\
	"e:\programme\tcl\include\tcl.h"\
	"e:\programme\tcl\include\tcldecls.h"\
	"e:\programme\viavoice tts 5.0 sdk\include\eci.h"\
	

"$(INTDIR)\tcleci.obj" : $(SOURCE) $(DEP_CPP_TCLEC) "$(INTDIR)"


!ELSEIF  "$(CFG)" == "TCLECI - Win32 Debug"

DEP_CPP_TCLEC=\
	"e:\programme\tcl\include\tcl.h"\
	"e:\programme\tcl\include\tcldecls.h"\
	"e:\programme\viavoice tts 5.0 sdk\include\eci.h"\
	

"$(INTDIR)\tcleci.obj" : $(SOURCE) $(DEP_CPP_TCLEC) "$(INTDIR)"


!ENDIF 


!ENDIF 




Should work out of the box using above makefile. No practical experiences.

Make sure the tcleci.dll is in your path, and modify the outloud program as follows:

  1. Locate the following line:

    load $tclTTS/tcleci.so
    

  2. and modify it to

    load $tclTTS/tcleci.dll
    

Now we are ready to test the outloud server by setting a environment variable and runnig outloud (don't forget to use your own path here):

>set EMACSPEAK_DIR=g:/projects/emacspeak-13.0
>tcl outloud

There is already code in Emacspeak to support Win32. However, to use the outloud speech server it is necessary to comment this part out:

  1. Edit the file dtk-speak.el

  2. and locate the following lines:

        (when (or (eq window-system 'win32)
                  (eq window-system 'w32))
          (dtk-select-server "dtk-sapi"))
    

  3. and comment them out

    ;    (when (or (eq window-system 'win32)
    ;              (eq window-system 'w32))
    ;      (dtk-select-server "dtk-sapi"))
    

Adding the following lines to emacspeak-speak.el allows to switch between US English, UK English and German in this example using ECI annotations (`l1, `l1.1 and `l4) between languages:

(defun emacspeak-language-us()
  "Language is now US English."
  (interactive)
  (setq dtk-language "en_us")
  (dtk-speak-setup-character-table )
  (dtk-dispatch "`l1")
  (message "Language is now US English!"))

(defun emacspeak-language-uk()
  "Language is now UK English."
  (interactive)
  (setq dtk-language "en_uk")
  (dtk-speak-setup-character-table )
  (dtk-dispatch "`l1.1")
  (setq dtk-language "en_uk")
  (message "Language is now UK English!"))

(defun emacspeak-language-de()
  "Language is now German."
  (interactive)
  (setq dtk-language "de")
  (dtk-speak-setup-character-table )
  (dtk-dispatch "`l4")
  (message "Sprache ist jetzt Deutsch!"))
; emacspeak
(setenv "DTK_PROGRAM" "outloud")
(setenv "EMACSPEAK_DIR" "g:/projects/emacspeak-13.0")
(load-file  "g:/projects/emacspeak-13.0/lisp/emacspeak-setup.el")

(define-key emacspeak-keymap "1" 'emacspeak-language-us)
(define-key emacspeak-keymap "2" 'emacspeak-language-uk)
(define-key emacspeak-keymap "4" 'emacspeak-language-de)

Currently there is no support for auditory icons on WIN32.

...