From a1c2c045108d5059421ad059eb4c1a56414af55a Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Fri, 5 Feb 2021 17:36:53 +0100 Subject: [PATCH] Playlist handling. --- wled00/json.cpp | 2 +- wled00/playlist.cpp | 108 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 84 insertions(+), 26 deletions(-) diff --git a/wled00/json.cpp b/wled00/json.cpp index 79d182f1..472ed44f 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -279,7 +279,7 @@ bool deserializeState(JsonObject root) JsonObject playlist = root[F("playlist")]; if (!playlist.isNull()) { - loadPlaylist(playlist); return stateResponse; + loadPlaylist(playlist); //return stateResponse; } colorUpdated(noNotification ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE); diff --git a/wled00/playlist.cpp b/wled00/playlist.cpp index d94126c9..911e2692 100644 --- a/wled00/playlist.cpp +++ b/wled00/playlist.cpp @@ -10,19 +10,73 @@ typedef struct PlaylistEntry { uint16_t tr; } ple; -byte playlistRepeat = 1; -byte playlistEndPreset = 0; - -uint8_t* playlistEntries; - -byte playlistLen; -int8_t playlistIndex = -1; - +int8_t playlistRepeat = 1; +byte playlistEndPreset = 0; +byte *playlistEntries = nullptr; +byte playlistLen; +int8_t playlistIndex = -1; uint16_t playlistEntryDur = 0; + +void shufflePlaylist() { + int currentIndex = playlistLen, randomIndex; + + PlaylistEntry temporaryValue, *entries = reinterpret_cast(playlistEntries); + + // While there remain elements to shuffle... + while (currentIndex--) { + // Pick a random element... + randomIndex = random(0, currentIndex); + // And swap it with the current element. + temporaryValue = entries[currentIndex]; + entries[currentIndex] = entries[randomIndex]; + entries[randomIndex] = temporaryValue; + } +} + +/* + * The same thing as saving and loading playlist can be achieved using JSON API saved in a preset. + * +void deserializePlaylist() { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + + DEBUG_PRINTLN(F("Reading playlist from /playlist.json...")); + + if (!readObjectFromFile("/playlist.json", nullptr, &doc)) return; //if file does not exist just exit + + JsonObject playlist = doc[F("playlist")]; + if (!playlist.isNull()) loadPlaylist(playlist); +} + + +void serializePlaylist() { + DynamicJsonDocument doc(JSON_BUFFER_SIZE/8); // we don't need big buffer (>1k is ok) + + DEBUG_PRINTLN(F("Writing playlist to /playlist.json...")); + + PlaylistEntry* entries = reinterpret_cast(playlistEntries); + + JsonObject playlist = doc.createNestedObject(F("playlist")); + JsonArray ps = playlist.createNestedArray(F("ps")); + JsonArray dur = playlist.createNestedArray(F("dur")); + JsonArray tr = playlist.createNestedArray(F("transition")); + for (uint8_t i=0; i (100*playlistEntryDur)) - { + if (millis() - presetCycledTime > (100*playlistEntryDur)) { presetCycledTime = millis(); if (bri == 0 || nightlightActive) return; - playlistIndex++; - if (playlistIndex >= playlistLen) { - playlistIndex = 0; - if (playlistRepeat == 1) { //stop - currentPlaylist = -1; - delete playlistEntries; - playlistEntries = nullptr; - if (playlistEndPreset) applyPreset(playlistEndPreset); - return; + ++playlistIndex %= playlistLen; // -1 at 1st run (limit to playlistLen) + + if (!playlistRepeat && !playlistIndex) { //stop if repeat == 0 and restart of playlist + currentPlaylist = -1; + delete[] playlistEntries; + playlistEntries = nullptr; + if (playlistEndPreset) applyPreset(playlistEndPreset); + return; + } + // playlist roll-over + if (!playlistIndex) { + if (playlistRepeat > 0) {// playlistRepeat < 0 => endless loop with shuffling presets + playlistRepeat--; // decrease repeat count on each index reset + } else { + shufflePlaylist(); // shuffle playlist and start over } - if (playlistRepeat > 1) playlistRepeat--; } PlaylistEntry* entries = reinterpret_cast(playlistEntries); @@ -103,4 +161,4 @@ void handlePlaylist() playlistEntryDur = entries[playlistIndex].dur; if (playlistEntryDur == 0) playlistEntryDur = 10; } -} \ No newline at end of file +}