Forum: Mikrocontroller und Digitale Elektronik Wie MP3 mit STM32F4 und DMA Output sauber machen


von Dirk (Gast)


Lesenswert?

Hallo,

ich versuche gerade eine saubere MP3 Ausgabe hinzu bekommen.

Ich habe einen STM32F4, 2 DMA Speicher die ich abwechselnd ausgebe bzw 
mit Daten füllen muss.
Das mit dem Ausgeben klappt auch soweit ganz gut.

Aber der MP3 Decoder müsste angehalten werden, wenn der DMA Speicher 
voll ist und erst wieder weiter arbeiten, wenn ich auf den 2. Speicher 
umgeschaltet habe.
Soweit die Theorie.

Wie macht man das aber jetzt in der Praxis?
Ein warte auf freien Speicher habe ich noch nicht gefunden.

Sollte ich ein RTOS benutzen um hier besser eingreifen zu können?

Ich habe zur Zeit den Helix MP3 Decoder!
Später will ich aber MAD mal testen und FLAC & ACC sollen auch rein.

Viele Grüsse,
Dirk

von Uwe B. (derexponent)


Lesenswert?

Hi Dirk,

> Aber der MP3 Decoder müsste angehalten werden, wenn der DMA Speicher
> voll ist und erst wieder weiter arbeiten, wenn ich auf den 2. Speicher
> umgeschaltet habe.
> Soweit die Theorie.

so macht man das nicht
(das anhalten vom Decoder erzeugt ein knacken im Sound)

sondern eher in der Art :

1. beim "MP3-start" beide Puffer mit Daten füllen
2. wenn beide Puffer voll -> MP-3 von Puffer-A abspielen
3. wenn Ende von Puffer-A erreicht -> auf Puffer-B umstellen
4. MP-3 von Puffer-B abspielen
5. in der Zeit von (4) den Puffer-A mit neuen Daten füllen
6. wenn Ende von Puffer-B erreicht -> auf Puffer-A umstellen
7. MP-3 von Puffer-A abspielen
8. in der Zeit von (7) den Puffer-B mit neuen Daten füllen
9. GOTO 3

das auffüllen muss schneller sein, wie das abspielen
sonst hört man das durch knack-geräusche

Gruss Uwe

von Dirk (Gast)


Lesenswert?

Unterhalb Deiner Punkte 5/8 kommst Du doch irgendwann an den Punkt das 
Dein DMA Puffer voll ist.
Dann wird bei 3/6 der Puffer wieder umgeschaltet und jetzt kann ich 
weiter machen mit dem füllen -> aber nun im anderen Puffer.

Das meinte ich mit Warten.

Wenn ich X MB hätte und die DMA Puffer immer in unterschiedlichen längen 
benutzen könnte, dann würde ich einfach 1/2 Frames berechnen lassen und 
diese dann jeweils ausgeben.
Aber da ich innerhalb eines Frames den Puffer Umschalten muss, muss ich 
auch irgendwie warten.

Ich hoffe das ich da keinen Denkfehler drin habe, Bitte korrigiert mich.

Dirk

von Uwe B. (derexponent)


Lesenswert?

der DMA muss nicht warten

der DMA braucht die Länge vom Puffer die er füllen soll (z.B. 2048 
Bytes)
-> diese Information ändert sich in deinem Programm nie mehr und hängt
nur von der Puffer größe ab

er braucht die Startadresse vom Puffer den er füllen soll
-> diese Adresse ändert sich zyklisch zwischen Puffer-A (Adr.0)  und 
Puffer-B (Adr.0)

und er braucht ein "Startimpuls"
dannach kopiert er brav 2048 Bytes so schnell er kann und wartet dann
auf den nächsten "Startimpuls"

du musst also an den zwei Stellen den DMA transfer starten :

5.) -> DMA Start-Adr = Puffer-A
    -> DMA start

8.) -> DMA Start-Adr = Puffer-B
    -> DMA start


P.S.

Frage .... benutzt du den DMA um die Daten vom RAM als TON-Signal
auszugeben oder benutzt du den DMA um die Daten
von einem Medium zu lesen und in den RAM Puffer zu füllen
(ich glaube da reden wir aneinander vorbei :-)

von Dirk (Gast)


Lesenswert?

Mit dem DMA werden die Daten ausgegeben über I2S.
Das Prinzip der Ausgabe ist mir schon klar, der Teil arbeitet auch schon 
wunderbar (2*8Kb).

Ich habe gerade was gefunden wo von 2304 Samples pro Ausgangsspeicher 
steht.
Wenn das immer nur so wenig ist was da raus kommt dann sollte ich das 
hin bekommen.
Ob das allerdings auch bei jeder Samplefrequenz so aussieht kann ich 
nicht beurteilen?

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.