diff --git a/firmware/src/gfx_decoder.cpp b/firmware/src/gfx_decoder.cpp index 80ec8c8..eb6cb34 100644 --- a/firmware/src/gfx_decoder.cpp +++ b/firmware/src/gfx_decoder.cpp @@ -3,7 +3,7 @@ #include "lodepng.h" #include "leds.h" -uint16_t gfxFrameLengthsBuffer[12000] = {0}; +uint16_t gfxFrameLengthsBuffer[24000] = {0}; uint16_t frameCount = 0; uint8_t gfxFrameBuffer[6400] = {0}; diff --git a/firmware/src/gfx_decoder.h b/firmware/src/gfx_decoder.h index 1a8126f..b218ac7 100644 --- a/firmware/src/gfx_decoder.h +++ b/firmware/src/gfx_decoder.h @@ -4,7 +4,7 @@ #include -extern uint16_t gfxFrameLengthsBuffer[12000]; +extern uint16_t gfxFrameLengthsBuffer[24000]; extern uint16_t frameCount; extern uint8_t gfxFrameBuffer[6400]; diff --git a/firmware/src/main.cpp b/firmware/src/main.cpp index a9c7e24..d465498 100644 --- a/firmware/src/main.cpp +++ b/firmware/src/main.cpp @@ -5,16 +5,19 @@ #include "leds.h" #include "gfx_decoder.h" +void loadVideo(size_t index); + void setup() { leds_init(); setupSDPins(); - pinMode(6, INPUT_PULLUP); + pinMode(4, INPUT_PULLUP); delay(2000); Serial.begin(115200); Serial.println("Hello worldd!"); init_audio(); + leds_initRenderer(); // while (!isSDCardInserted()) { // Serial.println("SD card not connected, waiting..."); @@ -23,25 +26,37 @@ void setup() { // delay(100); setupSD(); + sd_loadPlaylist(); - sd_loadAudio(); + loadVideo(0); +} - if (!sd_loadGfxFrameLengths()) { +size_t currentVideoIndex = 0; +bool isLoaded = false; + +void loadVideo(size_t index) { + audio_stop(); + + sd_loadAudio(index); + + if (!sd_loadGfxFrameLengths(index)) { Serial.println("Failed to load gfx frame lengths"); while (true) {} } - if (!sd_loadGfxBlob()) { + if (!sd_loadGfxBlob(index)) { Serial.println("Failed to load gfx blob"); while (true) {} } - leds_initRenderer(); + isLoaded = true; } void loop() { - if (digitalRead(6) == LOW) { - sd_loadNextAudio(); + if (digitalRead(4) == LOW) { + Serial.println("Next song!"); + currentVideoIndex = (currentVideoIndex + 1) % playlistSize; + loadVideo(currentVideoIndex); } // if (Serial.available() > 0) { @@ -57,7 +72,11 @@ void loop() { // } // } - if (!gfx_decoder_handleLoop()) { - Serial.println("Failed to load frame..."); + if (isLoaded) { + sd_loadNextAudio(); + + if (!gfx_decoder_handleLoop()) { + Serial.println("Failed to load frame..."); + } } } diff --git a/firmware/src/sd.cpp b/firmware/src/sd.cpp index 31f67b9..c0930db 100644 --- a/firmware/src/sd.cpp +++ b/firmware/src/sd.cpp @@ -156,10 +156,83 @@ void printSDStats(RP2040_SdVolume volume) { Serial.println((float)volumesize / 1024.0); } +String playlist[128] = {}; +size_t playlistSize = 0; + +void sd_loadPlaylist() { + auto path = "video/playlist.txt"; + + if (!SD.exists(path)) { + Serial.println("Could not find playlist for videos :("); + return; + } + + auto playlistFile = SD.open(path, FILE_READ); + Serial.println("Playlist file opened"); + + char playlist_buffer[512]; + auto fileSize = playlistFile.size(); + if (fileSize > sizeof(playlist_buffer)) { + Serial.print("Playlist file too large, max: "); + Serial.println(sizeof(playlist_buffer)); + return; + } + + if (playlistFile.read(&playlist_buffer, sizeof(playlist_buffer)) != fileSize) { + Serial.println("Could not read playlist file"); + return; + } + + playlistFile.close(); + + Serial.println("Parsing playlist..."); + + // parse playlist + auto playlistStr = String(playlist_buffer, fileSize); + Serial.println(playlistStr); + + auto idx = 0; + while (true) { + auto nextIdx = playlistStr.indexOf('\n', idx); + if (nextIdx == -1) { + break; + } + + auto line = playlistStr.substring(idx, nextIdx); + if (line.length() == 0) { + break; + } + if (line.length() > 8) { + Serial.print("Video name too long, size: "); + Serial.print(line.length()); + Serial.println(", max 8"); + break; + } + + playlist[playlistSize++] = line; + idx = nextIdx + 1; + } + + Serial.println("Playlist loaded"); + + for (size_t i = 0; i < playlistSize; i++) { + Serial.print(i); + Serial.print(": "); + Serial.println(playlist[i]); + } +} + File audioFile; -void sd_loadAudio() { - if (!SD.exists("byebyem/audio.bin")) { +void sd_loadAudio(size_t index) { + if (index >= playlistSize) { + Serial.println("Index out of range"); + return; + } + + auto path = "video/" + playlist[index] + "/audio.bin"; + + if (!SD.exists(path)) { Serial.println("Audio not found :("); return; } @@ -168,7 +241,7 @@ void sd_loadAudio() { audioFile.close(); } - audioFile = SD.open("byebyem/audio.bin", FILE_READ); + audioFile = SD.open(path, FILE_READ); Serial.println("Audio file opened"); audio_stop(); @@ -201,16 +274,23 @@ void sd_loadNextAudio() { Serial.println("End of audio file, rewinding..."); audioFile.seek(0); } else { + /* Serial.print("Read "); Serial.print(bytesRead); Serial.print(" bytes from audio file in "); Serial.print(millis() - b4); Serial.println("ms"); + */ } } -bool sd_loadGfxFrameLengths() { - auto path = "byebyem/gfx_len.bin"; +bool sd_loadGfxFrameLengths(size_t index) { + if (index >= playlistSize) { + Serial.println("Index out of range"); + return false; + } + + auto path = "video/" + playlist[index] + "/gfx_len.bin"; if (!SD.exists(path)) { Serial.println("Frame lengths file not found :("); @@ -241,8 +321,13 @@ File gfxFile; uint16_t frameIdx = 0; -bool sd_loadGfxBlob() { - auto path = "byebyem/gfx.bin"; +bool sd_loadGfxBlob(size_t index) { + if (index >= playlistSize) { + Serial.println("Index out of range"); + return false; + } + + auto path = "video/" + playlist[index] + "/gfx.bin"; if (!SD.exists(path)) { Serial.println("Gfx blob file not found :("); @@ -252,6 +337,8 @@ bool sd_loadGfxBlob() { gfxFile = SD.open(path, FILE_READ); Serial.println("Opened video frames"); + frameIdx = 0; + return true; } diff --git a/firmware/src/sd.h b/firmware/src/sd.h index ee49952..c243909 100644 --- a/firmware/src/sd.h +++ b/firmware/src/sd.h @@ -5,8 +5,11 @@ void setupSD(); bool isSDCardInserted(); -void sd_loadAudio(); +extern size_t playlistSize; + +void sd_loadPlaylist(); +void sd_loadAudio(size_t index); void sd_loadNextAudio(); -bool sd_loadGfxFrameLengths(); -bool sd_loadGfxBlob(); +bool sd_loadGfxFrameLengths(size_t index); +bool sd_loadGfxBlob(size_t index); int32_t sd_loadNextFrame();