Skip to content
Rookfighter edited this page Jun 27, 2014 · 10 revisions

Implementierung

Übersicht

Die hier implementierte Anwendung realisiert ein sprachgesteuertes Realzeitsystem. Die Kernkomponenten des Systems sind die Input Task, Interpreter Task, Simulation Task und Mapper Task, sowie die gemeinsamen Resourcen der Audio Queue, Hypothesis Queue, die Simulation, der Audio Buffer Pool und der String Pool, über welche die Tasks miteinander kommunizieren.

Tasks

Der Datenfluss des Systems wird in diesem Datenflussdiagramm beschrieben.

Audio Buffer Pool: Hierbei handelt es sich um einen im vorraus reservierten Speicherbereich mit einer festen Anzahl an Audio Puffern. Aus diesem Speicherbereich können sich Tasks dynamisch Audio Puffer reservieren und auch wieder freigeben. Somit wird ein undeterministischer Weg über das Betriebssystem (malloc) vermieden. Da der Pool eine feste Größe hat, kann die Task beim reservieren blockieren, falls keine Puffer mehr frei sind.

String Pool: Dieser Pool dient dem gleichen Zweck wie der "Audio Buffer Pool", nur dass der String Pool Strings fester Größe verwaltet.

Audio Queue: In dieser Queue werden Audio Puffer eingereiht. Hierbei handelt es sich um eine Blocking Queue mit fester Größe, sodass undeterministisches Warten auf eine Speicheranforderung vermieden wird. Hiedurch kann eine Task aber sowohl beim Entnehmen (leere Queue), als auch beim Einreihen (volle Queue) blockieren.

Hypothesis Queue: Die Implementierung dieser Queue ist diesselbe wie die der Audio Queue. Jedoch verwaltet diese Queue Strings (Hypothesen).

Simulation: Die Simulation hält alle Daten, die beim Fortschreiten eines Logikschritts in der Simulation Task wichtig sind. Über sie kann das Simulationsgeschehen manipuliert werden.

Input Task

Die Input Task ist für das Aufnehmen und Speichern von Audiodaten verantwortlich. Dabei werden die Audiodaten live, also zur Laufzeit aufgenommen. Das Aufnehmen der Daten beginnt durch das erste Wahrnehmen von Geräuschen (z.B. wenn gesprochen wird). Audiodaten werden in einer audioBuffer_t Struktur gespeichert. Dabei handelt es sich um einen einfachen Puffer mit einer festen Größe, der bei einem Überlauf weitere eintreffende Daten verwirft. Dieser Puffer wird mithilfe des Audio Buffer Pools reserviert. Ist die Aufnahme beendet, wird der Puffer in der Audio Queue eingereiht. Hierbei handelt es sich wiederrum um eine Blocking Queue. Das Beenden einer Aufnahme wird entweder durch eine kurze Ruhephase (200ms) oder durch einen Pufferüberlauf ausgelöst.

Interpreter Task

Die Interpreter Task verarbeitet die gesammelten Audio Daten zu Strings, sogenannten Hypothesen. Zuerst wird aus der Audio Queue ein Audio Puffer entnommen. Dessen Audiodaten werden mithilfe des Pocketsphinx Decoders interpretiert. Für die resultierende Hypothese wird eigens ein String aus dem String Pool reserviert. Danach wird die Hypothese in die Hypothesis Queue eingereiht. Zuletzt wird der aus der Audio Queue entnommene Audio Puffer wieder freigegeben.

Simulation Task

Die Simulation Task simuliert eine Art "Crash Test". Dabei gibt es einen Spieler, der durch Kommandos gesteuert werden kann, und Hindernisse, die sich auf den Spieler zu bewegen. Der Spieler hat 2 Bahnen, auf denen er sich befinden kann. Diese muss der Spieler nutzen, um den Hindernissen auszuweichen. Die Task simuliert dabei in einem Schritt die Spiellogik und zeichnet danach das ganze Geschehen auf den Bildschirm.

Mapper Task

Die Mapper Task übernimmt das Übersetzen der Hypothesen zu Kommandos für das System. Zuerst entnimmt die Task eine Hypothese aus der Hypthesis Queue. Danach wird über eine "if-else" Abfrage bestimmt, welches Kommando auszuführen ist. Zum Schluss wird die erhaltene Hypothesis wieder freigegeben.

Abhängigkeiten

Das System benutzt zur Spracherkennung die Bibliothek Pocketsphinx. Die Simulation wird mithilfe von Allegro 4 grafisch dargestellt.