From a6dbed81682e266c8c4cfe8349f6abdcaf0e4330 Mon Sep 17 00:00:00 2001 From: Tobias Platen Date: Tue, 7 Jul 2020 21:53:03 +0200 Subject: [PATCH] add output hooks for wavegen --- src/include/espeak-ng/espeak_ng.h | 14 ++++++++++++ src/libespeak-ng/synthesize.c | 18 ++++++++++++++++ src/libespeak-ng/synthesize.h | 1 + src/libespeak-ng/wavegen.c | 36 +++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+) diff --git a/src/include/espeak-ng/espeak_ng.h b/src/include/espeak-ng/espeak_ng.h index b9804fce..5456e073 100644 --- a/src/include/espeak-ng/espeak_ng.h +++ b/src/include/espeak-ng/espeak_ng.h @@ -77,6 +77,14 @@ typedef enum { ENGENDER_NEUTRAL = 3, } espeak_ng_VOICE_GENDER; +typedef struct +{ + void (*outputPhoSymbol)(char* pho_code,int pho_type); + void (*outputSilence)(short echo_tail); + void (*outputVoiced)(short sample); + void (*outputUnvoiced)(short sample); +} espeak_ng_OUTPUT_HOOKS; + /* eSpeak NG 1.49.0 */ typedef struct espeak_ng_ERROR_CONTEXT_ *espeak_ng_ERROR_CONTEXT; @@ -188,6 +196,12 @@ espeak_ng_CompilePhonemeDataPath(long rate, const char *destination_path, FILE *log, espeak_ng_ERROR_CONTEXT *context); + +ESPEAK_NG_API espeak_ng_STATUS +espeak_ng_SetOutputHooks(espeak_ng_OUTPUT_HOOKS* hooks); +ESPEAK_NG_API espeak_ng_STATUS +espeak_ng_SetConstF0(int f0); + #ifdef __cplusplus } diff --git a/src/libespeak-ng/synthesize.c b/src/libespeak-ng/synthesize.c index b274ae42..70cd8243 100644 --- a/src/libespeak-ng/synthesize.c +++ b/src/libespeak-ng/synthesize.c @@ -146,6 +146,14 @@ static void DoAmplitude(int amp, unsigned char *amp_env) WcmdqInc(); } +static void DoPhonemeAlignment(char* pho, int type) +{ + wcmdq[wcmdq_tail][0] = WCMD_PHONEME_ALIGNMENT; + wcmdq[wcmdq_tail][1] = pho; + wcmdq[wcmdq_tail][2] = type; + WcmdqInc(); +} + static void DoPitch(unsigned char *env, int pitch1, int pitch2) { intptr_t *q; @@ -1131,6 +1139,8 @@ void DoEmbedded(int *embix, int sourceix) } while ((word & 0x80) == 0); } +extern espeak_ng_OUTPUT_HOOKS* output_hooks; + int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) { static int ix; @@ -1187,6 +1197,14 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) while ((ix < (*n_ph)) && (ix < N_PHONEME_LIST-2)) { p = &phoneme_list[ix]; + + if(output_hooks && output_hooks->outputPhoSymbol) + { + char buf[30]; + int dummy=0; + WritePhMnemonic(buf, p->ph, p, 0, &dummy); + DoPhonemeAlignment(strdup(buf),p->type); + } if (p->type == phPAUSE) free_min = 10; diff --git a/src/libespeak-ng/synthesize.h b/src/libespeak-ng/synthesize.h index d7760f74..90cd7533 100644 --- a/src/libespeak-ng/synthesize.h +++ b/src/libespeak-ng/synthesize.h @@ -433,6 +433,7 @@ extern unsigned char pitch_adjust_tab[MAX_PITCH_VALUE+1]; #define WCMD_MBROLA_DATA 13 #define WCMD_FMT_AMPLITUDE 14 #define WCMD_SONIC_SPEED 15 +#define WCMD_PHONEME_ALIGNMENT 16 #define N_WCMDQ 170 #define MIN_WCMDQ 25 // need this many free entries before adding new phoneme diff --git a/src/libespeak-ng/wavegen.c b/src/libespeak-ng/wavegen.c index 13efb743..e48868cb 100644 --- a/src/libespeak-ng/wavegen.c +++ b/src/libespeak-ng/wavegen.c @@ -116,6 +116,9 @@ unsigned char *out_ptr; unsigned char *out_start; unsigned char *out_end; +espeak_ng_OUTPUT_HOOKS* output_hooks = NULL; +int const_f0 = 0; + // the queue of operations passed to wavegen from sythesize intptr_t wcmdq[N_WCMDQ][4]; int wcmdq_head = 0; @@ -545,6 +548,8 @@ static void AdvanceParameters() if ((ix = wdata.pitch_ix>>8) > 127) ix = 127; x = wdata.pitch_env[ix] * wdata.pitch_range; wdata.pitch = (x>>8) + wdata.pitch_base; + + amp_ix += amp_inc; @@ -554,6 +559,10 @@ static void AdvanceParameters() x = ((int)(Flutter_tab[Flutter_ix >> 6])-0x80) * flutter_amp; Flutter_ix += Flutter_inc; wdata.pitch += x; + + if(const_f0) + wdata.pitch = (const_f0<<12); + if (wdata.pitch < 102400) wdata.pitch = 102400; // min pitch, 25 Hz (25 << 12) @@ -884,6 +893,7 @@ static int Wavegen() } *out_ptr++ = z; *out_ptr++ = z >> 8; + if(output_hooks && output_hooks->outputVoiced) output_hooks->outputVoiced(z); echo_buf[echo_head++] = z; if (echo_head >= N_ECHO_BUF) @@ -917,6 +927,7 @@ static int PlaySilence(int length, bool resume) *out_ptr++ = value; *out_ptr++ = value >> 8; + if(output_hooks && output_hooks->outputSilence) output_hooks->outputSilence(value); echo_buf[echo_head++] = value; if (echo_head >= N_ECHO_BUF) @@ -969,6 +980,7 @@ static int PlayWave(int length, bool resume, unsigned char *data, int scale, int out_ptr[0] = value; out_ptr[1] = value >> 8; + if(output_hooks && output_hooks->outputUnvoiced) output_hooks->outputUnvoiced(value); out_ptr += 2; echo_buf[echo_head++] = (value*3)/4; @@ -1284,6 +1296,13 @@ static int WavegenFill2() case WCMD_PITCH: SetPitch(length, (unsigned char *)q[2], q[3] >> 16, q[3] & 0xffff); break; + case WCMD_PHONEME_ALIGNMENT: + { + char* data = (char*)q[1]; + output_hooks->outputPhoSymbol(data,q[2]); + free(data); + } + break; case WCMD_PAUSE: if (resume == false) echo_complete -= length; @@ -1418,3 +1437,20 @@ int WavegenFill(void) #endif return finished; } + +#pragma GCC visibility push(default) + +ESPEAK_NG_API espeak_ng_STATUS +espeak_ng_SetOutputHooks(espeak_ng_OUTPUT_HOOKS* hooks) +{ + output_hooks = hooks; + return 0; +} + +ESPEAK_NG_API espeak_ng_STATUS +espeak_ng_SetConstF0(int f0) +{ + const_f0 = f0; +} + +#pragma GCC visibility pop