2007-08-29

Cool & Useless: Creando nuestra propia aplicación para manejar la PC por medio de la voz, (casi) todo desde código manejado (Parte 2)

En el post anterior vimos hace para usar el motor de reconocimiento de voz usando el .Net Framework 3.0 para reconocer las frases que nosotros queremos. Sin embargo, para hacer esto estábamos usando el motor de reconocimiento predeterminado del sistema. Haciendo un pequeño retoque, veremos que es posible usar el motor en cualquier otro idioma.

El primer requerimiento será bajar el MUI Pack del idioma que queremos usar. El Windows Vista Ultimate que yo tengo instalado trae ya instalado el motor para inglés americano y británico. Desde Windows Update, baje el MUI Pack de español y con esto, se instaló el motor de reconocimiento en español.

Como comenté en el post anterior, Windows no permite el uso del reconocimiento de voz en un idioma distinto al que se está usando en el sistema. Sin embargo, con las siguientes líneas de código es posible inicializar la clase SpeechRecognitionEngine con cualquier otro motor instalado.

Este ejemplo busca algún motor que esté en español y empieza a reconocer voz con el idioma elegido:



static void Main(string[] args)
{
SpeechRecognitionEngine sre = null;
foreach (RecognizerInfo config in SpeechRecognitionEngine.InstalledRecognizers())
{
if (config.Culture.TwoLetterISOLanguageName == "es")
{
sre = new SpeechRecognitionEngine(config);
}
}

Choices choises = new System.Speech.Recognition.Choices(
new string[] { "hola", "como", "estas", "mi nombre es Pablo" });

GrammarBuilder gb = choises.ToGrammarBuilder();
gb.Culture = sre.RecognizerInfo.Culture;
Grammar grammar = new Grammar(gb);


sre.LoadGrammar(grammar);
sre.SpeechRecognized += new EventHandler(sre_SpeechRecognized);
sre.SetInputToDefaultAudioDevice();
sre.RecognizeAsync(RecognizeMode.Multiple);
}

Debemos recordar que al inicializar el SpeechRecognitionEngine con un idioma distinto al predeterminado, también debemos cambiar la cultura del GrammarBuilder usado para generar la gramática a cargar. El resto del ejemplo es igual a lo ya visto.

Volviendo a nuestro objetivo de manejar cualquier cosa con la voz, lo que necesitamos hacer ahora es poder simular el uso de teclado.

Si bien el .Net Framework trae la clase System.Windows.Forms.SendKeys con el método Send, el cual recibe un String y simula presionar esas teclas, veremos que esto no nos va a servir para simular es uso del teclado en juegos que usen DirectX.

Para poder hacer esto, usé la función SendInput() desde C++ la cual está disponible al incluir el header windows.h . Esta función sirve para simular desde un nivel mas bajo el input desde teclado, mouse o algún otro dispositivo de hardware (más información en http://msdn2.microsoft.com/en-us/library/ms646310.aspx).

A continuación un pequeño ejemplo de cómo usarlo para simular la letra 'A'



void SimulateKeyboard()
{
KEYBDINPUT kb={0};
INPUT Input={0};

kb.wVk = 'A';
Input.type = INPUT_KEYBOARD;
Input.ki = kb;
::SendInput(1,&Input,sizeof(Input));
}


Teniendo esto, creé un nuevo proyecto de DLL en C++ para poder exportarla y usarla desde código manejado.

Una vez obtenida la DLL que exporta el método creé un proyecto de DLL en C# para poder wrappear esta función y usarla cómodamente desde código manejado.

Con esto ya terminé de armar todas las herramientas necesarias para mi aplicación. Solo restó armar una aplicación que levante una configuración desde un archivo XML con las frases que quería decir, asociadas a las combinaciones de teclas a simular y listo! Ya tenía armado mi simulador de teclado manejado por voz.

Acá les dejo un link al código del proyecto entero para que lo bajen. Tengan en cuenta que esto lo hice medio a los apurones así que puede estar bastante buggeado, pero, como diría el Bambino Veira, La Base Está J


Saludos!


Z

3 comentarios:

Kbal311 dijo...

Hola disculpa el link esta roto, podria ver tu proyecto para colaborar un poco ?

Zaiden dijo...

El proyecto lo podes ver aca: http://www.codeplex.com/KeySimVoiceCommander/

Kbal311 dijo...

:) muchas gracias