Dev-Branch

Ich habe nun mal nochmals etwas herumgespielt.
Wenn ich das enthaltene cover lösche und wieder ein neues hinzufüge (png), funktioniert die Datei.
Hier der Auszug von mp3check:

> mp3check -e -a test-audioHeader-reading-timeout.mp3 
test-audioHeader-reading-timeout.mp3:
81705 bytes of junk before first frame header
anomaly: bitrate 320kbit/s
anomaly: mode stereo
anomaly: no crc

> mp3check -e -a test-no-cover.mp3 
test-no-cover.mp3:
1295 bytes of junk before first frame header
anomaly: bitrate 320kbit/s
anomaly: mode stereo
anomaly: no crc

> mp3check -e -a test-re-added-cover.mp3 
test-re-added-cover.mp3:
1942799 bytes of junk before first frame header
anomaly: bitrate 320kbit/s
anomaly: mode stereo
anomaly: no crc

Auszug aus dem ESPuino log:

I [916315] info        : Reading file: "/test/test-audioHeader-reading-timeout.mp3"
I [916324] info        : MP3Decoder has been initialized, free Heap: 136616 bytes , free stack 3196 DWORDs
N [916327] '/test/test-audioHeader-reading-timeout.mp3' wird abgespielt (1 von 1)
D [916341] no cover image for SD-card audio
I [916542] info        : Content-Length: 8055322
I [916542] info        : ID3 framesSize: 81705
I [916543] info        : ID3 version: 2.2
[918840][E][Audio.cpp:3165] processLocalFile(): audioHeader reading timeout


I [910307] info        : Reading file: "/test/test-no-cover.mp3"
I [910316] info        : MP3Decoder has been initialized, free Heap: 134548 bytes , free stack 3196 DWORDs
N [910319] '/test/test-no-cover.mp3' wird abgespielt (1 von 1)
D [910345] no cover image for SD-card audio
I [910537] info        : Content-Length: 7974912
I [910537] info        : ID3 framesSize: 1295
I [910538] info        : ID3 version: 2.3
I [910747] info        : ID3 normal frames


I [899423] info        : Reading file: "/test/test-re-added-cover.mp3"
I [899432] info        : MP3Decoder has been initialized, free Heap: 136572 bytes , free stack 3196 DWORDs
N [899434] '/test/test-re-added-cover.mp3' wird abgespielt (1 von 1)
D [899449] no cover image for SD-card audio
I [899651] info        : Content-Length: 9916416
I [899651] info        : ID3 framesSize: 1942799
I [899651] info        : ID3 version: 2.3
I [899855] info        : ID3 normal frames

Ich vermute, dass die Audiobibliothek ein Problem mit den Covers hat.
Wie schon erwähnt, ich bin mir recht sicher, dass das vor einigen Monaten alles noch funktioniert hat.

@Wolle Kannst Du das nachvollziehen (siehe MP3 in letztem Post)?

Ich habe nun mal automatisiert mittels dem Python-Script von https://www.reddit.com/r/rockbox/comments/156zbs3/comment/lp6e8s7/ alle meine MP3’s gefixt. Damit ist wieder alles i.O.

Hallo CaCo3,
die ID3 V2.2 ist seltener als die V2.3. In V2.3 war die Erkennung der eingebetteten Bilder bereits optimiert. Das habe ich jetzt für V2.2 nachgeholt. Timeouts werden jetzt nicht mehr auftreten.

1 „Gefällt mir“

Hoi @Wolle

Danke für die rasche Antwort.
Mit ID3 V2.2 resp. V2.3 beziehst Du dich vermutlich auf ID3-Tag – Wikipedia, oder?
Aber die Verbesserung hast Du ja vermutlich in deinen Library eingebaut. Wo ist die zu finden? Machst Du noch einen PR dafür ins dev?

Ich habs nicht überprüft, aber ich vermute, das sich noch viele mp3s habe, welche nur V2.2 haben. Und das sind alles moderne CDs, nichts altes. Daher gehe ich davon aus, dass es gar nicht so selten ist.

Das wird sofort wirksam sein. Du kannst mit „Full Clean“ die Bibliotheken neu laden.

Hmm, wie soll das funktionieren?
In platformio.ini ist ein fixer commit ausgewählt. Das automatische aktualisieren würde nur gehen, wenn wir auf den Branch verweisen würden (und davon würde ich unbedingt abraten).

@CaCO3 Es ist nicht das Problem von @Wolle, wie seine Lib den Weg in unser Repository findet. Wir können uns wirklich glücklich schätzen, dass er sogar hier ins Forum kommt und Fragen beantwortet + Fixes bereitstellt. Und das zudem super schnell.

Insofern kümmern wir uns natürlich selbst darum. Entweder stellst du einen PR oder @tueddy oder ich machen den Commit direkt. Es muss halt nur getestet werden.

1 „Gefällt mir“

Genau, um die Aktualisierung kümmern wir uns selbst. Die AudioI2s-Version ist einigermaßen aktuell (07.06.2024).
Achtung: Neuere AudioI2s-Versionen verwenden einen eigenen Task „PeriodicTask“ für die Audiowiedergabe. Das machen wir aber schon lange („mp3play“), wir hätten dann Task im Task. Ob das so gut ist? Evt. wären für eine Aktualisierung umfangreichere Arbeiten nötig…

Oh, ich muss zugeben, dass ich das gar nicht wusste. Ich denke man müsste es mal testen, vielleicht ist es gar nicht so arg viel Arbeit. Was auf jeden Fall aber nicht passt, das ist die Stacksize. Wie ist bei uns 6000 und in der Lib 3300. Und der Core passt für uns auch nicht.

@Wolle Würdest du solche Dinge auch als Compiler-Parameter konfigurierbar aus der Lib rausziehen oder geht dir das zu weit? Also wir müssen es eh erstmal testen. Ansonsten würden wir davon halt einfach einen Fork machen und es für solche Kleinigkeiten anpassen. Ganz generell würde ich gerne so nah wie möglich bei deiner Implementierung bleiben, wir müssen nur schauen, wie wir das jetzt wieder zusammenführen.

Das war auch gar nicht meine Intention! Ich wollte nur verstehen, wie es gemacht wird. Und darauf hinweisen, dass eine Referenz auf einen Branch nicht schlau wäre.

Anhand euren Antworten ist nun auch klar, dass der von @Wolle empfohlene Clean Build bei ESPuino nicht funktionieren würde.

Ich kann gerne heute Abend testen mit meinen MP3s. Aber das denkt halt nicht alles ab.

Dann wäre es ev. das Sinnvollste, solche Anpassungen zurück upstream zu @Wolles Repo zu geben.

Hi tueddy,
der zusätzliche Task war notwendig, weil der WiFiClient nicht blockierungsfrei ist. Bei HLS Streams wird oft eine neue m3u8 Datei benötigt. Häufig trennt Host vorher die Verbindung. Der WiFiClient baut die Verbindung neu auf, was bei verschlüsselten Verbindungen einiges an Zeit kostet. Die im I2S-DMA vorhandenen Daten reichen nicht aus, um die Zeit zu überbrücken, was zu Aussetzern führt. Der zusätzliche Task „füttert“ den I2S DMA auch wenn der WiFiClient blockiert.
Das erfordert leider einen weiteren Stack. Aber audio.loop() ist nicht mehr zeitkritisch. Im Notfall könnte der Stack von eurem Audiotask im PSRAM laufen. Etwa so:

// PSRAM für Task-Stack allokieren
    const size_t stack_size = 8192; // Größe des Stacks
    StackType_t *stack_memory = (StackType_t *)heap_caps_malloc(stack_size * sizeof(StackType_t), MALLOC_CAP_SPIRAM);

    if (stack_memory == NULL) {
        // Fehler: PSRAM nicht verfügbar
        return;
    }

    // Task mit PSRAM als Stack starten
    StaticTask_t *task_buffer = (StaticTask_t *)heap_caps_malloc(sizeof(StaticTask_t), MALLOC_CAP_SPIRAM);
    if (task_buffer == NULL) {
        // Fehler: PSRAM nicht verfügbar
        free(stack_memory);
        return;
    }

    xTaskCreateStatic(myTask, "PSRAM Task", stack_size, NULL, tskIDLE_PRIORITY, stack_memory, task_buffer);

Habs nicht getestet, ggf. sind Anpassungen nötig.

so habe ich das bei mir gemacht:

void audioTask(void *parameter) {
    CreateQueues();
    audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT, I2S_MCLK);
    audio.setI2SCommFMT_LSB(I2S_COMM_FMT);
    audio.setVolume(5, t_volCurve); // 0...volumeSteps
    while(true){
    ....
    ....
    audio.loop();
    vTaskDelay(10 / portTICK_PERIOD_MS);
}

TaskHandle_t Task1;
const size_t stack_size = 8192;
StackType_t *stack_memory;
StaticTask_t *task_buffer;
void audioInit() {
    stack_memory = (StackType_t *)heap_caps_malloc(stack_size * sizeof(StackType_t), MALLOC_CAP_SPIRAM);
    if (stack_memory == NULL) {log_e("Failed to allocate stack in PSRAM");  return;}
    task_buffer = (StaticTask_t *)malloc(sizeof(StaticTask_t));
    if (task_buffer == NULL) {free(stack_memory); log_e("Failed to allocate TCB in PSRAM"); return;}

    Task1 = xTaskCreateStaticPinnedToCore(  /* Task handle. */
        audioTask,                          /* Function to implement the task */
        "audioplay",                        /* Name of the task */
        stack_size,                         /* Stack size in words */
        NULL,                               /* Task input parameter */
        AUDIOCONTROLTASK_PRIO,              /* Priority of the task */
        stack_memory,
        task_buffer,
        AUDIOCONTROLTASK_CORE               /* Core where the task should run */
    );

}

void audioControlTaskDelete(){
    vTaskDelete(Task1);
    free(stack_memory);
    free(task_buffer);
}

und in menuconfig
image

Mit dem Release 2.3 können wir gerade noch so Musik abespielen auf Boards ohne PSRAM. Wenn wir Audio-I2S aktualisieren wird es wahrscheinlich nicht mehr möglich sein. Ich habe es z.B. nicht geschafft z.B. mit einem Lolin D32 mit einer neueren Audio-I2S Version noch Musik abzuspielen.

Bei einer Aktualisierung müsste man sich auch überlegen ob man diese Boards/Profile abkündigt:
lolin32, lolin_d32, lolin_d32_sdmmc_pe, az-delivery-devkit-v4

1 „Gefällt mir“

Ja, ich denke das werden wir tun müssen.
Eigentlich macht es jetzt schon keinen Sinn mehr. Lolin D32 hatte ich vor ner Weile mal probiert: Das ging auf jeden Fall nur bis 128 kBit/s. Bei 192 war schon Feierabend. Aber das a1s noch läuft weiß vermutlich auch kein Mensch, aber das hat zumindest 4 MB PSRAM (wenn ich das richtig in Erinnerung habe).

1 „Gefällt mir“

Könnte man da vielleicht eine Umfrage machen, ob diese Boards überhaupt noch verwendet werden?
Da hätte man eine Aussage ob das wirklich ein Problem ist - auf der anderen Seite werden nicht alle Nutzer permanent hier im Forum auftauchen. :man_shrugging:t2:

Das ist exakt der Punkt und insgesamt auch die Regel. Die meisten Leute kommen her, schreiben mich wegen Hardware an, tauchen hier öffentlich nicht auf und sind ziemlich schnell auch wieder weg. Manche posten noch ein Problem, aber das war’s dann. Und ganz generell mache ich immer wieder die Erfahrung, dass „mal in die Runde fragen“ idR zu wenig Resonanz führt. Also insofern verspreche ich mir sehr wenig davon :slight_smile:.

Ich denke die meisten Leute werden das irgendwann mal einrichten und dann SW-technisch nicht mehr anfassen. Was ich auch verstehen kann :slight_smile:

Die mini4L gibt’s inzwischen auf jeden Fall seit Januar 2023. Die Variante davor läuft an für sich auch, es gab da nur leider Probleme mit dem Deepsleep teilweise. Also damit hängt man, im Zweifelsfalle (leider), eh auf Arduino1 fest.

Um den Lolin D32 tut’s mir bisschen leid, da dieses Develboard ja pinkompatibel ist. Aber es hilft halt nix, wenn wir PSRAM brauchen. Insofern sollten wir das aus meiner Sicht machen, dass wir da ausmisten. Vielleicht auch a1s gleich mit, da der eh nicht genügend Pins hat und mir völlig unklar ist, ob das überhaupt noch jmd. verwendet.

Aber ich bin da für andere Meinungen natürlich offen.

2 „Gefällt mir“

Dann haben die Nutzer von Hardware ohne PSRAM (wenn sie hier nicht mehr vorbeischauen) wahrscheinlich auch gar nicht das Verlangen die Software zu aktualisieren.
Ich finde es einen sauberer Schnitt, wenn man ab Release XY veraltete Software nicht mehr unterstützt. Wenn man das klar kommuniziert wäre das aus meiner Sicht i.O., man kann ja im Zweifelsfall bis zur letzten unterstützten Version aktualisieren.

3 „Gefällt mir“

Das wäre meine Vermutung, ja.

Weiterer Vorteil: Wir könnten die Min-Version auf 3 stetzten und hätten sofort sehr viel IRAM zusätzlich zur Verfügung, so dass wir ohne Probleme z.B. auch die FreeRTOS Funktionen wieder im IRAM haben könnten…

1 „Gefällt mir“