Skip to content

Commit d0eb0db

Browse files
committed
FSEQ usermod update (resolve conflicts)
1 parent dad3c4e commit d0eb0db

File tree

8 files changed

+758
-581
lines changed

8 files changed

+758
-581
lines changed

usermods/FSEQ/fseq_player.cpp

Lines changed: 97 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,32 @@
11
#include "fseq_player.h"
2-
#include <Arduino.h>
2+
#include "usermod_fseq.h"
33
#include "wled.h"
4+
#include <Arduino.h>
45

56
#ifdef WLED_USE_SD_SPI
6-
#include <SPI.h>
7-
#include <SD.h>
7+
#include <SD.h>
8+
#include <SPI.h>
89
#elif defined(WLED_USE_SD_MMC)
9-
#include "SD_MMC.h"
10+
#include "SD_MMC.h"
11+
#endif
12+
13+
// Static member definitions moved from header to avoid multiple definition
14+
// errors
15+
const char UsermodFseq::_name[] PROGMEM = "usermod FSEQ sd card";
16+
17+
#ifdef WLED_USE_SD_SPI
18+
int8_t UsermodFseq::configPinSourceSelect = 5;
19+
int8_t UsermodFseq::configPinSourceClock = 18;
20+
int8_t UsermodFseq::configPinPoci = 19;
21+
int8_t UsermodFseq::configPinPico = 23;
1022
#endif
1123

1224
File FSEQPlayer::recordingFile;
13-
uint8_t FSEQPlayer::colorChannels = 3;
14-
int32_t FSEQPlayer::recordingRepeats = RECORDING_REPEAT_DEFAULT;
25+
String FSEQPlayer::currentFileName = "";
26+
float FSEQPlayer::secondsElapsed = 0;
27+
28+
uint8_t FSEQPlayer::colorChannels = 3;
29+
int32_t FSEQPlayer::recordingRepeats = RECORDING_REPEAT_DEFAULT;
1530
uint32_t FSEQPlayer::now = 0;
1631
uint32_t FSEQPlayer::next_time = 0;
1732
uint16_t FSEQPlayer::playbackLedStart = 0;
@@ -22,37 +37,42 @@ FSEQPlayer::FileHeader FSEQPlayer::file_header;
2237

2338
inline uint32_t FSEQPlayer::readUInt32() {
2439
char buffer[4];
25-
if (recordingFile.readBytes(buffer, 4) < 4) return 0;
26-
return (uint32_t)buffer[0] | ((uint32_t)buffer[1] << 8) | ((uint32_t)buffer[2] << 16) | ((uint32_t)buffer[3] << 24);
40+
if (recordingFile.readBytes(buffer, 4) < 4)
41+
return 0;
42+
return (uint32_t)buffer[0] | ((uint32_t)buffer[1] << 8) |
43+
((uint32_t)buffer[2] << 16) | ((uint32_t)buffer[3] << 24);
2744
}
2845

2946
inline uint32_t FSEQPlayer::readUInt24() {
3047
char buffer[3];
31-
if (recordingFile.readBytes(buffer, 3) < 3) return 0;
32-
return (uint32_t)buffer[0] | ((uint32_t)buffer[1] << 8) | ((uint32_t)buffer[2] << 16);
48+
if (recordingFile.readBytes(buffer, 3) < 3)
49+
return 0;
50+
return (uint32_t)buffer[0] | ((uint32_t)buffer[1] << 8) |
51+
((uint32_t)buffer[2] << 16);
3352
}
3453

3554
inline uint16_t FSEQPlayer::readUInt16() {
3655
char buffer[2];
37-
if (recordingFile.readBytes(buffer, 2) < 2) return 0;
56+
if (recordingFile.readBytes(buffer, 2) < 2)
57+
return 0;
3858
return (uint16_t)buffer[0] | ((uint16_t)buffer[1] << 8);
3959
}
4060

4161
inline uint8_t FSEQPlayer::readUInt8() {
4262
char buffer[1];
43-
if (recordingFile.readBytes(buffer, 1) < 1) return 0;
63+
if (recordingFile.readBytes(buffer, 1) < 1)
64+
return 0;
4465
return (uint8_t)buffer[0];
4566
}
4667

47-
bool FSEQPlayer::fileOnSD(const char* filepath) {
68+
bool FSEQPlayer::fileOnSD(const char *filepath) {
4869
uint8_t cardType = SD_ADAPTER.cardType();
49-
if(cardType == CARD_NONE) return false;
70+
if (cardType == CARD_NONE)
71+
return false;
5072
return SD_ADAPTER.exists(filepath);
5173
}
5274

53-
bool FSEQPlayer::fileOnFS(const char* filepath) {
54-
return false;
55-
}
75+
bool FSEQPlayer::fileOnFS(const char *filepath) { return false; }
5676

5777
void FSEQPlayer::printHeaderInfo() {
5878
DEBUG_PRINTLN("FSEQ file header:");
@@ -68,18 +88,21 @@ void FSEQPlayer::printHeaderInfo() {
6888

6989
void FSEQPlayer::processFrameData() {
7090
uint16_t packetLength = file_header.channel_count;
71-
uint16_t lastLed = min(playbackLedStop, uint16_t(playbackLedStart + (packetLength / 3)));
91+
uint16_t lastLed =
92+
min(playbackLedStop, uint16_t(playbackLedStart + (packetLength / 3)));
7293
char frame_data[buffer_size];
73-
CRGB* crgb = reinterpret_cast<CRGB*>(frame_data);
94+
CRGB *crgb = reinterpret_cast<CRGB *>(frame_data);
7495
uint16_t bytes_remaining = packetLength;
7596
uint16_t index = playbackLedStart;
7697
while (index < lastLed && bytes_remaining > 0) {
7798
uint16_t length = min(bytes_remaining, buffer_size);
7899
recordingFile.readBytes(frame_data, length);
79100
bytes_remaining -= length;
80101
for (uint16_t offset = 0; offset < length / 3; offset++) {
81-
setRealtimePixel(index, crgb[offset].r, crgb[offset].g, crgb[offset].b, 0);
82-
if (++index > lastLed) break;
102+
setRealtimePixel(index, crgb[offset].r, crgb[offset].g, crgb[offset].b,
103+
0);
104+
if (++index > lastLed)
105+
break;
83106
}
84107
}
85108
strip.show();
@@ -110,7 +133,8 @@ bool FSEQPlayer::stopBecauseAtTheEnd() {
110133
}
111134

112135
void FSEQPlayer::playNextRecordingFrame() {
113-
if (stopBecauseAtTheEnd()) return;
136+
if (stopBecauseAtTheEnd())
137+
return;
114138
uint32_t offset = file_header.channel_count * frame++;
115139
offset += file_header.channel_data_offset;
116140
if (!recordingFile.seek(offset)) {
@@ -124,12 +148,15 @@ void FSEQPlayer::playNextRecordingFrame() {
124148

125149
void FSEQPlayer::handlePlayRecording() {
126150
now = millis();
127-
if (realtimeMode != REALTIME_MODE_FSEQ) return;
128-
if (now < next_time) return;
151+
if (realtimeMode != REALTIME_MODE_FSEQ)
152+
return;
153+
if (now < next_time)
154+
return;
129155
playNextRecordingFrame();
130156
}
131157

132-
void FSEQPlayer::loadRecording(const char* filepath, uint16_t startLed, uint16_t stopLed, float secondsElapsed) {
158+
void FSEQPlayer::loadRecording(const char *filepath, uint16_t startLed,
159+
uint16_t stopLed, float secondsElapsed) {
133160
if (recordingFile.available()) {
134161
clearLastPlayback();
135162
recordingFile.close();
@@ -141,14 +168,19 @@ void FSEQPlayer::loadRecording(const char* filepath, uint16_t startLed, uint16_t
141168
playbackLedStart = sg.start;
142169
playbackLedStop = sg.stop;
143170
}
144-
DEBUG_PRINTF("FSEQ load animation on LED %d to %d\n", playbackLedStart, playbackLedStop);
171+
DEBUG_PRINTF("FSEQ load animation on LED %d to %d\n", playbackLedStart,
172+
playbackLedStop);
145173
if (fileOnSD(filepath)) {
146174
DEBUG_PRINTF("Read file from SD: %s\n", filepath);
147175
recordingFile = SD_ADAPTER.open(filepath, "rb");
176+
currentFileName = String(filepath);
177+
if (currentFileName.startsWith("/"))
178+
currentFileName = currentFileName.substring(1);
148179
} else if (fileOnFS(filepath)) {
149180
DEBUG_PRINTF("Read file from FS: %s\n", filepath);
150181
} else {
151-
DEBUG_PRINTF("File %s not found (%s)\n", filepath, USED_STORAGE_FILESYSTEMS);
182+
DEBUG_PRINTF("File %s not found (%s)\n", filepath,
183+
USED_STORAGE_FILESYSTEMS);
152184
return;
153185
}
154186
if ((uint64_t)recordingFile.available() < sizeof(file_header)) {
@@ -170,17 +202,23 @@ void FSEQPlayer::loadRecording(const char* filepath, uint16_t startLed, uint16_t
170202
printHeaderInfo();
171203
if (file_header.identifier[0] != 'P' || file_header.identifier[1] != 'S' ||
172204
file_header.identifier[2] != 'E' || file_header.identifier[3] != 'Q') {
173-
DEBUG_PRINTF("Error reading FSEQ file %s header, invalid identifier\n", filepath);
205+
DEBUG_PRINTF("Error reading FSEQ file %s header, invalid identifier\n",
206+
filepath);
174207
recordingFile.close();
175208
return;
176209
}
177-
if (((uint64_t)file_header.channel_count * (uint64_t)file_header.frame_count) + file_header.header_length > UINT32_MAX) {
178-
DEBUG_PRINTF("Error reading FSEQ file %s header, file too long (max 4gb)\n", filepath);
210+
if (((uint64_t)file_header.channel_count *
211+
(uint64_t)file_header.frame_count) +
212+
file_header.header_length >
213+
UINT32_MAX) {
214+
DEBUG_PRINTF("Error reading FSEQ file %s header, file too long (max 4gb)\n",
215+
filepath);
179216
recordingFile.close();
180217
return;
181218
}
182219
if (file_header.step_time < 1) {
183-
DEBUG_PRINTF("Invalid step time %d, using default %d instead\n", file_header.step_time, FSEQ_DEFAULT_STEP_TIME);
220+
DEBUG_PRINTF("Invalid step time %d, using default %d instead\n",
221+
file_header.step_time, FSEQ_DEFAULT_STEP_TIME);
184222
file_header.step_time = FSEQ_DEFAULT_STEP_TIME;
185223
}
186224
if (realtimeOverride == REALTIME_OVERRIDE_ONCE) {
@@ -197,37 +235,59 @@ void FSEQPlayer::loadRecording(const char* filepath, uint16_t startLed, uint16_t
197235
recordingRepeats = RECORDING_REPEAT_DEFAULT;
198236
}
199237
playNextRecordingFrame();
238+
playNextRecordingFrame();
200239
}
201240

202241
void FSEQPlayer::clearLastPlayback() {
203242
for (uint16_t i = playbackLedStart; i < playbackLedStop; i++) {
204243
setRealtimePixel(i, 0, 0, 0, 0);
205244
}
206245
frame = 0;
246+
currentFileName = "";
207247
}
208248

209249
bool FSEQPlayer::isPlaying() {
210250
return recordingFile && recordingFile.available();
211251
}
212252

253+
String FSEQPlayer::getFileName() { return currentFileName; }
254+
255+
float FSEQPlayer::getElapsedSeconds() {
256+
if (!isPlaying())
257+
return 0;
258+
// Calculate approximate elapsed seconds based on frame and step time
259+
// Or if secondsElapsed is updated elsewhere, return it.
260+
// Ideally secondsElapsed should be updated during playback.
261+
// But for now, let's just calculate it from frame count
262+
return (float)frame * (float)file_header.step_time / 1000.0f;
263+
}
264+
213265
void FSEQPlayer::syncPlayback(float secondsElapsed) {
214266
if (!isPlaying()) {
215267
DEBUG_PRINTLN("[FSEQ] Sync: Playback not active, cannot sync.");
216268
return;
217269
}
218-
219-
uint32_t expectedFrame = (uint32_t)((secondsElapsed * 1000.0f) / file_header.step_time);
270+
271+
// Update internal secondsElapsed if we were tracking it
272+
// FSEQPlayer::secondsElapsed = secondsElapsed; // If we were tracking it
273+
274+
uint32_t expectedFrame =
275+
(uint32_t)((secondsElapsed * 1000.0f) / file_header.step_time);
220276
int32_t diff = (int32_t)expectedFrame - (int32_t)frame;
221-
277+
222278
if (abs(diff) > 2) {
223279
frame = expectedFrame;
224-
uint32_t offset = file_header.channel_data_offset + file_header.channel_count * frame;
280+
uint32_t offset =
281+
file_header.channel_data_offset + file_header.channel_count * frame;
225282
if (recordingFile.seek(offset)) {
226-
DEBUG_PRINTF("[FSEQ] Sync: Adjusted frame to %lu (diff=%ld)\n", expectedFrame, diff);
283+
DEBUG_PRINTF("[FSEQ] Sync: Adjusted frame to %lu (diff=%ld)\n",
284+
expectedFrame, diff);
227285
} else {
228286
DEBUG_PRINTLN("[FSEQ] Sync: Failed to seek to new frame");
229287
}
230288
} else {
231-
DEBUG_PRINTF("[FSEQ] Sync: No adjustment needed (current frame: %lu, expected: %lu)\n", frame, expectedFrame);
289+
DEBUG_PRINTF("[FSEQ] Sync: No adjustment needed (current frame: %lu, "
290+
"expected: %lu)\n",
291+
frame, expectedFrame);
232292
}
233293
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include "fseq_player.h"
2+
#include "usermod_fseq.h"
3+
#include "wled.h"
4+
#include <Arduino.h>
5+
6+
#ifdef WLED_USE_SD_SPI
7+
#include <SD.h>
8+
#include <SPI.h>
9+
#endif
10+
11+
// Static member definitions moved from header to avoid multiple definition errors
12+
const char UsermodFseq::_name[] PROGMEM = "usermod FSEQ sd card";
13+
14+
#ifdef WLED_USE_SD_SPI
15+
int8_t UsermodFseq::configPinSourceSelect = 5;
16+
int8_t UsermodFseq::configPinSourceClock = 18;
17+
int8_t UsermodFseq::configPinPoci = 19;
18+
int8_t UsermodFseq::configPinPico = 23;
19+
#endif
20+
21+
File FSEQPlayer::recordingFile;
22+
uint8_t FSEQPlayer::colorChannels = 3;
23+
int32_t FSEQPlayer::recordingRepeats = RECORDING_REPEAT_DEFAULT;
24+
uint32_t FSEQPlayer::now = 0;
25+
uint32_t FSEQPlayer::next_time = 0;
26+
uint16_t FSEQPlayer::playbackLedStart = 0;
27+
uint16_t FSEQPlayer::playbackLedStop = uint16_t(-1);
28+
uint32_t FSEQPlayer::frame = 0;
29+
float FSEQPlayer::secondsElapsed = 0;
30+
// ... (rest of file content logic is not here, I should append or use replace)

usermods/FSEQ/fseq_player.h

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,56 @@
22
#define FSEQ_PLAYER_H
33

44
#ifndef RECORDING_REPEAT_LOOP
5-
#define RECORDING_REPEAT_LOOP -1
5+
#define RECORDING_REPEAT_LOOP -1
66
#endif
77
#ifndef RECORDING_REPEAT_DEFAULT
8-
#define RECORDING_REPEAT_DEFAULT 0
8+
#define RECORDING_REPEAT_DEFAULT 0
99
#endif
1010
#ifndef REALTIME_MODE_FSEQ
11-
#define REALTIME_MODE_FSEQ 3
11+
#define REALTIME_MODE_FSEQ 3
1212
#endif
1313

1414
#include "wled.h"
1515
#ifdef WLED_USE_SD_SPI
16-
#include <SPI.h>
17-
#include <SD.h>
16+
#include <SD.h>
17+
#include <SPI.h>
1818
#elif defined(WLED_USE_SD_MMC)
19-
#include "SD_MMC.h"
19+
#include "SD_MMC.h"
2020
#endif
2121

2222
class FSEQPlayer {
2323
public:
2424
struct FileHeader {
25-
uint8_t identifier[4];
25+
uint8_t identifier[4];
2626
uint16_t channel_data_offset;
27-
uint8_t minor_version;
28-
uint8_t major_version;
27+
uint8_t minor_version;
28+
uint8_t major_version;
2929
uint16_t header_length;
3030
uint32_t channel_count;
3131
uint32_t frame_count;
32-
uint8_t step_time;
33-
uint8_t flags;
32+
uint8_t step_time;
33+
uint8_t flags;
3434
};
3535

36-
static void loadRecording(const char* filepath, uint16_t startLed, uint16_t stopLed, float secondsElapsed = 0.0f);
36+
static void loadRecording(const char *filepath, uint16_t startLed,
37+
uint16_t stopLed, float secondsElapsed = 0.0f);
3738
static void handlePlayRecording();
3839
static void clearLastPlayback();
3940
static void syncPlayback(float secondsElapsed);
4041
static bool isPlaying();
42+
static String getFileName();
43+
static float getElapsedSeconds();
4144

4245
private:
4346
FSEQPlayer() {}
4447

4548
static const int FSEQ_DEFAULT_STEP_TIME = 50;
4649

47-
static File recordingFile;
48-
static uint8_t colorChannels;
49-
static int32_t recordingRepeats;
50+
static File recordingFile;
51+
static String currentFileName;
52+
static float secondsElapsed;
53+
static uint8_t colorChannels;
54+
static int32_t recordingRepeats;
5055
static uint32_t now;
5156
static uint32_t next_time;
5257
static uint16_t playbackLedStart;
@@ -60,8 +65,8 @@ class FSEQPlayer {
6065
static inline uint16_t readUInt16();
6166
static inline uint8_t readUInt8();
6267

63-
static bool fileOnSD(const char* filepath);
64-
static bool fileOnFS(const char* filepath);
68+
static bool fileOnSD(const char *filepath);
69+
static bool fileOnFS(const char *filepath);
6570
static void printHeaderInfo();
6671
static void processFrameData();
6772
static bool stopBecauseAtTheEnd();

usermods/FSEQ/register_usermod.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include "usermod_fpp.h"
2+
#include "usermod_fseq.h"
3+
#include "wled.h"
4+
5+
#ifdef USERMOD_FSEQ
6+
UsermodFseq usermodFseq;
7+
REGISTER_USERMOD(usermodFseq);
8+
#endif
9+
10+
#ifdef USERMOD_FPP
11+
UsermodFPP usermodFpp;
12+
REGISTER_USERMOD(usermodFpp);
13+
#endif

0 commit comments

Comments
 (0)