arduino-audio-tools
Loading...
Searching...
No Matches
AudioSourceSMB.h
Go to the documentation of this file.
1#pragma once
2
3#include "AudioSource.h"
5#include "SMB.h"
6
7namespace audio_tools {
8
26 public:
30 AudioSourceSMB(smb::SMBClient& client, const char* path = "/",
31 const char* ext = nullptr, int files = 0) {
32 p_client = &client;
34 setDirectory(path);
35 p_ext = ext;
36 setMaxFiles(files);
37 }
38
40 bool begin() override {
41 TRACED();
42 end();
43 if (p_client == nullptr) return false;
44 file_count = 0;
45 if (!walk(directory, -1, file_count, nullptr)) {
46 LOGE("Could not list directory: %s", directory.c_str());
47 file_count = -1;
48 return false;
49 }
50 LOGI("Number of files: %d", file_count);
51 return file_count > 0;
52 }
53
55 void end() {
56 idx = 0;
57 file.close();
58 }
59
61 Stream* nextStream(int offset) override {
62 return selectStream(idx + offset);
63 };
64
66 Stream* previousStream(int offset) override { return nextStream(-offset); };
67
70 Stream* selectStream(int index) override {
71 if (!isValidIdx(index)) return nullptr;
72 Str path;
73 int n = 0;
74 if (p_client == nullptr || !walk(directory, index, n, &path) ||
75 path.isEmpty()) {
76 LOGW("No file at index %d", index);
77 return nullptr;
78 }
79 idx = index;
80 return openFile(path.c_str());
81 }
82
84 int index() override { return idx; }
85
88 Stream* selectStream(const char* path) override {
89 TRACED();
90 if (p_client == nullptr || path == nullptr) return nullptr;
91 smb::FileInfo info;
92 if (!p_client->stat(path, info)) {
93 LOGE("Path not found: %s", path);
94 return nullptr;
95 }
96 if (info.isDirectory) {
97 setDirectory(path);
98 if (!begin()) return nullptr;
99 return selectStream(0);
100 }
101 return openFile(path);
102 }
103
105 const char* toStr() override { return file.path(); }
106
108 void setDirectory(const char* path) {
109 directory = "/";
110 if (path != nullptr) directory = path;
111 if (!directory.startsWith("/")) {
112 Str tmp{"/"};
113 tmp += directory.c_str();
114 directory = tmp.c_str();
115 }
116 }
117
119 void setMaxFiles(int maxCount) { max_files = maxCount; }
120
122 void setFileExtension(const char* ext) { p_ext = ext; }
123
125 void setBufferSize(size_t size) { buffer_size = size; }
126
128 size_t size() { return file_count < 0 ? 0 : file_count; }
129
130 protected:
131 smb::SMBClient* p_client = nullptr;
132 smb::SMBFile file;
134 int idx = 0;
135 int file_count = -1; // -1: unknown
136 size_t max_files = 0;
137 size_t buffer_size = 0;
138 const char* p_ext = nullptr;
139
140 Stream* openFile(const char* path) {
141 file.close(); // close the previous file
142 LOGI("open %s", path);
143 file = p_client->open(path, "r");
144 if (!file || file.isDirectory()) {
145 LOGE("Could not open %s", path);
146 return nullptr;
147 }
148 if (buffer_size > 0) file.setBufferSize(buffer_size);
149 return &file;
150 }
151
155 bool walk(Str& dir, int target, int& n, Str* result) {
156 bool done = false;
157 bool ok = p_client->listDir(dir.c_str(), [&](const smb::FileInfo& info) {
158 if (info.name.empty() || info.name == "." || info.name == "..")
159 return true;
160 Str path{dir.c_str()};
161 if (!path.endsWith("/")) path += "/";
162 path += info.name.c_str();
163 if (info.isDirectory) {
164 walk(path, target, n, result);
165 } else if (endsWith(info.name.c_str(), p_ext)) {
166 if (n == target && result != nullptr) {
167 *result = path.c_str();
168 }
169 n++;
170 }
171 done = (target >= 0 && n > target) || isMaxReached(n);
172 return !done;
173 });
174 return ok;
175 }
176
177 bool isMaxReached(int n) { return max_files > 0 && n >= (int)max_files; }
178
179 bool isValidIdx(int index) {
180 if (index < 0) return false;
181 if (max_files > 0 && index >= (int)max_files) return false;
182 if (file_count >= 0 && index >= file_count) {
183 LOGW("index %d is out of range (size: %d)", index, file_count);
184 return false;
185 }
186 return true;
187 }
188
189 bool endsWith(const char* file, const char* ext) {
190 if (file == nullptr) return false;
191 if (ext == nullptr) return true;
192 return StrView(file).endsWithIgnoreCase(ext);
193 }
194};
195
196} // namespace audio_tools
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGE(...)
Definition AudioLoggerIDF.h:30
Definition Arduino.h:136
Abstract Audio Data Source for the AudioPlayer which is used by the Audio Players.
Definition AudioSource.h:17
int timeout_auto_next_value
Definition AudioSource.h:76
An AudioSource that uses the SMBClient of the https://github.com/pschatzmann/TinySMB library to retri...
Definition AudioSourceSMB.h:25
bool isValidIdx(int index)
Definition AudioSourceSMB.h:179
size_t size()
Returns the number of files that were found by begin()
Definition AudioSourceSMB.h:128
Stream * openFile(const char *path)
Definition AudioSourceSMB.h:140
bool endsWith(const char *file, const char *ext)
Definition AudioSourceSMB.h:189
Stream * selectStream(const char *path) override
Definition AudioSourceSMB.h:88
Stream * selectStream(int index) override
Definition AudioSourceSMB.h:70
bool isMaxReached(int n)
Definition AudioSourceSMB.h:177
smb::SMBFile file
Definition AudioSourceSMB.h:132
const char * toStr() override
provides the actual file name with path
Definition AudioSourceSMB.h:105
void setBufferSize(size_t size)
Defines the read buffer size of the opened files (default 4096)
Definition AudioSourceSMB.h:125
size_t buffer_size
Definition AudioSourceSMB.h:137
bool walk(Str &dir, int target, int &n, Str *result)
Definition AudioSourceSMB.h:155
size_t max_files
Definition AudioSourceSMB.h:136
smb::SMBClient * p_client
Definition AudioSourceSMB.h:131
int index() override
Returns the actual index of the stream.
Definition AudioSourceSMB.h:84
Stream * nextStream(int offset) override
Returns next audio stream.
Definition AudioSourceSMB.h:61
void setFileExtension(const char *ext)
Defines the file extension filter (e.g. "mp3"): nullptr for all files.
Definition AudioSourceSMB.h:122
AudioSourceSMB(smb::SMBClient &client, const char *path="/", const char *ext=nullptr, int files=0)
Definition AudioSourceSMB.h:30
void end()
Closes the actual file.
Definition AudioSourceSMB.h:55
void setMaxFiles(int maxCount)
Defines the max number of files (if value is >0)
Definition AudioSourceSMB.h:119
int file_count
Definition AudioSourceSMB.h:135
bool begin() override
Counts the audio files in the start directory.
Definition AudioSourceSMB.h:40
const char * p_ext
Definition AudioSourceSMB.h:138
Str directory
Definition AudioSourceSMB.h:133
int idx
Definition AudioSourceSMB.h:134
Stream * previousStream(int offset) override
Returns previous audio stream.
Definition AudioSourceSMB.h:66
void setDirectory(const char *path)
Defines the start directory: call begin() afterwards.
Definition AudioSourceSMB.h:108
Str which keeps the data on the heap. We grow the allocated memory only if the copy source is not fit...
Definition Str.h:24
A simple wrapper to provide string functions on existing allocated char*. If the underlying char* is ...
Definition StrView.h:29
virtual bool startsWith(const char *str)
checks if the string starts with the indicated substring
Definition StrView.h:203
virtual bool isEmpty()
checks if the string is empty
Definition StrView.h:463
virtual const char * c_str()
provides the string value as const char*
Definition StrView.h:456
virtual bool endsWithIgnoreCase(const char *str)
checks if the string ends with the indicated substring
Definition StrView.h:218
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6