STM32: MP3 softwaremässig decodieren und abspielen

Gast #4173099
Lesenswert?

Hallo Mikrocontrollerfreunde

ich möchte als kleines Sommerferieprojekt einen kleinen MP3 Player 
bauen. Und zwar möchte ich dazu einen STM32F407 einsetzen. Dieser soll 
von einer SD-Karte ein paar MP3-Files lesen, diese softwaremässig 
decodieren und dann abspielen.

Jetzt die Frage: es gibt ja den Helix-MP3 Decoder. Dieser setzt auf 
Festpunktarithmetik. Gibt es noch einen etwas moderneren Decoder, 
welcher auf einen STM32 portiert werden könnte?

Ich stelle mir das Abspielen einigermassen einfach vor: MP3-File von der 
SD-Karte in einen Buffer lesen, den Decoder darüber lassen und dann die 
decodierten Daten auf einen DAC ausgeben.

Meine offenen Fragen sind:

1. hat der STM32 genug Dampf, um das brauchbar zu realisieren?
2. gibt es nebst dem Helix evtl. noch einen etwas besseren Decoder?
3. Muss ich einen speziellen Audio-DAC verwenden, oder kann ich sonst 
irgend einen 16 Bit DAC benutzen? ich hätte einige 16 Bit DACs hier, 
können 200 kS/s, das sollte ja reichen.

Die Idee ist, dass man die SD-Karte vom PC aus mit MP3's belädt und in 
den Player gibt. Dieser soll dann auch noch ein rudimentäres 
Userinterface haben, um z.B. auf einem Graphikdisplay den abgespielten 
Titel anzuzeigen.
Gast #4173151
Lesenswert?

> Gibt es noch einen etwas moderneren Decoder,
> welcher auf einen STM32 portiert werden könnte?

Wie definierst du modern? ICh hab mir libmad auf einen SH7262 portiert. 
Die Arbeit bestand im Prinzip darin 1-2Zeilen Assembler anzupassen und 
ansonsten den Compiler drueber laufen zu lassen. Also keine grosse 
Sache.
Vermutlich ist der Assemblercode fuer ARM bereits enthalten.

> MP3-File von der SD-Karte in einen Buffer lesen, den
> Decoder darüber lassen und dann die decodierten Daten
> auf einen DAC ausgeben.

Im Prinzip ist das so. Allerdings zwei Dinge solltest du bedenken:

1. Die Ausgabe sollte im DMA laufen damit der Prozessor in der Zeit was 
anderes machen kann.

2. Der Buffer muss sehr gross sein. Es kommt immer mal vor das eine 
SD-Karte mal ein kurzes Paeuschen einlegt bevor sie Daten lieferter. Das 
ganze haengt natuerlich von der SD-Karte und der Bitrate ab. Ich habe 
bei mir im SH7262 fast 1MByte internes Ram. Das ist natuerlich 
grosszuegig. :-)
Ich kann aber durchaus mal beobachten das der Bufferfuellstand von den 
ueblichen 99% auf 80 oder 90% abfaellt wenn ich 320kbit/s abspiele.

> 1. hat der STM32 genug Dampf, um das brauchbar zu realisieren?

Ich denke schon. Ein SH2A schafft es ohne eingeschalteten Cache so 
gerade eben und mit Cache vollkommen problemlos. Da sollte ein 407 damit 
auch klar kommen.

> 3. Muss ich einen speziellen Audio-DAC verwenden, oder kann ich sonst
> irgend einen 16 Bit DAC benutzen? ich hätte einige 16 Bit DACs hier,
> können 200 kS/s, das sollte ja reichen.

Wie willst du die anschliessen? Es ist wichtig das der DAC im 
Hintergrund vom DMA bedient werden kann. Da bietet sich ein DAC mit I2S 
irgendwie an.

Ich verwende einen PCM3060. Ich meine man macht den ganzen Aufwand ja 
nicht damit am Ende Mist rauskommt oder?

Es mach im uebrigen wirklich Spass soetwas zu programmieren weil man 
jeden Programmierfehler hoeren kann. :-)

Olaf
Gast #4173163
Lesenswert?

Hallo,

ja, den Datentransfer werde ich natürlich mit DMA erledigen. Der DMA 
transportiert einerseits die Daten von der SD-Karte in den Buffer, als 
auch die Daten vom Decodierbuffer via SPI zum DAC (so zumindest die 
Idee). Der STM32 hat 192k internes SRAM. Meinst du, das reicht nicht? 
Ich möchte nur ungern einen externen RAM spendieren, denn mein Gehäuse 
soll so klein wie möglich werden damit der Player portabel ist (Platine 
soll 55 x 100mm nicht überschreiten). Ein kleines Display soll ja noch 
mit drauf.
Gast #4173177
Lesenswert?

> Der STM32 hat 192k internes SRAM. Meinst du, das reicht nicht?

Muss ich natuerlich etwas raten. Aber ich denke das wird reichen.

> Ich möchte nur ungern einen externen RAM spendieren, denn mein Gehäuse
> soll so klein wie möglich werden damit der Player portabel ist (Platine
> soll 55 x 100mm nicht überschreiten).

Nicht nur das. Externes Ram ist auch eine EMV-Schleuder. Damit steigt 
dann der Aufwand den man treiben muss bis das System wieder sauber 
laeuft. Sonst hoerst du die Speicherzugriffe im Audioteil. .-)

> Ein kleines Display soll ja noch mit drauf.

Klar. Sowas kostet keinen Aufwand. Ich hab beim mir das BLutdruck-Oled 
ueber SPI dran.

Olaf
Gast #4173233
Lesenswert?

Olaf schrieb:
>> http://hackaday.com/2015/06/06/esp8266-as-a-networ...
>
> Interessant. Ich haette nicht gedacht das der Empfaenger soviel
> Rechenleistung hat. Schade das da nirgendwo steht wieviel Kbit er
> abspielt. Es ist ein Unterschied ob man 64kbit oder 320 dekodiert.
>
> Olaf
>
> ps: Ich hoere gerade "Ark/Brendan Perry" ueber meinen Player. Da weiss
> man das sich die Arbeit gelohnt hat. .-)

Vom Github des Projekts:
>The MP3 decoder has been tested for bitrates up to 320KBit/s and sample
> rates of up to 48KHz.
#4173243
Lesenswert?

Hallo Globi,

es geht auch spartanischer, allerdings in schlechterer Qualität. Habe 
mal dieses "Bühneninstrument" für ein Theaterstück gebaut. Das Herzstück 
ist ein ATMega16 mit 8MHz getaktet.

Das es damit funktioniert, brauchte es ein paar Einschränkungen:

Nur ein Kanal (Mono), und nur 24kHz Abtastrate. Damit der µC nicht 
soviel herumrechnen muß, hatte ich die MP3-Files auf dem PC in 
entsprechende WAV-Files umcodiert. So braucht der Mega16 die Sounddaten 
nur von SD-Karte lesen und zum 16Bit-D/A ausgeben.

Das Ganze läuft auch ohne DMA, ohne Lücken in ausreichender Qualität.

Gruß. Tom

P.S. Nicht über den seltsamen Spicktext wundern, das Stück war auf 
russisch :)
Angehängte Dateien:
#4173261
Lesenswert?

Hallo Olaf,

es sollte Globi zeigen, daß durch auslagern der rechenintensiven Teile 
auf den PC, auch mit einfacherer Hardware gearbeitet werden kann. Die 
SD-Karten bieten Platz genug, um nicht zwingend mit MP3 zu arbeiten.

Was er letzlich macht, ist seine Sache.

Gruß. Tom
Gast #4173659
Lesenswert?

Tom Amann schrieb:
> Die
> SD-Karten bieten Platz genug, um nicht zwingend mit MP3 zu arbeiten.

Wird aber schwierig, denn mit mp3 kommst du gut an 10-fach kleinerei 
Dateien und es wird echt umständlich dauernd die Sachen umwandeln. Zum 
Schluss auch noch stundenlanges kopieren auf die 
Class-zu-lahm-SD-Karte....
#4173740
Lesenswert?

Hallo Olaf,

Spaß hat der Bau dieses Gerätes auch gemacht, und ein ruhiges Gewissen.

Es stammt noch aus der Zeit, als für MP3 Geräte Lizenzegebühren fällig 
waren. Seit 2011 sind die MP3 Patente in Europa abgelaufen und man kann 
sich frei austoben. Geräte für den amerikanischen Markt sind allerdings 
noch lizenzpflichtig.

Vielleicht baue ich mir selbst noch eine Art "Musikbox" mit MP3 für den 
Partykeller :)

Gruß. Tom
Gast #4174076
Lesenswert?

Ingo Less schrieb:
> Globi schrieb:
>> Der STM32 hat 192k internes SRAM
> Vorsicht, er hat 128kB RAM und 64KB CCM. Du kannst auch nicht über DMA
> auf den CCM zugreifen.

Aber das STM32F4DISCOVERY hat einen Audio DAC mit an Bord. Und Libraries 
für MP3s oder FLACs finden sich im Internet.
http://mikrocontroller.bplaced.net/wordpress/?page_id=2180
http://mikrocontroller.bplaced.net/wordpress/?page_id=2228
Gast #4174648
Lesenswert?

Hallo zusammen

sorry für meine späte antwort. Vielen Dank für eure Tipps. Noch eine 
Frage zum Helix-Decoder: kommt dieser mit MP3s variabler Bitrate 
zurecht?
Im Moment sehe ich noch nicht so recht, wie die Decodierung und das 
Abspielen vor sich geht. Irgendwo her muss ich für die Ausgabe ja noch 
die Samplerate her haben? das sehe ich noch nicht, wie ich die raus 
finde.
Admin Persönliche Seite #4175023
Lesenswert?

Globi schrieb:
> och eine Frage zum Helix-Decoder: kommt dieser mit MP3s variabler
> Bitrate zurecht?

Ja, variable Bitrate ist ganz normaler Bestandteil des MP3-Standards.

> Im Moment sehe ich noch nicht so recht, wie die Decodierung und das
> Abspielen vor sich geht. Irgendwo her muss ich für die Ausgabe ja noch
> die Samplerate her haben?

https://embdev.net/svnbrowser/arm-mp3-aac-player/trunk/play_mp3.c?revision=127&view=markup
1
MP3GetLastFrameInfo(hMP3Decoder, &mp3FrameInfo);
2
debug_printf("%lu Hz, %i kbps\n", mp3FrameInfo.samprate, mp3FrameInfo.bitrate/1000);
Gast #4178379
Lesenswert?

Hallo Andreas,

ich habe mir mal deinen Code angesehen von deinem mp3 Player. AAC 
scheint mir auch was sehr interessantes zu sein. Wenn ich allerdings im 
Helix AAC Decoder dieses SBR aktiviere, dann habe ich nicht mehr genug 
RAM :-( muss ich bei AAC noch was beachten, oder kann ich da die 
decodierung nach dem selben Schema machen wie MP3?

Momentan mache ich es so:
-Syncword finden
-den Readpointer um diesem Offset incrementieren
-Bei MP3: Aufruf von Getnextframeinfo, um die Samplerate zu erfahren
- dann decode() aufrufen

Den Audio DAC habe ich noch nicht dran, deshalb kann ich das auch nicht 
testen. Im Ausgabepuffer steht allerdings was drin :-)
Admin Persönliche Seite #4178819
Lesenswert?

Globi schrieb:
> Wenn ich allerdings im Helix AAC Decoder dieses SBR aktiviere

Brauchst du nicht für LC-AAC (=99% aller AAC-Dateien), nur für HE-AAC 
(manche Streams).

> muss ich bei AAC noch was beachten, oder kann ich da die decodierung
> nach dem selben Schema machen wie MP3?

Ist im Grunde schon implementiert:
https://embdev.net/svnbrowser/arm-mp3-aac-player/trunk/play_aac.c?view=markup
Beachten muss man, dass das MP4-Dateiformat um einiges komplexer ist als 
normale MP3-Dateien. Meine Implementierung hat für meine paar 
Testdateien funktioniert, ist aber sicher nicht 100% wasserdicht.

> Im Ausgabepuffer steht allerdings was drin

Das ist schon mal ein guter Anfang. Das richtige Buffer-Handling für 
unterbrechungsfreie Wiedergabe kann einen aber auch noch genug Nerven 
kosten ;)
Gast #4179158
Lesenswert?

Hallo Andreas

danke dir für die Info.
Ich habe bei meinem STM32 jetzt sämtliche Datenstrukturen ins CCM RAM 
gelegt. Das passt gerade so, wenn ich für den AAC und den MP3-Decoder 
dynamisches Memory benutze (man braucht ja immer nur einen Decoder aufs 
Mal).

Damit steht mir das gesamte restliche RAM von 128k als Puffer zur 
Verfügung. Ich habe ausgerechnet, dass ich bei 320kbit/s eine halbe 
Secunde puffern kann - das sollte also auch für die SD-Karte genügen, 
oder.
#4190821
Lesenswert?

Moin zusammen

ich habe das auch ausprobiert. Und zwar habe ich das Discovery Board 
benutzt und ein MP3 als Hex-Daten im Flash vom STM32 gespeichert und mit 
dem Helix-Decoder decodiert. Zum Absipielen habe ich den internen DAC 
des STM32 benutzt und habe den Systick-Timer verwendet, um die Samples 
in der richtigen zeitlichen Abfolge auszugeben. Es funktioniert sehr gut 
:-) allerdings ist die Audioqualität aufgrund der "nur" 12 Bits des int. 
DAC natürlich nicht so toll.

Frage: könnte man als Audio-DAC jeden beliebigen DAC nehmen, welcher 16 
Bits Datenbreite hat? oder auf was müsste ich achten?

Was schätzt ihr, hat der STM32 genug Dampf, um auch noch einen digitalen 
Klangregler zu implementieren? Den Klangregler würde ich mit 3 digitalen 
Filtern implementieren (Tiefpass, Bandpass, Hochpass) wo man dann die 
einzelnen Verstärkungsfaktoren verändern kann. Oder was gäbe es für eine 
andere Möglichkeit?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren