@@ -10,19 +10,73 @@ typedef struct PlaylistEntry {
1010 uint16_t tr;
1111} ple;
1212
13- byte playlistRepeat = 1 ;
14- byte playlistEndPreset = 0 ;
13+ int8_t playlistRepeat = 1 ;
14+ byte playlistEndPreset = 0 ;
15+ byte *playlistEntries = nullptr ;
16+ byte playlistLen;
17+ int8_t playlistIndex = -1 ;
18+ uint16_t playlistEntryDur = 0 ;
1519
16- uint8_t * playlistEntries;
1720
18- byte playlistLen;
19- int8_t playlistIndex = -1 ;
21+ void shufflePlaylist () {
22+ int currentIndex = playlistLen, randomIndex;
23+
24+ PlaylistEntry temporaryValue, *entries = reinterpret_cast <PlaylistEntry*>(playlistEntries);
25+
26+ // While there remain elements to shuffle...
27+ while (currentIndex--) {
28+ // Pick a random element...
29+ randomIndex = random (0 , currentIndex);
30+ // And swap it with the current element.
31+ temporaryValue = entries[currentIndex];
32+ entries[currentIndex] = entries[randomIndex];
33+ entries[randomIndex] = temporaryValue;
34+ }
35+ }
36+
37+ /*
38+ * The same thing as saving and loading playlist can be achieved using JSON API saved in a preset.
39+ *
40+ void deserializePlaylist() {
41+ DynamicJsonDocument doc(JSON_BUFFER_SIZE);
42+
43+ DEBUG_PRINTLN(F("Reading playlist from /playlist.json..."));
44+
45+ if (!readObjectFromFile("/playlist.json", nullptr, &doc)) return; //if file does not exist just exit
46+
47+ JsonObject playlist = doc[F("playlist")];
48+ if (!playlist.isNull()) loadPlaylist(playlist);
49+ }
2050
21- uint16_t playlistEntryDur = 0 ;
51+
52+ void serializePlaylist() {
53+ DynamicJsonDocument doc(JSON_BUFFER_SIZE/8); // we don't need big buffer (>1k is ok)
54+
55+ DEBUG_PRINTLN(F("Writing playlist to /playlist.json..."));
56+
57+ PlaylistEntry* entries = reinterpret_cast<PlaylistEntry*>(playlistEntries);
58+
59+ JsonObject playlist = doc.createNestedObject(F("playlist"));
60+ JsonArray ps = playlist.createNestedArray(F("ps"));
61+ JsonArray dur = playlist.createNestedArray(F("dur"));
62+ JsonArray tr = playlist.createNestedArray(F("transition"));
63+ for (uint8_t i=0; i<playlistLen; i++) {
64+ ps.add(entries[i].preset);
65+ dur.add(entries[i].dur);
66+ tr.add(entries[i].tr);
67+ }
68+ playlist[F("repeat")] = playlistRepeat; // TODO: this one is decreasing with each loop
69+ playlist[F("end")] = playlistEndPreset;
70+
71+ File f = WLED_FS.open("/playlist.json", "w");
72+ if (f) serializeJson(doc, f);
73+ f.close();
74+ }
75+ */
2276
2377void loadPlaylist (JsonObject playlistObj) {
24- delete playlistEntries;
25- playlistIndex = -1 ; playlistEntryDur = 0 ;
78+ if (playlistEntries != nullptr ) { delete[] playlistEntries; playlistEntries = nullptr ;}
79+ currentPlaylist = playlistIndex = -1 ; playlistEntryDur = 0 ;
2680 JsonArray presets = playlistObj[" ps" ];
2781 playlistLen = presets.size ();
2882 if (playlistLen == 0 ) return ;
@@ -72,26 +126,30 @@ void loadPlaylist(JsonObject playlistObj) {
72126 currentPlaylist = 0 ; // TODO here we need the preset ID where the playlist is saved
73127}
74128
75- void handlePlaylist ()
76- {
129+
130+ void handlePlaylist () {
77131 if (currentPlaylist < 0 || playlistEntries == nullptr || presetCyclingEnabled) return ;
78132
79- if (millis () - presetCycledTime > (100 *playlistEntryDur))
80- {
133+ if (millis () - presetCycledTime > (100 *playlistEntryDur)) {
81134 presetCycledTime = millis ();
82135 if (bri == 0 || nightlightActive) return ;
83136
84- playlistIndex++;
85- if (playlistIndex >= playlistLen) {
86- playlistIndex = 0 ;
87- if (playlistRepeat == 1 ) { // stop
88- currentPlaylist = -1 ;
89- delete playlistEntries;
90- playlistEntries = nullptr ;
91- if (playlistEndPreset) applyPreset (playlistEndPreset);
92- return ;
137+ ++playlistIndex %= playlistLen; // -1 at 1st run (limit to playlistLen)
138+
139+ if (!playlistRepeat && !playlistIndex) { // stop if repeat == 0 and restart of playlist
140+ currentPlaylist = -1 ;
141+ delete[] playlistEntries;
142+ playlistEntries = nullptr ;
143+ if (playlistEndPreset) applyPreset (playlistEndPreset);
144+ return ;
145+ }
146+ // playlist roll-over
147+ if (!playlistIndex) {
148+ if (playlistRepeat > 0 ) {// playlistRepeat < 0 => endless loop with shuffling presets
149+ playlistRepeat--; // decrease repeat count on each index reset
150+ } else {
151+ shufflePlaylist (); // shuffle playlist and start over
93152 }
94- if (playlistRepeat > 1 ) playlistRepeat--;
95153 }
96154
97155 PlaylistEntry* entries = reinterpret_cast <PlaylistEntry*>(playlistEntries);
@@ -103,4 +161,4 @@ void handlePlaylist()
103161 playlistEntryDur = entries[playlistIndex].dur ;
104162 if (playlistEntryDur == 0 ) playlistEntryDur = 10 ;
105163 }
106- }
164+ }
0 commit comments