Deluge Firmware 1.3.0
Build date: 2026.10.29
Loading...
Searching...
No Matches
storage_manager.h
1/*
2 * Copyright © 2014-2023 Synthstrom Audible Limited
3 *
4 * This file is part of The Synthstrom Audible Deluge Firmware.
5 *
6 * The Synthstrom Audible Deluge Firmware is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software Foundation,
8 * either version 3 of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with this program.
15 * If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#pragma once
19
20#include "definitions_cxx.hpp"
21#include "extern.h"
22#include "fatfs/fatfs.hpp"
23#include "model/sync.h"
24#include "util/firmware_version.h"
25
26#include <cstdint>
27#include <optional>
28
29extern "C" {
30#include "fatfs/ff.h"
31}
32
33extern void deleteOldSongBeforeLoadingNew();
34
35extern FatFS::Filesystem fileSystem;
36
37class Instrument;
38class PlaybackMode;
41class Song;
42class InstrumentClip;
43class Drum;
44class String;
46class ParamManager;
47class SoundDrum;
48class FileItem;
49class MIDIInstrument;
50
51class SMSharedData {};
52
53class FileReader {
54public:
55 FileReader();
56 FileReader(char* memBuffer, uint32_t bufLen);
57 virtual ~FileReader();
58
59 FIL readFIL;
60 char* fileClusterBuffer;
61 UINT currentReadBufferEndPos;
62 int32_t fileReadBufferCurrentPos;
63
64 FRESULT closeWriter();
65
66 bool peekChar(char* thisChar);
67 bool readChar(char* thisChar);
68 uint32_t bytesRemainingInBuffer() { return currentReadBufferEndPos - fileReadBufferCurrentPos; }
69 char* GetCurrentAddressInBuffer() { return fileClusterBuffer + fileReadBufferCurrentPos; }
70
71protected:
72 bool callRoutines = true;
73 bool readFileCluster();
74 bool readFileClusterIfNecessary();
75
76 void readDone();
77
78 bool memoryBased = false;
79 int32_t readCount; // Used for multitask interleaving.
80 bool reachedBufferEnd;
81 void resetReader();
82};
83
84class FileWriter {
85public:
86 FIL writeFIL;
87 FileWriter();
88 FileWriter(bool inMem);
89
90 virtual ~FileWriter();
91
92 Error closeAfterWriting(char const* path, char const* beginningString, char const* endString);
93
94 void writeByte(int8_t b);
95 void writeBlock(uint8_t* block, uint32_t size);
96 void writeChars(char const* output);
97 FRESULT closeWriter();
98
99 char* getBufferPtr() { return writeClusterBuffer; }
100 int32_t bytesWritten();
101 void setMemoryBased() {
102 memoryBased = true;
103 callRoutines = false;
104 }
105
106protected:
107 void resetWriter();
108 Error writeBufferToFile();
109 Error verifyWrittenFile(char const* beginningString, char const* endString);
110 bool memoryBased = false;
111 bool callRoutines = true;
112 uint8_t indentAmount;
113 char* writeClusterBuffer;
114 uint32_t bufferSize;
115 int32_t fileWriteBufferCurrentPos;
116 int32_t fileTotalBytesWritten;
117 bool fileAccessFailedDuringWrite;
118};
119
121public:
122 virtual void writeAttribute(char const* name, int32_t number, bool onNewLine = true) = 0;
123 virtual void writeAttribute(char const* name, char const* value, bool onNewLine = true) = 0;
124 virtual void writeAttributeHex(char const* name, int32_t number, int32_t numChars, bool onNewLine = true) = 0;
125 virtual void writeAttributeHexBytes(char const* name, uint8_t* data, int32_t numBytes, bool onNewLine = true) = 0;
126 virtual void writeTagNameAndSeperator(char const* tag) = 0;
127 virtual void writeTag(char const* tag, int32_t number, bool box = false) = 0;
128 virtual void writeTag(char const* tag, char const* contents, bool box = false, bool quote = true) = 0;
129 virtual void writeOpeningTag(char const* tag, bool startNewLineAfter = true, bool box = false) = 0;
130 virtual void writeOpeningTagBeginning(char const* tag, bool box = false, bool newLineBefore = true) = 0;
131 virtual void writeOpeningTagEnd(bool startNewLineAfter = true) = 0;
132 virtual void closeTag(bool box = false) = 0;
133 virtual void writeClosingTag(char const* tag, bool shouldPrintIndents = true, bool box = false) = 0;
134 virtual void writeArrayStart(char const* tag, bool startNewLineAfter = true, bool box = false) = 0;
135 virtual void writeArrayEnding(char const* tag, bool shouldPrintIndents = true, bool box = false) = 0;
136 virtual void printIndents() = 0;
137 virtual void insertCommaIfNeeded() = 0;
138 virtual void write(char const* output) = 0;
139 virtual Error closeFileAfterWriting(char const* path = nullptr, char const* beginningString = nullptr,
140 char const* endString = nullptr) = 0;
141
142 virtual void reset() = 0;
143 void writeFirmwareVersion();
144
145 void writeEarliestCompatibleFirmwareVersion(char const* versionString) {
146 writeAttribute("earliestCompatibleFirmware", versionString);
147 }
148
149 void writeSyncTypeToFile(Song* song, char const* name, SyncType value, bool onNewLine) {
150 writeAttribute(name, (int32_t)value, onNewLine);
151 }
152
153 void writeAbsoluteSyncLevelToFile(Song* song, char const* name, SyncLevel internalValue, bool onNewLine);
154};
155
156class XMLSerializer : public Serializer, public FileWriter {
157public:
158 XMLSerializer();
159 ~XMLSerializer() override = default;
160
161 void writeAttribute(char const* name, int32_t number, bool onNewLine = true) override;
162 void writeAttribute(char const* name, char const* value, bool onNewLine = true) override;
163 void writeAttributeHex(char const* name, int32_t number, int32_t numChars, bool onNewLine = true) override;
164 void writeAttributeHexBytes(char const* name, uint8_t* data, int32_t numBytes, bool onNewLine = true) override;
165 void writeTagNameAndSeperator(char const* tag) override;
166 void writeTag(char const* tag, int32_t number, bool box = false) override;
167 void writeTag(char const* tag, char const* contents, bool box = false, bool quote = true) override;
168 void writeOpeningTag(char const* tag, bool startNewLineAfter = true, bool box = false) override;
169 void writeOpeningTagBeginning(char const* tag, bool box = false, bool newLineBefore = true) override;
170 void writeOpeningTagEnd(bool startNewLineAfter = true) override;
171 void closeTag(bool box = false) override;
172 void writeClosingTag(char const* tag, bool shouldPrintIndents = true, bool box = false) override;
173 void writeArrayStart(char const* tag, bool shouldPrintIndents = true, bool box = true) override;
174 void writeArrayEnding(char const* tag, bool shouldPrintIndents = true, bool box = true) override;
175 void insertCommaIfNeeded() override {}
176 void printIndents() override;
177 void write(char const* output) override;
178 Error closeFileAfterWriting(char const* path = nullptr, char const* beginningString = nullptr,
179 char const* endString = nullptr) override;
180 void reset() override;
181
182private:
183 uint8_t indentAmount;
184};
185
187public:
188 virtual bool prepareToReadTagOrAttributeValueOneCharAtATime() = 0;
189 virtual char readNextCharOfTagOrAttributeValue() = 0;
190 virtual int32_t getNumCharsRemainingInValueBeforeEndOfCluster() = 0;
191
192 virtual char const* readNextTagOrAttributeName() = 0;
193 virtual char const* readTagOrAttributeValue() = 0;
194 virtual int32_t readTagOrAttributeValueInt() = 0;
195 virtual int32_t readTagOrAttributeValueHex(int32_t errorValue) = 0;
196 virtual int readTagOrAttributeValueHexBytes(uint8_t* bytes, int32_t maxLen) = 0;
197 virtual Error tryReadingFirmwareTagFromFile(char const* tagName, bool ignoreIncorrectFirmware = false) = 0;
198
199 virtual char const* readNextCharsOfTagOrAttributeValue(int32_t numChars) = 0;
200 virtual Error readTagOrAttributeValueString(String* string) = 0;
201 virtual bool match(char const ch) = 0;
202 virtual void exitTag(char const* exitTagName = NULL, bool closeObject = false) = 0;
203
204 virtual void reset() = 0;
205
206 Error readTagOrAttributeValueString(std::string& string) {
207 String tmp;
208 Error error = readTagOrAttributeValueString(&tmp);
209 if (error == Error::NONE) {
210 string = tmp.get();
211 }
212 return error;
213 }
214};
215
216class FileDeserializer : public Deserializer, public FileReader {
217public:
218 FileDeserializer() : FileReader() {}
219 FileDeserializer(uint8_t* inbuf, size_t buflen) : FileReader((char*)inbuf, buflen) {}
220};
221
222class XMLDeserializer : public FileDeserializer {
223public:
224 XMLDeserializer();
225 ~XMLDeserializer() override = default;
226
227 bool prepareToReadTagOrAttributeValueOneCharAtATime() override;
228 char const* readNextTagOrAttributeName() override;
229 char readNextCharOfTagOrAttributeValue() override;
230 int32_t getNumCharsRemainingInValueBeforeEndOfCluster() override;
231
232 int32_t readTagOrAttributeValueInt() override;
233 int32_t readTagOrAttributeValueHex(int32_t errorValue) override;
234 int readTagOrAttributeValueHexBytes(uint8_t* bytes, int32_t maxLen) override;
235
236 int readHexBytesUntil(uint8_t* bytes, int32_t maxLen, char endPos);
237 char const* readNextCharsOfTagOrAttributeValue(int32_t numChars) override;
238 Error readTagOrAttributeValueString(String* string) override;
239 char const* readTagOrAttributeValue() override;
240 bool match(char const ch) override;
241
242 void exitTag(char const* exitTagName = NULL, bool closeObject = false) override;
243 Error openXMLFile(FilePointer* filePointer, char const* firstTagName, char const* altTagName = "",
244 bool ignoreIncorrectFirmware = false);
245 void reset() override;
246
247 Error tryReadingFirmwareTagFromFile(char const* tagName, bool ignoreIncorrectFirmware) override;
248
249private:
250 char charAtEndOfValue;
251 uint8_t xmlArea; // state variable for tokenizer
252
253 int32_t tagDepthCaller; // How deeply indented in XML the main Deluge classes think we are, as data being read.
254 int32_t tagDepthFile; // Will temporarily be different to the above as unwanted / unused XML tags parsed on the way
255 // to finding next useful data.
256
257 char stringBuffer[kFilenameBufferSize];
258
259 void skipUntilChar(char endChar);
260
261 char const* readTagName();
262 char const* readNextAttributeName();
263 char const* readUntilChar(char endChar);
264 char const* readAttributeValue();
265
266 int32_t readIntUntilChar(char endChar);
267 bool getIntoAttributeValue();
268 int32_t readAttributeValueInt();
269
270 Error readStringUntilChar(String* string, char endChar);
271 Error readAttributeValueString(String* string);
272};
273
274class JsonSerializer : public Serializer, public FileWriter {
275public:
276 JsonSerializer();
277 ~JsonSerializer() override = default;
278
279 void writeAttribute(char const* name, int32_t number, bool onNewLine = true) override;
280 void writeAttribute(char const* name, char const* value, bool onNewLine = true) override;
281 void writeAttributeHex(char const* name, int32_t number, int32_t numChars, bool onNewLine = true) override;
282 void writeAttributeHexBytes(char const* name, uint8_t* data, int32_t numBytes, bool onNewLine = true) override;
283 void writeTagNameAndSeperator(char const* tag) override;
284 void writeTag(char const* tag, int32_t number, bool box = false) override;
285 void writeTag(char const* tag, char const* contents, bool box = false, bool quote = true) override;
286 void writeOpeningTag(char const* tag, bool startNewLineAfter = true, bool box = false) override;
287 void writeOpeningTagBeginning(char const* tag, bool box = false, bool newLineBefore = true) override;
288 void writeOpeningTagEnd(bool startNewLineAfter = true) override;
289 void closeTag(bool box = false) override;
290 void writeClosingTag(char const* tag, bool shouldPrintIndents = true, bool box = false) override;
291 void writeArrayStart(char const* tag, bool shouldPrintIndents = true, bool box = false) override;
292 void writeArrayEnding(char const* tag, bool shouldPrintIndents = true, bool box = false) override;
293 void printIndents() override;
294 void insertCommaIfNeeded() override;
295 void write(char const* output) override;
296 Error closeFileAfterWriting(char const* path = nullptr, char const* beginningString = nullptr,
297 char const* endString = nullptr) override;
298 void reset() override;
299 // Begin Json-only API
300
301private:
302 uint8_t indentAmount;
303 bool firstItemHasBeenWritten = false;
304};
305
306class JsonDeserializer : public FileDeserializer {
307public:
308 JsonDeserializer();
309 JsonDeserializer(uint8_t* inbuf, size_t buflen);
310 ~JsonDeserializer() override = default;
311
312 bool prepareToReadTagOrAttributeValueOneCharAtATime() override;
313 char const* readNextTagOrAttributeName() override;
314 char readNextCharOfTagOrAttributeValue() override;
315 int32_t getNumCharsRemainingInValueBeforeEndOfCluster() override;
316
317 int32_t readTagOrAttributeValueInt() override;
318 int32_t readTagOrAttributeValueHex(int32_t errorValue) override;
319 int readTagOrAttributeValueHexBytes(uint8_t* bytes, int32_t maxLen) override;
320
321 int readHexBytesUntil(uint8_t* bytes, int32_t maxLen, char endPos);
322 char const* readNextCharsOfTagOrAttributeValue(int32_t numChars) override;
323 Error readTagOrAttributeValueString(String* string) override;
324 char const* readTagOrAttributeValue() override;
325 bool match(char const ch) override;
326 void exitTag(char const* exitTagName = NULL, bool closeObject = false) override;
327
328 Error openJsonFile(FilePointer* filePointer, char const* firstTagName, char const* altTagName = "",
329 bool ignoreIncorrectFirmware = false);
330 void reset() override;
331 Error tryReadingFirmwareTagFromFile(char const* tagName, bool ignoreIncorrectFirmware) override;
332 void setReplySeqNum(uint8_t msgNum) { replySeqNum = msgNum; }
333 uint8_t getReplySeqNum() { return replySeqNum; }
334
335private:
336 uint8_t replySeqNum = 0;
337 int32_t objectDepth;
338 int32_t arrayDepth;
339
340 enum JsonState { NewFile, KeyRead, ValueRead, ReadError };
341 JsonState readState = NewFile;
342
343 char stringBuffer[kFilenameBufferSize];
344
345 void skipUntilChar(char endChar);
346 char unescape(char inchar);
347 bool skipWhiteSpace(bool commasToo = true);
348 char const* readQuotedString();
349 char const* readKeyName();
350 char const* readNextAttributeName();
351 char const* readUntilChar(char endChar);
352 char const* readAttributeValue();
353
354 int32_t readInt();
355 bool getIntoAttributeValue();
356 int32_t readAttributeValueInt();
357 Error readAttributeValueString(String* string);
358
359 Error readStringUntilChar(String* string, char endChar);
360};
361
362extern XMLSerializer smSerializer;
363extern XMLDeserializer smDeserializer;
364extern JsonSerializer smJsonSerializer;
365extern JsonDeserializer smJsonDeserializer;
366extern Serializer& GetSerializer();
367extern FileDeserializer* activeDeserializer;
368
369namespace StorageManager {
370
371std::expected<FatFS::File, Error> createFile(char const* filePath, bool mayOverwrite);
372Error createXMLFile(char const* pathName, XMLSerializer& writer, bool mayOverwrite = false, bool displayErrors = true);
373Error createJsonFile(char const* pathName, JsonSerializer& writer, bool mayOverwrite = false,
374 bool displayErrors = true);
375Error openXMLFile(FilePointer* filePointer, XMLDeserializer& reader, char const* firstTagName,
376 char const* altTagName = "", bool ignoreIncorrectFirmware = false);
377Error openJsonFile(FilePointer* filePointer, JsonDeserializer& reader, char const* firstTagName,
378 char const* altTagName = "", bool ignoreIncorrectFirmware = false);
379Error openDelugeFile(FileItem* currentFileItem, char const* firstTagName, char const* altTagName = "",
380 bool ignoreIncorrectFirmware = false);
381Error initSD();
382
383bool fileExists(char const* pathName);
384bool fileExists(char const* pathName, FilePointer* fp);
386bool buildPathToFile(const char* fileName);
387
388bool checkSDPresent();
389bool checkSDInitialized();
390
391Instrument* createNewInstrument(OutputType newOutputType, ParamManager* getParamManager = nullptr);
392Error loadInstrumentFromFile(Song* song, InstrumentClip* clip, OutputType outputType, bool mayReadSamplesFromFiles,
393 Instrument** getInstrument, FilePointer* filePointer, String* name, String* dirPath);
394Instrument* createNewNonAudioInstrument(OutputType outputType, int32_t slot, int32_t subSlot);
395
396Error openMidiDeviceDefinitionFile(FilePointer* filePointer);
397Error loadMidiDeviceDefinitionFile(MIDIInstrument* midiInstrument, FilePointer* filePointer, String* fileName,
398 bool updateFileName = true);
399
400Error openPatternFile(FilePointer* filePointer);
401Error loadPatternFile(FilePointer* filePointer, String* fileName, bool overwriteExisting, bool noScaling,
402 bool previewOnly, bool selectedDrumOnly);
403
404Error openFavouriteFile(FilePointer* filePointer);
405Error loadFavouriteFile(FilePointer* filePointer, String* fileName);
406
407Drum* createNewDrum(DrumType drumType);
408Error loadSynthToDrum(Song* song, InstrumentClip* clip, bool mayReadSamplesFromFiles, SoundDrum** getInstrument,
409 FilePointer* filePointer, String* name, String* dirPath);
410void openFilePointer(FilePointer* fp, FileReader& reader);
411
412Error checkSpaceOnCard();
413
414Error openInstrumentFile(OutputType outputType, FilePointer* filePointer);
415} // namespace StorageManager
416
417extern FirmwareVersion song_firmware_version;
418extern FILINFO staticFNO;
419extern FatFS::Directory staticDIR;
420extern const bool writeJsonFlag;
421
422inline bool isCardReady() {
423 return !sdRoutineLock && Error::NONE == StorageManager::initSD();
424}
Definition arpeggiator.h:48
Definition storage_manager.h:186
Definition drum.h:44
Definition storage_manager.h:216
Definition file_item.h:24
Definition storage_manager.h:53
Definition instrument_clip.h:48
Definition instrument.h:45
Definition storage_manager.h:306
Definition storage_manager.h:274
Definition midi_instrument.h:38
Definition midi_param_collection.h:30
Definition param_manager.h:155
Definition param_manager.h:45
Definition playback_mode.h:30
Definition storage_manager.h:51
Definition storage_manager.h:120
Definition song.h:103
Definition sound_drum.h:28
Definition d_string.h:41
Definition storage_manager.h:222
Definition storage_manager.h:156