diff --git a/src/libespeak-ng/readclause.c b/src/libespeak-ng/readclause.c index 85d87c39..7dd2873f 100644 --- a/src/libespeak-ng/readclause.c +++ b/src/libespeak-ng/readclause.c @@ -42,6 +42,7 @@ #include "voice.h" #include "synthesize.h" #include "translate.h" +#include "ssml.h" #define N_XML_BUF 500 @@ -64,17 +65,6 @@ static int sayas_mode; static int sayas_start; static int ssml_ignore_l_angle = 0; -// stack for language and voice properties -// frame 0 is for the defaults, before any ssml tags. -typedef struct { - int tag_type; - int voice_variant_number; - int voice_gender; - int voice_age; - char voice_name[40]; - char language[20]; -} SSML_STACK; - #define N_SSML_STACK 20 static int n_ssml_stack; static SSML_STACK ssml_stack[N_SSML_STACK]; @@ -560,66 +550,7 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output return short_pause; } -#define SSML_SPEAK 1 -#define SSML_VOICE 2 -#define SSML_PROSODY 3 -#define SSML_SAYAS 4 -#define SSML_MARK 5 -#define SSML_SENTENCE 6 -#define SSML_PARAGRAPH 7 -#define SSML_PHONEME 8 -#define SSML_SUB 9 -#define SSML_STYLE 10 -#define SSML_AUDIO 11 -#define SSML_EMPHASIS 12 -#define SSML_BREAK 13 -#define SSML_IGNORE_TEXT 14 -#define HTML_BREAK 15 -#define HTML_NOSPACE 16 // don't insert a space for this element, so it doesn't break a word -#define SSML_CLOSE 0x20 // for a closing tag, OR this with the tag type - -// these tags have no effect if they are self-closing, eg. -static char ignore_if_self_closing[] = { 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0 }; - -static MNEM_TAB ssmltags[] = { - { "speak", SSML_SPEAK }, - { "voice", SSML_VOICE }, - { "prosody", SSML_PROSODY }, - { "say-as", SSML_SAYAS }, - { "mark", SSML_MARK }, - { "s", SSML_SENTENCE }, - { "p", SSML_PARAGRAPH }, - { "phoneme", SSML_PHONEME }, - { "sub", SSML_SUB }, - { "tts:style", SSML_STYLE }, - { "audio", SSML_AUDIO }, - { "emphasis", SSML_EMPHASIS }, - { "break", SSML_BREAK }, - { "metadata", SSML_IGNORE_TEXT }, - - { "br", HTML_BREAK }, - { "li", HTML_BREAK }, - { "dd", HTML_BREAK }, - { "img", HTML_BREAK }, - { "td", HTML_BREAK }, - { "h1", SSML_PARAGRAPH }, - { "h2", SSML_PARAGRAPH }, - { "h3", SSML_PARAGRAPH }, - { "h4", SSML_PARAGRAPH }, - { "hr", SSML_PARAGRAPH }, - { "script", SSML_IGNORE_TEXT }, - { "style", SSML_IGNORE_TEXT }, - { "font", HTML_NOSPACE }, - { "b", HTML_NOSPACE }, - { "i", HTML_NOSPACE }, - { "strong", HTML_NOSPACE }, - { "em", HTML_NOSPACE }, - { "code", HTML_NOSPACE }, - - { NULL, 0 } -}; - -static const char *VoiceFromStack() +const char *VoiceFromStack() { // Use the voice properties from the SSML stack to choose a voice, and switch // to that voice if it's not the current voice diff --git a/src/libespeak-ng/ssml.h b/src/libespeak-ng/ssml.h new file mode 100644 index 00000000..0ab59221 --- /dev/null +++ b/src/libespeak-ng/ssml.h @@ -0,0 +1,76 @@ +// stack for language and voice properties +// frame 0 is for the defaults, before any ssml tags. +typedef struct { + int tag_type; + int voice_variant_number; + int voice_gender; + int voice_age; + char voice_name[40]; + char language[20]; +} SSML_STACK; + +#define SSML_SPEAK 1 +#define SSML_VOICE 2 +#define SSML_PROSODY 3 +#define SSML_SAYAS 4 +#define SSML_MARK 5 +#define SSML_SENTENCE 6 +#define SSML_PARAGRAPH 7 +#define SSML_PHONEME 8 +#define SSML_SUB 9 +#define SSML_STYLE 10 +#define SSML_AUDIO 11 +#define SSML_EMPHASIS 12 +#define SSML_BREAK 13 +#define SSML_IGNORE_TEXT 14 +#define HTML_BREAK 15 +#define HTML_NOSPACE 16 // don't insert a space for this element, so it doesn't break a word +#define SSML_CLOSE 0x20 // for a closing tag, OR this with the tag type + +// these tags have no effect if they are self-closing, eg. +static char ignore_if_self_closing[] = { 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0 }; + +static MNEM_TAB ssmltags[] = { + { "speak", SSML_SPEAK }, + { "voice", SSML_VOICE }, + { "prosody", SSML_PROSODY }, + { "say-as", SSML_SAYAS }, + { "mark", SSML_MARK }, + { "s", SSML_SENTENCE }, + { "p", SSML_PARAGRAPH }, + { "phoneme", SSML_PHONEME }, + { "sub", SSML_SUB }, + { "tts:style", SSML_STYLE }, + { "audio", SSML_AUDIO }, + { "emphasis", SSML_EMPHASIS }, + { "break", SSML_BREAK }, + { "metadata", SSML_IGNORE_TEXT }, + + { "br", HTML_BREAK }, + { "li", HTML_BREAK }, + { "dd", HTML_BREAK }, + { "img", HTML_BREAK }, + { "td", HTML_BREAK }, + { "h1", SSML_PARAGRAPH }, + { "h2", SSML_PARAGRAPH }, + { "h3", SSML_PARAGRAPH }, + { "h4", SSML_PARAGRAPH }, + { "hr", SSML_PARAGRAPH }, + { "script", SSML_IGNORE_TEXT }, + { "style", SSML_IGNORE_TEXT }, + { "font", HTML_NOSPACE }, + { "b", HTML_NOSPACE }, + { "i", HTML_NOSPACE }, + { "strong", HTML_NOSPACE }, + { "em", HTML_NOSPACE }, + { "code", HTML_NOSPACE }, + + { NULL, 0 } +}; + +int attrcmp(const wchar_t *string1, const char *string2); +int attrlookup(const wchar_t *string1, const MNEM_TAB *mtab); +int attrnumber(const wchar_t *pw, int default_value, int type); +int attrcopy_utf8(char *buf, const wchar_t *pw, int len); +int GetVoiceAttributes(wchar_t *pw, int tag_type, SSML_STACK *ssml_sp, SSML_STACK *ssml_stack, int n_ssml_stack, char current_voice_id[]); +