Initial commit
This commit is contained in:
775
engines/watchmaker/t2d/expr.cpp
Normal file
775
engines/watchmaker/t2d/expr.cpp
Normal file
@@ -0,0 +1,775 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
|
||||
|
||||
#include "watchmaker/t2d/expr.h"
|
||||
#include "watchmaker/windows_hacks.h"
|
||||
#include "watchmaker/globvar.h"
|
||||
|
||||
|
||||
#define MAX_VISEMA 1000
|
||||
|
||||
#define MIN_VISEMA_LENG 70
|
||||
|
||||
#define RandomInt(Max) (rand()%(Max+1))
|
||||
#define RandomFloat(Max) ((float)rand()/MAX_RAND)*Max)
|
||||
|
||||
#define VIS_DEFAULT_TIME -10
|
||||
#define VIS_NULL -999
|
||||
|
||||
#define WAVE_TOLLERANCE 15
|
||||
|
||||
#define MAXCICLES 10000
|
||||
#define CICLECONTROL(CV) { CV++; if (CV>MAXCICLES) break; }
|
||||
|
||||
#define VIS_PAUSE_VAR 30
|
||||
|
||||
//#define PROVAMODE
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
struct SilbsStruct {
|
||||
const char *Text;
|
||||
int Res[3];
|
||||
} Silbs[] = {
|
||||
{ " ", {14, -1, -1} },
|
||||
{ ",", {14, -1, -1} },
|
||||
{ "'", {-1, -1, -1} },
|
||||
{ ";", {14, -1, -1} },
|
||||
{ ".", {0, 14, 0} },
|
||||
{ ":", {0, -1, -1} },
|
||||
{ "?", {0, 14, 0} },
|
||||
{ "!", {0, 14, 0} },
|
||||
{ "-", {14, -1, -1} },
|
||||
{ "<", {-1, -1, -1} },
|
||||
{ ">", {-1, -1, -1} },
|
||||
{ "a", {13, -1, -1} },
|
||||
{ "ae", {11, -1, -1} },
|
||||
{ "b", {1, -1, -1} },
|
||||
{ "bb", {1, -1, -1} },
|
||||
{ "c", {9, -1, -1} },
|
||||
{ "cc", {9, -1, -1} },
|
||||
{ "ch", {8, -1, -1} },
|
||||
{ "ck", {9, -1, -1} },
|
||||
{ "ce", {7, -1, -1} },
|
||||
{ "ci", {7, -1, -1} },
|
||||
{ "d", {7, -1, -1} },
|
||||
{ "dd", {7, -1, -1} },
|
||||
{ "det", {10, 7, -1} },
|
||||
{ "ded", {10, 7, -1} },
|
||||
{ "e", {11, -1, -1} },
|
||||
{ "5e", {11, -1, -1} },
|
||||
{ "ea", {10, -1, -1} },
|
||||
{ "ee", {10, -1, -1} },
|
||||
{ "e|", {10, -1, -1} },
|
||||
{ "$e|", {-1, -1, -1} },
|
||||
{ "ed|", {7, -1, -1} },
|
||||
{ "en|", {7, -1, -1} },
|
||||
{ "et|", {7, -1, -1} },
|
||||
{ "ened|", {7, -1, -1} },
|
||||
{ "f", {4, -1, -1} },
|
||||
{ "ff", {4, -1, -1} },
|
||||
{ "g", {9, -1, -1} },
|
||||
{ "gp", {1, -1, -1} },
|
||||
{ "gb", {1, -1, -1} },
|
||||
{ "gm", {1, -1, -1} },
|
||||
{ "gg", {9, -1, -1} },
|
||||
{ "gh", {-1, -1, -1} },
|
||||
{ "h", {-1, -1, -1} },
|
||||
{ "i", {10, -1, -1} },
|
||||
{ "j", {8, -1, -1} },
|
||||
{ "ja", {8, -1, -1} },
|
||||
{ "je", {8, -1, -1} },
|
||||
{ "ji", {8, -1, -1} },
|
||||
{ "jo", {8, -1, -1} },
|
||||
{ "ju", {8, -1, -1} },
|
||||
{ "k", {9, -1, -1} },
|
||||
{ "kk", {9, -1, -1} },
|
||||
{ "l", {6, -1, -1} },
|
||||
{ "ll", {6, -1, -1} },
|
||||
{ "m", {1, -1, -1} },
|
||||
{ "mm", {1, -1, -1} },
|
||||
{ "n", {7, -1, -1} },
|
||||
{ "nn", {7, -1, -1} },
|
||||
{ "nd", {7, -1, -1} },
|
||||
{ "ng", {9, -1, -1} },
|
||||
{ "nt", {9, -1, -1} },
|
||||
{ "ntr", {9, -1, -1} },
|
||||
{ "nce|", {9, -1, -1} },
|
||||
{ "o", {12, -1, -1} },
|
||||
{ "oo", {2, 2, -1} },
|
||||
{ "ou", {12, -1, -1} },
|
||||
{ "or", {13, -1, -1} },
|
||||
{ "ou|", {2, -1, -1} },
|
||||
{ "one", {7, 11, 1} },
|
||||
{ "oul", {2, -1, -1} },
|
||||
{ "p", {1, -1, -1} },
|
||||
{ "pp", {1, -1, -1} },
|
||||
{ "q", {9, 2, -1} },
|
||||
{ "qq", {9, 2, -1} },
|
||||
{ "rr", {3, -1, -1} },
|
||||
{ "|r", {3, -1, -1} },
|
||||
{ "%r", {7, -1, -1} },
|
||||
{ "$r<>", {3, -1, -1} },
|
||||
{ "<EFBFBD>r%", {-1, -1, -1} },
|
||||
{ "s", {7, -1, -1} },
|
||||
{ "ss", {7, -1, -1} },
|
||||
{ "si", {8, -1, -1} },
|
||||
{ "sh", {8, -1, -1} },
|
||||
{ "some", {2, 11, 7} },
|
||||
{ "t", {7, -1, -1} },
|
||||
{ "tt", {7, -1, -1} },
|
||||
{ "th", {5, -1, -1} },
|
||||
{ "ted", {10, 7, -1} },
|
||||
{ "tet", {10, 7, -1} },
|
||||
{ "tp", {1, -1, -1} },
|
||||
{ "tm", {1, -1, -1} },
|
||||
{ "tb", {1, -1, -1} },
|
||||
{ "u", {11, -1, -1} },
|
||||
{ "uh", {9, -1, -1} },
|
||||
{ "v", {4, -1, -1} },
|
||||
{ "vv", {4, -1, -1} },
|
||||
{ "w", {2, -1, -1} },
|
||||
{ "ww", {2, -1, -1} },
|
||||
{ "wa", {2, 12, -1} },
|
||||
{ "x", {7, -1, -1} },
|
||||
{ "xx", {7, -1, -1} },
|
||||
{ "y", {9, -1, -1} },
|
||||
{ "y|", {8, -1, -1} },
|
||||
{ "z", {7, -1, -1} },
|
||||
{ "zz", {7, -1, -1} }
|
||||
|
||||
};
|
||||
|
||||
//Spiegazione caratteri:
|
||||
// <20> vocale
|
||||
// $ consonante
|
||||
// % qualcosa
|
||||
// | fine parola
|
||||
// i numeri all'inizio o alla fine indicano i visemi precedenti o successivi
|
||||
// La priorit<69> <20> data dalla posizione, il piu in alto viene scelto
|
||||
|
||||
//Il visema 14 <20> un random fra la pausa con occhi aperti (0) e quella con occhi chiusi (14)
|
||||
//Il visema 15 <20> un random fra la pausa veloce con occhi aperti (11) e quella con occhi chiusi (15)
|
||||
|
||||
#define NumSilbs 106
|
||||
|
||||
struct VisemaBufStruct {
|
||||
int Visema; //Id del visema
|
||||
int TimeLeng; //Lunghezza in milliseconda
|
||||
};
|
||||
|
||||
struct VisemaBufStruct VisemaBuf[MAX_VISEMA];
|
||||
int risFaces[MAX_VISEMA]; //Buffer dove verranno registrati i visemi della frase
|
||||
int TotTime; //Durata della frase in millisecondi
|
||||
int TimeXVis; //Tempo in millisecondi per ogni visema
|
||||
int NumVis; //Numero dei visemi
|
||||
|
||||
int VisDefaultTime = 75;
|
||||
|
||||
bool VisemaInitialized = false;
|
||||
|
||||
//Gestione Wave
|
||||
#ifndef ER_MEM
|
||||
#define ER_MEM 0xe000
|
||||
#endif
|
||||
|
||||
#ifndef ER_CANNOTOPEN
|
||||
#define ER_CANNOTOPEN 0xe100
|
||||
#endif
|
||||
|
||||
#ifndef ER_NOTWAVEFILE
|
||||
#define ER_NOTWAVEFILE 0xe101
|
||||
#endif
|
||||
|
||||
#ifndef ER_CANNOTREAD
|
||||
#define ER_CANNOTREAD 0xe102
|
||||
#endif
|
||||
|
||||
#ifndef ER_CORRUPTWAVEFILE
|
||||
#define ER_CORRUPTWAVEFILE 0xe103
|
||||
#endif
|
||||
|
||||
#ifndef ER_CANNOTWRITE
|
||||
#define ER_CANNOTWRITE 0xe104
|
||||
#endif
|
||||
|
||||
//Fine Gestione Wave
|
||||
|
||||
//Controlla se un carattere rappresenta una vocale
|
||||
bool Vocale(char C) {
|
||||
C = tolower(C);
|
||||
if ((C == 'a') | (C == 'e') | (C == 'i') | (C == 'o') | (C == 'u'))
|
||||
return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
//Da carattere a intero
|
||||
int ctoi(char C) {
|
||||
char Text[2];
|
||||
Text[0] = C;
|
||||
Text[1] = 0;
|
||||
|
||||
return atoi(Text);
|
||||
}
|
||||
|
||||
//Restituisce la lunghezza reale di un silb
|
||||
//Praticamente restituisce la lunghezza - i caratteri speciali
|
||||
int TrueSilbLeng(int Silb) {
|
||||
int Leng = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < strlen(Silbs[Silb].Text); i++) {
|
||||
warning("TODO: Properly fix the special character handling in TrueSilbLeng");
|
||||
if ((Silbs[Silb].Text[i] != '|') && // (Silbs[Silb].Text[i]!='<27>') &&
|
||||
(Silbs[Silb].Text[i] != '$') && (Silbs[Silb].Text[i] != '%') &&
|
||||
((Silbs[Silb].Text[i] < '0') || (Silbs[Silb].Text[i] > '9'))) Leng++;
|
||||
}
|
||||
|
||||
return Leng;
|
||||
}
|
||||
|
||||
|
||||
//Riconosce i silbs in una stringa
|
||||
bool SilbRecon(char *Text, int tp, int LastVis, int NewSilb, int *CurrentSilb) {
|
||||
int TextLen = strlen(Text);
|
||||
int NewSilbLeng = strlen(Silbs[NewSilb].Text);
|
||||
int CurrentSilbLeng = 0;
|
||||
int i;
|
||||
bool Equal;
|
||||
|
||||
if (*CurrentSilb != -1) CurrentSilbLeng = strlen(Silbs[*CurrentSilb].Text);
|
||||
|
||||
if (NewSilbLeng <= CurrentSilbLeng) return FALSE;
|
||||
|
||||
|
||||
for (i = 0; i < NewSilbLeng; i++) {
|
||||
Equal = false;
|
||||
|
||||
switch (Silbs[NewSilb].Text[i]) {
|
||||
case '|':
|
||||
if ((i == 0) && ((tp == 0) || ((tolower(Text[tp - 1] < 'a')) && (tolower(Text[tp - 1] > 'z'))))) Equal = TRUE;
|
||||
if ((i != 0) && ((tp == TextLen) || ((tolower(Text[tp]) < 'a') || (tolower(Text[tp]) > 'z')))) Equal = TRUE;
|
||||
break;
|
||||
|
||||
case (char)0xA3: // '£' // TODO: Create a proper constant for the Pound symbol.
|
||||
if ((i == 0) && (tp > 0) && (Vocale(Text[tp - 1]))) Equal = TRUE;
|
||||
if ((i != 0) && (Vocale(Text[tp]))) {
|
||||
Equal = TRUE;
|
||||
tp++;
|
||||
}
|
||||
break;
|
||||
|
||||
case '$':
|
||||
if ((i == 0) && (tp > 0) && (!Vocale(Text[tp - 1]))) Equal = TRUE;
|
||||
if ((i != 0) && (!Vocale(Text[tp]))) {
|
||||
Equal = TRUE;
|
||||
tp++;
|
||||
}
|
||||
break;
|
||||
|
||||
case '%':
|
||||
if ((i == 0) && (tolower(Text[tp - 1]) >= 'a') && (tolower(Text[tp - 1]) <= 'z')) Equal = TRUE;
|
||||
if ((i != 0) && (tolower(Text[tp]) >= 'a') && (tolower(Text[tp]) <= 'z')) {
|
||||
Equal = TRUE;
|
||||
tp++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if ((Silbs[NewSilb].Text[i] >= '0') && (Silbs[NewSilb].Text[i] <= '9')) {
|
||||
if (LastVis == ctoi(Silbs[NewSilb].Text[i]))
|
||||
Equal = TRUE;
|
||||
else Equal = false;
|
||||
} else {
|
||||
if (tolower(Text[tp]) == Silbs[NewSilb].Text[i]) Equal = TRUE;
|
||||
tp++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (Equal == FALSE) return FALSE;
|
||||
}
|
||||
|
||||
*CurrentSilb = NewSilb;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//Riconosce le pause in un file wave
|
||||
int WavePauseRecon(int32 /*n*/, int /*PauseBuf*/[100][5]) {
|
||||
warning("STUBBED: WavePauseRecon");
|
||||
#if 0
|
||||
WAVEFORMATEX *pwfxInfo;
|
||||
MMCKINFO ckIn;
|
||||
MMCKINFO ckInRIFF;
|
||||
HMMIO hmmioIn;
|
||||
UINT cbActualRead;
|
||||
BYTE *Buffer;
|
||||
int Size;
|
||||
int i;
|
||||
int Pausa, NPause = 0, PausaStart = -1, PausaEnd = -1;
|
||||
int Play, PlayStart = -1, PlayEnd = -1;
|
||||
int Var = WAVE_TOLLERANCE;
|
||||
int MinLeng = 300;
|
||||
int IgnoreLeng = 10;
|
||||
int Centro = 0;
|
||||
|
||||
char FileName[MAX_PATH];
|
||||
sprintf(FileName, "%ss%04d.wav", WmSpeechDir, n);
|
||||
|
||||
//Per prove
|
||||
#ifdef PROVAMODE
|
||||
if (strcmp(Sound[wPROVA].name, "") == 0) return -1;
|
||||
if (WaveOpenFile(Sound[wPROVA].name, &hmmioIn, &pwfxInfo, &ckInRIFF) != 0) return -1;
|
||||
* /
|
||||
#else
|
||||
if (WaveOpenFile(FileName, &hmmioIn, &pwfxInfo, &ckInRIFF) != 0) return -1;
|
||||
#endif
|
||||
if (WaveStartDataRead(&hmmioIn, &ckIn, &ckInRIFF) != 0) return -1;
|
||||
Size = ckIn.cksize;
|
||||
Buffer = (BYTE *)VirtualAlloc(NULL, Size, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (Buffer == NULL) return -1;
|
||||
if (WaveReadFile(hmmioIn, Size, Buffer, &ckIn, &cbActualRead) != 0) return -1;
|
||||
|
||||
Centro = (1 << pwfxInfo->wBitsPerSample) / 2;
|
||||
|
||||
Pausa = -999;
|
||||
Play = -999;
|
||||
|
||||
for (i = 0; i < Size; i++) {
|
||||
if ((Buffer[i] >= Centro - Var) && (Buffer[i] <= Centro + Var)) {
|
||||
//Pausa
|
||||
if (PausaStart == -1) PausaStart = i;
|
||||
Pausa = i;
|
||||
} else {
|
||||
//Play
|
||||
if (PlayStart == -1) PlayStart = i;
|
||||
Play = i;
|
||||
|
||||
if (i == Pausa + IgnoreLeng) {
|
||||
//FinePausa
|
||||
PausaEnd = i - IgnoreLeng;
|
||||
if (PausaEnd - PausaStart > MinLeng) {
|
||||
PauseBuf[NPause][0] = (int)(((double)PausaStart / pwfxInfo->nSamplesPerSec) * 1000);
|
||||
PauseBuf[NPause][1] = (int)(((double)PausaEnd / pwfxInfo->nSamplesPerSec) * 1000);
|
||||
NPause++;
|
||||
}
|
||||
PausaStart = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (PausaStart != -1) {
|
||||
PausaEnd = Size;
|
||||
PauseBuf[NPause][0] = (int)(((double)PausaStart / pwfxInfo->nSamplesPerSec) * 1000);
|
||||
PauseBuf[NPause][1] = (int)(((double)PausaEnd / pwfxInfo->nSamplesPerSec) * 1000);
|
||||
NPause++;
|
||||
}
|
||||
|
||||
i = pwfxInfo->nSamplesPerSec;
|
||||
|
||||
WaveCloseReadFile(&hmmioIn, &pwfxInfo);
|
||||
|
||||
return (int)((double)Size / i * 1000.0);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
//Restituisce il tempo del discorso a un determinato visema
|
||||
int VisemaBufTimeLeng(struct VisemaBufStruct *Buf, int Leng) {
|
||||
int i;
|
||||
int TimeLeng = 0;
|
||||
|
||||
for (i = 0; i < Leng; i++) {
|
||||
if (Buf[i].TimeLeng == VIS_NULL) continue;
|
||||
|
||||
if (Buf[i].TimeLeng == VIS_DEFAULT_TIME)
|
||||
TimeLeng += VisDefaultTime;
|
||||
else TimeLeng += Buf[i].TimeLeng;
|
||||
}
|
||||
|
||||
return TimeLeng;
|
||||
}
|
||||
|
||||
//Riconosce le pause probabili in una lista di visemi rappresentanti una frase
|
||||
bool ProbPauseRecon(int ProbPause[100][5]) {
|
||||
int LastVis = -2;
|
||||
int i;
|
||||
int NPause = 0;
|
||||
|
||||
LastVis = -1;
|
||||
for (i = 0; i < NumVis; i++) {
|
||||
if ((VisemaBuf[i].Visema == 0) || (VisemaBuf[i].Visema == 14) || (VisemaBuf[i].Visema == 15)) {
|
||||
if ((LastVis != 0) && (LastVis != 14) && (LastVis != 15)) {
|
||||
ProbPause[NPause][0] = VisemaBufTimeLeng(VisemaBuf, i);
|
||||
ProbPause[NPause][2] = i;
|
||||
}
|
||||
} else {
|
||||
if ((LastVis == 0) || (LastVis == 14) || (LastVis == 15)) {
|
||||
ProbPause[NPause][1] = VisemaBufTimeLeng(VisemaBuf, i);
|
||||
ProbPause[NPause++][3] = i;
|
||||
}
|
||||
}
|
||||
|
||||
LastVis = VisemaBuf[i].Visema;
|
||||
}
|
||||
if ((LastVis == 0) || (LastVis == 14) || (LastVis == 15)) {
|
||||
ProbPause[NPause][1] = VisemaBufTimeLeng(VisemaBuf, i);
|
||||
ProbPause[NPause++][3] = i;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//Restituisce la distanza vera in numero dei visemi
|
||||
//Praticamente la distanza - il numero dei visemi speciali
|
||||
int TrueVisemaDist(struct VisemaBufStruct */*Buf*/, int Start, int End) {
|
||||
int i;
|
||||
int Leng = 0;
|
||||
|
||||
for (i = Start; i < End; i++) {
|
||||
if (VisemaBuf[i].TimeLeng != VIS_NULL) Leng++;
|
||||
}
|
||||
|
||||
return Leng;
|
||||
}
|
||||
|
||||
// Sovrappone le pause probabili con le pause del wave, e calcola di conseguenza
|
||||
// il TimeLeng dei visemi.
|
||||
bool PauseOnPause(int32 n) {
|
||||
int LastVis = -2;
|
||||
int i, j;
|
||||
int Rnd;
|
||||
int DistCentro;
|
||||
int ProbPause[500][5]; //Posizione probabile delle pause
|
||||
int WavePause[500][5]; //(TimeStart, TimeEnd, VisStart, VisEnd, Misc)
|
||||
// int NPause=0;
|
||||
|
||||
//Inizializzazione Buffers
|
||||
for (i = 0; i < 100; i++) {
|
||||
ProbPause[i][0] = -1;
|
||||
ProbPause[i][1] = -1;
|
||||
ProbPause[i][2] = -1;
|
||||
ProbPause[i][3] = -1;
|
||||
ProbPause[i][4] = -1;
|
||||
WavePause[i][0] = -1;
|
||||
WavePause[i][1] = -1;
|
||||
WavePause[i][2] = -1;
|
||||
WavePause[i][3] = -1;
|
||||
WavePause[i][4] = -1;
|
||||
}
|
||||
i = -1;
|
||||
|
||||
//Riconoscimento pause nel Wave
|
||||
i = WavePauseRecon(n, WavePause);
|
||||
if (i == -1) return FALSE;
|
||||
|
||||
VisDefaultTime = i / (NumVis - 2);
|
||||
|
||||
//Riconoscimento pause probabili
|
||||
ProbPauseRecon(ProbPause);
|
||||
|
||||
//Sovrapposizione pause
|
||||
j = 0;
|
||||
while (WavePause[j][0] != -1) {
|
||||
i = 0;
|
||||
DistCentro = -1;
|
||||
while (ProbPause[i][0] != -1) {
|
||||
if (((ProbPause[i][0] > WavePause[j][0] - VIS_PAUSE_VAR) && (ProbPause[i][1] < WavePause[j][1] + VIS_PAUSE_VAR)) ||
|
||||
((ProbPause[i][0] < WavePause[j][0] + VIS_PAUSE_VAR) && (ProbPause[i][1] > WavePause[j][0] - VIS_PAUSE_VAR) && (ProbPause[i][1] < WavePause[j][1] + VIS_PAUSE_VAR)) ||
|
||||
((ProbPause[i][0] > WavePause[j][0] - VIS_PAUSE_VAR) && (ProbPause[i][0] < WavePause[j][1] + VIS_PAUSE_VAR) && (ProbPause[i][1] > WavePause[j][1] - VIS_PAUSE_VAR)) ||
|
||||
((ProbPause[i][0] < WavePause[j][0] + VIS_PAUSE_VAR) && (ProbPause[i][1] > WavePause[j][1] - VIS_PAUSE_VAR))) {
|
||||
/*if (DistCentro==-1)
|
||||
{
|
||||
WavePause[j][2]=ProbPause[i][2];
|
||||
WavePause[j][3]=ProbPause[i][3];
|
||||
DistCentro=abs((ProbPause[i][0]+ProbPause[i][1])/2-(WavePause[j][0]-WavePause[j][1])/2);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rnd=abs((ProbPause[i][0]+ProbPause[i][1])/2-(WavePause[j][0]-WavePause[j][1])/2);
|
||||
if (Rnd<DistCentro)
|
||||
{
|
||||
DistCentro=Rnd;
|
||||
WavePause[j][2]=ProbPause[i][2];
|
||||
WavePause[j][3]=ProbPause[i][3];
|
||||
}
|
||||
}
|
||||
break;*/
|
||||
|
||||
/*if (DistCentro==-1)
|
||||
{
|
||||
if (WavePause[j][4]==-1)
|
||||
{
|
||||
WavePause[j][2]=ProbPause[i][2];
|
||||
WavePause[j][3]=ProbPause[i][3];
|
||||
DistCentro=abs((ProbPause[i][0]+ProbPause[i][1])/2-(WavePause[j][0]-WavePause[j][1])/2);
|
||||
WavePause[j][4]=DistCentro;
|
||||
}
|
||||
else
|
||||
{
|
||||
DistCentro=abs((ProbPause[i][0]+ProbPause[i][1])/2-(WavePause[j][0]-WavePause[j][1])/2);
|
||||
if (DistCentro<WavePause[j][4])
|
||||
{
|
||||
WavePause[j][2]=ProbPause[i][2];
|
||||
WavePause[j][3]=ProbPause[i][3];
|
||||
WavePause[j][4]=DistCentro;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Rnd=abs((ProbPause[i][0]+ProbPause[i][1])/2-(WavePause[j][0]-WavePause[j][1])/2);
|
||||
if (Rnd<DistCentro)
|
||||
{
|
||||
WavePause[j][2]=ProbPause[i][2];
|
||||
WavePause[j][3]=ProbPause[i][3];
|
||||
DistCentro=Rnd;
|
||||
WavePause[j][4]=DistCentro;
|
||||
}
|
||||
}*/
|
||||
|
||||
if (DistCentro == -1) {
|
||||
WavePause[j][2] = ProbPause[i][2];
|
||||
WavePause[j][3] = ProbPause[i][3];
|
||||
DistCentro = abs((ProbPause[i][0] + ProbPause[i][1]) / 2 - (WavePause[j][0] + WavePause[j][1]) / 2);
|
||||
//DistCentro=abs(ProbPause[i][0]-WavePause[j][0]);
|
||||
WavePause[j][4] = i;
|
||||
ProbPause[i][4] = j;
|
||||
} else {
|
||||
Rnd = abs((ProbPause[i][0] + ProbPause[i][1]) / 2 - (WavePause[j][0] + WavePause[j][1]) / 2);
|
||||
//Rnd=abs(ProbPause[i][0]-WavePause[j][0]);
|
||||
if (Rnd < DistCentro) {
|
||||
WavePause[j][2] = ProbPause[i][2];
|
||||
WavePause[j][3] = ProbPause[i][3];
|
||||
ProbPause[WavePause[j][4]][4] = -1;
|
||||
WavePause[j][4] = i;
|
||||
ProbPause[i][4] = j;
|
||||
DistCentro = Rnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
//Fine Sovrapposizione pause
|
||||
|
||||
//Controllo pause non trovate
|
||||
i = 0;
|
||||
while (ProbPause[i][0] != -1) {
|
||||
j = 0;
|
||||
DistCentro = false;
|
||||
while (WavePause[j][0] != -1) {
|
||||
if ((WavePause[j][2] == ProbPause[i][2]) && (WavePause[j][3] == ProbPause[i][3])) {
|
||||
DistCentro = TRUE;
|
||||
break;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (!DistCentro) {
|
||||
for (j = ProbPause[i][2]; j < ProbPause[i][3]; j++)
|
||||
VisemaBuf[j].TimeLeng = VIS_NULL;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
//Fine Controllo pause non trovate
|
||||
|
||||
//Calcolo TimeLeng dei visemi in base alle pause trovate
|
||||
j = 0;
|
||||
LastVis = 0;
|
||||
while (WavePause[j][0] != -1) {
|
||||
if (WavePause[j][2] == -1) {
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TrueVisemaDist(VisemaBuf, LastVis, WavePause[j][2]) > 0) {
|
||||
TimeXVis = (WavePause[j][0] - VisemaBufTimeLeng(VisemaBuf, LastVis)) / (TrueVisemaDist(VisemaBuf, LastVis, WavePause[j][2]));
|
||||
|
||||
//Correzione Velocit<69>
|
||||
i = 0;
|
||||
while ((TimeXVis < MIN_VISEMA_LENG) && (TimeXVis != 0)) {
|
||||
CICLECONTROL(i);
|
||||
error("TODO: Randomness");
|
||||
#if 0
|
||||
Rnd = LastVis + RandomInt(WavePause[j][2] - LastVis - 1);
|
||||
#endif
|
||||
if (VisemaBuf[Rnd].Visema != 0)
|
||||
VisemaBuf[Rnd].TimeLeng = VIS_NULL;
|
||||
if (TrueVisemaDist(VisemaBuf, LastVis, WavePause[j][2]) == 0) break;
|
||||
TimeXVis = (WavePause[j][0] - VisemaBufTimeLeng(VisemaBuf, LastVis)) / (TrueVisemaDist(VisemaBuf, LastVis, WavePause[j][2]));
|
||||
}
|
||||
//Fine Correzione Velocit<69>
|
||||
|
||||
for (i = LastVis; i < WavePause[j][2]; i++) {
|
||||
if (VisemaBuf[i].TimeLeng != VIS_NULL)
|
||||
VisemaBuf[i].TimeLeng = TimeXVis;
|
||||
}
|
||||
}
|
||||
|
||||
if (TrueVisemaDist(VisemaBuf, WavePause[j][2], WavePause[j][3]) > 0) {
|
||||
TimeXVis = (WavePause[j][1] - WavePause[j][0]) / (TrueVisemaDist(VisemaBuf, WavePause[j][2], WavePause[j][3]));
|
||||
|
||||
for (i = WavePause[j][2]; i < WavePause[j][3]; i++) {
|
||||
if (VisemaBuf[i].TimeLeng != VIS_NULL)
|
||||
VisemaBuf[i].TimeLeng = TimeXVis;
|
||||
}
|
||||
}
|
||||
|
||||
LastVis = WavePause[j][3];
|
||||
|
||||
j++;
|
||||
}
|
||||
//Fine Calcolo TimeLeng dei visemi in base alle pause trovate
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//Funzione principale del lip-sync
|
||||
//Riconosce i silb, trova le pause, le sovrappone, e setta le variabili globali
|
||||
int VisemaRecon(int32 n) {
|
||||
char Text[1000];
|
||||
int RPos = 0;
|
||||
int Leng;
|
||||
int LastVis = -2;
|
||||
int tp = 0; //Text Position
|
||||
int i;
|
||||
int Silb = -1;
|
||||
int Rnd;
|
||||
bool Pensiero = false;
|
||||
//int NPause=0;
|
||||
|
||||
strcpy(Text, Sentence[n]);
|
||||
Leng = strlen(Text);
|
||||
|
||||
VisemaInitialized = false;
|
||||
|
||||
for (i = 0; i < MAX_VISEMA; i++) {
|
||||
VisemaBuf[i].Visema = 0;
|
||||
VisemaBuf[i].TimeLeng = 0;
|
||||
}
|
||||
|
||||
if ((Text[0] == '<') && (Text[Leng - 1] == '>')) Pensiero = TRUE;
|
||||
|
||||
// FIXME: condition never happen
|
||||
//if (Text==NULL) return -1;
|
||||
error("TODO: Randomness");
|
||||
#if 0
|
||||
srand((unsigned int)time(NULL));
|
||||
#endif
|
||||
VisemaBuf[RPos].Visema = 0;
|
||||
VisemaBuf[RPos++].TimeLeng = VIS_NULL;
|
||||
|
||||
while (tp < Leng) {
|
||||
for (i = 0; i < NumSilbs; i++) {
|
||||
SilbRecon(Text, tp, LastVis, i, &Silb);
|
||||
}
|
||||
|
||||
if (Silb == -1) tp++;
|
||||
else {
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (!Pensiero)
|
||||
switch (Silbs[Silb].Res[i]) {
|
||||
case -1:
|
||||
break;
|
||||
case 0:
|
||||
VisemaBuf[RPos].Visema = 0;
|
||||
VisemaBuf[RPos++].TimeLeng = VIS_DEFAULT_TIME;
|
||||
LastVis = 0;
|
||||
break;
|
||||
case 14:
|
||||
/*if (RandomInt(100)<80) VisemaBuf[RPos].Visema=0;
|
||||
else VisemaBuf[RPos].Visema=14;*/
|
||||
VisemaBuf[RPos].Visema = 0;
|
||||
VisemaBuf[RPos++].TimeLeng = VIS_DEFAULT_TIME;
|
||||
LastVis = 0;
|
||||
break;
|
||||
case 15:
|
||||
error("TODO: Randomness");
|
||||
#if 0
|
||||
Rnd = RandomInt(100);
|
||||
#endif
|
||||
if (Rnd < 15) VisemaBuf[RPos].Visema = 15;
|
||||
else if (Rnd < 30) VisemaBuf[RPos].Visema = 15;
|
||||
VisemaBuf[RPos++].TimeLeng = VIS_DEFAULT_TIME;
|
||||
LastVis = 0;
|
||||
break;
|
||||
default:
|
||||
VisemaBuf[RPos].Visema = Silbs[Silb].Res[i];
|
||||
VisemaBuf[RPos++].TimeLeng = VIS_DEFAULT_TIME;
|
||||
LastVis = Silbs[Silb].Res[i];
|
||||
break;
|
||||
} else if (Silbs[Silb].Res[i] != -1) {
|
||||
VisemaBuf[RPos].Visema = 0;
|
||||
VisemaBuf[RPos++].TimeLeng = VIS_NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
tp += TrueSilbLeng(Silb);
|
||||
|
||||
Silb = -1;
|
||||
}
|
||||
}
|
||||
|
||||
VisemaBuf[RPos].Visema = 0;
|
||||
VisemaBuf[RPos++].TimeLeng = VIS_NULL;
|
||||
|
||||
NumVis = RPos;
|
||||
|
||||
PauseOnPause(n);
|
||||
|
||||
TotTime = NumVis * VisDefaultTime;
|
||||
TimeXVis = TotTime / NumVis;
|
||||
|
||||
VisemaInitialized = TRUE;
|
||||
|
||||
return TotTime;
|
||||
}
|
||||
|
||||
//Restituisce il visema corrispondente a un determinato tempo
|
||||
int32 VisemaTimeRecon(int32 Time) {
|
||||
if (Time < 0) return 0;
|
||||
if (!VisemaInitialized) return 0;
|
||||
|
||||
#ifdef PROVAMODE
|
||||
static bool Partito = FALSE;
|
||||
if (Time == 0) Partito = FALSE;
|
||||
|
||||
if ((!Partito) && (Time > 0)) {
|
||||
Partito = TRUE;
|
||||
StartSound(wPROVA);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < NumVis; i++) {
|
||||
if ((Time >= VisemaBufTimeLeng(VisemaBuf, i)) && (Time < VisemaBufTimeLeng(VisemaBuf, i + 1)))
|
||||
return VisemaBuf[i].Visema;
|
||||
}
|
||||
|
||||
return VisemaBuf[NumVis - 1].Visema;
|
||||
}
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
Reference in New Issue
Block a user