Moved the Windows build files together with DOS and others into a new directory: "platforms". git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@76 d46cf337-b52f-0410-862d-fd96e6ae7743master
CC = gcc | |||||
CFLAGS += -g -Wall | |||||
all: espeak-phoneme-data | |||||
espeak-phoneme-data: espeak-phoneme-data.c | |||||
$(CC) $(CFLAGS) -o $@ $< | |||||
clean: | |||||
rm -f espeak-phoneme-data |
espeak-utils | |||||
============ | |||||
A utility to convert the phonindex, phontab and phondata to | |||||
big-endian form if necessary. | |||||
* espeak-phoneme-data | |||||
This is the little-endian to big-endian conversion tool. It uses an | |||||
external file (by default called 'phondata-manifest') in order to convert | |||||
the phondata file. | |||||
The 'phondata-manifest' file is produced by espeakedit when it compiles | |||||
the phoneme data. If it is not present here, find it in the espeak-data directory. | |||||
--- | |||||
To contact the author of these utilities, please send an e-mail to | |||||
<[email protected]> |
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <sys/types.h> | |||||
#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN | |||||
#define IS_BIG_ENDIAN 1 | |||||
#else | |||||
#define IS_BIG_ENDIAN 0 | |||||
#endif | |||||
#if IS_BIG_ENDIAN | |||||
# define SWAP_USHORT(val) ((unsigned short) ( \ | |||||
(unsigned short) ((unsigned short) (val) >> 8) | \ | |||||
(unsigned short) ((unsigned short) (val) << 8))) | |||||
# define SWAP_UINT(val) ((unsigned int) ( \ | |||||
(((unsigned int) (val) & (unsigned int) 0x000000ffU) << 24) | \ | |||||
(((unsigned int) (val) & (unsigned int) 0x0000ff00U) << 8) | \ | |||||
(((unsigned int) (val) & (unsigned int) 0x00ff0000U) >> 8) | \ | |||||
(((unsigned int) (val) & (unsigned int) 0xff000000U) >> 24))) | |||||
#else | |||||
# define SWAP_USHORT(val) (val) | |||||
# define SWAP_UINT(val) (val) | |||||
#endif | |||||
#define N_PHONEME_TAB_NAME 32 | |||||
typedef struct { | |||||
unsigned int mnemonic; | |||||
unsigned int phflags; | |||||
unsigned short std_length; | |||||
unsigned short spect; | |||||
unsigned short before; | |||||
unsigned short after; | |||||
unsigned char code; | |||||
unsigned char type; | |||||
unsigned char start_type; | |||||
unsigned char end_type; | |||||
unsigned char length_mod; | |||||
unsigned char reduce_to; | |||||
unsigned char alternative_ph; | |||||
unsigned char link_out; | |||||
} PHONEME_TAB; | |||||
typedef struct { | |||||
short frflags; | |||||
unsigned char length; | |||||
unsigned char rms; | |||||
short ffreq[9]; | |||||
unsigned char fheight[9]; | |||||
unsigned char fwidth[6]; | |||||
unsigned char fright[6]; | |||||
} frame_t; | |||||
#define N_SEQ_FRAMES 25 | |||||
typedef struct { | |||||
short length; | |||||
unsigned char n_frames; | |||||
unsigned char flags; | |||||
frame_t frame[N_SEQ_FRAMES]; | |||||
} SPECT_SEQ; | |||||
void swap_phondata (const char *infile, const char *outfile, | |||||
const char *manifest); | |||||
void swap_phonindex (const char *infile, const char *outfile); | |||||
void swap_phontab (const char *infile, const char *outfile); | |||||
void usage (const char *program_name); | |||||
int | |||||
main (int argc, char *argv[]) | |||||
{ | |||||
const char *indir = "/usr/share/espeak-data"; | |||||
const char *outdir = "."; | |||||
const char *manifest = "phondata-manifest"; | |||||
char *f1, *f2; | |||||
if (argc > 4) | |||||
usage (argv[0]); | |||||
if (argc > 1) { | |||||
if (strcmp (argv[1], "-h") == 0 || | |||||
strcmp (argv[1], "--help") == 0) | |||||
usage (argv[0]); | |||||
indir = argv[1]; | |||||
} | |||||
if (argc > 2) | |||||
outdir = argv[2]; | |||||
if (argc > 3) | |||||
manifest = argv[3]; | |||||
f1 = (char *) malloc (strlen (indir) + 20); | |||||
if (f1 == NULL) { | |||||
fprintf (stderr, "Unable to allocate memory\n"); | |||||
exit (1); | |||||
} | |||||
f2 = (char *) malloc (strlen (outdir) + 20); | |||||
if (f2 == NULL) { | |||||
fprintf (stderr, "Unable to allocate memory\n"); | |||||
exit (1); | |||||
} | |||||
#if IS_BIG_ENDIAN | |||||
printf ("Host seems to be big-endian ..\n"); | |||||
#else | |||||
printf ("Host seems to be little-endian ..\n"); | |||||
#endif | |||||
sprintf (f1, "%s/phontab", indir); | |||||
sprintf (f2, "%s/temp_1", outdir); | |||||
printf ("Processing phontab ..\n"); | |||||
swap_phontab (f1, f2); | |||||
sprintf (f1, "%s/phontab", outdir); | |||||
rename (f2, f1); | |||||
sprintf (f1, "%s/phonindex", indir); | |||||
sprintf (f2, "%s/temp_1", outdir); | |||||
printf ("Processing phonindex ..\n"); | |||||
swap_phonindex (f1, f2); | |||||
sprintf (f1, "%s/phonindex", outdir); | |||||
rename (f2, f1); | |||||
sprintf (f1, "%s/phondata", indir); | |||||
sprintf (f2, "%s/temp_1", outdir); | |||||
printf ("Processing phondata ..\n"); | |||||
swap_phondata (f1, f2, manifest); | |||||
sprintf (f1, "%s/phondata", outdir); | |||||
rename (f2, f1); | |||||
free (f1); | |||||
free (f2); | |||||
printf ("Done.\n"); | |||||
return 0; | |||||
} | |||||
void | |||||
swap_phondata (const char *infile, const char *outfile, | |||||
const char *manifest) | |||||
{ | |||||
FILE *in, *mfest, *out; | |||||
char line[1024]; | |||||
unsigned char buf_4[4]; | |||||
in = fopen (infile, "rb"); | |||||
if (in == NULL) { | |||||
fprintf (stderr, "Unable to read from file %s\n", infile); | |||||
exit (1); | |||||
} | |||||
mfest = fopen (manifest, "rb"); | |||||
if (mfest == NULL) { | |||||
fprintf (stderr, "Unable to read from file %s\n", manifest); | |||||
exit (1); | |||||
} | |||||
out = fopen (outfile, "wb"); | |||||
if (out == NULL) { | |||||
fprintf (stderr, "Unable to open file %s for writing\n", outfile); | |||||
exit (1); | |||||
} | |||||
fread (buf_4, 4, 1, in); | |||||
fwrite (buf_4, 4, 1, out); | |||||
while (fgets (line, 1024, mfest)) { | |||||
if (line[0] == 'S') { | |||||
SPECT_SEQ buf_spect; | |||||
size_t ix; | |||||
int n; | |||||
fread (&buf_spect.length, 2, 1, in); | |||||
fread (&buf_spect.n_frames, 1, 1, in); | |||||
fseek (in, -3, SEEK_CUR); | |||||
ix = (char *)(&buf_spect.frame[buf_spect.n_frames]) - | |||||
(char *)(&buf_spect); | |||||
ix = (ix+3) & 0xfffc; | |||||
fread (&buf_spect, ix, 1, in); | |||||
buf_spect.length = (short) SWAP_USHORT (buf_spect.length); | |||||
for (n = 0; n < buf_spect.n_frames; n++) { | |||||
int k; | |||||
buf_spect.frame[n].frflags = (short) | |||||
SWAP_USHORT (buf_spect.frame[n].frflags); | |||||
for (k = 0; k < 9; k++) { | |||||
buf_spect.frame[n].ffreq[k] = (short) | |||||
SWAP_USHORT (buf_spect.frame[n].ffreq[k]); | |||||
} | |||||
} | |||||
fwrite (&buf_spect, ix, 1, out); | |||||
} | |||||
else if (line[0] == 'W') { | |||||
long pos; | |||||
int length; | |||||
char *wave_data; | |||||
fread (buf_4, 4, 1, in); | |||||
fwrite (buf_4, 4, 1, out); | |||||
length = buf_4[1] * 256 + buf_4[0]; | |||||
wave_data = (char *) malloc (length); | |||||
if (wave_data == NULL) { | |||||
fprintf (stderr, "Memory allocation error\n"); | |||||
exit (1); | |||||
} | |||||
fread (wave_data, 1, length, in); | |||||
fwrite (wave_data, 1, length, out); | |||||
pos = ftell (in); | |||||
while((pos & 3) != 0) { | |||||
fgetc (in); | |||||
pos++; | |||||
} | |||||
pos = ftell (out); | |||||
while((pos & 3) != 0) { | |||||
fputc (0, out); | |||||
pos++; | |||||
} | |||||
free (wave_data); | |||||
} | |||||
else if (line[0] == 'E') { | |||||
char env_buf[128]; | |||||
fread (env_buf, 1, 128, in); | |||||
fwrite (env_buf, 1, 128, out); | |||||
} | |||||
} | |||||
fclose (in); | |||||
fclose (out); | |||||
fclose (mfest); | |||||
} | |||||
void | |||||
swap_phonindex (const char *infile, const char *outfile) | |||||
{ | |||||
FILE *in, *out; | |||||
unsigned int val; | |||||
in = fopen (infile, "rb"); | |||||
if (in == NULL) { | |||||
fprintf (stderr, "Unable to read from file %s\n", infile); | |||||
exit (1); | |||||
} | |||||
out = fopen (outfile, "wb"); | |||||
if (out == NULL) { | |||||
fprintf (stderr, "Unable to open file %s for writing\n", outfile); | |||||
exit (1); | |||||
} | |||||
while (! feof (in)) { | |||||
size_t n; | |||||
n = fread (&val, 4, 1, in); | |||||
if (n != 1) | |||||
break; | |||||
val = SWAP_UINT (val); | |||||
fwrite (&val, 4, 1, out); | |||||
} | |||||
fclose (in); | |||||
fclose (out); | |||||
} | |||||
void | |||||
swap_phontab (const char *infile, const char *outfile) | |||||
{ | |||||
FILE *in, *out; | |||||
char buf_4[4]; | |||||
int i, n_phoneme_tables; | |||||
in = fopen (infile, "rb"); | |||||
if (in == NULL) { | |||||
fprintf (stderr, "Unable to read from file %s\n", infile); | |||||
exit (1); | |||||
} | |||||
out = fopen (outfile, "wb"); | |||||
if (out == NULL) { | |||||
fprintf (stderr, "Unable to open file %s for writing\n", outfile); | |||||
exit (1); | |||||
} | |||||
fread (buf_4, 4, 1, in); | |||||
fwrite (buf_4, 4, 1, out); | |||||
n_phoneme_tables = buf_4[0]; | |||||
for (i = 0; i < n_phoneme_tables; i++) { | |||||
int n_phonemes, j; | |||||
char tab_name[N_PHONEME_TAB_NAME]; | |||||
fread (buf_4, 4, 1, in); | |||||
fwrite (buf_4, 4, 1, out); | |||||
n_phonemes = buf_4[0]; | |||||
fread (tab_name, N_PHONEME_TAB_NAME, 1, in); | |||||
fwrite (tab_name, N_PHONEME_TAB_NAME, 1, out); | |||||
for (j = 0; j < n_phonemes; j++) { | |||||
PHONEME_TAB table; | |||||
fread (&table, sizeof (PHONEME_TAB), 1, in); | |||||
table.mnemonic = SWAP_UINT (table.mnemonic); | |||||
table.phflags = SWAP_UINT (table.phflags); | |||||
table.std_length = SWAP_USHORT (table.std_length); | |||||
table.spect = SWAP_USHORT (table.spect); | |||||
table.before = SWAP_USHORT (table.before); | |||||
table.after = SWAP_USHORT (table.after); | |||||
fwrite (&table, sizeof (PHONEME_TAB), 1, out); | |||||
} | |||||
} | |||||
fclose (in); | |||||
fclose (out); | |||||
} | |||||
void | |||||
usage (const char *program_name) | |||||
{ | |||||
fprintf (stderr, | |||||
"This program copies the phontab, phonindex and phondata files from a given\n" | |||||
"directory, swapping values to big-endian form if necessary.\n\n" | |||||
"Usage:\n" | |||||
" %s [INPUT_DIR] [OUTPUT_DIR] [MANIFEST_FILE]\n\n" | |||||
"By default, the MANIFEST_FILE used is a file called 'phondata-manifest' in\n" | |||||
"the current directory. The default INPUT_DIR is /usr/share/espeak-data and\n" | |||||
"OUTPUT_DIR is the current directory.\n", program_name); | |||||
exit (1); | |||||
} |
BINDIR=/usr/bin | |||||
INCDIR=/usr/include/espeak | |||||
LIBDIR=/usr/lib | |||||
DATADIR=espeak-data | |||||
RELEASE = 1.28 | |||||
BIN_NAME = speak | |||||
INSTALL = /usr/bin/install | |||||
LN_SF = /bin/ln -sf | |||||
MKDIR = mkdir -p | |||||
speak_SOURCES = speak.cpp compiledict.cpp dictionary.cpp intonation.cpp \ | |||||
readclause.cpp setlengths.cpp numbers.cpp synth_mbrola.cpp \ | |||||
synthdata.cpp synthesize.cpp translate.cpp tr_english.cpp \ | |||||
tr_languages.cpp voices.cpp wavegen.cpp phonemelist.cpp | |||||
SRCS1=$(speak_SOURCES) | |||||
OBJS1=$(patsubst %.cpp,%.o,$(SRCS1)) | |||||
LIBS1= | |||||
CXXFLAGS=-O2 | |||||
all: $(BIN_NAME) | |||||
.cpp.o: | |||||
$(CXX) $(CXXFLAGS) -D PATH_ESPEAK_DATA=\"$(DATADIR)\" -Wall -pedantic -I. -c -fno-exceptions $< | |||||
$(BIN_NAME): $(OBJS1) | |||||
$(CXX) -o $@ $(OBJS1) $(LIBS1) | |||||
clean: | |||||
rm -f *.o *.a *~ | |||||
distclean: clean | |||||
rm -f $(BIN_NAME) | |||||
rm -f $(BIN2_NAME) | |||||
rm -f $(LIB_NAME)* | |||||
install: all | |||||
# Create directories | |||||
rm -rf $(DESTDIR)$(DATADIR) | |||||
$(MKDIR) $(DESTDIR)$(BINDIR) | |||||
$(MKDIR) $(DESTDIR)$(LIBDIR) | |||||
$(MKDIR) $(DESTDIR)$(INCDIR) | |||||
$(MKDIR) $(DESTDIR)$(DATADIR) | |||||
# Install espeak executable | |||||
$(INSTALL) -m 755 $(BIN2_NAME) $(DESTDIR)$(BINDIR) | |||||
# Install shared library | |||||
$(INSTALL) -m 755 $(LIB_NAME).$(LIBTAG) $(DESTDIR)$(LIBDIR) | |||||
# Install static library | |||||
$(INSTALL) -m 755 $(STATIC_LIB_NAME) $(DESTDIR)$(LIBDIR) | |||||
$(LN_SF) $(LIB_NAME).$(LIBTAG) $(DESTDIR)$(LIBDIR)/$(LIB_NAME).$(LIB_VERSION) | |||||
$(LN_SF) $(LIB_NAME).$(LIB_VERSION) $(DESTDIR)$(LIBDIR)/$(LIB_NAME) | |||||
# Install development headers | |||||
$(INSTALL) -pm 644 speak_lib.h $(DESTDIR)$(INCDIR) | |||||
# Install data files | |||||
cp -prf ../espeak-data/* $(DESTDIR)$(DATADIR) | |||||
/*************************************************************************** | |||||
* Copyright (C) 2005 to 2007 by Jonathan Duddington * | |||||
* email: [email protected] * | |||||
* * | |||||
* This program is free software; you can redistribute it and/or modify * | |||||
* it under the terms of the GNU General Public License as published by * | |||||
* the Free Software Foundation; either version 3 of the License, or * | |||||
* (at your option) any later version. * | |||||
* * | |||||
* This program is distributed in the hope that it will be useful, * | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||||
* GNU General Public License for more details. * | |||||
* * | |||||
* You should have received a copy of the GNU General Public License * | |||||
* along with this program; if not, write see: * | |||||
* <http://www.gnu.org/licenses/>. * | |||||
***************************************************************************/ | |||||
#include <sys/types.h> | |||||
// conditional compilation options | |||||
#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN | |||||
#define ARCH_BIG | |||||
#endif | |||||
#define PLATFORM_DOS | |||||
#define NEED_WCHAR_FUNCTIONS | |||||
#define NEED_GETOPT | |||||
typedef unsigned int uint32_t; | |||||
#define PATHSEP '\\' | |||||
//#define USE_PORTAUDIO | |||||
#define USE_NANOSLEEP | |||||
#define __cdecl | |||||
#define ESPEAK_API extern "C" | |||||
#ifdef LIBRARY | |||||
#define USE_ASYNC | |||||
//#define USE_MBROLA_LIB | |||||
#endif | |||||
#ifdef _ESPEAKEDIT | |||||
#define USE_ASYNC | |||||
#define LOG_FRAMES // write keyframe info to log-espeakedit | |||||
#endif | |||||
// will look for espeak_data directory here, and also in user's home directory | |||||
#ifndef PATH_ESPEAK_DATA | |||||
#define PATH_ESPEAK_DATA "/usr/share/espeak-data" | |||||
#endif | |||||
#ifdef PLATFORM_DOS | |||||
int iswalpha(int c); | |||||
int iswdigit(int c); | |||||
int iswalnum(int c); | |||||
int towlower(int c); | |||||
int iswupper(int c); | |||||
int iswlower(int c); | |||||
int iswspace(int c); | |||||
int iswpunct(int c); | |||||
const wchar_t *wcschr(const wchar_t *str, int c); | |||||
const int wcslen(const wchar_t *str); | |||||
float wcstod(const wchar_t *str, wchar_t **tailptr); | |||||
int towupper(int c); | |||||
#endif | |||||
typedef unsigned short USHORT; | |||||
typedef unsigned char UCHAR; | |||||
typedef double DOUBLEX; | |||||
typedef struct { | |||||
const char *mnem; | |||||
int value; | |||||
} MNEM_TAB; | |||||
int LookupMnem(MNEM_TAB *table, char *string); | |||||
#define N_PATH_HOME 120 | |||||
extern char path_home[N_PATH_HOME]; // this is the espeak-data directory | |||||
extern void strncpy0(char *to,const char *from, int size); | |||||
int GetFileLength(const char *filename); | |||||
char *Alloc(int size); | |||||
void Free(void *ptr); | |||||
Building speak.exe with djgpp: | |||||
1. | |||||
unzip the source with the unzip32.exe utility from djgpp. | |||||
2. | |||||
change into the src directory. | |||||
copy the makefile.dj and the speech.h file into the src directory | |||||
type in the src directory make -f makefile.dj | |||||
3. | |||||
copy the speak.exe into the main directory (cp speak.exe ..\speak.exe | |||||
Now you can use speak.exe to produce wave-files: | |||||
speak -v de -f test.txt -w test.wav | |||||
or you can produce phonemes for mbrola: | |||||
speak -v mb\mb-de4 -f test.txt >test.pho | |||||
speak --voices will list all voices. | |||||
Test it and enjoy. |
eSpeak - RISCOS Version | |||||
======================== | |||||
NOTE: The contents of the files in the espeak-dat directory, | |||||
and the format of their contents has changed for this version. | |||||
Please delete your old espeak-dat directory and replace it | |||||
with the new one in this package. | |||||
Requirements | |||||
============ | |||||
RISCOS 3.6 or later with 16 bit sound system enabled. | |||||
On my 200MHz StrongArm, it takes 51 sec to process 6m 3s of speech output, | |||||
so it will probably run OK on an ARM7 processor also. | |||||
Installation and Use | |||||
==================== | |||||
1. Copy the !eSpeak directory onto your harddrive. | |||||
2. To load the Speak module: double-click on !eSpeak. | |||||
This sets the <eSpeak$Dir> system variable, and then runs | |||||
the "speakmod" file to load the Speak module. | |||||
Note, <eSpeak$Dir> refers to the directory that contains the | |||||
espeak-dat directory, which contains the speech data. It must | |||||
be set before the module is loaded. | |||||
3. Example commands: | |||||
*help speak | |||||
should now show version 3.10 | |||||
*speak -h | |||||
shows the available commands | |||||
*speak "this is some text" | |||||
speaks the string "this is some text" | |||||
*speak -v en-f "this is some text" | |||||
speaks with a different voice | |||||
*speak -f textfile | |||||
speaks the text from file "textfile" | |||||
*speak -a30 "this is some text" | |||||
speaks more quietly (range 0 to 200) | |||||
*speak -s200 "this is some text" | |||||
speaks more quickly (200 words per minute) | |||||
The improvement in speech quality over Speak v.2 are most clearly | |||||
heard when listening through a good sound system (eg. domestic | |||||
stereo system) rather than small computer speakers. | |||||
4. Adding words to the pronunciation dictionary | |||||
The directory "data" contains pronunciation rules and exceptions | |||||
lists. To add words, add the word and its pronunciation | |||||
phonemes to en_extra and then do the speak command | |||||
speak --compile=en | |||||
from within the data directory. This will recompile the files: | |||||
en_dict in the espeak_dat directory. | |||||
Details of the phoneme codes are given in docs.phonemes/html | |||||
You can see the translated phoneme codes for a word by | |||||
speak -x "word" | |||||
Use with Pluto | |||||
============== | |||||
!Pluto will use the new module if speakmod has already | |||||
been run. Pluto's Speak dialog should show the new voices. | |||||
If you wish, you can give them more meaningful names by | |||||
renaming the files in espeak-dat.voices | |||||
To install permanently in Pluto, you can copy "speakmod" into | |||||
!Pluto to replace the old speakmod for Speak version 2. | |||||
Note that the system variable <eSpeak$dir> must be set before | |||||
speakmod is loaded. This can be done by either: | |||||
a. Making sure that !eSpeak is seen by the RISC OS filer | |||||
before Pluto is run. | |||||
or | |||||
b. Putting the line: | |||||
Set eSpeak$dir <obey$dir> | |||||
in the !Pluto.!Run file and copying the espeak-dat directory | |||||
into !Pluto | |||||
Re-select the voices that Pluto uses. These may have changed. | |||||
To Re-Compile the Speak Module | |||||
============================== | |||||
Download the "speak-*-source.zip" package and follow the instruction | |||||
int the ReadMe file in the "riscos" directory. | |||||
Problems | |||||
======== | |||||
1. It uses the sound system directly rather than through the | |||||
SharedSound module, would allow the system volume control apply | |||||
to speech. | |||||
2. There is no session management implemented, so changes to speed, | |||||
amplitude etc by one user of the module will affect the others. | |||||
# Project: Speak3 | |||||
# Toolflags: | |||||
CCflags = -c -C90 -depend !Depend -IC: -throwback -zM | |||||
C++flags = -c -depend !Depend -IC: -throwback -zM | |||||
Linkflags = -rmf -c++ -o $@ | |||||
ObjAsmflags = -throwback -NoCache -depend !Depend | |||||
CMHGflags = | |||||
LibFileflags = -c -o $@ | |||||
Squeezeflags = -o $@ | |||||
# Final targets: | |||||
@.speakmod: @.o.speak_riscos @.o.compiledict @.o.dictionary \ | |||||
@.o.intonation @.o.readclause @.o.setlengths @.o.synthdata \ | |||||
@.o.synthesize @.o.translate @.o.tr_languages @.o.numbers \ | |||||
@.o.synth_mbrola @.o.phonemelist \ | |||||
@.o.tr_english @.o.wavegen @.o.voices @.o.assemb @.o.cmhgfile | |||||
Link $(Linkflags) C:o.stubs C:o.c++lib @.o.speak_riscos @.o.compiledict \ | |||||
@.o.dictionary @.o.intonation @.o.readclause @.o.setlengths \ | |||||
@.o.synthdata @.o.synthesize @.o.numbers @.o.synth_mbrola \ | |||||
@.o.translate @.o.tr_english @.o.wavegen @.o.tr_languages \ | |||||
@.o.voices @.o.phonemelist @.o.assemb @.o.cmhgfile | |||||
# User-editable dependencies: | |||||
# Static dependencies: | |||||
@.o.speak_riscos: @.cpp.speak_riscos | |||||
c++ $(c++flags) -o @.o.speak_riscos @.cpp.speak_riscos | |||||
@.o.compiledict: @.cpp.compiledict | |||||
c++ $(c++flags) -o @.o.compiledict @.cpp.compiledict | |||||
@.o.dictionary: @.CPP.dictionary | |||||
c++ $(c++flags) -o @.o.dictionary @.CPP.dictionary | |||||
@.o.intonation: @.CPP.intonation | |||||
c++ $(c++flags) -o @.o.intonation @.CPP.intonation | |||||
@.o.numbers: @.CPP.numbers | |||||
c++ $(c++flags) -o @.o.numbers @.CPP.numbers | |||||
@.o.phonemelist: @.CPP.phonemelist | |||||
c++ $(c++flags) -o @.o.phonemelist @.CPP.phonemelist | |||||
@.o.readclause: @.CPP.readclause | |||||
c++ $(c++flags) -o @.o.readclause @.CPP.readclause | |||||
@.o.setlengths: @.CPP.setlengths | |||||
c++ $(c++flags) -o @.o.setlengths @.CPP.setlengths | |||||
@.o.synthdata: @.CPP.synthdata | |||||
c++ $(c++flags) -o @.o.synthdata @.CPP.synthdata | |||||
@.o.synth_mbrola: @.CPP.synth_mbrola | |||||
c++ $(c++flags) -o @.o.synth_mbrola @.CPP.synth_mbrola | |||||
@.o.synthesize: @.CPP.synthesize | |||||
c++ $(c++flags) -o @.o.synthesize @.CPP.synthesize | |||||
@.o.translate: @.CPP.translate | |||||
c++ $(c++flags) -o @.o.translate @.CPP.translate | |||||
@.o.tr_english: @.CPP.tr_english | |||||
c++ $(c++flags) -o @.o.tr_english @.CPP.tr_english | |||||
@.o.tr_languages: @.CPP.tr_languages | |||||
c++ $(c++flags) -o @.o.tr_languages @.CPP.tr_languages | |||||
@.o.voices: @.CPP.voices | |||||
c++ $(c++flags) -o @.o.voices @.CPP.voices | |||||
@.o.wavegen: @.CPP.wavegen | |||||
c++ $(c++flags) -o @.o.wavegen @.CPP.wavegen | |||||
@.o.assemb: @.s.assemb | |||||
objasm $(objasmflags) -from @.s.assemb -to @.o.assemb | |||||
# Dynamic dependencies: |
These files are for a version for RISC OS computers (formerly | |||||
known as "Acorn" computers), which use ARM processors. | |||||
To compile the speakmod module for RISC OS. | |||||
1. Run the "copysource" script to copy the source files from the | |||||
general source.src directory into the riscos.cpp and | |||||
riscos.h directories. These already contain the RISC OS | |||||
specific files. | |||||
2. Run the Makefile to compile and link and produce the | |||||
"speakmod" module. | |||||
I used the AcornC/C++ compiler. |
copy <obey$dir>.^.src.compiledict/cpp <obey$dir>.cpp.compiledict fq~c | |||||
copy <obey$dir>.^.src.dictionary/cpp <obey$dir>.cpp.dictionary fq~c | |||||
copy <obey$dir>.^.src.intonation/cpp <obey$dir>.cpp.intonation fq~c | |||||
copy <obey$dir>.^.src.numbers/cpp <obey$dir>.cpp.numbers fq~c | |||||
copy <obey$dir>.^.src.phonemelist/cpp <obey$dir>.cpp.phonemelist fq~c | |||||
copy <obey$dir>.^.src.readclause/cpp <obey$dir>.cpp.readclause fq~c | |||||
copy <obey$dir>.^.src.setlengths/cpp <obey$dir>.cpp.setlengths fq~c | |||||
copy <obey$dir>.^.src.synthdata/cpp <obey$dir>.cpp.synthdata fq~c | |||||
copy <obey$dir>.^.src.synth_mbrola/cpp <obey$dir>.cpp.synth_mbrola fq~c | |||||
copy <obey$dir>.^.src.synthesize/cpp <obey$dir>.cpp.synthesize fq~c | |||||
copy <obey$dir>.^.src.translate/cpp <obey$dir>.cpp.translate fq~c | |||||
copy <obey$dir>.^.src.tr_english/cpp <obey$dir>.cpp.tr_english fq~c | |||||
copy <obey$dir>.^.src.tr_languages/cpp <obey$dir>.cpp.tr_languages fq~c | |||||
copy <obey$dir>.^.src.voices/cpp <obey$dir>.cpp.voices fq~c | |||||
copy <obey$dir>.^.src.wavegen/cpp <obey$dir>.cpp.wavegen fq~c | |||||
copy <obey$dir>.^.src.phoneme/h <obey$dir>.h.phoneme fq~c | |||||
copy <obey$dir>.^.src.sintab/h <obey$dir>.h.sintab fq~c | |||||
copy <obey$dir>.^.src.speak_lib/h <obey$dir>.h.speak_lib fq~c | |||||
copy <obey$dir>.^.src.synthesize/h <obey$dir>.h.synthesize fq~c | |||||
copy <obey$dir>.^.src.translate/h <obey$dir>.h.translate fq~c | |||||
copy <obey$dir>.^.src.tr_languages/h <obey$dir>.h.tr_languages fq~c | |||||
copy <obey$dir>.^.src.voice/h <obey$dir>.h.voice fq~c | |||||
copy <obey$dir>.^.src.wave/h <obey$dir>.h.wave fq~c |
; h.RegNames | |||||
; | |||||
; This header file for GETting from assembler source defines register names | |||||
; | |||||
;************************************************************************** | |||||
; | |||||
; Use the RN directive to define ARM register names | |||||
; | |||||
r0 RN 0 | |||||
r1 RN 1 | |||||
r2 RN 2 | |||||
r3 RN 3 | |||||
r4 RN 4 | |||||
r5 RN 5 | |||||
r6 RN 6 | |||||
r7 RN 7 | |||||
r8 RN 8 | |||||
r9 RN 9 | |||||
r10 RN 10 | |||||
sl RN 10 | |||||
r11 RN 11 | |||||
fp RN 11 | |||||
r12 RN 12 | |||||
ip RN 12 | |||||
r13 RN 13 | |||||
sp RN 13 | |||||
r14 RN 14 | |||||
lr RN r14 ; Note: register names can be defined from each other | |||||
r15 RN 15 | |||||
pc RN r15 | |||||
; Use the FN directive to define floating point register names | |||||
f0 FN 0 | |||||
f1 FN 1 | |||||
f2 FN 2 | |||||
f3 FN 3 | |||||
f4 FN 4 | |||||
f5 FN 5 | |||||
f6 FN 6 | |||||
f7 FN 7 | |||||
END | |||||
/*************************************************************************** | |||||
* Copyright (C) 2005,2006 by Jonathan Duddington * | |||||
* [email protected] * | |||||
* * | |||||
* This program is free software; you can redistribute it and/or modify * | |||||
* it under the terms of the GNU General Public License as published by * | |||||
* the Free Software Foundation; either version 2 of the License, or * | |||||
* (at your option) any later version. * | |||||
* * | |||||
* This program is distributed in the hope that it will be useful, * | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||||
* GNU General Public License for more details. * | |||||
* * | |||||
* You should have received a copy of the GNU General Public License * | |||||
* along with this program; if not, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||||
***************************************************************************/ | |||||
// Header file for RISCOS build | |||||
#define N_PEAKS 9 | |||||
#define N_MARKERS 7 | |||||
// comment this out when compiling the "speak" process | |||||
//#define SPECT_EDITOR | |||||
#define PATHSEP '.' | |||||
#define USE_ASSEMBLER_1 | |||||
#define PLATFORM_RISCOS | |||||
#define NEED_WCHAR_FUNCTIONS | |||||
#define __cdecl // define as null, needed for Borland compiler | |||||
#define ESPEAK_API | |||||
typedef unsigned short USHORT; | |||||
typedef unsigned char UCHAR; | |||||
typedef int DOUBLEX; | |||||
typedef struct { | |||||
const char *mnem; | |||||
int value; | |||||
} MNEM_TAB; | |||||
int LookupMnem(MNEM_TAB *table, char *string); | |||||
typedef struct { | |||||
short pkfreq; | |||||
short pkheight; | |||||
short pkwidth; | |||||
short pkright; | |||||
} peak_t; | |||||
typedef struct { | |||||
short frflags; | |||||
unsigned char length; | |||||
unsigned char rms; | |||||
short ffreq[9]; | |||||
unsigned char fheight[9]; | |||||
unsigned char fwidth[6]; // width/4 | |||||
unsigned char fright[6]; // width/4 | |||||
} frame_t; | |||||
extern int GetFileLength(const char *filename); | |||||
extern char *Alloc(int size); | |||||
extern void Free(void *ptr); | |||||
extern void strncpy0(char *to,const char *from, int size); | |||||
extern char path_home[]; | |||||
extern const char *version_string; | |||||
extern const int version_phdata; | |||||
const int wcslen(const wchar_t *str); | |||||
extern "C" { | |||||
// optional assembler routine to speed-up Wavegen() | |||||
int AddSineWaves(int waveph, int h_switch_sign, int maxh, int *harmspect); | |||||
} | |||||
#define strcasecmp(a,b) strcmp(a,b) | |||||
const wchar_t *wcschr(const wchar_t *str, int c); | |||||
typedef int wchar_t; | |||||
int iswalpha(int c); | |||||
int iswdigit(int c); | |||||
int iswalnum(int c); | |||||
int towlower(int c); | |||||
int iswupper(int c); | |||||
int iswlower(int c); | |||||
int iswspace(int c); | |||||
int iswpunct(int c); | |||||
; 32 bit version | |||||
; SWI numbers | |||||
OS_File * &8 | |||||
OS_Module * &1e | |||||
XOS_AddCallBack * &20054 | |||||
XOS_RemoveCallBack * &2005f | |||||
GET h.RegNames | |||||
EXPORT DMA_Handler | |||||
EXPORT AddSineWaves | |||||
IMPORT |callback_entry| | |||||
IMPORT |sound_entry| | |||||
IMPORT |sin_tab| | |||||
AREA Assemb , CODE, READONLY | |||||
; pointers to data items | |||||
ADR_callback_entry | |||||
DCD callback_entry | |||||
ADR_sound_entry | |||||
DCD sound_entry | |||||
ADR_sin_tab | |||||
DCD sin_tab | |||||
DMA_Handler | |||||
;********** | |||||
; fill the sound buffer of the linear sound handler | |||||
; preserve r11,r12,r13 (fp,ip,sp) | |||||
MOV r5,ip ; need to save ip | |||||
MOV ip,sp ;set up a stack | |||||
STMFD sp!, {fp,ip,lr} | |||||
STMFD sp!, {r5} | |||||
MOV r12,r0 ; put the module_data word in r12 | |||||
BL sound_entry ; call C function through veneer in CMHG | |||||
; returns with r0=1 set callback, r1=module_data address | |||||
CMP r0,#1 | |||||
BNE DMA_return | |||||
;--------- | |||||
TEQ pc,pc | |||||
MRSEQ r8, CPSR ; 32bit version of call SWI from IRQ mode | |||||
MOVNE r8,pc | |||||
ORR r9,r8,#3 | |||||
MSREQ CPSR_c, r9 | |||||
TEQNEP r9,#0 | |||||
NOP | |||||
STR r14, [r13,#-4]! | |||||
;--------- | |||||
; r1=module_data address | |||||
LDR r0,ADR_callback_entry ; call C function through CMHG veneer | |||||
SWI XOS_AddCallBack | |||||
;--------- | |||||
LDR r14, [r13],#4 ; 32bit version of 'reenter original processor mode' | |||||
TEQ pc,pc | |||||
MSREQ CPSR_c, r8 | |||||
TEQNEP r8,#0 | |||||
NOP | |||||
;--------- | |||||
DMA_return | |||||
LDMFD sp!,{ip} | |||||
LDMFD sp, {fp,sp,pc} | |||||
AddSineWaves | |||||
;total += AddSineWaves(waveph, h_switch_sign, maxh, harmspect); | |||||
; using this assembler routine increases overall speed by about 7.5% | |||||
; define the USE_ASSEMBLER_1 macro in speech.h to enable this routine | |||||
; input: r0=waveph r1=h_switch_sign r2=maxh r3=harmspect | |||||
; local: r5=sin_tab r6=total r7=h r8=theta | |||||
; return(total) | |||||
MOV ip,sp | |||||
STMFD sp!, {r5-r9,ip,lr} | |||||
LDR r5,ADR_sin_tab | |||||
MOV r6,#0 ; total = 0 | |||||
MOV r0,r0,LSL #16 | |||||
MOV r8,r0 ; theta = waveph | |||||
MOV r7,#1 | |||||
as1 | |||||
MOV ip,r8,LSR #21 | |||||
LDR r9,[r5,ip,LSL #1] ; sin_tab[theta >> 5] | |||||
MOV r9,r9,LSL #16 | |||||
MOV r9,r9,ASR #16 | |||||
LDR ip,[r3,r7,LSL #2] ; harmspect[h] | |||||
MLA r6,r9,ip,r6 | |||||
ADD r8,r8,r0 ; theta += waveph | |||||
ADD r7,r7,#1 ; h++ | |||||
CMP r7,r1 | |||||
BLE as1 | |||||
RSB r6,r6,#0 ; change sign | |||||
as2 | |||||
MOV ip,r8,LSR #21 | |||||
LDR r9,[r5,ip,LSL #1] ; sin_tab[theta >> 5] | |||||
MOV r9,r9,LSL #16 | |||||
MOV r9,r9,ASR #16 | |||||
LDR ip,[r3,r7,LSL #2] ; harmspect[h] | |||||
MLA r6,r9,ip,r6 | |||||
ADD r8,r8,r0 ; theta += waveph | |||||
ADD r7,r7,#1 ; h++ | |||||
CMP r7,r2 | |||||
BLE as2 | |||||
MOV r0,r6 | |||||
LDMFD sp, {r5-r9,sp,pc} | |||||
END |
initialisation-code: user_init | |||||
title-string: Speak | |||||
help-string: Speak 3.25 Text to Speech (32 bit) | |||||
swi-chunk-base-number: &4ad80 | |||||
swi-handler-code: swi_handler | |||||
swi-decoding-table: Speak, | |||||
Ready,X,Misc,Say,Sayw,Stop,X,Pitch,Speed,WordGap,PitchRange,X,X,Volume | |||||
vector-handlers: callback_entry/callback_handler | |||||
vector-handlers: sound_entry/sound_handler | |||||
command-keyword-table: command_handler | |||||
SAY(min-args: 1, max-args: 255, | |||||
help-text: "Says English string <string>\n"), | |||||
SAYW(min-args: 1, max-args: 255, | |||||
help-text: "Says English string <string>\n"), | |||||
SPEAK(min-args: 1, max-args: 255, | |||||
help-text: "Says English string <string>\n") |
Copy the source files from the Linux "src" directory into this | Copy the source files from the Linux "src" directory into this | ||||
"src" directory, EXCEPT for speech.h. Keep the original Windows | "src" directory, EXCEPT for speech.h. Keep the original Windows | ||||
command-line version iof speech.h. | |||||
command-line version of speech.h. | |||||
// This is a dummy file. | |||||
// A file of this name is needed on Windows | |||||