ein Speicher von 80kB fest reserviert.
Jetzt habe ich Play von SD-Card dazu gebaut, läuft auch soweit alles
wunschgemäß. Der Stream-File-Buffer bleibt dabei reserviert (für das
zurückschalte auf Stream-Play zur Laufzeit auch so nötig, selbst ein
ESP32 hat begrenzten Ram und wenn ich den Freigebe wissen nur die
Götter, ob ich ihn jemals wiederbekomme(Fragmentierung des Ram).
Jetzt zum Thema: ich möchte in diesem Bereich, der ja bei
preallocateBuffer beginnt, ein String oder c-String array anlegen für
die Titelliste der SD-Card.
Das darf beim Umschalten auf Stream-Play gern überschrieben oder
entfernt werden, es kann bei SD-Card-Start neu angelegt und/oder neu
beüfllt werden.
Es wird NIE gleichzeitig das Array und der Stream-File-Buffer benutzt.
Hier verläßt es mich jetzt komplett...
Nochmal aus dem aktuellen Source:
1
// hier wird der Bereich bei Streamply benutzt
2
buff = new AudioFileSourceBuffer(file, preallocateBuffer, preallocateBufferSize);
3
4
// und hier das Playende:
5
if (buff)
6
{
7
buff->close();
8
delete buff;
9
buff = NULL;
10
}
Bei SD-Card wird das nie aufgerufen, ich hätte dort dann eben gern ein
String titelliste[500];
oder auch ein Array[500] of Char-Arrays[100];
angelegt ab preallocateBuffer
und am Ende wieder entfernt.
Gruß aus Berlin
Michael
Drei Dinge die evtl. relevant sind:
-std::variant (oder boost::variant oder union wenn std < c++17)
-allocator (vermutlich viel Arbeit)
-placement new (vermutlich keine gute Idee, wenn du fragen musst ;-) )
Michael U. schrieb:> // hier wird der Bereich bei Streamply benutzt> buff = new AudioFileSourceBuffer(file, preallocateBuffer,> preallocateBufferSize);
Hier wird eine Instanz der Klasse AudioFileSourceBuffer
angelegt. Was hat die denn für Member? Wird in der Klasse
Speicher dynamisch reserviert oder als Value-Member?
merciless
Hallo,
es wird ein Char-Buffer angelegt, der bei preallocateBuffer beginnt und
preallocateBufferSize lang ist. Der wird bei Playende eben mit
1
// und hier das Playende:
2
if (buff)
3
{
4
buff->close();
5
delete buff;
6
buff = NULL;
7
}
für die Klasse komplett beendet und beim nächsten Titel wieder erzeugt.
Das stört mich bei meinen Absichten nicht, Stop wurde da schon
aufgerufen.
Ich habe jetzt mal mit wenig Sachkenntnis probiert:
Das macht soweit, was ich mir vorstelle, ich werde es erstmal als
Char-Array benutzen, ich habe 80kB in der malloc-Reservierung, ins Array
sollen max. 500 Strings mit maximal 100 Zeichen (99 und \0).
Die Zugriffpositionen kann ich ja problemlos berechnen.
Wenn ich aus dem SD-Card Mode rausgehe setze ich eben titelliste = NULL;
dann kann ich beim Benutzen gegenprüfen, ob ich das Array schon gebaut
habe.
Ein String-Array mit der Arduino Stringklasse wäre beim Füllen und
benutzen nur meiner Bequemlichkeit entgegengekommen...
Danke für die Anregungen, ich werde mal meine Bildungslücken auf meine
alten Tage noch ewas aufbessern.
Gruß aus Berlin
Michael
Erstens:
Wenn du dem Buffer immer brauchst und nie freigeben willst, dann würde
ich ihn fest anlegen, und nicht malloc() verwenden.
Zweitens:
Wenn du den Buffer wechselweise für verschiedene Zwecke nutzen möchtest,
Dann entweder eine Union verwenden, oder die zu verwendenden Pointer
casten.
Hier die Cast Variante
Hallo,
Arduino Fanboy D. schrieb:> Erstens:> Wenn du dem Buffer immer brauchst und nie freigeben willst, dann würde> ich ihn fest anlegen, und nicht malloc() verwenden.
naja, das ist in der ESP8266Audio Lib so drin und da habe ich keinen
zwingenden Grund, das zu ändern. Er holt sich den Buffer sowieso in
setup(), das stört mich auch direkt. Die Lib macht es beim Nutzen des
Buffers mit
buffer = (uint8_t*)inBuff;
bei .close(); setzt er den Zeiger wieder NULL.
Da habe meine Anleihe her und das scheint erstmal soweit
zusammenzupassen.
Das ist daß, was ich oben probiert habe:
char * titelliste;
titelliste = (char*)preallocateBuffer;
Gruß aus Berlin
Michael
Michael U. schrieb:> Der Stream-File-Buffer bleibt dabei reserviert (für das> zurückschalte auf Stream-Play zur Laufzeit auch so nötig, selbst ein> ESP32 hat begrenzten Ram und wenn ich den Freigebe wissen nur die> Götter, ob ich ihn jemals wiederbekomme(Fragmentierung des Ram).
Gibt es denn noch andere Teile des Systems, die Speicher alloziieren und
freigeben? Falls nein, dann ist die Fragmentierung eigentlich nicht
relevant: nach "x = malloc(size); free(x)" ist der alte Zustand
wiederhergestellt, falls die libc nicht selbst kaputt ist.
Ansonsten kannst du auch einfach zwei Zeiger auf den gleichen Puffer
anlegen:
Hallo,
S. R. schrieb:> Gibt es denn noch andere Teile des Systems, die Speicher alloziieren und> freigeben? Falls nein, dann ist die Fragmentierung eigentlich nicht> relevant: nach "x = malloc(size); free(x)" ist der alte Zustand> wiederhergestellt, falls die libc nicht selbst kaputt ist.
Die anderen Teile gibt es prinzipbedingt, weil der Kram auf einem ESP32
läuft und da irgendwo drunter ein RTOS ist, was auch WLAN usw. bedient.
Dazu die Lib von Display und Touch, die prinzipiell auch machen kann,
was sie will.
Deshalb hat der Autor der AudioLib auch diesen Weg (für sich) genommen.
> Ansonsten kannst du auch einfach zwei Zeiger auf den gleichen Puffer> anlegen:void *buf = malloc(80000);> AudioBuf *playbuf = (AudioBuf*)buf;> SdBuf *sdbuf = (SdBuf*)buf;
So hat es auch geendet und läuft hier jetzt seit einiger Zeit stabil.
Ich nehme den Buffer jetzt als Char-Buffer und berechne meine Offsets
eben.
Es war ja nur der Gedanke, es als "Array of Array of Char" handeln zu
können, also die Titeleinträger über z.B. titelliste[293] erreichen zu
können statt über titelliste + 293 * 100. Das ist mir aber nicht
gelungen.
Sieht eben z.B. ein strcpy(...); etwas "seltsam" aus.
Letztlich will ich ja nur max. 500 Titelnamen mit max. je 100 Zeichen
incl. \0 verwalten...
Gruß aus Berlin
Michael
Michael U. schrieb:> Die anderen Teile gibt es prinzipbedingt,
Okay, das ist natürlich ein verdammt gutes Argument. :-)
Michael U. schrieb:> Es war ja nur der Gedanke, es als "Array of Array of Char" handeln zu> können, also die Titeleinträger über z.B. titelliste[293] erreichen zu> können statt über titelliste + 293 * 100.
Wie wäre es mit (ungetestet):
1
unionu_buf{
2
charrawData[80000];
3
uint16_taudioData[40000];
4
structtiteltitelData[128];
5
}
Ein "union u_buf" ist exakt 80000 Bytes groß, oder 128 * sizeof(struct
titel), je nachdem was größer ist. :-)
Hallo,
S. R. schrieb:> Ein "union u_buf" ist exakt 80000 Bytes groß, oder 128 * sizeof(struct> titel), je nachdem was größer ist. :-)
Klingt erstmal gut, werde ich mal testen.
Gruß aus Berlin
Michael