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
@@ -0,0 +1,11 @@ | |||
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 |
@@ -0,0 +1,18 @@ | |||
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]> |
@@ -0,0 +1,368 @@ | |||
#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); | |||
} |
@@ -0,0 +1,61 @@ | |||
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) | |||
@@ -0,0 +1,95 @@ | |||
/*************************************************************************** | |||
* 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); | |||
@@ -0,0 +1,24 @@ | |||
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. |
@@ -0,0 +1,122 @@ | |||
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. | |||
@@ -0,0 +1,65 @@ | |||
# 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: |
@@ -0,0 +1,14 @@ | |||
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. |
@@ -0,0 +1,24 @@ | |||
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 |
@@ -0,0 +1,45 @@ | |||
; 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 | |||
@@ -0,0 +1,82 @@ | |||
/*************************************************************************** | |||
* 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) | |||
@@ -0,0 +1,3 @@ | |||
const wchar_t *wcschr(const wchar_t *str, int c); | |||
@@ -0,0 +1,11 @@ | |||
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); | |||
@@ -0,0 +1,127 @@ | |||
; 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 |
@@ -0,0 +1,22 @@ | |||
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") |
@@ -7,5 +7,5 @@ of eSpeak for Windows. | |||
Copy the source files from the Linux "src" directory into this | |||
"src" directory, EXCEPT for speech.h. Keep the original Windows | |||
command-line version iof speech.h. | |||
command-line version of speech.h. | |||
@@ -0,0 +1,3 @@ | |||
// This is a dummy file. | |||
// A file of this name is needed on Windows | |||