Listing 4
Vosk: Vokabular und Beispiele
$ git clone https://github.com/alphacep/vosk-api $ cd vosk-api/python/example $ wget https://alphacephei.com/kaldi/models/vosk-model-small-de-0.15.zip $ unzip vosk-model-small-de-0.15.zip $ ln -s vosk-model-small-de-0.15 model $ python3 ./test_simple.py test.wav |& grep "text" $ arecord -Dac108 -f S16_LE -r 16000 -c 1 meintest.wav $ python3 ./test_microphone.py -d 1 |& grep '"text"'
Als ein Teil der Beispiele dient die Datei test.wav (Zeile 6). Allerdings eignet sie sich für uns nicht, denn der Sprecher liest eine Reihe von Zahlen auf Englisch vor. Mit dem deutschen Vokabular kommt dabei nur Dadaismus heraus. Eine eigene Testdatei erstellt das Kommando aus Zeile 7. Vosk benötigt 16-KHz-PCM (16 Bit, mono) und reizt damit den vollen Leistungsumfang des ReSpeakers nicht aus.
Der Umweg über eine Datei ist allerdings gar nicht notwendig, denn der Aufruf in Zeile 8 liest direkt vom Device Nummer 1, in unserem Konstrukt der ReSpeaker. Im Zweifelsfall rufen Sie das Programm mit der Option --list-devices auf. Das Umleiten aller Ausgaben via Grep aus Zeile 8 filtert dabei diverse Log-Meldungen und Zwischenergebnisse heraus. Bei Problemen sollten Sie das Filtern weglassen und die Meldungen nach Fehlern durchsuchen.
Anwendungstest
Jetzt einfach mit dem Befehl aus Zeile 8 loszudiktieren funktioniert aber dennoch nicht. Zum einen kennt das Vokabular nur Kleinbuchstaben; der Aufwand einer nachträglichen Korrektur wäre also extrem hoch. Zum anderen hört Vosk sehr genau hin. Wer wie die meisten Menschen “sexundzwanzig” sagt, muss sich nicht wundern, wenn Vosk “sex und zwanzig” erkennt. Stark dialektgefärbtes Sprechen senkt die Treffgenauigkeit noch weiter.
Bei Anwendungen mit eingeschränktem Vokabular brilliert Vosk dagegen. Für das Webradio des Autors [7] funktioniert inzwischen auch die Sprachsteuerung mit Kommandos wie “an”, “aus”, “lauter”, “leiser”, “Kanalwechsel” und so weiter. Der dafür notwendige Code bleibt dabei überraschend klein (Listing 5).
Listing 5
Vosk-Verarbeitungsschleife
import soundevice as sd
[...]
dev_info = sd.query_devices(self._device_id, 'input')
rate = int(dev_info['default_samplerate'])
model = vosk.Model('/usr/local/lib/vosk/model')
with sd.RawInputStream(samplerate=rate, blocksize = 8000, device=self._device_id, dtype='int16', channels=1, callback=self._process_audio_block):
rec = vosk.KaldiRecognizer(model, rate, json.dumps(list(self._api_map.keys()),ensure_ascii=False))
while True:
data = self._audio_queue.get()
if not data:
break
if rec.AcceptWaveform(data):
phrase = json.loads(rec.FinalResult())['text']
if phrase in self._api_map:
process_api(self._api_map[phrase])
else:
continue
Zuerst fragen die Zeilen 3 bis 5 das Eingabegerät/Mikro ab und erzeugen das Sprachmodell. Zeile 7 generiert das Objekt für die Sprachverarbeitung. Vosk basiert auf Kaldi, und das Programm übergibt das Model, die Sampling-Rate des Mikrofons und eine Wortliste an das Objekt. Die Wortliste kommt aus einer Python-Map, die Phrasen auf APIs abbildet, etwa "an" -> "radio_on()".
In einer Endlosschleife liest das Programm dann die Audiodaten per Mikrofon und übergibt sie an Kaldi (Zeile 12). Die Methode liefert TRUE zurück, wenn sie ein Wort beziehungsweise eine Phrase aus der Liste von Zeile 7 findet. Die Zeile 14 prüft dann, ob die gefundenen Worte eine gültige Kombination darstellen. Falls ja, verarbeitet das Programm den Befehl.
Der reale Code gerät etwas komplexer, was aber nicht an Vosk liegt. Ein spezielles Kommandowort versetzt das Programm in den Kommandomodus und verhindert so, dass die Software jeglichen aufgeschnappten Text als Befehl interpretiert. Via LED signalisiert das Programm dann die Aktivierung des Mikros. Den gesamten Code gibt es im Repository zum Pi-Webradio [7]. Der sehr generisch gehaltene Code lässt sich mit wenig Aufwand für eigene Projekte abwandeln.
Performance
Zum Schluss werfen wir einen Blick auf die Performance. Für den reinen Betrieb des HATs und seiner Aufnahmefunktion genügt auch ein Pi Zero, die Datenrate für vier Kanäle mit 16K-Samples überlastet selbst den kleinsten aus der Familie nicht. Unsere Messungen ergaben eine CPU-Last von rund 10 Prozent und eine etwa gleich hohe Speicherauslastung. Das liegt nicht wesentlich über den Werten eines unbelasteten Systems.
Das Weiterverarbeiten der Audiodaten erfordert dann allerdings mehr Rechenleistung, als sie der Pi Zero bereitstellt. Das gilt auch beim speziell für den Zero gedachten kleineren HAT. Konsequenterweise läuft Vosk nicht auf dem Zero mit seiner Armv6l-Architektur. Mit dem Zero 2 steht aber eine Alternative zur Verfügung, mit der sich ein noch kompakteres intelligentes Mikrofon bauen lässt, sofern Sie eins der seltenen Exemplare ergattern.
Wir testeten das kleine Kraftpaket mit dem WM8960-Audio-HAT [8] von Waveshare [9]. Er bringt etwa die gleiche Ausstattung mit wie der 2-Mic-HAT von Seeed – beide verwenden den gleichen Soundchip und verbauen zwei Mikrofone (Abbildung 4). Dem WM8960 fehlen zwar die APA102-LEDs, aber dafür führt er alle Pins heraus und die Audioausgabe unterstützt Stereo. Als intelligentes Mikro funktioniert der HAT mit dem Zero 2 perfekt. Einzig das optische Feedback fehlt, aber dank der herausgeführten Pins fällt das Nachrüsten der LEDs nicht schwer, zum Beispiel mit Pimoronis Blinkt! [10].
Fazit
Seeed bietet mit dem ReSpeaker einen preislich interessanten Mikrofon-HAT, der sich perfekt für die Offline-Sprachautomation in kleineren Projekten mittels Vosk eignet. Für die reine Aufnahmefunktion gibt es günstigere Lösungen, aber die verbauten LEDs bringen spürbar mehr Pep.






