3#include "AudioTools/CoreAudio/AudioBasic/Str.h"
4#include "AudioTools/CoreAudio/AudioBasic/Collections/List.h"
6#define MAX_FILE_LEN 256
7#define MAX_FILE_COUNT 1000000
21template <
class SDT,
class FileT>
26 void begin(
const char *startDir,
const char *extension,
27 const char *file_name_pattern) {
29 this->start_dir = startDir;
30 this->ext = extension;
31 this->file_name_pattern = file_name_pattern;
37 if (max_idx != -1 && idx > max_idx) {
45 if (!found)
return nullptr;
46 return result.c_str();
52 requested_idx = MAX_FILE_COUNT;
63 const char *start_dir;
72 const char *ext =
nullptr;
73 const char *file_name_pattern =
nullptr;
77 if (dirname ==
nullptr)
return;
78 LOGD(
"listDir: %s", dirname);
79 FileT root = open(dirname);
81 LOGE(
"Open failed: %s", dirname);
85 if (!isDirectory(root)) {
86 LOGD(
"Is not directory: %s", dirname);
90 if (
StrView(dirname).startsWith(
".")) {
91 LOGD(
"Invalid file: %s", dirname);
95 if (isDirectory(root)) {
99 FileT file = openNext(root);
100 while (file && !found) {
101 if (isDirectory(file)) {
103 LOGD(
"name: %s", name.c_str());
111 LOGD(
"File %s at index: %d", fn, actual_idx);
112 if (actual_idx == requested_idx) {
117 LOGD(
"Ignoring %s", fn);
120 file = openNext(root);
123 if (!found && file_path_stack.size() == 0) {
124 max_idx = actual_idx;
129 void rewind(FileT &f) {
138 bool isDirectory(FileT &f) {
143 result = f.isDirectory();
145 LOGD(
"isDirectory %s: %d",
fileName(f), result);
149 FileT openNext(FileT &dir) {
153 if (!result.openNext(&dir, O_READ)) {
154 LOGD(
"No next file");
158 return dir.openNextFile();
162 void pushPath(
const char *name) {
164 LOGD(
"pushPath: %s", name);
165 String nameStr(name);
166 file_path_stack.push_back(nameStr);
172 file_path_stack.pop_back(str);
173 LOGD(
"popPath: %s", str.c_str());
178 const char *file_name =
fileName(file);
179 if (file.isDirectory()) {
180 LOGD(
"-> isValidAudioFile: '%s': %d", file_name,
false);
183 StrView strFileTName(file_name);
185 strFileTName.
matches(file_name_pattern) && !isHidden(file);
186 LOGD(
"-> isValidAudioFile: '%s': %d", file_name, result);
194 static char name[MAX_FILE_LEN];
195 file.getName(name, MAX_FILE_LEN);
204 return file.name() + pos;
210#if defined(USE_SDFAT) || ESP_IDF_VERSION_MAJOR >= 4
211 LOGD(
"-> fileNamePath: %s",
fileName(file));
212 file_path_str = start_dir;
213 if (!file_path_str.endsWith(
"/")) {
214 file_path_str +=
"/";
216 for (
int j = 0; j < file_path_stack.size(); j++) {
217 file_path_str += file_path_stack[j] +
"/";
220 static char name[MAX_FILE_LEN];
221 strncpy(name,
fileName(file), MAX_FILE_LEN);
222 file_path_str += name;
223 const char *result = file_path_str.c_str();
224 LOGD(
"<- fileNamePath: %s", result);
231 bool isHidden(FileT &f) {
239 FileT open(
const char *name) {
243 if (!result.open(name)) {
244 if (name !=
nullptr) {
245 LOGE(
"File open error: %s", name);
247 LOGE(
"File open error: name is null");
252 return p_sd->open(name, FILE_READ);