mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-11 16:39:15 +00:00
Added makefile and speech.h for DOS build.
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-fd96e6ae7743
This commit is contained in:
@@ -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
|
||||
<leonardop@gentoo.org>
|
||||
@@ -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: jonsd@users.sourceforge.net *
|
||||
* *
|
||||
* 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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
Executable → Regular
@@ -0,0 +1,82 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005,2006 by Jonathan Duddington *
|
||||
* jsd@clara.co.uk *
|
||||
* *
|
||||
* 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);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -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.
|
||||
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
// This is a dummy file.
|
||||
// A file of this name is needed on Windows
|
||||
|
||||
Reference in New Issue
Block a user