Forum: Mikrocontroller und Digitale Elektronik Cortex-M4 mit 168MHz zu langsam für MP3 Wiedergabe?


von Star K. (starkeeper)


Lesenswert?

Hallo,
ich habe einen STM32F4 (Cortex-M4) mit 168MHz laufen und versuche 
MP3-Dateien zu dekodieren. Dazu verwende ich den Dekoder des Helix 
Projektes.
Leider will es mir nicht gelingen während des Abspielens die ganze Datei 
zu dekodieren, was scheinbar an der Rechenleitung liegt. Das reine 
Dekodieren dauert auf dem Mikrocontroller 16ms, dazu kommen 
normalerweise noch ca. 6ms für das Lesen der Daten vom USB-Stick. Doch 
auch wenn die Daten vom internen Flash kommen sind die 16ms 
Verarbeitungszeit viel zu lang.

Nach dem Dekodieren eines MP3-Frame habe ich 2304 Byte Daten im RAM 
liegen die per DMA an einen externen DAC gesendet werden. Der benötigt 
zum Abspielen aber nur 12ms. Sodass ich niemals so schnell dekodieren 
kann wie ich wiedergeben muss.

Hat jemand ähnliche Erfahrungen mit dem Codec gesammelt?

Angeblich soll ein 30MHz Cortex-M3 ausreichend sein um einen kostanten 
MP3-Datenstrom mit 320kbps zu dekodieren und wiederzugeben.

Gruß starkeeper

: Bearbeitet durch User
von Tobi D. (fanti)


Lesenswert?

vielleicht ist deine Programmierung nicht auf das Timing optimiert?

Uwe hat da schon eine super Arbeit gemacht, funktioniert bei mir 
perfekt:
http://mikrocontroller.bplaced.net/wordpress/?page_id=2228

von Jim M. (turboj)


Lesenswert?

Schalte mal den Optimizer vom C Compiler an (GCC: -O3).

Ansonsten versuche anderen Code zu benutzen, IIRC hatte mpg123 damals 
einen Integer Modus für die (zu langsamen) 486ger.

von Star K. (starkeeper)


Lesenswert?

Danke für die Tipps! Ich werde mir mal den Code von der Seite anschauen, 
ein Discovery-Board habe ich hier auch noch rumfliegen. Dann kann ich 
mal an dem Projekt messen wie lange dort ein Dekodieren dauert.

Die optimierung von meinem Kompiler habe ich schon eingeschaltet, 
allerdings verwende ich den IAR ARM Compiler, wobei ich denke, dass die 
in Sachen Optimierung auch sehr gut sein sollten.

von Star K. (starkeeper)


Lesenswert?

Also ich habe nun testhalber mal ein leeres Demoprojekt aufgesetzt in 
dem ich lediglich einen MP3-Frame aus dem Flash dekodiere und im RAM 
ablege. Es geschieht sonst nichts nebenbei. Die Messung ergibt auch hier 
eine Dauer von 14ms für das Dekodieren dieses einen Frame (320kbps).

Es ist mir noch immer ein Rätsel wie andere es schaffen MP3 on-the-fly 
zu dekodieren und sogar noch Zeit für eine GUI oder ähnliches zu haben.

von Kai G. (kpl)


Lesenswert?

Hmm... Mit dem helix mp3 codec hab ich "damals" auf nem 60MHz arm7tdmi 
320kbps in echtzeit dekodieren koennen. Genug Zeit fuer die gui war auch 
noch ueber.

Die low level dsp funktionen liegen fuer verschiedene targets vor, 
glaube z.B. arm7tdmi, arm9, intel, ... Oder auch eine völlig 
platformunabhängige, die natürlich schnarchlangsam ist.

Was hast du denn da ausgewählt?

von old man (Gast)


Lesenswert?

Der Helix-Decoder hatte am Anfang keine asm-Optimierung für die Cortexe. 
Such mal nach der AN11178 von NXP. Da sind die Helix-Quellen incl. Asm 
für GCC, Keil und IAR dabei. Eventuell wird das damit noch ein wenig 
schneller. Vor allem weil der da auf einem LPC1769 läuft und der hat 
weniger Power als dein F4.

von Jan (Gast)


Lesenswert?

Irgendwie muss es wohl gehen, schließlich gab es auch für einen 486er 
mit 40MHz MP3-Decoder,die ohne Aussetzer Mussigg gespielt haben. Oder 
kann man das nicht vergleichen?

von m.n. (Gast)


Lesenswert?

Star Keeper schrieb:
> allerdings verwende ich den IAR ARM Compiler,

ART hast Du aktiviert? Alternativ könntest Du den Code im RAM laufen 
lassen; schneller geht es dann nicht mehr.

von Olaf (Gast)


Lesenswert?

> Es ist mir noch immer ein Rätsel wie andere es schaffen MP3 on-the-fly
> zu dekodieren und sogar noch Zeit für eine GUI oder ähnliches zu haben.

Das geht ganz einfach, ich verwende einen SH2A und habe mir erst die 
Finger Wund optimiert bis ich 320kbit mit der libmad laufen hatten. Und 
ganz am Ende ist mir aufgefallen das ich vergessen hatte den Cache 
meines Controllers einzuschalten. Nachdem ich das dann nachgeholt habe, 
funktioniert es mit jeder Menge Reserve. :-)

Wichtig ist das dein Code viel gleichzeitig macht. Bei mir erfolgt die 
Ausgabe an den Codec im DMA. Ausserdem brauchst du fuer 320kbit 
ordentlich Ram. Ich glaube wenigstens 50-100kByte sind sinnvoll. Es 
passiert dir sonst im Betrieb schonmal das eine SD-Karte die Daten nicht 
schnell genug nachliefert. (haengt ein bisschen von der Karte ab)

Ansonsten bau dir doch ein paar Debuginfos in deinen Code ein und schaue 
wo er genau seine Zeit braucht. So hab ich das bei mir auch gemacht.

Und erinnere dich daran das C Zeiger kennt. Komm nicht auf die bloede 
Idee deine Buffer umzukopieren. Das gilt auch fuer FIFO und DMA.

Olaf

von Star K. (starkeeper)


Lesenswert?

Also ich denke du meinst die assembly Funktionen in der Datei assembly.h 
dort sind für verschiedene Targets und Compiler Beispiele hinterlegt. Da 
sind aber nur Hilfsfunktionen für mathematische Berechnungen drin, für 
die der Prozessor keine eigenen Befehle hat.
Dort habe ich mich an die Implementierung für ARM mit gcc gehalten. 
Zuletzt habe ich nun die Implementierung aus dem Projekt das hier oben 
im Thread verlinkt ist benutzt. Das unterscheidet sich aber nicht 
wirklich von dem was ich vorher hatte, messbar gabs da keinen 
Unterschied.

Ich habe nun auch mal mit Hilfe eines Timers eine PWM erzeugt um den 
Takt zu messen. Wenn ich die PWM-Frequenz auf den Ursprungstakt 
zurückrechne komme ich tatsächlich auf die 168MHz. Der Mikrocontroller 
scheint also auch mit dem vollen Takt zu arbeiten.

Vielleicht habe ich ein Problem bei dem Abspielen der Daten? Wie lange 
ist denn die Tonsequenz die ich aus einem MP3-Frame holen kann. Ist das 
immer gleich lang oder hängt das mit der Datenrate von 320kbps zusammen?

von PittyJ (Gast)


Lesenswert?

Ich hatte im letzten Jahrtausend auch schon MP3-Abspieler auf meinem 
100MHz 486 DX4. mpg123 hat das wunderbar gemacht.
Einfach mal die alten Sourcen und libmp3 Bibliotheken besorgen.
Evtl kommen die mit 320 KBit oder Variabler Kodierung nicht klar. Aber 
mit normalen 128 KBit/sek Dateien sollten 168 MHz ausreichen.

von Star K. (starkeeper)


Lesenswert?

old man schrieb:
> Der Helix-Decoder hatte am Anfang keine asm-Optimierung für die Cortexe.
> Such mal nach der AN11178 von NXP. Da sind die Helix-Quellen incl. Asm
> für GCC, Keil und IAR dabei. Eventuell wird das damit noch ein wenig
> schneller. Vor allem weil der da auf einem LPC1769 läuft und der hat
> weniger Power als dein F4.

Okay die Jungs von NXP sind gut! Mit deren Implementierung kann der 
Frame in 5,2ms dekodiert werden, was ja deutlich unterhalb der 
Abspieldauer liegt.

Vielen Dank für den Tipp!

Damit kann man doch arbeiten, eventuell überlege ich mir noch den Code 
in das RAM zu packen, aber auch nur wenn es sein muss. Den 
ART-Accelerator habe ich schon aktiv, sodass da nix mehr raus zu holen 
ist.

von Marian (phiarc) Benutzerseite


Lesenswert?

Jan schrieb:
> Irgendwie muss es wohl gehen, schließlich gab es auch für einen 486er
> mit 40MHz MP3-Decoder,die ohne Aussetzer Mussigg gespielt haben. Oder
> kann man das nicht vergleichen?

Der Cortex-M4 ist wahrscheinlich perfomanter/Instruktion als der 486er 
:D

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Star Keeper schrieb:
> Wie lange
> ist denn die Tonsequenz die ich aus einem MP3-Frame holen kann. Ist das
> immer gleich lang oder hängt das mit der Datenrate von 320kbps zusammen?

Also das was als PCM rauskommt ist immer gleich lang.
So 4608 Audiobytes, also 1152 PCM Frames.

Was als MP3 vorne reinkommt ist immer unterschiedlich lang bei 
unterschiedlicher Bitrate (iwie logisch).
Bei 44,1kHz Samplerate ist ein MP3 Frame auch bei CBR immer 1byte 
länger/kürzer als sein Nachbar durch nen Paddingbyte.

von Tobias P. (hubertus)


Lesenswert?

Hallo,
mit dem Helix habe ich auch einmal rumgepröbelt. Allerdings habe ich da 
nichts zum Laufen bekommen. Du sagst, du hättest ein Minimalbeispiel, 
was auf dem Discoveryboard läuft.... Könntest du das hier mal hochladen, 
damit man da mal reinschauen kann? da wäre ich sehr interessiert dran.

Was verwendest du für einen DAC?

Gruss!

von Star K. (starkeeper)


Lesenswert?

Moin,
also mein Prolem ist gelöst, ich kann nun MP3 mit 320kbps abspielen. 
laut FreeRTOS Statistik liegt die Last bei ca. 40%!

Ich hatte im Grunde zwei Probleme:
1. Nach dem Dekodieren eines MP3 Frame liegen 2304 samples im RAM. Die 
habe ich per DMA zum DAC transferiert. Allerdings ist ein sample 16Bit 
und nicht 8Bit sodass ich lediglich die Hälfte eines sample abgespielt 
habe, die Spielzeit verdoppelt sich also und schafft so mehr Zeit für 
das Dekodieren des nächsten Sample.

2. Die Performance beim Dekodieren war zeimlich mieß und lag Anfangs bei 
12ms. Nachdem ich den optimierten Code aus der AN11178 von NXP benutzt 
habe reduzierte sich die Zeit auf 5ms!

Nun klappt alles Prima, vielen Dank für die starke Hilfe!


Tobias Plüss schrieb:
> Hallo,
> mit dem Helix habe ich auch einmal rumgepröbelt. Allerdings habe ich da
> nichts zum Laufen bekommen. Du sagst, du hättest ein Minimalbeispiel,
> was auf dem Discoveryboard läuft.... Könntest du das hier mal hochladen,
> damit man da mal reinschauen kann? da wäre ich sehr interessiert dran.
>
> Was verwendest du für einen DAC?
>
> Gruss!

Mein Minimalbeispiel umfasst nur das Initialisieren des Helix-Codec und 
das entschlüsseln eines vorgegebenen MP3 Frames, kein Abspielen. An 
deiner Stelle würde ich mit dem Projekt beginnen, dass weiter oben 
gepostet wurde:
http://mikrocontroller.bplaced.net/wordpress/?page_id=2228

Das soll auf einem Discovery-Board laufen. Lediglich den Helix-Codec 
würde ich gegen den aus der NXP-AppNote ersetzen, dann läuft alles viel 
performanter. Das betrift aber eventuell nur den IAR-Kompiler.

: Bearbeitet durch User
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.