Deluge Firmware 1.3.0
Build date: 2026.03.02
Loading...
Searching...
No Matches
audio_file_manager.h
1/*
2 * Copyright © 2017-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#include "definitions_cxx.hpp"
20#include "storage/audio/audio_file_vector.h"
21#include "storage/cluster/cluster.h"
22#include "storage/cluster/cluster_priority_queue.h"
23#include <array>
24#include <cstdint>
25
26extern "C" {
27#include "fatfs/ff.h"
28}
29
30class Sample;
31class SampleCache;
32class String;
33class SampleRecorder;
34class Output;
35
36enum class AlternateLoadDirStatus {
37 NONE_SET,
38 NOT_FOUND,
39 MIGHT_EXIST,
40 DOES_EXIST,
41};
42
43char const* const audioRecordingFolderNames[] = {
44 "SAMPLES/CLIPS",
45 "SAMPLES/RECORD",
46 "SAMPLES/RESAMPLE",
47 "SAMPLES/EXPORTS",
48};
49
50/*
51 * ===================== SD card audio streaming ==================
52 *
53 * Audio streaming (for Samples and AudioClips) from the SD card functions by loading
54 * and caching Clusters of audio data from the SD card. A formatted card will have a
55 * cluster size for the filesystem - often 32kB, but it could be as small as 4kB, or even smaller maybe?
56 * The Deluge deals in these Clusters, whatever size they may be for the card, which makes
57 * sense because one Cluster always exists in one physical place on the SD card (or any disk),
58 * so may be easily loaded in one operation by DMA. Whereas consecutive clusters making up an
59 * (audio) file are often placed in completely different physical locations.
60 *
61 * For a Sample associated with a Sound or AudioClip, the Deluge keeps the first two Clusters of that file
62 * (from its set start-point and subject to reversing) permanently loaded in RAM, so playback of the
63 * Sample may begin instantly when the Sound or AudioClip is played. And if the Sample has a loop-start point,
64 * it keeps the first two Clusters from that point permanently loaded too.
65 *
66 * Then as the Sample plays, the currently-playing Cluster and the next one are kept loaded in RAM.
67 * Or rather, as soon as the “play-head” enters a new Cluster, the Deluge immediately enqueues
68 * the following Cluster to be loaded from the card ASAP.
69 *
70 * And then also, loaded Clusters remain loaded/cached in RAM for as long as possible while that RAM
71 * isn’t needed for something more important, so they may be played again without having to reload
72 * them from the card. Details on that process below.
73 *
74 * Quick note - Cluster objects are also used (in RAM) to store SampleCache data (which caches
75 * Sample data post-repitching or post-pitch-shifting), and “percussive” audio data (“perc” for short)
76 * which is condensed data for use by the time-stretching algorithm. The reason for these types
77 * of data being housed in Cluster objects is largely legacy, but it also is handy because all
78 * Cluster objects are made to be the same size in RAM, so “stealing” one will always make the
79 * right amount of space for another (see below to see what “stealing” means).
80 */
81
82class AudioFileManager {
83public:
84 AudioFileManager();
85
86 AudioFileVector audioFiles;
87
88 void init();
89 AudioFile* getAudioFileFromFilename(String& fileName, bool mayReadCard, Error* error, FilePointer* filePointer,
90 AudioFileType type, bool makeWaveTableWorkAtAllCosts = false);
91 bool loadCluster(Cluster& cluster, int32_t minNumReasonsAfter = 0);
92 void loadAnyEnqueuedClusters(int32_t maxNum = 128, bool mayProcessUserActionsBetween = false);
93 void removeReasonFromCluster(Cluster& cluster, char const* errorCode, bool deletingSong = false);
94
95 bool ensureEnoughMemoryForOneMoreAudioFile();
96
97 void slowRoutine();
98
99 Error setupAlternateAudioFilePath(String& newPath, int32_t dirPathLength, String& oldPath);
100 Error setupAlternateAudioFileDir(String& newPath, char const* rootDir, String& songFilenameWithoutExtension);
101 bool loadingQueueHasAnyLowestPriorityElements();
104 Error getUnusedAudioRecordingFilePath(String& filePath, String* tempFilePathForRecording,
105 AudioRecordingFolder folder, uint32_t* getNumber, const char* channelName,
106 String* songName);
107 void deleteAnyTempRecordedSamplesFromMemory();
108 void deleteUnusedAudioFileFromMemory(AudioFile& audioFile, int32_t i);
109 void deleteUnusedAudioFileFromMemoryIndexUnknown(AudioFile& audioFile);
110 bool tryToDeleteAudioFileFromMemoryIfItExists(char const* filePath);
111
112 void thingBeginningLoading(ThingType newThingType);
113 void thingFinishedLoading();
114
115 void setCardRead() { cardReadOnce = true; }
116 void setCardEjected() { cardEjected = true; }
117
118 ClusterPriorityQueue loadingQueue;
119
120 Cluster* clusterBeingLoaded;
121 int32_t minNumReasonsForClusterBeingLoaded; // Only valid when clusterBeingLoaded is set. And this exists for bug
122 // hunting only.
123
124 String alternateAudioFileLoadPath;
125 AlternateLoadDirStatus alternateLoadDirStatus = AlternateLoadDirStatus::NONE_SET;
126 ThingType thingTypeBeingLoaded = ThingType::NONE;
127 DIR alternateLoadDir;
128
129 std::array<int32_t, kNumAudioRecordingFolders> highestUsedAudioRecordingNumber;
130 std::bitset<kNumAudioRecordingFolders> highestUsedAudioRecordingNumberNeedsReChecking;
131 void firstCardRead();
132
133private:
134 bool cardReadOnce{false};
135 bool cardEjected;
136 bool cardDisabled = false;
137
138 uint32_t clusterSizeAtBoot{0};
139
140 void cardReinserted();
141 int32_t readBytes(char* buffer, int32_t num, int32_t* byteIndexWithinCluster, Cluster** currentCluster,
142 uint32_t* currentClusterIndex, uint32_t fileSize, Sample* sample);
143 int32_t loadAiff(Sample* newSample, uint32_t fileSize, Cluster** currentCluster, uint32_t* currentClusterIndex);
144 int32_t loadWav(Sample* newSample, uint32_t fileSize, Cluster** currentCluster, uint32_t* currentClusterIndex);
145};
146
147extern AudioFileManager audioFileManager;
Definition audio_file_manager.h:82
Error getUnusedAudioRecordingFilePath(String &filePath, String *tempFilePathForRecording, AudioRecordingFolder folder, uint32_t *getNumber, const char *channelName, String *songName)
Definition audio_file_manager.cpp:244
Definition audio_file_vector.h:24
Definition audio_file.h:26
Definition cluster_priority_queue.h:34
Definition cluster.h:34
Definition output.h:81
Definition sample_cache.h:25
Definition sample_recorder.h:49
Definition sample.h:50
Definition d_string.h:41