f/bape - Ein FPGA-basierter Audioplayer mit Equalizer
Digitale Audiosysteme kann man mittlerweile für wenige hundert Euro käuflich erwerben. Aber manchmal braucht man doch vielleicht etwas Spezielles, was es nicht von der Stange zu Kaufen gibt. Auch ich hatte 2023 die Idee, ein Audiosystem etwas anders zu verwenden, als es üblich ist. Daher beschäftigte ich mich mit digitaler Signalverarbeitung und was es braucht, um Audiosamples in eine Signalverarbeitung zu bekommen (Analog-Digital-Wandlung), diese Samples zu verarbeiten (Equalizer, Noise-Gate, Audio-Kompressor) und wieder in die analoge Welt zurückzubringen (Digital-Analog-Wandler).
Wer mag, kann auf Youtube das passende Video von mir dazu sehen: https://youtu.be/ntZmuW3fBnc
Sicherlich gibt es potente Audio-DSPs, die genau für diese Aufgabe vorgesehen sind, aber ich hatte den Ehrgeiz auf der Ebene von digitaler Logik innerhalb eines FPGAs diese Signalverarbeitung zu verstehen und zu implementieren. Schließlich fügte ich noch einen MP3-Audioplayer, eine Frequenzweichen und eine Webserver-Steuerung hinzu... inzwischen ist da also schon ein richtig potentes System herausgekommen, was mit einem einzelnen Sample Latenz auch noch absolut Echtzeitfähig ist.
Die Hardware basiert dabei auf einem Arduino MKR Vidor 4000 mit einem Intel Cyclone 10 LP FPGA, einem SAMD21 32-Bit-Cortex-M0+ Controller und einem ESP32-Chip. Weitere Informationen zum System findet ihr hier: https://store.arduino.cc/products/arduino-mkr-vidor-4000. Auf diesem Vidor 4000-Board sind insgesamt drei Haupt-ICs enthalten:
- Atmel/Microchip SAMD21 ATSAMD21G18A Cortex-M0+ 32-Bit Microcontroller
- Intel Cyclone 10LP 10CL016 FPGA
- uBlox NINA W102 (ESP32 D0WDQ6 Dual-Core)
Die wichtigsten Funktionen als Stichpunkte
- MP3-Wiedergabe über SD-Karte
- I2S-Eingang von externem Audio-ADC
- SPDIF-Eingang (Stereo) oder Eingang über Behringer UltraNet (16 Kanäle)
- 5x Parametrischer-Equalizer
- 24dB/Oktave Linkwitz-Riley-Frequenzweiche für Hochtöner und Subwoofer
- Noise-Gate und dynamische Audio-Kompression
- Lautstärkeregelung, Balancing zwischen links/rechts
- Webserver zur Steuerung vom EQing und anderen Parametern
- Steuerung über ASCII-basierte Befehle (oder optional MQTT)
- Analoger Audio-Ausgang über 3x PDM und/oder SPDIF
- Verzögerung vom Eingang zum Ausgang bei ca. 20µs, daher Echtzeit-Verarbeitung
Übersicht
Der SAMD21 wird als USB-2-UART-Konverter für die Steuerung und Aktualisierung der einzelnen Geräte verwendet. Außerdem enthält er den Bitstream für den Cyclone 10 FPGA, da wir den originalen Flash-Chip nicht verwenden, um das gesamte System leichter aktualisieren zu können. Das Gerät steuert auch das angeschlossene I2C-Display, externe GPIO-Puffer und den externen ADC. Er stellt dem Benutzer eine einfache GUI zur Verfügung, über die die wichtigsten Funktionen ohne Webserver eingestellt werden können. Der FPGA empfängt Audiodaten über I2S und Steuerdaten über eine UART-Verbindung vom NINA W102. Außerdem implementiert er eine Frequenzweiche für die beiden Hochtöner und den Subwoofer sowie parametrische Equalizer und Lautstärkeregler. Der uBlox NINA W102 (ESP32) fungiert als WiFi Accesspoint mit Webserver. Mit ihm lassen sich die Lautstärke regeln, MP3-Tracks auswählen, der Equalizer einstellen und weitere Funktionen des Systems nutzen. Die Audiodaten werden über I2S an den FPGA weitergeleitet. Er kann auch als Bluetooth-A2DP-Sink verwendet werden.
Audio-Qualität
Als DIY-Projekt ist die Audio-Performance recht gut, hängt aber von der Art des Ausgangs ab. Bei Verwendung des digitalen SPDIF-Ausgangs hat das System die gleiche Qualität wie vergleichbare HiFi-Geräte. Bei Verwendung des preisgünstigen PDM-Ausgangs kann es jedoch nicht ganz mit High-End-Audiogeräten mithalten. Hier die Messung einer Wave-Datei bei gleichzeitiger Wiedergabe von 1kHz, 5kHz, 10kHz und 16kHz über den PDM:
Verwendete Systemressourcen
Insgesamt wurden die verfügbaren Systemressourcen schon ganz gut in Anspruch genommen. Der SAMD21 hat bislang noch den größten freien Speicher. Der FPGA ist bereits zu 95% ausgelastet und bietet kaum noch Freiraum für Ergänzungen. Auch der ESP32 besitzt leider mit seinen 2MB kaum Speicher, sodass bei diesem Modell eine zeitgleiche Wiedergabe von MP3s und Bluetooth A2DP nicht möglich scheint. Größere Modelle gibt es aber mit bis zu 16MB, wo dies dann möglich ist:
- Atmel SAMD21 ATSAMD21G18A: 26% of program storage space
- Intel Cyclone 10LP 10CL016: 95% logic elements used / 79% Embedded Multipliers used
- uBlox NINA W102 (ESP32 D0WDQ6): 73% of program storage space
Grafische Benutzeroberflächen
Bei den grafischen Benutzeroberflächen habe ich mich ausgetobt. Es gibt einen integrierten Webserver, der auf jedem Endgerät funktioniert. Des Weiteren gibt es eine Windows 10/11-Anwendung, die über USB die Einstellungen zum Gerät sendet. Aber auch für Retro-Fans habe ich eine Windows 3.11-App und sogar eine OS/2-Anwendung geschrieben, die unter OS/2 Warp 3 (getestet) und vermutlich auch früheren Versionen lauffähig sein sollte. Es gibt aber auch die Möglichkeit via MQTT und UART das System fernzusteuern:
- WiFi via integrated Webinterface
- UART via FBAPE.EXE, FBAPE311.EXE (Windows 3.11), FBAPECPP.EXE (Windows 3.x) or FBAPEWLO.EXE (OS/2)
- via MQTT
- via ASCII-commands via UART
Der Aufbau
Zum Testen des Systems habe ich alles mit Breadboard-Verbindungen oder direkten Jumper-Kabeln verbunden. Bei höheren Taktraten muss man auf die Signalqualität achten: eine 16MHz SPI-Verbindung zur SD-Karte braucht etwas mehr Sorgfalt als ein 1MHz-Signal.
Quelltext
Der Quelltext kann auf GitHub eingesehen und heruntergeladen werden: https://www.github.com/xn--nding-jua/Audioplayer