Projet SARAH: Implémentation C#

Cet article fait suite à un précédent article dans lequel j’essayais de mettre en place un système de maison intelligente nommée S.A.R.A.H.

Speech to Text en C#

Les API de reconnaissance vocale de Microsoft marchent très bien. Malheureusement, les implémentations sont très mauvaises:

  • Windows Speech Recognition Macro (WSR Macro) n’est pas maintenu
  • Peu d’évolution des technos depuis 2007-2008 (à part SIRI)
  • Les produits Microsoft Tell Me sont très mal décrits
  • La doc du Kinect est très dense … beta/1.0/1.5

Bref, comme il n’est pas possible de configurer WSRMacro pour n’utiliser QUE MES macros, j’ai donc décidé de coder ma propre implémentation en C#.

J’ai donc un projet C# qui:

  • Monitore un répertoire de Macros
  • Charge des grammaires XML
  • Envoie une requête HTTP pour traiter l’action reconnue

Ainsi, le traitement des actions peut être déporté sur un serveur Java, NodeJS, … potentiellement sur une autre machine.

Je mettrai les sources en lignes plus tard car pour le moment « c’est pas sec ». Voici l’exécutable.

Grammaire

Le principe de la grammaire Microsoft.Speech est très simple. Des petits morceaux de règle XML se référencent pour former une phrase.

La balise <tag> permet d’exécuter du code pour alimenter un objet « Sémantique ».

  • L’attribut URI définit l’adresse à attaquer.
  • L’attribut speech déclenche un Text to Speech.
  • Les attributs sont transformés en paramètre de requête HTTP.

Text to Speech en NodeJS

L’objectif du serveur NodeJS est de dispatcher les commandes vers:

  • Un script spécifique
  • L’exécution d’un process windows
  • L’exécution d’une requête HTTP
  • L’exécution d’une réponse vocale
  • Un scraping PhantomJS

Voici un début de projet.

Synthèse vocale

J’ai trouvé un petit programme qui utilise la synthèse vocale de l’OS (sinon c’est très simple à recoder en C#).

Ensuite, il faut installer des voix de qualité pour avoir un meilleur rendu.

  • Loquendo (qui s’est fait racheter par Nuance) a les meilleurs voix. Mais impossible d’avoir plus d’infos …
  • Au détour d’un blog, j’ai vu que ScanSoft proposait une voix correcte « Virginie »

Note: pour utiliser des voix 32bit sur un windows 64bit, il faut lancer le sapi.cpl 32bit (%windir%SysWOW64speechSpeechUXsapi.cpl)

Conclusion

Pour le moment, je n’en suis qu’à l’état de POC. Mais assez satisfait du résultat avec un Kinect.

Prochaines étapes:

  • Tester les fonctions natives de Kinect comme microphone.
  • Créer plusieurs grammaires fonctionnelles
  • Faire un peu de scraping PhantomJS
  • Piloter la box Eedomus
  • Piloter le karotz en C#/Protobuff (ça marche bien)

8 pensées sur “Projet SARAH: Implémentation C#

  • 31 juillet 2012 à 23 h 54 min
    Permalink

    Pour « tester » (rien d’extraordinaire et très verbeux):

    • 1.1 Télécharger et Lancer l’exécutable SpeechToText
    • 1.2 La grammaire se trouve dans le répertoire macros
    • 2.1 Télécharger projet NodeJS
    • 2.2 Installer Virginie
    • 2.3 Lancer le .bat pour NodeJS
    Répondre
  • 2 août 2012 à 13 h 29 min
    Permalink

    J’ai fais un peu de refactoring du code car le recognizer est très sensible. Il a un cycle start/stop qu’il ne faut pas titiller sous peine d’exception. J’ai donc fait une sorte de mini automate pour gérer:
    – Le chargement de la grammaire
    – Les chargements de FileSystem
    – …

    Côté NodeJS, j’ai codé une mini architecture pour appeler des scripts.

    Je mets à jour les archives:
    WSRMacro
    WSRNode

    Je pense que le serveur NodeJS va répondre dans la requête HTTP le TTS à lire par le code C#. Ainsi Sarah n’essaiera pas d’écouter sa propre voix ^^.

    Répondre
  • 9 août 2012 à 0 h 29 min
    Permalink

    Après avoir trifouillé pendant plusieurs soirée le programme j’ai réussi à me faire un ordre en 2 étapes:

    1. Sarah il y a quoi au ciné à Parly II ?
    => NodeJS => PhantomJS => Allocine
    => Reponse HTTP « Il y a … » => TTS
    => Ecriture d’un bout de grammaire en live

    2. Sarah quand passe The Dark Night ?
    => Reload de la Grammaire
    => NodeJS …

    Bon le seul petit problème dans ce cas précis c’est prononcer « The Dark Night Rise » comme elle à la française 😛

    Mais je suis content de pouvoir mettre a jour « son cerveau ».

    PS: J’ai fais tout le framework en générique tout propre je ferais un billet sur le sujet plus tard :-)

    Répondre
  • 14 septembre 2012 à 14 h 14 min
    Permalink

    Une question que je me pose, j’ai pas encore testé : si on veut obtenir les horaires de films dans un autre cinéma on doit lui redemander ce qu’il y a dans tel ciné pour lui demander les horaires de tel film ou c’est directement possible de demander « Sarah, quand passe The Dark Knight au Pathé Vaise ? » ? Merci 🙂

    Répondre
  • 14 septembre 2012 à 18 h 22 min
    Permalink

    Mon implémentation se fait en 2 étapes:

    1. Qu’est ce qu’il y a au ciné (Identifiant du ciné)
    => Je requête la page du ciné et récupère les infos
    => Je construit une liste XML des films et mémorise le ciné

    2. Quand passe le film (Identifiant du film)
    => Je requête le cine, je vais cherché le film dans le DOM (je prends le Nième DIV)

    Problèmes:
    1. The Dark Night doit se prononcer à la française « the dirque nitch »
    2. Je pourrais préciser le ciné mais si le film ne passe pas que faire ?
    3. Si le DOM du site change faut refaire le script

    Donc en pratique il faudrait coder un truc plus fonctionnel du genre:
    – Qu’est qu’il y a « dans mes cinés » en ce moment
    – Quand passe machin (dans mes ciné)
    – (Ou récupérer la géolocalisation)

    Enfin c’est un POC qui démontre qu’on fait ce qu’on veux ce n’est qu’une requête HTTP vers un site puis un parcours du DOM pour aller chercher les infos. Et du chercher/remplacer pour avoir des dates « lisibles ».

    La mécanique est générique quand on attaque /phantom/script ca appel le script phantom js du bon nom.

    Répondre
  • Ping : HomePi – Projet domotique « PHP Visions

  • Ping : HomePi – Projet domotique

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *