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.
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.
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
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.
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.
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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.