[1.39.14]

Provide Viseme events on the Windows SAPI5 interface.


git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@199 d46cf337-b52f-0410-862d-fd96e6ae7743
This commit is contained in:
jonsd
2008-11-03 01:37:45 +00:00
parent 57d43881f5
commit af5209f741
23 changed files with 250 additions and 80 deletions
+78 -5
View File
@@ -23,13 +23,12 @@
#include "src/speak_lib.h"
#include "stdio.h"
#define CTRL_EMBEDDED 1
CTTSEngObj *m_EngObj;
ISpTTSEngineSite* m_OutputSite;
FILE *f_log2=NULL;
ULONGLONG event_interest;
extern int AddNameData(const char *name, int wide);
extern void InitNamedata(void);
@@ -49,6 +48,10 @@ char *path_install = NULL;
unsigned long audio_offset = 0;
unsigned long audio_latest = 0;
int prev_phoneme = 0;
int prev_phoneme_position = 0;
unsigned long prev_phoneme_time = 0;
unsigned int gBufSize = 0;
wchar_t *TextBuf=NULL;
@@ -65,6 +68,48 @@ int frag_count=0;
FRAG_OFFSET *frag_offsets = NULL;
int VisemeCode(unsigned int phoneme_name)
{//======================================
// Convert eSpeak phoneme name into a SAPI viseme code
int ix;
unsigned int ph;
unsigned int ph_name;
#define PH(c1,c2) (c2<<8)+c1 // combine two characters into an integer for phoneme name
const unsigned char initial_to_viseme[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 0, 0,19, 0, 0, 0, 0, 0,
0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,
4, 2,18,16,17, 4,18,20,12, 6,16,20,14,21,20, 3,
21,20,13,16,17, 4, 1, 5,20, 7,16, 0, 0, 0, 0, 0,
0, 1,21,16,19, 4,18,20,12, 6, 6,20,14,21,19, 8,
21,20,13,15,19, 7,18, 7,20, 7,15, 0, 0, 0, 0, 0 };
const unsigned int viseme_exceptions[] = {
PH('a','I'), 11,
PH('a','U'), 9,
PH('O','I'), 10,
PH('t','S'), 16,
PH('d','Z'), 16,
PH('_','|'), 255,
0
};
ph_name = phoneme_name & 0xffff;
for(ix=0; (ph = viseme_exceptions[ix]) != 0; ix+=2)
{
if(ph == ph_name)
{
return(viseme_exceptions[ix+1]);
}
}
return(initial_to_viseme[phoneme_name & 0x7f]);
}
int SynthCallback(short *wav, int numsamples, espeak_EVENT *events);
int SynthCallback(short *wav, int numsamples, espeak_EVENT *events)
@@ -73,6 +118,8 @@ int SynthCallback(short *wav, int numsamples, espeak_EVENT *events)
wchar_t *tailptr;
unsigned int text_offset;
int length;
int phoneme_duration;
int this_viseme;
espeak_EVENT *event;
#define N_EVENTS 100
@@ -86,7 +133,7 @@ int SynthCallback(short *wav, int numsamples, espeak_EVENT *events)
m_EngObj->CheckActions(m_OutputSite);
// return the events
for(event=events; event->type != 0; event++)
for(event=events; (event->type != 0) && (n_Events < N_EVENTS); event++)
{
audio_latest = event->audio_position + audio_offset;
@@ -121,6 +168,28 @@ int SynthCallback(short *wav, int numsamples, espeak_EVENT *events)
Event->lParam = (long)event->id.name;
Event->wParam = wcstol((wchar_t *)event->id.name,&tailptr,10);
}
if(event->type == espeakEVENT_PHONEME)
{
if(event_interest & SPEI_VISEME)
{
phoneme_duration = audio_latest - prev_phoneme_time;
// ignore some phonemes (which translate to viseme=255)
if((this_viseme = VisemeCode(event->id.number)) != 255)
{
Event = &Events[n_Events++];
Event->eEventId = SPEI_VISEME;
Event->elParamType = SPET_LPARAM_IS_UNDEFINED;
Event->ullAudioStreamOffset = ((prev_phoneme_position + audio_offset) * srate)/10; // ms -> bytes
Event->lParam = phoneme_duration << 16 | this_viseme;
Event->wParam = VisemeCode(prev_phoneme);
prev_phoneme = event->id.number;
prev_phoneme_time = audio_latest;
prev_phoneme_position = event->audio_position;
}
}
}
#ifdef deleted
if(event->type == espeakEVENT_SENTENCE)
{
@@ -286,7 +355,7 @@ STDMETHODIMP CTTSEngObj::SetObjectToken(ISpObjectToken * pToken)
gEmphasis = 0;
gSayas = 0;
espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS,100,path_install,0);
espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS,100,path_install,1);
espeak_SetVoiceByName(voice);
espeak_SetSynthCallback(SynthCallback);
@@ -654,7 +723,7 @@ STDMETHODIMP CTTSEngObj::Speak( DWORD dwSpeakFlags,
m_ullAudioOff = 0;
m_OutputSite = pOutputSite;
pOutputSite->GetEventInterest(&event_interest);
xVolume = gVolume;
xSpeed = gSpeed;
@@ -694,6 +763,10 @@ STDMETHODIMP CTTSEngObj::Speak( DWORD dwSpeakFlags,
}
audio_latest = 0;
prev_phoneme = 0;
prev_phoneme_time = 0;
prev_phoneme_position = 0;
size = ProcessFragList(pTextFragList,TextBuf,pOutputSite,&n_text_frag);
if(size > 0)