miércoles, 30 de mayo de 2007

A vueltas con SAPI

Me han recomendado que para hacer hablar al avatar prueba con SAPI, la librería de Microsoft para síntesis y reconocimiento de voz. Llevo varios días con ello y mis avances son pocos. Se hace dificil encontrar información sobre SAPI para PocketPC/Windows Mobile/Windows CE porque casi todo lo que encuentro se refiere a las plataformas de escritorio y de servidor.

Por otro lado, según lo que voy encontrando "parece" que los entornos de programación donde se usa son Visual Studio 2003 y Visual Studio .NET. Sobre el Embedded Visual C++ que venía utilizando hasta ahora no he encontrado nada.

Mucho me temo que hay un conflicto en ciernes: Si utilizo el eVC me funcionará la librería de OpenGL-ES pero no la SAPI. Si utilizo Visual Studio pasará lo contrario. Temo que tenga que volver a los problemas que ya tuve al principio de este trabajo.

Mientras tanto estoy descargando e instalando SDKs variados, a ver si acierto con el que necestio, porque hay tantos productos de Microsoft con nombres parecidos que ya no se cuál es cuál.

lunes, 21 de mayo de 2007

Intentado hablar

He buscado la forma de hacer hablar al avatar, y más en general a la PDA sobre la que estoy haciendo el desarrollo.

Por un lado, existen las librería SAPI de Microsoft, pero no tengo claro que me vayan a servir, ya que son "demasiado modernas" para el entorno que estoy usando.

He encontrado también Flite, que es una implementación ligera de un conocido programa de sintésis de voz llamado Festival. Hay disponible una versión precompilada para PocketPC y la he instalado en el mío para probarla. Es un ejecutable que al lanzarlo muestra una ventana donde se puede escribir un texto, y a continuación la PDA lo "habla" por el altavoz, hablando eso sí muy robóticamente y con la fonética del inglés norteamericano.

El programa puede ejecutarse pasándole como parámetros de la línea de comandos la frase que se desea decir. Podría hacer una prueba quick-and-dirty ejecutando desde el programa del avatar el Flite con las frases que quiero oir, aunque solo funcionará en una PDA "de verdad", porque para que funcionara en el emulador el programa tendría que estar compilado para x86 en lugar de para ARM

Algo tan aparentemente sencillo como ejecutar un programa (el Flite) desde otro programa (el del avatar) se ha convertido en una tarea imposible. En las ayudas del Embedded Visual C no he encontrado cómo hacerlo. Las funciones de C que se usan habitualmente para esa tarea, como exec(...), execve(...) o incluso popen(...) o system(...) no están disponibles en este entorno.

Lo malo es que no he encontrado ninguna forma de hacerlo, ninguna, ni bonita ni fea, y he estado toda una tarde con ese "detalle". De paso me he enterado que el emulador que viene con el Visual Studio 2005 sí que es un emulador real de ARM, y se le pueden instalar binarios que funcionarán, como (quizás) el Flite. Lástima que tuviera que abandonarlo porque no funcionaba la librería Vincent Mobile.

martes, 15 de mayo de 2007

Primera aproximación

He hecho una primera prueba para ver qué tal queda la animación. Disponía de varios ficheros del modelo con la boca en posiciones diferentes, y simplemente he programado que se carguen todos (son siete) y luego se muestren de forma aleatoria durante el tiempo suficiente para que no vaya ni muy deprisea ni muy lento.

Queda bastante bien. No se hace ningún cálculo, en lugar de eso se ocupa memoria aunque no demasiada: La estructura de datos tiene un tamaño de unos 160 kb, así que los siete más la imagen del programa (unos 75 kb) no llegan a 1 megabyte.

La primera prueba ha sido hacer mover solo la boca de la cabeza, pero quedaba muy frío. Después he introducido un pequeño movimiento de uno o dos grados hacia los lados y hacia arriba/abajo, para que al hablar produjera un movimiento como de "cabeceo". Quedaba menos rígido pero entonces a reaparecido el problema de los polígonos que no se pintan bien cuando hay mucha concentración en una zona, provocando un efecto muy feo.

Lo siguiente que probaré será el habla, y juntarlo con esta animación. Si consigo las dos cosas, me dedicaré a refinarlo y hacerlo más elegante.

miércoles, 9 de mayo de 2007

Ideas para la animación

El problema de los polígonos finalmente va a ser "rodeado". En vez de invertir tiempo en intentar solucionarlo con la programación o cambiando la librería, se van a usar mallas más sencillas para que no ocurra.

Hemos comenzado a pensar en la animación. De momento se quiere mover solo la boca y luego ya se verá cómo añadir sonido y sincronizar ambas cosas. Para hacer la animación se valoran dos aproximaciones:

- Animación de esqueleto: Definir una estructura de datos que representa los huesos, y asociar una malla a cada uno. Cada vez que se muevan, la malla lo hará con él. Esta forma es muy apropiada para personajes completos y con una estructura más o menos compleja, pero no parece muy adecuado para nuestro caso, donde solo hay una cabeza, sin apenas articulaciones.

- Deformación de malla: Se tienen dos modelos, uno con la boca completamente abierta y otro completamente cerrada. Han de tener la misma estructura geométrica, con los puntos y los polígonos definidos con los mismos índices de la lista. A partir de las diferencias de coordenadas entre ambos modelos, se pueden calcular interpolando los puntos intermedios y generar la animación. Más sencillo para animación facial.

Se va a optar por el segundo. Los problemas que pueden surgir son limitaciones de memoria (al tener que almacenar dos o más mallas) o de CPU (al tener que recalcular todo el modelo al variar las coordenadas de sus vértices). Si se da cualquiera de los dos, habrá que pensar en alguna forma de optimización para evitarlo.

martes, 1 de mayo de 2007

Probando Hybrid Rasteroid

He estado intentado utilizar una librería de OpenGL ES alternativa a la Vincent 3D, y he probado Hybrid Rasteroid, que se menciona en los primeros tutoriales de la página de ZeusCMD.

La forma de utilizarla es similar a la que ya estaba utilizando, y consiste en copiar los ficheros que vienen en el archivo descargado (los Includes, los .lib y los .dll) a los respectivos directorios del entorno de desarrollo. Haciendo algunos pequeños cambios en el código he conseguido compilar sin problemas el programa del avatar, y hasta ahí he podido avanzar. Después de eso al cargar el ejecutable en el emulador no funcionaba, devolvía un error en el que decía que no era una aplicación válida o que le faltaba un componente. Después de buscar en páginas y foros apenas he encontrado nada de información, solo un "truco" para nada lógico ni intuitivo. Tras aplicarlo, he conseguido que la aplicación hiciera un "amago" de funcionar (llega a escribir algo en el fichero de log) pero entonces me aparecía una ventana de error en la PDA que venía a decir que GLUT|ES no podía iniciar las OpenGL ES. He vuelto a buscar en Google sobre este problema, pero no he encontrado ninguna solución. Así pues:

- Podría ser fallo de la librería GLUT|ES, lo cual es malo pero no desastroso porque en su defecto podría utilizar las llamadas similares que implementa la Vincent 3D, pero comencé a usar GLUT precisamente para evitar usarlas, así que no me habría valido de nada el cambio, y además con las Vincent 3D funciona bien.

- Podría ser fallo de la librería Hybrid Rasteroid, lo que es también malo, porque justamente las he probado como alternativa a la Vicent 3D por el problema que parece que tiene al pintar polígonos.

- Podría ser problema de la combinación GLUT+Hybrid, aunque teóricamente se han probado el buen funcionamiento de ambas a la vez.

Una solución un tanto chapucera que habría que probar para ver si funciona sería tratar de utilizar ambas librerías a la vez, la Vincent y la Rasteroid, y de la primera utilziar las funciones de acceso a las ventanas y al teclado y renderizar con la segunda.

O seguramente más sencillo y directo, utilzar un modelo cuya malla sea más simple y no tenga esos problemas, aunque no quedará tan bien.

Utilizando GLUT|ES

He modificado el código para que todo lo relacionado con la gestión de ventanas, teclado, ratón y alguna cosa más lo gestione la librería GLUT|ES en lugar de las funciones equivalentes que vienen con la librería Vincent 3D.

La razón es que GLUT es la forma "estándar" de manejar esas partes del entorno que se suele utilizar en OpenGL. De esta manera si se diera el caso se podrá usar otra librería diferente a la Vincent 3D sin tener que preocuparse porque deje de funcionar, por ejemplo, el teclado.

Esta modificación ha sido algo problemática, no tanto por cambiar las funciones de manejo del teclado y las ventanas (que tienen nombre similares y parámetros parecidos) como por la preparación del entorno de programación. Una vez más la web de ZeusCMD ha sido de enorme ayuda, ya que la página de la versión oficial de la librería GLUT|ES no es nada clara en cuanto al proceso de instalación (sobre todo en lo referente al uso del emulador) e incluso en algunas circunstancias se producen errores al compilar. Gracias a la labor de los usuarios de ZeusCMD he podido instalar y utilizar una versión modificada que funciona correctamente con el entorno de programación y el emulador.