Forum: Mikrocontroller und Digitale Elektronik Konzipierung I2S mit oder ohne DMA


von Bülent C. (mirki)


Lesenswert?

Hallo zusammen,

für mein zweites Hobby - Musik Machen - konzipiere ich mir derzeit eine 
Sampler-Box. Im Grunde genommen soll es nur in der Lage sein Sound 
aufzunehmen, zu verarbeiten, und auszugeben.
Im Moment habe ich weder einen Schaltplan gezeichnet und auch noch keine 
Zeile Code geschrieben.
Vorgaben habe ich mir unter anderem diese gemacht:
STM32F4
I2S Audio DAC für PCM 16Bit
Audio Samples mit 8Khz Samplingrate
Audiosamples mit ca. 12k Werten.
Flash für >32Mbyte

Haken tut es beim I2S Audio DAC, diesen würde ich gerne per DMA 
befeuern, um ein aufgenommenes Stück im Loop abzuspielen.
Das aufgenommene Stück werde ich durch ein paar Filter jagen müssen. Die 
Filter die ich verwenden möchte ändern nicht die Größe.
Nur wenn ich ein re-sampling während des abspielen im Loop mache, also 
die Abtatsrate ändere, verändert sich die Größe. Für DMA wäre dies ein 
KO Kriterium, da DMA feste Größen behandelt. Ich könnte zwar das 
Resultat des Re-Samplings auf die benötigte Größe abschneiden, aber dann 
könnte ich knacken im Loop haben, weil ich evtl. nicht an der richtigen 
Stelle schneiden würde.
Ich könnte mir zwar das Leben einfach machen und die Abstastrate direkt 
am I2S DAC ändern, aber das geht nicht, da ich im Stereo Betrieb 
arbeiten muss, um zwei Kanäle unabhängig zueinander steuern und befeuern 
zu können.

Das Thema ist vielleicht zu speziell, aber vielleicht könnte mir jemand 
netterweise den einen oder anderen Tip geben.

VG,
Bülent

von Clemens L. (c_l)


Lesenswert?

Bülent C. schrieb:
> Nur wenn ich ein re-sampling während des abspielen im Loop mache, also
> die Abtatsrate ändere, verändert sich die Größe. Für DMA wäre dies ein
> KO Kriterium, da DMA feste Größen behandelt.

Normalerweise muss ein Synthesizer in der Lage sein, mehrere Töne 
zusammenzumixen. (Wie du bemerkt hast, brauchst du so etwas für Stereo.)

In der Praxis wird das so implementiert, dass die CPU Blöcke fester 
Größe berechnet (z.B. 256 Samples), und diese dann per DMA ausgegeben 
werden. Die Größe eines Blocks hat mit der Loop-Größe exakt gar keinen 
Zusammenhang, aber das kannst du eh nicht vermeiden.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Die Benutzung des DMA ist nicht zwingend. Du kannst auch den I2Sn Empty 
Interrupt (eigentlich SPIn Empty) benutzen, um den DAC mit Daten zu 
befüllen.
Die ISR füttert dabei abwechselnd linken und rechten Kanal mit Daten aus 
den Audiopuffern. Nebenbei kann die ISR auch gleich die 
Pointerinkrementierung usw. machen.
Die Anpassung an die Samplerate geschieht dabei automatisch.

: Bearbeitet durch User
von Bülent C. (mirki)


Lesenswert?

Danke für die Hinweise an euch beiden.

hierbei habe ich zwei Methoden entnehmen können:

a)
Der feste DMA Speicherblock wird aus einem "Hilfsspeicher", wo ich dass 
Ergebnis eines re-sampling/Filters ablege, blockweise gefüttert.

b)
Keinen DMA zu nutzen, und dabei das dezunieren/interpolieren beim 
resamplen aus dem - bzw. mit dem - I2Sn Empty Interrupt zu steuern.

Ich hoffe die Ansätze richtig verstanden zu haben.
Beides hat seinen charm, nur bei b) sehe ich ein paar Nachteile mehr als 
wie bei a). Hier würde ich den Controller evtl. zu sehr belasten. Bei a) 
sehe ich das Problem die DMA Blöcke rechtzeitig "mit den richtigen" 
samples zu füllen.

von Clemens L. (c_l)


Lesenswert?

Bülent C. schrieb:
> Der feste DMA Speicherblock wird aus einem "Hilfsspeicher", wo ich dass
> Ergebnis eines re-sampling/Filters ablege, blockweise gefüttert.

Nein. Du hast zwei DMA-Speicherblöcke; während einer ausgegeben wird, 
wird der andere berechnet.

von Bülent C. (mirki)


Lesenswert?

Clemens L. schrieb:
> Bülent C. schrieb:
>> Der feste DMA Speicherblock wird aus einem "Hilfsspeicher", wo ich dass
>> Ergebnis eines re-sampling/Filters ablege, blockweise gefüttert.
>
> Nein. Du hast zwei DMA-Speicherblöcke; während einer ausgegeben wird,
> wird der andere berechnet.

Wie soll das gehen wenn ich aus dem Buffer einen Block interpoliere oder 
dezuniere?

von Olaf (Gast)


Lesenswert?

> Das Thema ist vielleicht zu speziell, aber vielleicht könnte mir jemand
> netterweise den einen oder anderen Tip geben.

Ich verstehe nicht so ganz dein Problem, aber im Prinzip laeuft das so.

Du hast drei Speichbloecke. Auf einem laeuft der DMA und gibt das 
aktuelle Sample aus. Der zweite Block ist bereits fertig und wartet 
darauf das der IRQ vom DMA kommt damit du etwas zum umschalten hast. Den 
dritten Block fuellst du mit neuen Daten. Und dann laeuft das immer der 
Reihe nach durch.

Wenn du genug Speicher hast dann kannst du dir auch aus vielen solcher 
Bloecke eine FIFO aufbauen. So mache ich das bei meinem MP3-Player. Das 
hat dann den Vorteil das die Ranschaffung neuer Daten auch mal laenger 
dauern darf. (z.B wenn die SD-Karte rumzickt)

Auf DMA wuerde ich keineswegs verzichten. Das wuerde dein Restsystem zu 
sehr unter Stress setzen.

Olaf

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Clemens L. schrieb:
> Nein. Du hast zwei DMA-Speicherblöcke; während einer ausgegeben wird,
> wird der andere berechnet.

Bei Stereo sogar vier. Wobei die Verwaltung der beiden Kanäle ein wenig 
tricky ist, vor allem, wenn auf den Audiopuffern unterschiedliche, nicht 
schon fertig ineinander verschachtelte Datenblöcke stehen.

Das 'SPIn_Empty_ISR' Prinzip läuft hier auf dem STM32F407 mit 168Mhz auf 
einen 4-Kanal Tracker (ein Retrofit einer alten Fostex 280) und nebenbei 
macht die Kiste auch USB MSC Host, emuliert ein Cassettenlaufwerk für 
das Original Paneel, bedient ein serielles Terminal und nimmt wahlweise 
auf 1-4 Kanäle auf.
Da ist von Auslastung noch nix zu merken.

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.