Forum: Mikrocontroller und Digitale Elektronik Welche Mp3-Lib für STM32F411?


von Mike (Gast)


Lesenswert?

Hier gab es ja schon öfters Diskussionen zum Thema MP3-Player auf 
ARM-Controllern.

Ich möchte mit Hilfe einer Black-Pill, bestückt mit STM32F411 und einem 
I2S-DAC-Verstärker (MAX98357A) Sounds wie Tierlaute und kurze 
Melodieschnipsel ausgeben. Ich habe nur wenig Speicherplatz (16MByte) 
zur Verfügung. Da die Qualität ohnehin durch den verwendeten 
Lautsprecher begrenzt ist, müßte MP3 mit 64kbit/s Mono, genügen. Besser 
wäre natürlich AAC. Nun bin ich auf der Suche nach einer geeigneten 
Decoder-Library, die idealerweise die Features des Arm M4 wie floating 
point und DSP-Funktionen nutzt.

Die altbewährten Helix und MADlib scheinen schon seit langem nicht mehr 
gepflegt zu werden, der Link zu  helixcommunity.org ist tot, das letzte 
Github-update von Madlib stammt aus dem Jahre 2004.

Welche Library würdet Ihr empfehlen, die mit den Ressoucen des STM32 
(max. 100MHz, 128kB Ram) zurechtkommt?

Ich wünsche noch einen schönen Sonntag.

von M. Н. (Gast)


Lesenswert?

Ich weiß, dass das nicht ist, was du gefragt hast, aber: Was spricht 
gegen eine SD-Karte mit WAV Dateien? Diese können quasi einfach 
abgespielt werden ohne aufwendige Prozessierung.

Wenn es doch MP3 sein soll:

Mike schrieb:
> Die altbewährten Helix und MADlib scheinen schon seit langem nicht mehr
> gepflegt zu werden, der Link zu  helixcommunity.org ist tot, das letzte
> Github-update von Madlib stammt aus dem Jahre 2004.

Ist das ein Problem? Code altert nicht. Wenn das Featureset ausreichend 
ist, warum nicht?

Mike schrieb:
> Nun bin ich auf der Suche nach einer geeigneten
> Decoder-Library, die idealerweise die Features des Arm M4 wie floating
> point und DSP-Funktionen nutzt.

Floating Point wird für MP3 gar nicht gebraucht. Wäre aber egal, da du 
die Library ja eh als Quellcode mitcompilierst und somit, wenn du mit 
"hardfpu" compilierst FPU Befehle eingebaut werden. Die DSP 
Funktionalitäten sind schon etwas schwieriger... So richtig hardcore 
optimiert wird das nur, wenn man die selektiv als Programmierer 
einstreut. Ansonsten ist man auf die Gnade des Compilers angewiesen, 
dass er in etwa das baut, was man haben will. Das ist aber meist 
tatsächlich nicht wirklich der Fall.

Je nachdem, was dein STM sonst noch machen soll, ist aber eine so starke 
Optimierung gar nicht notwendig. Der STM hat genug Power, um eine 
niederqualitative MP3 auch mit eher suboptimaler Implementierung 
abspielen zu können.

Eine weitere Alternative wären die klassischen VSxxxx ICs von VLSI zum 
MP3 dekodieren. Sind halt teuer und benötigen eventuell dann noch einen 
kleinen Ausgangsverstärker.

von Jürgen H. (juh)


Lesenswert?

Moin,
wie bereits gesagt, Code verdirbt üblicherweise nicht:

ich habe vor vielen Jahren(2014) das schöne Projekt/die Library von Uwe 
Becker
54-CS43L22_MP3_USB-Library (STM32F4)
(https://mikrocontroller.bplaced.net/wordpress/?page_id=438(aktueller 
link))
vom STM32F407-disco auf das STM32F401C-disco sehr leicht 'portieren' 
können.
Verwendet wird der decoder helix(integer only, no float), der gut 
funktioniert mit allen getesteten MP3s(verschiedene 
Bitraten,'Soundarten').

Es ist also lediglich der MP3-decoder aus dem Projekt zu 
'extrahieren'...

Deine 'schwarze Pille' steht ja mit den Ressourcen (100Mhz,128K Ram) 
noch besser da als das 401-disco(84Mhz,64K Ram) und verwendet wohl auch 
kein USB...

Gruss
Jürgen

von Mike (Gast)


Lesenswert?

Ich habe mir die STM XCubeAudio Library gezogen. Dort ist ein 
MP3-Decoder namens Spirit enthalten. Auf den ersten Blick sehr schön, da 
die Einbindung des Decoder sehr einfach erscheint. Es gibt nur zwei 
Funktionen, eine zur Initialisierung, die andere zum häppchenweisen 
Dekodieren. Er scheint auch keinen dynamischen Speicher zu allozieren 
sondern verwendet ein festes Array als Workspace.

Leider bin ich an der Einbindung in mein Projekt gescheitert. Das Ding 
existiert nur als vorkompilierte Library, der Quelltext ist nicht 
verfügbar. Die Compileroptionen, mit denen die Bibliothek übersetzt 
wurde, sind nirgends dokumentiert. Unsinnigerweise wurde bei der 
Cortex-M4 Version -mfloat-abi=soft verwendet, so dass ich 
Gleitkommarechnung in Hardware in meinem Projekt nicht mehr verwenden 
kann. Mit der Krücke softfp hat es dann funktioniert. Leider hängt sich 
bereits die Initialisierungsfunktion beim Aufruf auf, die Ursache läßt 
sich mangels Quellcode nicht herausfinden. Eine Fehlerursache könnte 
sein, dass die Bibliothek 2 byte breite wchar verwendet, der Rest des 
Programmes aber 4 Byte. Umstellen mit -fshort-wchar geht leider nicht, 
da es dann woanders (stdlib?) knirscht.

Die Dokumentation des Decoders an sich ist gut, die Implementierung 
seitens STM äußerst lieblos.

@Jürgen Vielen Dank für den Link. Ich werde es noch mal mit Helix 
probieren, da gibt es wenigstens Quellcode. DSP-Funktionen scheint er 
tatsächlich in Form von 32x32->64 bit MAC - Instruktionen (SMLAL) zu 
nutzen.

von Jim M. (turboj)


Lesenswert?

Schau mal ob Du minimp3 https://github.com/lieff/minimp3 zum Laufen 
bekommst.

Das hatte ich hier auf einem Cortex-M7, braucht IIRC ca. 20KB Stack RAM.
Auf der Seite ist auch eine ältere Lib verlinkt die Integer Berechnungen 
macht.

Den Unterschied MP3 als Integer vs. MP3 als float hört man aber deutlich 
im direkten Vergleich, wenn die Sound Ausgabe einigermaßen rauschfrei 
ist.

von Mike (Gast)


Lesenswert?

Ich habe jetzt mal den Helix-Decoder verwendet. Das Abspielen 
funktioniert flüssig mit Bitraten von ca. 64kBit bei einem Prozessortakt 
von 48MHz. Die Soundqualität ist unabhängig von der Bit-und Samplerate 
leider recht mäßig, was vermutlich aber am Lautsprecher und nicht an der 
Software liegt. Für meine Zwecke aber ausreichend.

Mit der Verwaltung des MP3-Eingangsdatenpuffers habe ich aber noch ein 
Problem. Bei variablen Bitraten sind die MP3-Frames unterschiedlich 
lang, es ist also nicht immer möglich, vorauszuberechnen, wann der 
Puffer nachgeladen werden muss.Der Decoder rennt dann gegen das 
Pufferende und gibt die Fehlermeldung ERR_MP3_INDATA_UNDERFLOW zurück. 
Ich setze dann den Datenpointer auf den Frameheader zurück und starte 
den Dekodiervorgang noch einmal. Das scheint zu funktionieren, ist aber 
nicht sonderlich elegant. Gibt es eine Möglichkeit, die Framelänge vorab 
auszulesen?

von Uli (Gast)


Lesenswert?

Mp3 und aac-adts hat einen Header mit fester Struktur und da drin steht 
auch die Länge.

Aber es ist besser man hat einen eingangsspeicher der groß genug ist um 
mehr als 3 frames zu speichern und den nach decodierung (wenn genug raus 
ist) wieder auf füllen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.