Riesenringpuffer

  • Themenstarter Gelöschtes Mitglied 9001
  • Beginndatum
Diskutiere Riesenringpuffer im Allgemeine Java-Themen Bereich.
G

Gelöschtes Mitglied 9001

Hallo Forum,

wie man einen Ringpuffer implementiert, ist mir klar, schon gefühlt hundertmal gemacht. Nun sind die Bedingungen aber etwas ungünstig: der Puffer soll bis zu einige Gigabyte umfassen (~5GB), der verfügbare Arbeitsspeicher ist < 1GB, Festplatte ist eine Micro-SD-Karte (ja, es ist ein Raspi).
Bei jedem Schreib- und Lesevorgang werden Datenblöcke von ca 1-2 MB in den Puffer eingefügt/herausgeholt. Mein erster Gedanke war natürlich, FileChannel zu verwenden. Dann erinnerte ich mich, dass SD-Karten es nicht so sehr mögen, häufig beschrieben zu werden. Also müßte man wenigstens teilweise den Puffer im Arbeitsspeicher vorhalten.
Die (Audio-)Eingabedaten kommen von einem Audiointerface in schneller Folge in den Puffer. Die Daten werden von einem Server-Prozess aus dem Puffer herausgeholt und an einen Client ausgeliefert, der per Wlan verbunden ist. Diese Verbindung kann sehr gut sein - in dem Fall würden wohl nur einige MB des Ringpuffers belegt sein. Die Verbindung kann aber auch sehr schlecht sein und gelegentlich unterbrochen werden. Für genau diesen Fall muß der Puffer sehr groß sein, um sicherzugehen, dass keine Daten verloren gehen. (Dass die Audiolatenz dann enorm ist, ist richtig, spielt aber bei meinem Anwendungszweck keine Rolle).

Mich würden eure Gedanken dazu interessieren. Ist das mit den SD-Karten immer noch so? Gibt es bereits vorhandene Ansätze für irgendwie geartete zweistufige Ringpuffer, die teils im Ram, teils auf dem Dateisystem agieren?
 
Thallius

Thallius

Ich frage mich wie du auf 5GB kommst. Das sind ja fast 20 Stunden unkomprimiertes Audio in CD Qualität..... So schlecht kann die Lazenz ja wohl gar nicht sein....
 
G

Gelöschtes Mitglied 9001

6 Kanäle, 24bit, 96 kHz. 5GB sind da ca. 51 Minuten. Da ich den Aufnahmeprozess nicht überwachen kann, da ich selbst spiele, muss das System einen ausreichend großen Puffer haben für den Fall, dass unbemerkt die Verbindung abbrach, was bei einer Entfernung von 30m durchaus passieren kann.
Der Raspi hat 1 GB Ram, der natürlich dem Programm nicht in Gänze zur Verfügung steht, da ja auch noch andere Programme laufen. Gehen wir mal von 500MB benutzbarem Speicher aus, sind das dann nur noch 5 Minuten Puffer. Für den Ernstfall zu wenig, wenn z.B. das aufzunehmende Stück 12 Minuten dauert und die Verbindung nach 4 Minuten unbemerkt abbrach.
Daher suche ich also eine effiziente Möglichkeit, einen Ringpuffer teilweise auf der SD-Karte liegen zu haben.
 
Thallius

Thallius

und warum kompremierst du die daten nicht vorm speichern? Oder brauchst du unbedingt raw format?
 
G

Gelöschtes Mitglied 9001

Ja, ich brauche unbedingt raw.
Ich würd mich wirklich gerne eher über das Thema Ringpuffer unterhalten als über Sinn und Zweck, warum und wieso ich meine Tonaufnahme mache.
 
L

LimDul

Was du probieren könntest, anstelle das Problem in Java zu lösen - einfach 10 GB Swap Space anlegen und der JVM entsprechend RAM zur Verfügung zu stellen. Dann löst das OS das Problem für dich..
 
Thallius

Thallius

Ja, ich brauche unbedingt raw.
Ich würd mich wirklich gerne eher über das Thema Ringpuffer unterhalten als über Sinn und Zweck, warum und wieso ich meine Tonaufnahme mache.
Ich mag es wenn Leute so überheblich sind, daß sie nicht mal darüber nachdenken das ihr Konzept vielleicht scheiße sein könnte.
 
L

LimDul

Naja, ich kann die Anforderung schon verstehen, dass man die RAW-Daten übertragen möchte. Und 5 GB sind jetzt auch nicht viele Daten.

Wenn man es in Java umsetzen würde, würde ich es wie folgt machen:

* Einen Ringpuffer der tatsächlich komplett über FileChannel geht.
* Da eine CachedRingpuffer drum wrappen, der einen Cache von X Megabyte hat und wie folgt arbeitet:

Beim Schreiben
- Wenn der FileChannelPuffer nicht leer ist => FileChannel Schreiben
- Wenn der FileChannelPuffer leer ist und Platz im Cache => In den Cache hinten anhängen
- Wenn der FileChannelPuffer leer ist und zuwenig Platz im Cache => FileChannel Schreiben

Beim Lesen
* Aus dem Cache lesen
* Danach, wenn der FileChannelPuffer nicht leer ist, den Cache aus dem FileChannelPuffer wieder auffüllen bis entweder Cache voll oder FileChannelPuffer leer

Etwas aufpassen muss man mit MultiThreading, dass das klappt. Ggf. muss man da mit einer gemeinsamen Semaphore arbeiten.
 
G

Gelöschtes Mitglied 9001

Was du probieren könntest, anstelle das Problem in Java zu lösen - einfach 10 GB Swap Space anlegen und der JVM entsprechend RAM zur Verfügung zu stellen. Dann löst das OS das Problem für dich..
Ja, darüber habe ich nachgedacht. Jedoch: Gängige Ringpufferimplementationen arbeiten ja auf einem linearen Speicher und wandern durch den von vorn bis hinten durch. Selbst wenn die Nutzdaten nur einen Bruchteil der Kapazität des Speichers betragen, wird so der gesamte Speicher genutzt, was dazu führt, dass das Betriebssystem permanent auch die ungenutzten Daten zwischen Harddisk und Ram hin und herschaufeln wird. Ich glaube nicht, dass das effizient sein wird.
 
L

LimDul

Ja, darüber habe ich nachgedacht. Jedoch: Gängige Ringpufferimplementationen arbeiten ja auf einem linearen Speicher und wandern durch den von vorn bis hinten durch. Selbst wenn die Nutzdaten nur einen Bruchteil der Kapazität des Speichers betragen, wird so der gesamte Speicher genutzt, was dazu führt, dass das Betriebssystem permanent auch die ungenutzten Daten zwischen Harddisk und Ram hin und herschaufeln wird. Ich glaube nicht, dass das effizient sein wird.
Stimmt, du bräuchtest dann eine Implementierung, die den Speicher dynamisch verwaltet z.B. in Form einer doppelt verketteten Liste (damit man hinten anhängen kann und vorne wegnehmen kann). Das wäre dann allerdings kein Ringpuffer mehr sondern ein potentiell unendlich großer Puffer.
 
G

Gelöschtes Mitglied 9001

* Einen Ringpuffer der tatsächlich komplett über FileChannel geht.
* Da eine CachedRingpuffer drum wrappen, der einen Cache von X Megabyte hat und wie folgt arbeitet:

Beim Schreiben
- Wenn der FileChannelPuffer nicht leer ist => FileChannel Schreiben
- Wenn der FileChannelPuffer leer ist und Platz im Cache => In den Cache hinten anhängen
- Wenn der FileChannelPuffer leer ist und zuwenig Platz im Cache => FileChannel Schreiben

Beim Lesen
* Aus dem Cache lesen
* Danach, wenn der FileChannelPuffer nicht leer ist, den Cache aus dem FileChannelPuffer wieder auffüllen bis entweder Cache voll oder FileChannelPuffer leer
Das klingt vielversprechend! Werde ich ausprobieren.
 
G

Gelöschtes Mitglied 9001

Stimmt, du bräuchtest dann eine Implementierung, die den Speicher dynamisch verwaltet z.B. in Form einer doppelt verketteten Liste (damit man hinten anhängen kann und vorne wegnehmen kann). Das wäre dann allerdings kein Ringpuffer mehr sondern ein potentiell unendlich großer Puffer.
Das würde gehen. Man müßte die ankommenden Daten in Blöcke aufteilen, die nicht zu groß und nicht zu klein sind. Und damit das ganze nicht ins Unendliche wächst, die Menge mit einem Zähler überwachen und ggf. Datenblöcke verwerfen. Oder man fragt den verfügbaren Speicher ab, das könnte aber evtl. etwas teurer sein.
 
L

LimDul

Ja, ich denke die einzelnen Listen-Elemente könnten z.B. 1 MB Blöcke sein, die dann als Cache funktionieren. Und ein Listenelement wird erst entfernt, wenn es komplett geleert ist.
 
G

Gelöschtes Mitglied 9001

Praktischerweise überläßt man das Auslagern, wie du schon schriebst, dem Betriebssystem oder aber man lagert die frischsten Blöcke manuell aus, wenn der Speicher knapp wird, vermerkt im Block den Verweis und holt die Daten wieder ein, wenn sie gelesen werden sollen.
 
G

Gelöschtes Mitglied 9001

Gerade festgestellt: man kann beim Starten eines Java-Programmes den Heap-Speicher nicht auf einen größeren Wert einstellen als physikalisch vorhanden ist. Also muss man das Auslagern selbst übernehmen.
 
G

Gelöschtes Mitglied 9001

Es geht hier um eine professionelle Tonaufnahme mit 6 Mikrofonen = 6 Kanäle in 24bit und 96kHz Auflösung. MP3 hat im professionellen Umfeld nichts zu suchen und ist vom Fraunhofer Institut (=Erfinder von MP3) schon lange als veraltet bezeichnet worden. Bei Tonaufnahmen wird einzig und allein unkomprimierter Ton verwendet.
 
Thema: 

Riesenringpuffer

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben