Wie wir Mikrofonsysteme auf STM32 testen: die Erfahrung von Yandex-Geräteentwicklern



Hallo, ich bin Gennady "Crail" Kruglov vom Yandex-Team für Hardwarelösungen.

Die Auswahl der Mikrofone für die Mikrofonmatrix ist ein komplexer und interessanter Teil unserer Arbeit: Wir testen Modelle mit verschiedenen Parametern, experimentieren mit verschiedenen Matrixkonfigurationen und verbessern die Klangverarbeitungsalgorithmen.

Entwickler, die Echo- und Rauschunterdrückungsalgorithmen erstellen, können nicht nur Rohdaten verarbeiten, die zuvor von einem Gerät im Labor entnommen wurden, sondern auch in Echtzeit mit einer neuen Mikrofonmatrix interagieren, indem sie diese an ihren Laptop anschließen.

Es scheint nur auf den ersten Blick einfach. In diesem Artikel werde ich erklären, wie wir das Problem der Übertragung von Ton von sieben Mikrofonen mit einer PDM-Schnittstelle auf einen Computer über USB gelöst haben, auf welche Hardware- und Software-Nuancen wir gestoßen sind und wie diese überwunden werden können (Spoiler: Dieser Ansatz kann für Matrizen mit einer Anzahl von Mikrofonen ≤ 8 angepasst werden ) Am Ende des Beitrags werde ich einen Link zum Stream freigeben, in dem ich den Entwicklungsprozess auf dem STM32-Mikrocontroller zeige und über die nächste Serie spreche.

Formulierung des Problems


Ein kleiner Hintergrund: Um einen kontrollierten Empfindlichkeitsstrahl zu erzeugen, wurde für die erste Yandex.Station eine Schaltung mit sieben Mikrofonen (analog) für die Mini-Version ausgewählt - mit vier (bereits digital). Für andere Produkte werden verschiedene Konfigurationen in Betracht gezogen, aber die Sieben-Mikrofon-Matrix ist für uns immer noch einfach und klassisch.

Also gegeben: sieben digitale Mikrofone, die Notwendigkeit, sie zu testen. Finden: nicht zu schwierig zu implementieren und flexible Art der Interaktion mit ihnen. Es ist logisch, die Aufgabe in zwei Teile zu unterteilen:

1. Daten von Mikrofonen abrufen.

2. Senden Sie sie an einen Computer.

Wenn der Benutzer im fertigen Gerät Alice kontaktiert, werden die Signale von digitalen Mikrofonen direkt an den Zentralprozessor gesendet (es ist richtiger, es als SoC - System-on-Chip zu bezeichnen, aber der „Prozessor“ ist vertrauter und bequemer). Er verfügt über ausreichende Leistung, um sie zu verarbeiten. Für Debugging-Algorithmen ist es jedoch viel bequemer, diese Daten direkt auf den Computer des Entwicklers zu übertragen. Der einfachste Weg ist die Verbindung über USB: Daher muss die Karte über einen Mikrocontroller mit der entsprechenden Einheit verfügen. Wir lieben den STM32-Controller, aber es ist unmöglich, den Schallstrom von den Mikrofonen direkt an ihn zu senden: Es gibt keine PDM-Signalempfangseinheit (Pulsdichtemodulation) - die Ausgangsschnittstelle digitaler Mikrofone.

Eine andere Möglichkeit besteht darin, die Mikrofonplatine mit der Debug-Platine des Herstellers des verwendeten SoC zu verbinden. Diese Entscheidung ist jedoch an Linux alsamixer gebunden, und ihre Parameter wirken sich stark auf das Ergebnis der Konvertierung von PDM in PCM aus. Diese Blöcke können sich nicht nur für Prozessoren verschiedener Hersteller unterscheiden, sondern auch für zwei Modelle desselben Herstellers. Ich erinnere Sie daran, dass wir eine einfache Lösung brauchten, die transparent und vorhersehbar ist.

Hardwarelösung


Akzeptieren Sie die Unfähigkeit des STM32, Mehrkanal-PDM zu akzeptieren. Man könnte den SPI-Block verwenden, um ein PDM-Signal zu empfangen, aber nur ein Mikrofon kann an einen SPI-Bus angeschlossen werden. Wir arbeiten mit dem STM32L476RC-Controller, bei dem es nur drei solcher Busse gibt. Zusätzliche Komplexität: Das PDM-Signal ist ziemlich hochfrequent, es muss dezimiert, gemittelt, verarbeitet und gefiltert werden - für sieben Mikrofone ist diese Aufgabe ziemlich kompliziert.

Da es sich um ein Debugboard und nicht um einen Prototyp für die Massenproduktion handelt, konzentrieren wir uns auf einen speziellen Chip TSDP18xx. Es macht alles Notwendige: Es erzeugt die notwendigen Frequenzen und Signale für PDM, mittelt und verarbeitet das PDM-Signal, wandelt alles in ein I2S-Signal um. Genauer gesagt, TDM (Time Division Multiplexing), da der I2S-Bus zwei Kanäle annimmt und wenn Sie mehr über dieselben Kabel fahren, ist es nicht mehr ganz richtig, ihn I2S zu nennen.

Der Vorteil dieses Ansatzes besteht darin, dass alle Arbeiten zur Vorbereitung und Mittelwertbildung von TSDP durchgeführt werden. Minus - alle Algorithmen sind in diesem Mikrokreis fest verdrahtet und können nicht geändert werden. Insbesondere können Sie die Lautstärke nicht anpassen, indem Sie die Mittelungsparameter ändern. Für das Debuggen ist dies jedoch nicht kritisch.

Achten Sie auf Ihre Hände: Auf dem Mikrokreis befinden sich sieben Mikrofone und acht Kanäle. Der Ausgang, der nicht verwendet wird, ist immer noch vorhanden. In Zukunft werde ich der Einfachheit halber über den Acht-Kanal-Audiostream sprechen.

Wenn wir also das 8-Kanal-TDM auf STM32 erhöhen, erhalten wir einen 8-Kanal-Audiostream. So verschieben sich Daten:



SAI - STM32-Hardwareeinheit für die Arbeit mit I2S / TDM. Es ist sehr flexibel und ermöglicht die Implementierung vieler Protokolloptionen. Aus diesem Grund kann es leicht zu Verwechslungen bei den Anforderungen an Frequenzen kommen.

Der Uhrenbaum verdient einen genaueren Blick. Ein 12-MHz-Quarzresonator ist an den Mikrocontroller angeschlossen. Wir teilen diese Frequenz, bevor wir sie auf die PLL-Blöcke anwenden, durch 3 und erhalten 4 MHz. Dann funktioniert es so:

1. Es wäre schön, die Kernfrequenz höher zu machen, um mit allem Schritt zu halten: Das Maximum für diesen Controller beträgt beispielsweise 80 MHz. Wir verwenden den ersten PLL-Block: Wir multiplizieren 4 MHz mit 40 und dividieren durch 2.

2. USB benötigt 48 MHz. Verwenden Sie dazu den zweiten PLL-Block: Multiplizieren Sie 4 MHz mit 24 und dividieren Sie durch 2.

3. Informationen zu Mikrofonen. Unsere Testkarten verwenden eine Abtastfrequenz von Fs = 16 kHz, ein Standard, der im Bereich der Spracherkennung angewendet wird. Ab der Anfangsfrequenz von 4 MHz benötigen Sie etwas, das in 16-kHz-TDM-Busrahmenfrequenzen umgewandelt werden kann (auch bekannt als LRCK, auch bekannt als FCK, auch bekannt als FrameSync). In diesem Fall:

[Häufigkeit der Bitsynchronisation (BCLK, BitClk, Sync, SCK)] = Fs ∙ [Anzahl der Kanäle] ∙ [Anzahl der Bits pro Kanal]

Das heißt: SCK = 16 kHz ∙ 8 ∙ 16 = 2048 kHz.

4. Das Datenblatt zeigt, dass das Verhältnis zwischen Haupttakt und Abtastrate Fs wie folgt ist: MasterClock = 16 kHz ∙ Teiler MCLK ∙ 256. Hier ist 256 eine Konstante, und der Teiler kann im Register eingestellt werden. Lassen Sie uns das Schema überprüfen - für die erforderliche Funktionalität gibt es Koeffizienten zum Teilen der PLL-Frequenz durch 7 oder 17:



Um das Problem zusammenzufassen: Sie müssen einen solchen Satz von PLL- und SAI-Faktoren und -Teilern auswählen, um eine Abtastfrequenz von 16 kHz und eine Bitfrequenz von 128-mal mehr zu erhalten. Da das Set einen obligatorischen Teiler von 7 (oder 17) hatte, funktionierte es nicht, um genau das gewünschte Ergebnis zu erzielen. Ich musste eine Tabelle mit Multiplikatoren und Teilern erstellen, um 24,571 MHz zu erhalten. Wenn wir diese Frequenz durch 6 (MCLK-Teiler) und dann durch 256 (Konstante) teilen, erhalten wir schließlich eine Zahl nahe genug an 16 kHz. Jetzt werde ich erklären, warum dies so wichtig ist.

USB-Betrieb


USB verwendet eine isochrone Übertragungsart, um mit Multimediadaten zu arbeiten: In diesem Fall ist eine bestimmte Bandbreite und ein bestimmter Verzögerungswert auf dem USB-Bus garantiert. Die Datenlieferung kann nicht garantiert werden: Wenn ein Paket mit einem Fehler eintrifft, gilt es als verloren. Dies liegt an strengen Fristen: Es gibt keine Möglichkeit, erneut zu fragen.

Bei der isochronen Art der Übertragung mit USB-FullSpeed-Geschwindigkeit (12 Mbit / s; bei dieser Geschwindigkeit kann der STM32-USB-Block arbeiten) kommt der Computer jede Millisekunde zum Gerät, um Daten zu erhalten. Nach dieser Zeit sollten die gesammelten Daten erfasst werden. Ich möchte Sie an die einleitenden erinnern: Die Abtastfrequenz beträgt 16 kHz, 8 Kanäle, jeder Kanal benötigt zwei Bytes, da der Ton 16 Bit ist. Insgesamt 16000 ∙ 2 ∙ 8/1000 = 256 Bytes pro Millisekunde. Die Größe eines Pakets für eine isochrone Übertragungsart kann 1023 Byte erreichen, sodass an dieser Stelle keine Probleme auftreten.

Die Paketgröße beträgt also 256 Bytes. Es scheint, dass alles in Ordnung ist. Sechzehn Mal empfangene Daten auf TDM, in den Puffer gelegt, USB kam, wir geben ihm ein Paket, wir wiederholen ... Aber das passiert nur in einer idealen Welt. Das Problem ist, dass wir einerseits unvollständige 16 kHz (etwas weniger) haben und die Daten daher etwas weniger als einmal pro Millisekunde eingehen. Andererseits schwebt auch die Millisekunde des Computers, da er beschäftigt ist: Wenn es könnte, dann kam es. Das heißt, die Mikrofonabruffrequenz unterscheidet sich von 16 kHz (aber immer gleich), und die USB-Millisekunde unterscheidet sich auch in der Länge (der Unterschied ist höchstwahrscheinlich schwebend: Er stellt sich als etwas mehr heraus, dann als etwas weniger als eine ideale Millisekunde).

Warum ist das ein Problem? Sie können das Paket verlieren. Es ist wahrscheinlich nicht notwendig zu erklären, dass vollständige Daten für das korrekte Debuggen der Algorithmen erforderlich sind. Wie das Paket verloren geht: Sie haben 256 Bytes an Ergebnissen gesammelt, sie in den Puffer gelegt und die Messung fortgesetzt. Ein Computer kam, nahm die ersten 256, wir messen noch weiter. Der Computer kam wieder, aber die Messung ist noch nicht abgeschlossen - der Computer hat ein leeres Paket zurückgelassen. Dann füllen wir den Puffer vollständig aus und füllen einen weiteren aus, den nächsten, bis der Computer wieder eintrifft. Der Computer nimmt nur das letzte Paket entgegen, wodurch ein Paket verloren geht.



Das Problem ist in der Tat bekannt. Es gibt drei Ansätze, um damit umzugehen:

  • . USB. — . «» — . USB . , , ( , 16 ), . , .
  • . .
  • Asynchron ist das Beste für diese Aufgabe. Das Gerät verfügt über einen stabilen Frequenzgenerator. Die Abtastrate bleibt ohne Bezug auf USB exakt gleich. In diesem Fall müssen Sie Daten auf das Gerät übertragen, damit keine wesentlichen Abweichungen auftreten.

All dies wurde mehr als einmal im Internet für den Fall der Wiedergabe von einem Computer zum Lautsprecher über ein Gerät mit einem Digital-Analog-Codierer diskutiert, wobei das Gerät als Rückmeldung angibt, wie viele Abtastperioden seit dem Empfang des letzten Pakets vergangen sind.



Unsere Aufgabe ist jedoch das Gegenteil: Beim Debuggen müssen Daten von Mikrofonen an einen Computer empfangen werden, und die Frage der Aufzeichnung eines Signals von Mikrofonen an einen Computer wird bestenfalls erwähnt. Warum nicht dasselbe tun: Feedback vom Computer einführen? Es gibt eine einfachere Option.

Da ist er


Wir verwenden das häufige Hinzufügen von Samples und zwei Puffern, um Daten zum Senden zu speichern. 16 Mal pro Millisekunde fügen wir dem ausgewählten Puffer die nächste Probe hinzu. Irgendwann tritt eine Unterbrechung auf: USB hat das vorherige Paket genommen. Wenn Puffer Nr. 1 voll ist, wird auf Puffer Nr. 2 umgeschaltet. Wenn USB für das nächste Paket ankommt, ist es bereits vorbereitet. Senden Sie Puffer Nummer 2 und wechseln Sie zurück zu Nummer 1.



USB kommt für Daten zu unterschiedlichen Zeitpunkten, das Paket enthält eine unterschiedliche Anzahl von Proben. Es kann sich herausstellen, dass es mehr und weniger als 16 sind. Daher besteht die Möglichkeit, dass ein Paket mit einer Größe von 256 Byte überschritten wird. Es ist besser, Platz für Manöver zu lassen. Es sei 384 = 256 + 128: Dies ergibt einen Spielraum von einer halben Millisekunde, dh es wird die Schwimmphase des USB-Signals um 50% vergeben - ein solcher Spielraum sollte mehr als ausreichend sein. Gesamt: Manchmal werden mehr oder weniger 256 Bytes gesendet, aber niemals ein leeres Paket, wodurch Datenverlust vermieden wird. Das heißt, das Problem der Unebenheit wurde gelöst, indem das Paket auf Kosten einer Erhöhung eines Teils der für unser Gerät zugewiesenen Busbandbreite und einer Verringerung dieses Teils für andere Geräte erhöht wurde.

Damit endete die Übermittlung von Daten an den Computer. Entwickler können debuggt werden, und Sie können in den Kommentaren Fragen stellen, wenn eine Art Datenpaket für ein vollständiges Verständnis nicht ausreicht.

Meine Streams und die nächste Folge


In letzter Zeit habe ich zweimal aus meinem Lötlabor gestreamt. Zuerst habe ich nur den Lötprozess gezeigt und gesagt, welche Geräte ich benutze. Die zweite Serie war nur der Entwicklung des STM32 gewidmet.

Streams werden fortgesetzt. Diesen Freitag um 19:00 Uhr wird mein Kollege vom Entwicklungsteam für Hardwarelösungen, Andrey Laptev, eine Online-Analyse von Yandex.Stations Mini arrangieren - zeigen Sie die Innenseiten und teilen Sie die Produktionshistorien. Für mehr Spaß wird Andrey die Batterie an die Säule schrauben - nicht egal, arbeiten Sie vom Draht. Im Finale erhalten Sie einen Leitfaden, mit dem Sie diese Erfahrung selbst wiederholen oder ein interessanteres Design entwickeln können.

Anmeldenden Stream zu sehen. Sie erhalten einen Brief mit einer Datei für den Kalender und einer Erinnerung am Sendetag. Danke fürs Lesen!

All Articles