*** ACHTUNG! NEU 2015! ***


mb2psp
======

... boah, bin voellig uebermuedet, wie immer... nur so nebenbei. :-)

Konvertiert die phonetische Ausgabe von eSpeak in das phonetische Format fuer PSpSyn (siehe unten).
eSpeak findet man hier:
http://espeak.sourceforge.net/
Benoetigt wird ausserdem noch eine Voice-Datei von hier (ich habe nur de2 getestet):
http://www.tcts.fpms.ac.be/synthesis/mbrola/mbrcopybin.html
Die Voice-Datei de2 wird fuer eSpeak nur zur Transkription benoetigt, nicht zur Audio-Erzeugung und solange man auch keine Sprache damit hoerbar machen will, wird der Mbrola-Synthesizer auch nicht benoetigt (sonst den auch noch herunterladen, ist hier aber nicht das Thema).
Wo diese de2-Datei hinkopiert werden muss bitte in der eSpeak-Doku nachlesen.

Verwendung von mb2psp.lua:
espeak -q -v mb-de2 --pho --phonout=esp.txt -f meintext.txt
lua mb2psp.lua <esp.txt >psp.txt

Die psp.txt kann nun von PSpSyn vorgelesen werden.
Ich habe in das PSpSyn-Archiv (pspsyn2015.zip, siehe unten) noch ein kleines Programm namens psay.lua rein kopiert, das Text von der Standardeingabe liest und in out.mp3 das Ergebnis schreibt. Obige psp.txt wird dann also wie folgt in out.mp3 gewandelt:

lua psay.lua <psp.txt

Wohlgemerkt: out.mp3 wird hier nicht mehr angegeben! Dieser Name ist in psay.lua fest vorgegeben (laesst sich ja leicht aendern).
out.mp3 kann jedenfalls dann mit einem entsprechenden Abspielprogramm wiedergegeben werden.

Es ist nicht so klar verstaendlich wie eSpeak selbst, aber ich konnte einen mir nicht vorher bekannten Text schon verstehen.

Dieses Programm ist nuetzlich solange es noch keine eigene Graphemtext-Phonemtext-Transkription gibt (siehe im Abschnitt ueber den Praeprozessor unten).
Oben habe ich auf meinen Praeprozessor verzichtet, weil der im Archiv kein Programm enthaelt, das oben direkt verwendet werden koennte. Ein solches zu tippen ist schnell erledigt und dann saehe der ganze Kommando-Salat eben so aus (angenommen das Praeprozessor-Programm hiesse pp.lua und ffmpeg unten ist der mp3-Player):

lua pp.lua <meintext.txt >tmp.txt
espeak -q -v mb-de2 --pho --phonout=esp.txt -f tmp.txt
lua mb2psp.lua <esp.txt >psp.txt
lua psay.lua <psp.txt
ffmpeg out.mp3

Der Praeprozessordurchlauf duerfte aber kaum merklich sein, da eSpeak selbst einen beinhaltet.
Wie auch immer - hier also der Link zum Download von mb2psp.zip:
http://www.erbsenkopf.de/mb2psp.zip

Wie immer... von mir aus zur freiesten Verfuegung.


Ein schmuddeliger kleiner TTS-Praeprozessor fuer PSpSyn
=======================================================

... geschrieben in weniger als 350 Zeilen Lua-Code. :-)

Das ist die erste Stufe (nach dem Einlesen eines Textes an sich) eines TTS-Systems: der Praeprozessor.
Eine phonetische Sprachausgabe findet sich weiter unten (letzte Stufe).
Es fehlen aber noch Stufen zur Uebersetzung von graphemischem in phonetischen Text, zur Generierung der Sprachmelodie durch den Text usw.
Die Stufen komplett waeren also in etwa folgende:
* Einlesen des Textes mit evtl. Korrektur des Zeichensatzes/der Zeichendarstellung.
* Praeprozessor zur Textvorbereitung durch Ausschreiben von Zahlen in Woerter usw. (davon handelt dieser Abschnitt hier).
* Uebersetzung der Praeprozessor-Ausgabe: Graphemischen Text nach phonetischen Text (hier noch nicht vorhanden).
Diese Stufe teilt sich in zwei Unterstufen auf:
- woerterbuchbasierte Uebersetzung (hier noch nicht vorhanden) und fuer den evtl. noch nicht uebersetzten Rest
- regelbasierte Uebersetzung (hier noch nicht vorhanden).
* Der phonetische Text enthaelt neben generierten Silbenbetonungszeichen noch die vom Praeprozessor hinterlassenen Satzzeichen.
Anhand dieser Zeichen wird nun die Sprachmelodie generiert und entsprechende Steuerbefehle fuer den Synthesizer in den Text eingefuegt.
* Synthesizer (vorhanden, siehe unten bei PSpSyn).
erzeugt Audio-Signal.
* Ausgabe (zur Soundkarte oder als Web-Stream zum Beispiel, hier nicht vorhanden).

Dieses "Kapitel" beschraenkt sich nur auf den Praeprozessor.

Der Praeprozessor hier, den man weiter unten downloaden kann, erwartet einen Text aus den Buchstaben A-Z, a-z, Ä, Ö, Ü, ä, ö, ü und ß.
Alle anderen Zeichen ausserhalb des ASCII-Bereichs, egal ob Buchstabe oder nicht, werden einfach geloescht.

Mit dem Text passiert sonst noch folgendes:
Der Gesamttext wird in (Teil-)Saetze, nachfolgend einfach nur Saetze/Satz genannt, aufgeteilt und diese in einer eigenen Zeile ausgegeben.
Ein Satz endet mit einem Punkt, einem Ausrufezeichen oder einem Fragezeichen.
Saetze, die eine Ueberlaenge erreichen, koennen auch schon vorher "beendet" werden, dann nach einem Komma, einem Semikolon, einem Doppelpunkt, einem Bindestrich, Leerzeichen oder Zeilentrenner oder, im Notfall auch mitten im Wort.
Ein Rest eines evtl. abgeschnittenen Teils eines Satzes geht nicht verloren, sondern wandert einfach nur in eine Folgezeile.

Weitere Umwandlungen:
* Vor der Ausgabe der Saetze werden, sofern vorhanden, ein paar wenige Abkuerzungen wie "usw." ausgeschrieben.
Bei einigen Abkuerzungen bleibt der evtl. vorhandene Punkt erhalten, wodurch der Satz hier (eigentlich faelschlicherweise) endet - Sprachausgaben sind dumm und verstehen den Inhalt eines Textes nun mal nicht (solche Fehler sind aber im Rahmen des Ertraeglichen).
* Zahlen werden in Zahlwoerter uebersetzt, also z. B. "123" in "einhundertdreiundzwanzig".
Bei zu grossen Zahlen oder solchen, die mit einer 0 beginnen, werden einfach nur die Ziffern in Zahlwoerter uebersetzt: "0123" wird bspw. zu "null eins zwei drei".
In dem kleinen Praeprozessor hier finden sonst keine Zahluebersetzungen mehr statt, also z. B. auch keine Zeit-/Datumsuebersetzungen.
"24.12.2015" wird also schlicht zu "vierundzwanzig.", "zwoelf." und "zweitausendfuenfzehn (und weitere Woerter falls Satz nicht beendet)".
* Ausserdem werden noch ein paar Satzzeichen entweder geloescht oder als Woerter uebersetzt.
Zeichen wie $, # oder % werden immer in ein Wort uebersetzt.
Zeichen wie das Apostroph werden auch in ein Wort uebersetzt ausser wenn es am Wortende steht, dann wird es geloescht (durch einfache Aenderung der entsprechenden Tabelle im Quelltext kann das auch bspw. in der Wortmitte passieren).
* Zeichen wie Tabulatoren und Zeilentrenner werden in Leerzeichen uebersetzt und mehrfache Leerzeichen durch ein einzelnes.
Leerzeichen am Anfang oder am Ende eines Satzes werden geloescht.

Das Ergebnis des Praeprozessors ist eine Liste von Saetzen, die keine Zahlen und "unbekannte" Zeichen mehr enthalten, bei denen (einige) Abkuerzungen als Wort ausgeschrieben und die Leerzeichen minimiert wurden.
Als Satzzeichen kommen nur noch Komma, Punkt, Ausrufezeichen und Fragezeichen vor, als Leerzeichen nur noch das ASCII-Leerzeichen (Code 32).
Es ist moeglich dass Leerzeilen ausgegeben werden und je nach Eingabe natuerlich auch, dass Saetze keinen Abschluss (Punkt usw.) haben.
Bei unveraenderten Textteilen bleibt die Gross-/Kleinschreibung erhalten (sonst kann das schon mal etwas wuest/falsch sein).

Die Textausgabe kann nun an andere (noch zu schreibende) TTS-Stufen weitergeleitet werden.

Verwendung des Praeprozessors:

require "preproc"
ausgabeliste = preproc(textstring)
for i = 1, #ausgabeliste do print(ausgabeliste[i]) end -- Beispiel

Falls ein Fehler 
"setlocale failed."
beim Start des Demos auftritt:
Dann bitte am Anfang des Quelltextes preproc.lua folgendes nach Bedarf anpassen:
local language = "German"
language country = "Germany"
local codepage = "OCP"
local seperator = "_"
Dummerweise muss das je nach Betriebssystem etwas anders aussehen.
Statt "German" kann man "de" (in Klein- oder Grossbuchstaben) ausprobieren,
statt "Germany" kann man "DE" (in Gross- oder Kleinbuchstaben) ausprobieren,
statt dem Seperator "_" den Seperator "-",
statt der Codepage "OCP" oder "ACP" auch sowas wie "1152" oder "850"; "UTF8" oder sowas wird aber nicht funktionieren, da der Praeprozessor nur mit 1-Byte-pro-Zeichen arbeitet.
Die Codepage zu korrigieren kann auch noetig sein, wenn der Praeprozessor die Umlaute nicht richtig erkennt.

Es macht keinen Sinn, den Praeprozessor auf eine andere Sprache als Deutsch zu setzen.
Er wird als Programm fuer die deutsche Sprache nicht die russischen, tuerkischen, franzoesischen ... Eigenheiten beruecksichtigen, sondern entweder einfach beim Deutschen bleiben oder Unsinn veranstalten.

Auch wenn man mit dem Praeprozessor alleine noch nicht so viel anfangen kann, das TTS-System also noch sehr unvollstaendig ist, hier der Download (inklusive Mini-Demo):

http://www.erbsenkopf.de/preproc.zip


Nachtraegliche Anmerkungen:
* Der Praeprozessor ist kaum getestet, kann also durchaus noch echte Fehler enthalten.
* Im Quelltext verwende ich fuer die Umlaute in den "Woerterbuechern" usw. eine besondere Schreibweise:
:A fuer Ä, :O fuer Ö usw.
und es gibt eine Funktion xde, die diese Schreibweise in echte Umlaute wandelt.
Dadurch kann der Quelltext auf reine ASCII-Zeichen beschraenkt bleiben und die Woerterbucheintraege usw. bleiben trotzdem noch halbwegs lesbar und Zeichen-Codes wuerden ohnehin nicht unbedingt stimmen.
* Im Quelltext gibt es keine Einrueckungen. Das ist so wie es ist. :-)


SpSyn2015
=========

Vorweg:
Ja ich schreibe schneller als ich denke. :-)
Korrektur (keinen Bock das da unten zu korrigieren).
PSpSyn2015 benoetigt nicht weniger, sondern *mehr* Bandbreite als die 2012er-Version, weil es naemlich 64kbps beansprucht und die Samplerate liegt bei 24kHz.
Der Fehler in der Beschreibung steht so auch noch in der readme.txt und bleibt da auch so... nerviges Hin- und Hergeschaufel von dem Zeug macht mich voellig krank. :-)
Mp3SpSyn, SpSyn, PSpSyn ist alles das gleiche - habe ein schlechtes Namensgedaechtnis. :-)

Phonetische Sprachausgabe mit variabler Sprechgeschwindigkeit und -tonlage in 100 Zeilen Lua-Code! :-)

Ui! Wie die Zeit vergeht! 2012 hatte ich damit rumgespielt... :-o

Also, es gibt nochmal eine phonetische mp3-Sprachausgabe.
Die ist jetzt einfacher/einleuchtender/uebersichtlicher, klingt zwar nicht unbedingt verstaendlicher als die unten von 2012, aber dieser olle reverb-artige Effekt ist weg und die Sampleraten stimmen (klingt in der alten Version unten zu tief).
Die hier produziert nun 24 kbps, braucht also auch weniger Bandbreite.
Damit aber noch nicht genug, denn die Phonemdatei ist auf etwas unter 3 MB geschrumpft; das ist glaube ich ca. 1/4 oder 1/3 der Groesse von dem Vorgaenger (weiss gerade nicht deren genaue Groesse).
Dafuer gibt's hier nur ein zip-Archiv mit der Phonemdatei und einem bloeden Demo, und diesmal auch nur in Lua 5.2 - die paar Zeilen sind leicht nach Python, PHP, Perl oder sonst was zu portieren. :-) Link siehe weiter unten.

Kurz noch der Aufbau der Phonemdatei:

Die Phonemdatei enthaelt zuerst 28 Phonembloecke, naemlich fuer die Phoneme
2 6 9 @ a A D e E i I j l L m n N o O r R u U v y Y z Z (entsprechen im wesentlichen den deutschen Mbrola-Phoneme; deren Bedeutung liste ich unten noch auf).
Jeder Phonemblock besteht aus 8 mp3-Frames zu je 192 Bytes.
Obige Phoneme sind stimmhafte Phoneme und obige Sequenz ist deshalb 64 mal hintereinander in absteigender Tonlage abgelegt.
Danach kommen nur noch stimmlose Phoneme, die deshalb auch jeweils nur einmal vorkommen (haben auch jeweils 8 Frames zu je 192 Bytes).
Die stimmlosen Phoneme teilen sich in die Rauschphoneme plus ein Pausenphonem einerseits und die sogenannten Plossive andererseits auf:
C f h q s S T x (Rauschen und Pause q)
b d g k p t (Plossive)

Und nun das ganze nochmal als C-Typ-Definition - ist vielleicht verstaendlicher (dabei auch gleich die Bedeutung der Phoneme):

typedef char mp3frame_t[192]; // nicht generell, aber fuer diese Datei

typedef mp3frame_t phonemblock_t[8]; // 8 mp3-Frames fuer ein Phonem

typedef struct {
struct {
phonemblock_t _2; // OEkonom
phonemblock_t _6; // vatER
phonemblock_t _9; // OEffnung
phonemblock_t _at; // (@) hebEn
phonemblock_t _a; // Anton
phonemblock_t _A; // hier identisch mit a
phonemblock_t _D; // engl. faTHer
phonemblock_t _e; // Emil
phonemblock_t _E; // AEgypten
phonemblock_t _i; // Ida
phonemblock_t _I; // kIppe
phonemblock_t _j; // Julius
phonemblock_t _l; // Ludwig
phonemblock_t _L; // engl. Left
phonemblock_t _m; // Marta
phonemblock_t _n; // Nordpol
phonemblock_t _N; // fiNGer
phonemblock_t _o; // ottO
phonemblock_t _O; // Otto
phonemblock_t _r; // engl. Right
phonemblock_t _R; // Richard
phonemblock_t _u; // Uwe
phonemblock_t _U; // Ulrich
phonemblock_t _v; // Viktor, Wasser
phonemblock_t _y; // sUEden
phonemblock_t _Y; // hUEfte
phonemblock_t _z; // Samstag
phonemblock_t _Z; // Garage, Journal
} stimmhaft[64]; // fuer jeden der moeglichen 64 Pitchwerte
struct {
phonemblock_t _C; // beCHer
phonemblock_t _f; // Fritz
phonemblock_t _h; // Heinrich
phonemblock_t _q; // Das ist das Pausenphonem ("Stille")
phonemblock_t _s; // hauS
phonemblock_t _S; // SCHule
phonemblock_t _T; // engl. norTH
phonemblock_t _x; // flaCH
} stimmlos;
struct {
phonemblock_t _b; // Berta
phonemblock_t _d; // Dora
phonemblock_t _g; // Gustl
phonemblock_t _k; // Kaufmann
phonemblock_t _p; // Paula
phonemblock_t _t; // Theo
} plossive;
} phonemdatenbank_t;

Die Sprache kann nicht grossartig in der Geschwindigkeit veraendert werden.
3 Frames fuer unverlaengerte Phoneme, die keine Plossive sind, hat ein angenehmes Sprechtempo.
2 ist schon deutlich schneller und
1 klingt eigentlich unbrauchbar, auch wenn man es mit Uebung verstehen kann.
Verlaengerte Vokale, koennen z. B. um die Haelfte der Kurzvariante verlaengert werden, also bei obiger "Stufe" 3 waeren das dann 4 oder 5 Frames.
Die Plossive haben 3 Frames (natuerlich auch 8 Frames in der Phonemdatei, die hinteren 5 Frames sind aber Fuellframes=Pause) und sollten auch immer vollstaendig ausgegeben werden.
Es kann jedoch sinnvoll sein, je nach Sprechtempo, evtl. ein Pausen-Frame voranzustellen und ein/zwei hinten dran zu haengen.

Wie koennen Tempo und Sprachtonlage veraendert werden:

Im phonetischen Text durch
/p<nn> : Pitch 1 (hoch) bis 64 (tief) setzen; 35 ist in etwa die Normaltonlage. <nn> ohne die spitzen Klammern ist eine 2stellige Dezimalzahl.
/<n> : Kurzform von /p mit groeberem Abstand der Pitchwerte (spart ggf. Tipperei). <n> ist eine einstellige Dezimalzahl.
/s<n> : Sprechgeschwindigkeit 1 (zu schnell) bis 5 (langsam); 3 ist in etwa das Normalsprechtempo. <n> ist eine einstellige Dezimalzahl.
/l<n> : legt die Dauer fuer durch einen Doppelpunkt verlaengerte Phoneme fest (1 bis 8 Frames). /s setzt auch den Wert von /l, nicht aber umgekehrt.
' : Pitch um eine Stufe erhoehen
, : Pitch um eine Stufe vermindern
. : Pitch auf Normalwert zuruecksetzen
< : Sprechtempo um eine Stufe verlangsamen
> : Tempo um eine Stufe beschleunigen
= : Tempo auf Normalwert zuruecksetzen

Ausserdem:

Zeilenvorschub, Leerzeichen oder Tabulator entsprechen dem Pausen-Phonem q.
Der Unterstrich (_) entspricht einer 0-Pause, hat also keine hoerbare Funktion.
Das Minuszeichen entspricht zwei mal q, also qq.
Ein Doppelpunkt (:) hinter einem Phonem verlaengert dieses um etwa die Haelfte (nur bei stimmhaften Phonemen, wird anderenfalls ignoriert).

Verwendung von PSpSyn siehe Mini-Demo im Archiv - simpel!

Ok, hier also die Phonemdatei und einem kleinen Beispiel-Script, beides in Lua:
http://www.erbsenkopf.de/pspsyn2015.zip

Zum Anhoeren noch die Ausgabe des im Archiv enthaltenen Demos:
http://www.erbsenkopf.de/pspsyndemo.mp3

Nachtrag: Die Phonemdatei sollte genau 192 * 8 * (64 * 28 + 8 + 6) Bytes umfassen, was auch sizeof(phonemdatenbank_t) von oben entsprechen sollte.

Noch ein Nachtrag: Dass die Quelldateien keine oder nur einstellige Einrueckungen haben ist so wie es ist. :-)

SpSyn von mir aus zur freiesten Verfuegung.


mp3spsyn 12.2012
Phonetische Sprachausgabe mit mp3-Ausgabe
(im Rahmen eines Experiments auf die Schnelle zusammengebastelt)

Zuviel sollte man nicht erwarten; es war nur ein Experiment, wie gesagt.

Download (Python-Quelltext)
Groesse: ca. 14 MB (bedingt durch die grosse Phonemdatei)
Download (kleines Update#1)
Groesse: ca. 2 KB. Die hier enthaltenen Dateien ueberschreiben obige (nur phoneme.txt).


Hier noch eine sprechende Uhr zum Download (benoetigt erstes Archiv wegen Phonemdatei)
...und hier die sprechende Uhr als Online-Demo

Unterstuetzt ueberwiegend deutsche Phoneme,
einige englische Behelfsphoneme sind vorhanden und
das franzoesische stimmhafte SCH wie in Journal.

Zum Ausgabeformat:
.wav oder LPC ist eindeutig besser fuer solche Dinge geeignet als MP3
(jedenfalls in der hier durchgefuehrten Art und Weise).
MP3 wird allerdings von den meisten Medienspielern unterstuetzt
(im Gegensatz zu irgendwelchen LPC-Formaten) und benoetigt relativ
wenig Netzbandbreite (im Gegensatz zu .wav in dieser 
"kompatiblen Qualitaetsklasse").

Ausgegeben wird hier MP3, 32kbps, 16kHz, mono.

Zur Verwendung werden, neben dem von Dir selbstgeschriebenen Programm, benoetigt:
1. mp3spsyn.py und
2. mp3photab.dat.
Ein Beispiel-Prograemmchen (example.py) ist hier vorhanden, das
ine.txt nach out.mp3 konvertiert (synthetisiert).

Zur Erstellung von geeigneten phonetischen Quellsprachtexten
(das Format, das auch von Mbrola verwendet wird)
eignet sich tx2pho oder eSpeak,
falls man nicht selbst einen Deutsch->Phonem-Uebersetzer schreiben moechte.

Geschrieben und mehr oder weniger getestet mit Python 2.7.
Python 3 sollte funktionieren (?).
Besondere Bibliotheken werden nicht benoetigt - das ist ja das tolle. :-)

Von mir aus zur freiesten Verfuegung.
Viel Spass damit

PS:
Bezueglich des Beispielgedichts:
Natuerlich habe ich nichts gegen Schuhmacher.
Es ist einfach nur ein Beispielgedicht und das einzige
das ich kann. :-)