Möglichkeiten DF-Player hier "Large folder"

Hallo Ihr Lieben!

Mein TonUINO-Nutzer zuhause fängt langsam sich für Harry Potter zu interessieren. Die Hörbücher liegen aus meiner Vergangenheit zuhause auch noch rum.
Die mp3s sind schnell kopiert und aufgespielt. Allerdings werden die Hörbücher von Band zu Band immer länger und ich habe u.a. für ein einzelnes Hörbuch 268 mp3-Dateien.
Ich bin u.a. hier auf die Möglichkeit des DF-Players gestoßen sog. „Large-Folders“ zu verwenden, die mehr als 255 Dateien unterstützen, ähnlich dem Ordner MP3. Ein Befehl zu Ansprache dieser Ordner scheint es mir in der Makuna Lib. mit
// sd:/##/####track name // track number must be four digits, zero padded void playFolderTrack16(uint8_t folder, uint16_t track) { uint16_t arg = (((uint16_t)folder) << 12) | track; sendPacket(0x14, arg); }
auch zu geben.
Habe es auch schon geschafft in dem ich im sketch an einigen Stellen den uint8_t auf uint16_t umgeändert habe und die mp3.playFolderTrack Funktion gegen mp3.playFolderTrack16 getauscht habe, dass die zusätzlichen Dateien erkannt werden und im Hörbuch-Modus der Reihenfolge nach abgespielt werden und über die next-/previous-Track-Taste angewählt werden können.
Was nicht klappt, ist das Fortschritt speichern sobald das Hörbuch über die Datei 255 hinweg gelaufen ist. Bis zur 255 läuft es ohne Probleme, in der Konsole wird beim „Sprung“ auf die zusätzlichen Dateien auch angezeigt „Hörbuch Modus ist aktiv -> nächster Track und Fortschritt speichern“ aber wenn ich dann den tag wieder auflege, wird der erste Track aus dem Ordner abgespielt.
Vielleicht hat von euch ja auch schon jemand mit diesen „large foldern“ experimentiert und kann mir einen Tipp geben?!

Danke für eure Hilfe.
Gruß

1 Like

Klar, im eeprom liegt ein 100 Elemente großes Array mit je 1 Byte großen Einträgen, d.h. es können nur Zahlen von 00 bis FF gespeichert werden (0-255). Wenn er bei 255 angekommen ist und +1 rechnet, fängt er wieder bei 0 an.
Das Array muss also auch als Grundtyp 2 Bytes haben.
Genaueres kann ich gerade am Handy aber nicht schreiben :wink:

Ok, Danke für Deine Ausführungen! Warum der Fortschritt im Moment nicht gespeichert wir, wird mir klarer.
Aber kann ich denn den Grundtyp des Array ändern?
Sorry, falls das eine blöde Frage ist :blush:

Okay, es war schon länger her, dass ich mich dem Code beschäftigt habe. Wenn du konsequent alles auf mehr Tracks umbauen möchtest hast du mächtig was zu tun. Auf den RFID-Karten ist alles drauf ausgelegt, dass in jedem Ordner nur 255 Dateien passen (Special 1 und 2, bzw. Byte 8 und 9).
Die Größe müsste im struct myfoldersettings hinterlegt sein. Das eigentlich Abspeichern findest du, wenn du nach „EEPROM“ suchst. Es wird sicherlich noch viele andere Stellen geben, die zu ändern sind, aber da hab ich gerade keine Zeit noch nach zu suchen bzw. mich da rein zu denken.
Es ist auf jeden Fall ein bisschen Arbeit :wink:

Danke!
Ich werd einfach mal mein Glück versuchen.
Mehr als schiefgehen kann es ja nicht und man will ja auch was lernen :smile:

Bevor ich so einen act mit Code umbauen machen würde,würde ich lieber ein paar Dateien miteinander mergen.

1 Like

Hatte ich wohl auch schon überlegt. :wink: Aber wie ich oben schon geschrieben habe, man will ja auch was lernen.
Habe die Funktion auch schon weiter studiert und festgestellt, dass man sie nicht global einpflegen kann. Die large folder können nur die Ordner 1 bis 15 sein. Es ist also noch mehr Arbeit, als zu Anfang gedacht. Werde trotzdem erstmal weiter fummeln. Mal sehen, wie weit ich komme :exploding_head:

Bin relativ erstaunt über mich selbst! In Grundzügen funktioniert es schon! :tada:
Habe erstmal die Hörbuchfunktion mit if aufgeteilt in den Fall Ordner 1 bis 15 für die large folder und eben der Rest mit den normalen Ordnern.
Habe dann aus aus dem Fork von @marco-117 bei dem zusätzlichen Hörbuchspeicher abgeguckt, um sein dort implementiertes „special4“ zur Übergabe der hohen Dateinummer zu nehmen. Dazu habe ich zwei neue Methoden eingebaut
uint16_t readLargeTrack (uint8_t folder, uint8_t track, uint8_t track2) { return (EEPROM.read(track + (255*track2)), EEPROM.read(folder)); }
void writeLargeTrack (uint8_t folder, uint8_t track, uint8_t track2) { EEPROM.update(folder, track + (255*track2)); }
Den Fortschritt übergebe ich mit
writeLargeTrack (myFolder->folder, currentTrack, myFolder->special4);
anstatt EEPROM.update.
Das Auslesen, hatte ich gehofft würde über
readLargeTrack (myFolder->folder, currentTrack, myFolder->special4);;Serial.print(currentTrack);
funktionieren.
Allerdings wird die Ordnernummer nicht komplett richtig übergeben.
Wenn ich zwischen zwei Hörbüchern hin und her wechsle, (in meinen Testaufbau mit nur zwei programmierten Karten, ein normaler Ordner und ein large Ordner) übernimmt der large Ordner den Stand aus normalen Ordner. Wenn ich nicht wechsle klappt alles gut. Die Karte für das Hörbuch im normalen Ordner arbeitet normal (ist ja auch der original-Code :joy:)
Vielleicht hat ja noch jemand einen Tipp, wo ich ansetzen kann?!

1 Like

Large Folder. Wieso hör ich erst jetzt davon…
Da macht mein Hörbuch von bis ja noch viel mehr sinn.
Leider habich gerade keine Zeit meinen Fork weiter zu entwickeln.
Aber das kommt auf die ToDo Liste.
Vielleicht kann ich mich dann ja an deinen Lösungen bedienen?

1 Like

Nur zu! Vielleicht hab ich bis dahin ja sogar den Fehler mit der falschen Übergabe des Ordners gelöst :thinking:

So, hatte einige Denkfehler durch mangelndes Wissen, aber jetzt habe ich eine Lösung gefunden, die tatsächlich (auf meinem reduzierten Testaufbau) bisher anstandslos funktioniert.
Für erfahrene Programmierer ist mein Code möglicherweise ein Graus, aber ich möchte meine Änderungen zur original DEV trotzdem hier einmal posten.
Danke nochmal an @marco-117!

Meine Änderungen:

unter Zeile 37 einfügen:
uint8_t special3;

unter Zeile 578 einfügen:

  if (myFolder->mode == 10) {
    if (currentTrack != numTracksInFolder) {
      currentTrack = currentTrack + 1;
      Serial.print(F("Hörbuch Modus ist aktiv -> nächster Track und "
                     "Fortschritt speichern"));
      Serial.println(currentTrack);
      mp3.playFolderTrack16(myFolder->folder, currentTrack);
  // Fortschritt im EEPROM abspeichern
        writeLargeTrack (myFolder->folder, currentTrack, myFolder->special3);
    } else {
//    mp3.sleep();  // Je nach Modul kommt es nicht mehr zurück aus dem Sleep!
  // Fortschritt zurück setzen
      EEPROM.update(myFolder->folder, 0);
      setstandbyTimer();
    }
  }

unter Zeile 621 einfügen:

  if (myFolder->mode == 10) {
    Serial.println(F("Hörbuch Modus ist aktiv -> vorheriger Track und "
                     "Fortschritt speichern"));
    if (currentTrack != 1) {
      currentTrack = currentTrack - 1;
    }
    mp3.playFolderTrack16(myFolder->folder, currentTrack);
  // Fortschritt im EEPROM abspeichern
        writeLargeTrack (myFolder->folder, currentTrack, myFolder->special3);
  }

unter Zeile 927 einfügen:

  if (myFolder->mode == 10) {
    Serial.println(F("Spezialmodus Big-Folder: Hörbuch-> kompletten Big-Folder spielen und "
                     "Fortschritt merken"));
    int a = EEPROM.read(myFolder->folder);
    if (a==255) {
      int b = readLargeTrack(myFolder->folder, myFolder->special3);
       currentTrack = a + b;
    }
    else currentTrack = a;
    if (currentTrack == 0 || currentTrack > numTracksInFolder) {
      currentTrack = 1;
    }
    mp3.playFolderTrack16(myFolder->folder, currentTrack);
  }

Zeilen 1251 bis 1254 ersetzen mit:

uint8_t special = voiceMenu(mp3.getFolderTrackCount(tempCard.nfcFolderSettings.folder), 341, 0,
                            true, tempCard.nfcFolderSettings.folder);
uint8_t special2 = voiceMenu(mp3.getFolderTrackCount(tempCard.nfcFolderSettings.folder), 342, 0,
                             true, tempCard.nfcFolderSettings.folder, special);

Zeile 1342 ersetzen mit:

uint8_t readLargeTrack (uint8_t folder, uint8_t memorySpace) {
  return EEPROM.read(folder + (255*memorySpace));
}
void writeLargeTrack (uint8_t folder, uint8_t track, uint8_t memorySpace) {
  if (currentTrack < 255) {
    EEPROM.update(myFolder->folder, currentTrack);
  }
  if (currentTrack > 255) {
    EEPROM.update(myFolder->folder, 255);
    EEPROM.update(folder + (255*memorySpace), currentTrack-255);
  }
  if (currentTrack == 255) {
    EEPROM.update(myFolder->folder, currentTrack);
    EEPROM.update(folder + (255*memorySpace), 0);
  }
}

Zeile 1471 ersetzen mit:
theFolder->mode = voiceMenu(10, 310, 310, false, 0, 0, true);

Zeile 1479 ersetzen mit:
theFolder->special = voiceMenu(mp3.getFolderTrackCount(theFolder->folder), 340, 0,

Zeilen 1489 bis 1492 ersetzen mit:

theFolder->special = voiceMenu(mp3.getFolderTrackCount(theFolder->folder), 341, 0,
                               true, theFolder->folder);
theFolder->special2 = voiceMenu(mp3.getFolderTrackCount(theFolder->folder), 342, 0,
                                true, theFolder->folder, theFolder->special);

unter Zeile 1493 einfügen:

  if (theFolder->mode == 10) {
    theFolder->special3 = true;
  }

unter Zeile 1623 einfügen:
tempCard.nfcFolderSettings.special3 = buffer[9];

Zeile 1703 ersetzen mit:

             nfcTag.nfcFolderSettings.special3,
             0x00, 0x00, 0x00, 0x00, 0x00, 0x00

Im Ordner mp3 durchzufühern:
320_select_file.mp3 in 340_select_file.mp3 umbenennen
321_select_first_file.mp3 in 341_select_first_file.mp3 umbennen
322_select_last_file.mp3 in 342_select_last_file.mp3 umbenennen

neue Datei 320.mp3 erstellen (zur Auswahl des neuen Modus „Hörbuch mit mehr als 255 Dateien und Fortschritt speichern“)

Ich werde noch weiter testen, ob auch der reguläre Aufbau reagiert wie gewünscht.

Edit2: Habe nach Tests auf meinem „regulären Aufbau“ den Code nochmal angepasst.

2 Like

Mir fällt gerade auf, dass ich die falschen Code-Änderungen rein gestellt habe.
Sollte es schon jemand probiert haben und keinen Erfolg vermelden können, ist das nicht verwunderlich.
Werde den Beitrag, sobald ich wieder am Rechner bin, also noch berichtigen.
Sorry
Edit: habe den Code so berichtigt wie er bei mir bisher funktioniert.

Bei mir funktioniert es so (denke ich :wink: ):
Wird eine Karte auf einen „Large Folder“ mit dem Hörbuch-Modus konfiguriert, dann wird für diesen Ordner ein zusätzlicher Speicherplatz geschaffen, in den bei Dateien über 255 die Differenz zu 255 gespeichert wird. Beim Neuauflegen der Karte werden beide Speicherstände abgefragt, addiert und an playFolder übergeben.
Da ich nur ein zusätzliches special reingeschrieben haben werden nur Speicherstände bis 510 verarbeitet.
Die Dateien müssen im „Large Folder“ vierstellig benannt sein, also 0001…
Die „Large Folder“ werden nur bei Ordner-Nummern 1 bis 15 verarbeitet.

Habe weiter getestet und festgestellt, dass eine „Zweiteilung“ des Modus 5/Hörbuch teilweise ganz seltsame Auswirkungen hatte. Also habe ich aus dem „Large-Folder“ einen eigenen Wiedergabemodus gemacht.
Meinen Code habe ich oben aktualisiert.
Da es nun einen weiteren Modus über das Adminmenü auszuwählen gibt, waren ein paar Kleinigkeiten im mp3-Ordner der DEV zu ändern.

1 Like

Hi,

ich bin auf genau das gleiche Problem gestoßen: Die Harry Potter Hörbücher haben zu viele Einzeltracks. Die Nummer an Tracks wollte ich auch nicht reduzieren, damit die einzelnen Abschnitte nicht zu lang werden.

Ich bin zufällig auf diesen Thread gestoßen und habe mich aber entschieden selbst eine Implementierung vorzunehmen, da ich diese als sehr kompliziert empfunden habe (funktioniert sicherlich - ich selbst habe es nicht getestet.)

Deswegen würde ich gerne anderen Leuten, die eventuell auf die gleiche Limitierung stoßen, eine Alternative anbieten:

142c142

<   int address = sizeof(myFolder->folder) * 100;

---

>   int address = sizeof(myFolder->folder) * 200;

186c186

<   int address = sizeof(myFolder->folder) * 100;

---

>   int address = sizeof(myFolder->folder) * 200;

574c574

<       mp3.playFolderTrack(myFolder->folder, currentTrack);

---

>       mp3.playFolderTrack16(myFolder->folder, currentTrack);

576c576

<       EEPROM.update(myFolder->folder, currentTrack);

---

>       EEPROM.put(myFolder->folder * sizeof(uint16_t), currentTrack);

580c580

<       EEPROM.update(myFolder->folder, 1);

---

>       EEPROM.put(myFolder->folder * sizeof(uint16_t), 1);

623c623

<     mp3.playFolderTrack(myFolder->folder, currentTrack);

---

>     mp3.playFolderTrack16(myFolder->folder, currentTrack);

625c625

<     EEPROM.update(myFolder->folder, currentTrack);

---

>     EEPROM.put(myFolder->folder * sizeof(uint16_t), currentTrack);

894c894

<     currentTrack = EEPROM.read(myFolder->folder);

---

>     EEPROM.get(myFolder->folder * sizeof(uint16_t), currentTrack);

898c898

<     mp3.playFolderTrack(myFolder->folder, currentTrack);

---

>     mp3.playFolderTrack16(myFolder->folder, currentTrack);

Meine Implementierung basiert auf dem letzten DEV (commit 36ec283). Ich habe für den Hörbuch-Modus nur mp3.playFolderTrack durch mp3.playFolderTrack16 ersetzt um mp3 in einem Ordner lesen zu können. Die Variable currentTrack ist sowieso schon eine uint16_t. Damit der Fortschritt gespeichert werden kann, habe ich noch die EEPROM von read/update auf get/put geändert. Dann können auch mehr als 8-bits geschrieben werden. Dazu muss dann noch der Adress-Offset der einzelnen Einträge und der Settings angepasst werden.

Nachdem man den neuen Code auf den Arduino geflasht hat, würde ich empfehlen den EEPROM zu reseten (alle drei Knöpfe beim Einschalten halten). Danach muss man noch eimal seine Einstellungen im Admin Menü einstellen. (Die angelernten Karten funktionieren natürlich noch.) Die mp3s in Ordnern, die den Hörbuch Modus verwenden, müssen dann auch 4-stellig Benannt werden.

Gruß Sören

1 Like

Moin, finde es super noch einen anderen Ansatz zu sehen! Werde ich auf jeden Fall auch mal testen!
Habe noch eine Frage zum Verständnis: du kannst so den Hörbuchmodus, egal ob mehr als 255 Tracks oder nicht, nur für die Ordner 1 bis 15 nutzen, richtig?
Und eine habe ich noch:

Wie umgeht deine Verschiebung des offset dieses Problem, teilt die Verschiebung die Tracknummer auf?
Ich lerne noch und möchte einfach mehr darüber verstehen

Hi,

ich habe es nicht getestet, aber vom Code her sehe ich keinen Grund warum der Hörbuchmodus nur für die Ordner 1-15 funktionieren sollte. Der aktuelle Track kann für alle 99 Ordner gespeichert werden.

Genau, dadurch das ich die Adresse im EEPROM mit myFolder->Folder * sizeof(uint16_t) berechne, ist quasi ein Offset von 2 in den Adressen. D.h. Ordner 01 hat die Adresse 2, Ordner 02 hat die Adresse 4 und so weiter. Die Settings habe ich an die Adresse 200 verschoben (sizeof(myFolder->folder) = 1 (wegen Datentyp uint8_t)). Vom Code her ist das nicht ganz sauber. Eigentlich müsste es sizeof(uint16_t) * 99 sein bzw. sizeof(currentTrack) * 99. Dann würde man auch nicht den ersten Speicherplatz bzw. die ersten zwei Bytes im EEPROM verschenken. Dann müsste man aber auch die Adressberechnung für die abgespeicherten Tracks anpassen: (myFolder->folder - 1) * sizeof(uint16_t)

Durch die Veränderung von EEPROM.update()/EEPROM.read() auf EEPROM.put()/EEPROM.get() wird immer die gesamte Größe der Variable geschrieben. Für currentTrack 2 Byte da uint16_t. uint16_t kann 0x0 bis 0xFFFF repräsentieren (0 - 65535). Das ist mehr als der DF-Player mit seinen 4 Digits verwalten kann.

Ich hoffe, es ist etwas klarer geworden.

Super, danke für die Erklärung!

Vom Code her nicht, aber, so wie ich die specs vom DFPlayer verstanden habe, können nur in den Ordnern advert, mp3 und 1 bis 15 mehr als 255 Tracks und vierstellige Nummern verwendet werden, so dass mp3.playFolderTrack16 in den anderen Ordner zu Fehlern führt :thinking:

Ich hatte nur in API Reference von dem Autor der Library geschaut: API Reference · Makuna/DFMiniMp3 Wiki · GitHub

Dort steht nichts. Wenn man in den Code der DFMiniMP3 Lib schaut, sieht man, dass die Ordnernummer um 12 Stellen nach links geshiftet wird. D.h. von den 16 Bits bleiben nur 4 Bits über => Also können nur Ordner von 1 - 15 verwendet werden. Du hast recht.

Ich denke ich werde meinen Code noch etwas anpassen. Danke für den Hinweis.

Ich reserviere dann auf meiner SD-Karte, die ersten 15 Ordner für große Hörbücher…

Danke nochmal für deinen Code!
Habe jetzt für mich sozusagen das Beste aus beiden Welten zusammengelegt.
Von mir nutze ich den Teil mit dem zusätzlichen Abspielmodus „Big-Folder-Hörbuch“ und von dir die Art und Weise den Speicherstand abzulegen.
Allerdings habe ich das ursprüngliche offset aus der dev beibehalten und lege nur für den neuen Abspielmodus die Speicherstände ganz an’s Ende des EEPROM.
Suche das bei Gelegenheit zusammen und stelle meine entgültige Version hier vor.