summaryrefslogtreecommitdiff
path: root/navit/support/espeak/synth_mbrola.c
diff options
context:
space:
mode:
Diffstat (limited to 'navit/support/espeak/synth_mbrola.c')
-rw-r--r--[-rwxr-xr-x]navit/support/espeak/synth_mbrola.c504
1 files changed, 237 insertions, 267 deletions
diff --git a/navit/support/espeak/synth_mbrola.c b/navit/support/espeak/synth_mbrola.c
index 1055f549f..3d58c350e 100755..100644
--- a/navit/support/espeak/synth_mbrola.c
+++ b/navit/support/espeak/synth_mbrola.c
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
+ * Copyright (C) 2005 to 2013 by Jonathan Duddington *
* email: jonsd@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -17,6 +17,8 @@
* <http://www.gnu.org/licenses/>. *
***************************************************************************/
+
+
#include "StdAfx.h"
#include <stdio.h>
@@ -33,17 +35,16 @@
#include "translate.h"
#include "voice.h"
-extern int Read4Bytes(FILE *f);
-extern void SetPitch2(voice_t *voice, int pitch1, int pitch2, int *pitch_base, int *pitch_range);
+int option_mbrola_phonemes;
-#ifdef USE_MBROLA_LIB
+#ifdef INCLUDE_MBROLA
+#include "wavegen.h"
extern unsigned char *outbuf;
#ifndef PLATFORM_WINDOWS
-#include "mbrolib.h"
-void * mb_handle;
+#include "mbrowrap.h"
#else
#include <windows.h>
@@ -64,7 +65,7 @@ PROCVV reset_MBR;
PROCIV lastError_MBR;
PROCVCI lastErrorStr_MBR;
PROCVI setNoError_MBR;
-PROCVI setFreq_MBR;
+PROCIV getFreq_MBR;
PROCVF setVolumeRatio_MBR;
@@ -75,9 +76,9 @@ HINSTANCE hinstDllMBR = NULL;
BOOL load_MBR()
{
if(hinstDllMBR != NULL)
- return TRUE; // already loaded
+ return TRUE; // already loaded
- if (!(hinstDllMBR=LoadLibraryA("mbrola.dll")))
+ if ((hinstDllMBR=LoadLibraryA("mbrola.dll")) == 0)
return FALSE;
init_MBR =(PROCIC) GetProcAddress(hinstDllMBR,"init_MBR");
write_MBR =(PROCIC) GetProcAddress(hinstDllMBR,"write_MBR");
@@ -103,14 +104,11 @@ void unload_MBR()
}
#endif // windows
-#endif // USE_MBROLA_LIB
static MBROLA_TAB *mbrola_tab = NULL;
static int mbrola_control = 0;
-
-
-
+static int mbr_name_prefix = 0;
espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int srate)
{//===================================================================================
@@ -124,6 +122,7 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int
mbrola_name[0] = 0;
mbrola_delay = 0;
+ mbr_name_prefix = 0;
if(mbrola_voice == NULL)
{
@@ -133,37 +132,50 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int
}
sprintf(path,"%s/mbrola/%s",path_home,mbrola_voice);
-#ifdef USE_MBROLA_LIB
+#ifdef PLATFORM_POSIX
+ // if not found, then also look in
+ // usr/share/mbrola/xx, /usr/share/mbrola/xx/xx, /usr/share/mbrola/voices/xx
+ if(GetFileLength(path) <= 0)
+ {
+ sprintf(path,"/usr/share/mbrola/%s",mbrola_voice);
+
+ if(GetFileLength(path) <= 0)
+ {
+ sprintf(path,"/usr/share/mbrola/%s/%s",mbrola_voice,mbrola_voice);
+
+ if(GetFileLength(path) <= 0)
+ {
+ sprintf(path,"/usr/share/mbrola/voices/%s",mbrola_voice);
+ }
+ }
+ }
+ close_MBR();
+#endif
#ifdef PLATFORM_WINDOWS
if(load_MBR() == FALSE) // load mbrola.dll
- return(EE_INTERNAL_ERROR);
+ {
+ fprintf(stderr, "Can't load mbrola.dll\n");
+ return(EE_INTERNAL_ERROR);
+ }
+#endif
if(init_MBR(path) != 0) // initialise the required mbrola voice
return(EE_NOT_FOUND);
setNoError_MBR(1); // don't stop on phoneme errors
-#else
- mb_handle = mbrolib_init(srate);
- mbrolib_parameter m_parameters;
-
- if(mb_handle == NULL)
- return(EE_INTERNAL_ERROR);
-
- MBROLIB_ERROR a_status = mbrolib_set_voice(mb_handle, mbrola_voice);
- if(a_status != MBROLIB_OK)
- return(EE_NOT_FOUND);
-#endif // not windows
-#endif // USE_MBROLA_LIB
// read eSpeak's mbrola phoneme translation data, eg. en1_phtrans
sprintf(path,"%s/mbrola_ph/%s",path_home,phtrans);
size = GetFileLength(path);
- if((f_in = fopen(path,"r")) == NULL)
+ if((f_in = fopen(path,"rb")) == NULL) {
+ close_MBR();
return(EE_NOT_FOUND);
+ }
if((mbrola_tab = (MBROLA_TAB *)realloc(mbrola_tab,size)) == NULL)
{
fclose(f_in);
+ close_MBR();
return(EE_INTERNAL_ERROR);
}
@@ -173,29 +185,19 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int
{
*pw++ = Read4Bytes(f_in);
}
- fread(mbrola_tab,size,1,f_in);
+ size = fread(mbrola_tab,1,size,f_in);
fclose(f_in);
-
-#ifdef USE_MBROLA_LIB
-#ifdef PLATFORM_WINDOWS
setVolumeRatio_MBR((float)(mbrola_control & 0xff) /16.0f);
-#else
- mbrolib_get_parameter(mb_handle,&m_parameters);
- m_parameters.ignore_error = 1;
- m_parameters.volume_ratio = (float)(mbrola_control & 0xff) /16.0;
- mbrolib_set_parameter(mb_handle,&m_parameters);
-#endif // not windows
-#endif // USE_MBROLA_LIB
-
- option_quiet = 1;
+// srate = getFreq_MBR();
samplerate = srate;
if(srate == 22050)
SetParameter(espeakVOICETYPE,0,0);
else
SetParameter(espeakVOICETYPE,1,0);
strcpy(mbrola_name,mbrola_voice);
- mbrola_delay = 3800; // improve synchronization of events
+// mbrola_delay = 3800; // improve synchronization of events
+ mbrola_delay = 1000; // improve synchronization of events
return(EE_OK);
} // end of LoadMbrolaTable
@@ -204,16 +206,24 @@ static int GetMbrName(PHONEME_LIST *plist, PHONEME_TAB *ph, PHONEME_TAB *ph_prev
{//==========================================================================================================================================
// Look up a phoneme in the mbrola phoneme name translation table
// It may give none, 1, or 2 mbrola phonemes
- int mnem = ph->mnemonic;
MBROLA_TAB *pr;
PHONEME_TAB *other_ph;
int found = 0;
+ static int mnem;
// control
// bit 0 skip the next phoneme
// bit 1 match this and Previous phoneme
// bit 2 only at the start of a word
// bit 3 don't match two phonemes across a word boundary
+ // bit 4 add this phoneme name as a prefix to the next phoneme name (used for de4 phoneme prefix '?')
+ // bit 5 only in stressed syllable
+ // bit 6 only at the end of a word
+
+ *name2=0;
+ *split=0;
+ *control=0;
+ mnem = ph->mnemonic;
pr = mbrola_tab;
while(pr->name != 0)
@@ -248,20 +258,36 @@ static int GetMbrName(PHONEME_LIST *plist, PHONEME_TAB *ph, PHONEME_TAB *ph_prev
if((pr->control & 4) && (plist->newword == 0)) // only at start of word
found = 0;
+ if((pr->control & 0x40) && (plist[1].newword == 0)) // only at the end of a word
+ found = 0;
+
+ if((pr->control & 0x20) && (plist->stresslevel < plist->wordstress))
+ found = 0; // only in stressed syllables
+
if(found)
{
*name2 = pr->mbr_name2;
*split = pr->percent;
*control = pr->control;
- return(pr->mbr_name);
+
+ if(pr->control & 0x10)
+ {
+ mbr_name_prefix = pr->mbr_name;
+ return(0);
+ }
+ mnem = pr->mbr_name;
+ break;
}
}
pr++;
}
- *name2=0;
- *split=0;
- *control=0;
+
+ if(mbr_name_prefix != 0)
+ {
+ mnem = (mnem << 8) | (mbr_name_prefix & 0xff);
+ }
+ mbr_name_prefix = 0;
return(mnem);
}
@@ -383,155 +409,10 @@ static char *WritePitch(int env, int pitch1, int pitch2, int split, int final)
} // end of WritePitch
-#ifdef USE_MBROLA_LIB
-
-static void MbrolaMarker(int type, int char_posn, int length, int value)
-{//=====================================================================
-
- MarkerEvent(type,(char_posn & 0xffffff) | (length << 24),value,outbuf);
-
-}
-
-
-static void MbrolaEmbedded(int &embix, int sourceix)
-{//=================================================
- // There were embedded commands in the text at this point
- unsigned int word; // bit 7=last command for this word, bits 5,6 sign, bits 0-4 command
- unsigned int value;
- int command;
- int sign=0;
-
- do {
- word = embedded_list[embix++];
- value = word >> 8;
- command = word & 0x1f;
-
- if((word & 0x60) == 0x60)
- sign = -1;
- else
- if((word & 0x60) == 0x40)
- sign = 1;
-
- if(command < N_EMBEDDED_VALUES)
- {
- if(sign == 0)
- embedded_value[command] = value;
- else
- embedded_value[command] += (value * sign);
- }
-
- switch(command & 0x1f)
- {
- case EMBED_M: // named marker
- MbrolaMarker(espeakEVENT_MARK, (sourceix & 0x7ff) + clause_start_char, 0, value);
- break;
- }
- } while ((word & 0x80) == 0);
-}
-
-
-#ifdef PLATFORM_WINDOWS
-static int MbrolaSynth(char *p_mbrola)
-{//===================================
-// p_mbrola is a string of mbrola pho lines - Windows
- int len;
- int finished;
- int result=0;
-
- if(synth_callback == NULL)
- return(1);
-
- if(p_mbrola == NULL)
- flush_MBR();
- else
- result = write_MBR(p_mbrola);
-
-
- finished = 0;
- while(!finished && ((len = read_MBR((short *)outbuf, outbuf_size/2)) > 0))
- {
- out_ptr = outbuf + len*2;
-
- if(event_list)
- {
- event_list[event_list_ix].type = espeakEVENT_LIST_TERMINATED; // indicates end of event list
- event_list[event_list_ix].user_data = 0;
- }
- count_samples += len;
- finished = synth_callback((short *)outbuf, len, event_list);
- event_list_ix=0;
- }
-
- if(finished)
- {
- // cancelled by user, discard any unused mbrola speech
- flush_MBR();
- while((len = read_MBR((short *)outbuf, outbuf_size/2)) > 0);
- }
- return(finished);
-} // end of SynthMbrola
-#else
-
-static int MbrolaSynth(char *p_mbrola)
-{//===================================
-// p_mbrola is a string of mbrola pho lines - Linux
-
-// This is wrong
-// It must be called from WavegenFill()
-
- int len;
- int finished;
- int result=0;
-
- if(synth_callback == NULL)
- return(1);
-
- if(p_mbrola == NULL)
- mbrolib_flush(mb_handle);
- else
- result = mbrolib_write(mb_handle,p_mbrola,strlen(p_mbrola));
-
-
- finished = 0;
- while(!finished && (mbrolib_read(mb_handle, (short *)out_ptr, (out_end - out_ptr)/2, &len) == MBROLIB_OK))
- {
- if(len == 0)
- break;
-
- out_ptr += (len*2);
-
- if(event_list)
- {
- event_list[event_list_ix].type = espeakEVENT_LIST_TERMINATED; // indicates end of event list
- event_list[event_list_ix].user_data = 0;
- }
- count_samples += len;
- finished = synth_callback((short *)outbuf, len, event_list);
- event_list_ix=0;
- }
-
- if(finished)
- {
- // cancelled by user, discard any unused mbrola speech
- mbrolib_flush(mb_handle);
- while(mbrolib_read(mb_handle, (short *)outbuf, outbuf_size/2, &len) == MBROLIB_OK)
- {
- if(len == 0)
- break;
- }
- }
- return(finished);
-} // end of SynthMbrola
-#endif // not windows
-#endif // USE_MBROLA_LIB
-
-
-
-void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola)
-{//======================================================================
+int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbrola)
+{//=================================================================================
// Generate a mbrola pho file
unsigned int name;
- int phix;
int len;
int len1;
PHONEME_TAB *ph;
@@ -539,7 +420,8 @@ void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola)
PHONEME_TAB *ph_prev;
PHONEME_LIST *p;
PHONEME_LIST *next;
- PHONEME_LIST *prev;
+ PHONEME_DATA phdata;
+ FMT_PARAMS fmtp;
int pause = 0;
int released;
int name2;
@@ -547,75 +429,76 @@ void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola)
int done;
int len_percent;
const char *final_pitch;
- char buf[80];
+ char *ptr;
char mbr_buf[120];
-#ifdef USE_MBROLA_LIB
- int embedded_ix=0;
- int word_count=0;
+ static int phix;
+ static int embedded_ix;
+ static int word_count;
- event_list_ix = 0;
- out_ptr = outbuf;
-#ifdef PLATFORM_WINDOWS
- setNoError_MBR(1); // don't stop on phoneme errors
-#endif
-#else
-// fprintf(f_mbrola,";; v=%.2f\n",(float)(mbrola_control & 0xff)/16.0); // ;; v= has no effect on mbrola
-#endif
+ if (!resume) {
+ phix = 1;
+ embedded_ix = 0;
+ word_count = 0;
+ }
- for(phix=1; phix < n_phonemes; phix++)
+ while (phix < n_phonemes)
{
- mbr_buf[0] = 0;
+ if (WcmdqFree() < MIN_WCMDQ)
+ return 1;
+
+ ptr = mbr_buf;
p = &plist[phix];
next = &plist[phix+1];
- prev = &plist[phix-1];
ph = p->ph;
ph_prev = plist[phix-1].ph;
ph_next = plist[phix+1].ph;
-#ifdef USE_MBROLA_LIB
if(p->synthflags & SFLAG_EMBEDDED)
{
- MbrolaEmbedded(embedded_ix, p->sourceix);
+ DoEmbedded(&embedded_ix, p->sourceix);
}
- if(p->newword & 4)
- MbrolaMarker(espeakEVENT_SENTENCE, (p->sourceix & 0x7ff) + clause_start_char, 0, count_sentences);
+ if(p->newword & 4)
+ DoMarker(espeakEVENT_SENTENCE, (p->sourceix & 0x7ff) + clause_start_char, 0, count_sentences);
if(p->newword & 1)
- MbrolaMarker(espeakEVENT_WORD, (p->sourceix & 0x7ff) + clause_start_char, p->sourceix >> 11, clause_start_word + word_count++);
-#endif
+ DoMarker(espeakEVENT_WORD, (p->sourceix & 0x7ff) + clause_start_char, p->sourceix >> 11, clause_start_word + word_count++);
name = GetMbrName(p,ph,ph_prev,ph_next,&name2,&len_percent,&control);
if(control & 1)
phix++;
- if(name == 0)
+ if(name == 0) {
+ phix++;
continue; // ignore this phoneme
+ }
if((ph->type == phPAUSE) && (name == ph->mnemonic))
{
// a pause phoneme, which has not been changed by the translation
name = '_';
- len = (p->length * speed.speed_factor1)/256;
+ len = (p->length * speed.pause_factor)/256;
// if(len == 0) continue;
if(len == 0)
len = 1;
}
else
- len = (80 * speed.speed_factor2)/256;
+ len = (80 * speed.wav_factor)/256;
-#ifdef USE_MBROLA_LIB
- MbrolaMarker(espeakEVENT_PHONEME, (p->sourceix & 0x7ff) + clause_start_char, 0, ph->mnemonic);
-#endif
+ if(ph->code != phonEND_WORD)
+ {
+ char phoneme_name[16];
+ WritePhMnemonic(phoneme_name, p->ph, p, option_phoneme_events & espeakINITIALIZE_PHONEME_IPA, NULL);
+ DoPhonemeMarker(espeakEVENT_PHONEME, (p->sourceix & 0x7ff) + clause_start_char, 0, phoneme_name);
+ }
- sprintf(buf,"%s\t",WordToString(name));
- strcat(mbr_buf,buf);
+ ptr += sprintf(ptr,"%s\t",WordToString(name));
if(name2 == '_')
{
// add a pause after this phoneme
- pause = PauseLength(len_percent,0);
+ pause = len_percent;
name2 = 0;
}
@@ -635,17 +518,19 @@ void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola)
if(name2 == 0)
{
- sprintf(buf,"%d\t%s", len, WritePitch(p->env,p->pitch1,p->pitch2,0,0));
- strcat(mbr_buf,buf);
+ char *pitch = WritePitch(p->env,p->pitch1,p->pitch2,0,0);
+ ptr += sprintf(ptr,"%d\t%s", len, pitch);
}
else
{
+ char *pitch;
+
+ pitch = WritePitch(p->env,p->pitch1,p->pitch2,len_percent,0);
len1 = (len * len_percent)/100;
- sprintf(buf,"%d\t%s", len1, WritePitch(p->env,p->pitch1,p->pitch2,len_percent,0));
- strcat(mbr_buf,buf);
+ ptr += sprintf(ptr,"%d\t%s", len1, pitch);
- sprintf(buf,"%s\t%d\t%s", WordToString(name2), len-len1, WritePitch(p->env,p->pitch1,p->pitch2,-len_percent,0));
- strcat(mbr_buf,buf);
+ pitch = WritePitch(p->env,p->pitch1,p->pitch2,-len_percent,0);
+ ptr += sprintf(ptr,"%s\t%d\t%s", WordToString(name2), len-len1, pitch);
}
done = 1;
break;
@@ -655,23 +540,25 @@ void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola)
if(next->type==phVOWEL) released = 1;
if(next->type==phLIQUID && !next->newword) released = 1;
- if(released)
- len = DoSample(p->ph,next->ph,2,0,-1);
- else
- len = DoSample(p->ph,phoneme_tab[phonPAUSE],2,0,-1);
+ if(released == 0)
+ p->synthflags |= SFLAG_NEXT_PAUSE;
+ InterpretPhoneme(NULL, 0, p, &phdata, NULL);
+ len = DoSample3(&phdata, 0, -1);
+
len = (len * 1000)/samplerate; // convert to mS
len += PauseLength(p->prepause,1);
break;
case phVSTOP:
- len = (80 * speed.speed_factor2)/256;
+ len = (80 * speed.wav_factor)/256;
break;
case phFRICATIVE:
len = 0;
+ InterpretPhoneme(NULL, 0, p, &phdata, NULL);
if(p->synthflags & SFLAG_LENGTHEN)
- len = DoSample(ph,ph_next,2,p->length,-1); // play it twice for [s:] etc.
- len += DoSample(ph,ph_next,2,p->length,-1);
+ len = DoSample3(&phdata, p->length, -1); // play it twice for [s:] etc.
+ len += DoSample3(&phdata, p->length, -1);
len = (len * 1000)/samplerate; // convert to mS
break;
@@ -679,7 +566,11 @@ void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola)
case phNASAL:
if(next->type != phVOWEL)
{
- len = DoSpect(p->ph,prev->ph,phoneme_tab[phonPAUSE],2,p,-1);
+ memset(&fmtp, 0, sizeof(fmtp));
+ InterpretPhoneme(NULL, 0, p, &phdata, NULL);
+ fmtp.fmt_addr = phdata.sound_addr[pd_FMT];
+ len = DoSpect2(p->ph, 0, &fmtp, p, -1);
+// len = DoSpect(p->ph,prev->ph,phoneme_tab[phonPAUSE],2,p,-1);
len = (len * 1000)/samplerate;
if(next->type == phPAUSE)
len += 50;
@@ -701,60 +592,139 @@ void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola)
if(name2 != 0)
{
len1 = (len * len_percent)/100;
- sprintf(buf,"%d\n%s\t",len1,WordToString(name2));
- strcat(mbr_buf,buf);
+ ptr += sprintf(ptr,"%d\n%s\t",len1,WordToString(name2));
len -= len1;
}
- sprintf(buf,"%d%s\n",len,final_pitch);
- strcat(mbr_buf,buf);
+ ptr += sprintf(ptr,"%d%s\n",len,final_pitch);
}
if(pause)
{
- sprintf(buf,"_ \t%d\n",PauseLength(pause,0));
- strcat(mbr_buf,buf);
+ len += PauseLength(pause,0);
+ ptr += sprintf(ptr,"_ \t%d\n",PauseLength(pause,0));
pause = 0;
}
if(f_mbrola)
{
- fwrite(mbr_buf,1,strlen(mbr_buf),f_mbrola); // write .pho to a file
+ fwrite(mbr_buf,1,(ptr-mbr_buf),f_mbrola); // write .pho to a file
}
else
{
-#ifdef USE_MBROLA_LIB
- if(MbrolaSynth(mbr_buf) != 0)
- return;
-#endif
+ int res = write_MBR(mbr_buf);
+ if (res < 0)
+ return 0; /* don't get stuck on error */
+ if (res == 0)
+ return 1;
+ wcmdq[wcmdq_tail][0] = WCMD_MBROLA_DATA;
+ wcmdq[wcmdq_tail][1] = len;
+ WcmdqInc();
}
+
+ phix++;
}
-#ifdef USE_MBROLA_LIB
- MbrolaSynth(NULL);
-#endif
+ if(!f_mbrola)
+ {
+ flush_MBR();
+
+ // flush the mbrola output buffer
+ wcmdq[wcmdq_tail][0] = WCMD_MBROLA_DATA;
+ wcmdq[wcmdq_tail][1] = 500;
+ WcmdqInc();
+ }
+
+ return 0;
} // end of MbrolaTranslate
-#ifdef TEST_MBROLA
+int MbrolaGenerate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
+{//==================================================================
+ FILE *f_mbrola = NULL;
-static PHONEME_LIST mbrola_phlist;
-static int mbrola_n_ph;
-static int mbrola_phix;
+ if(*n_ph == 0)
+ return(0);
+ if(option_mbrola_phonemes)
+ {
+ // send mbrola data to a file, not to the mbrola library
+ f_mbrola = f_trans;
+ }
-int MbrolaFill(int fill_zeros)
-{//===========================
+ int again = MbrolaTranslate(phoneme_list, *n_ph, resume, f_mbrola);
+ if (!again)
+ *n_ph = 0;
+ return again;
}
-int MbrolaGenerate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
-{//==================================================================
- if(resume == 0)
+
+int MbrolaFill(int length, int resume, int amplitude)
+{//==================================================
+// Read audio data from Mbrola (length is in millisecs)
+
+ static int n_samples;
+ int req_samples, result;
+ int ix;
+ short value16;
+ int value;
+
+ if (!resume)
+ n_samples = samplerate * length / 1000;
+
+ req_samples = (out_end - out_ptr)/2;
+ if (req_samples > n_samples)
+ req_samples = n_samples;
+ result = read_MBR((short *)out_ptr, req_samples);
+ if (result <= 0)
+ return 0;
+
+ for(ix=0; ix < result; ix++)
{
- mbrola_phlist = phoneme_list;
- mbrola_n_ph = n_ph;
- mbrola_phix = 0;
+ value16 = out_ptr[0] + (out_ptr[1] << 8);
+ value = value16 * amplitude;
+ value = value / 40; // adjust this constant to give a suitable amplitude for mbrola voices
+ if(value > 0x7fff)
+ value = 0x7fff;
+ if(value < -0x8000)
+ value = 0x8000;
+ out_ptr[0] = value;
+ out_ptr[1] = value >> 8;
+ out_ptr += 2;
}
+ n_samples -= result;
+ return n_samples ? 1 : 0;
+}
- resume(0); // finished phoneme list
+
+void MbrolaReset(void)
+{//===================
+// Reset the Mbrola engine and flush the pending audio
+
+ reset_MBR();
}
-#endif
+
+#else // INCLUDE_MBROLA
+
+// mbrola interface is not compiled, provide dummy functions.
+
+espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int srate)
+{
+ return(EE_INTERNAL_ERROR);
+}
+
+int MbrolaGenerate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
+{
+ return(0);
+}
+
+int MbrolaFill(int length, int resume, int amplitude)
+{
+ return(0);
+}
+
+void MbrolaReset(void)
+{
+}
+
+
+#endif // INCLUDE_MBROLA