arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
FileLoop.h
1#pragma once
2
3#include "AudioTools/CoreAudio/BaseStream.h"
4#include "AudioTools/CoreAudio/AudioBasic/StrView.h"
5#ifdef ARDUINO
6# include "FS.h"
7# define READTYPE char
8#else
9# define READTYPE uint8_t
10#endif
11namespace audio_tools {
12
24template <class FileType> class FileLoopT : public BaseStream {
25public:
26 FileLoopT() = default;
27 FileLoopT(FileType file, int count = -1, int rewindPos = -1) {
29 setLoopCount(count);
30 setStartPos(rewindPos);
31 }
32
33 // restarts the file from the beginning
34 bool begin() {
35 TRACEI();
36 // automatic determination of start pos
37 if (start_pos <= 0){
38 current_file.seek(0);
39 char tmp[5] = {0};
40 current_file.readBytes(tmp, 4);
41 // for wav files remove header
42 start_pos = StrView(tmp).equals("RIFF") ? 44 : 0;
43 current_file.seek(0);
44 } else {
45 current_file.seek(start_pos);
46 }
47 size_open = total_size;
48 return current_file;
49 }
50
51 // closes the file
52 void end() {
53 TRACEI();
54 current_file.close();
55 }
56
58 void setFile(FileType file) { this->current_file = file; }
59
61 FileType &file(){
62 return current_file;
63 }
64
66 void setStartPos(int pos) { start_pos = pos; }
67
69 void setSize(size_t len) {
70 total_size = len;
71 }
72
74 size_t size() {
75 return total_size == -1 ? current_file.size() : total_size;
76 }
77
79 void setCallback(void (*cb)(FileLoopT &loop)){
80 callback = cb;
81 }
82
85 void setLoopCount(int count) { loop_count = count; }
86
87 int available() override {
88 // if we manage the size, we return the open amount
89 if (total_size!=-1) return size_open;
90 // otherwise we return DEFAULT_BUFFER_SIZE if looping is active
91 return isLoopActive() ? DEFAULT_BUFFER_SIZE : current_file.available();
92 }
93
94 size_t readBytes(uint8_t *data, size_t len) override {
95 LOGD("FileLoopT::readBytes %d at %d", (int)len, (int)current_file.position());
96 if (!current_file)
97 return 0;
98
99 // limit the copy size if necessary
100 int copy_len = len;
101 if (total_size!=-1){
102 copy_len = min((int)len, size_open);
103 }
104
105 // read step 1;
106 int result1 = current_file.readBytes((READTYPE *)data, copy_len);
107 int result2 = 0;
108 int open = copy_len - result1;
109 if (isLoopActive() && open > 0) {
110 if (start_pos < 0) start_pos = 0;
111 LOGI("seek %d", start_pos);
112 // looping logic -> rewind to beginning: read step 2
113 current_file.seek(start_pos);
114 // notify user
115 if (callback!=nullptr){
116 callback(*this);
117 }
118 result1 = current_file.readBytes((READTYPE*)data + result1, open);
119 if (loop_count>0)
120 loop_count--;
121 }
122 // determine the result size
123 int result = result1 + result2;
124 // calculate the size_open if necessary
125 if (total_size!=-1){
126 size_open -= result;
127 }
128 return result;
129 }
130
131 // Returns the bool of the current file
132 operator bool() {
133 return current_file;
134 }
135
137 bool isLoopActive() { return loop_count > 0 || loop_count == -1; }
138
139 size_t write(const uint8_t* data, size_t len) { return current_file.write(data, len);}
140
141protected:
142 int start_pos = -1;
143 int loop_count = -1;
144 int size_open = -1;
145 int total_size = -1;
146 void (*callback)(FileLoopT &loop) = nullptr;
147 FileType current_file;
148};
149
161class FileLoop : public FileLoopT<File> {
162public:
163 FileLoop() = default;
164 FileLoop(File file, int count = -1, int rewindPos = 0)
165 : FileLoopT<File>(file, count, rewindPos) {}
166};
167
168} // namespace audio_tools
Base class for all Streams. It relies on write(const uint8_t *buffer, size_t size) and readBytes(uint...
Definition BaseStream.h:36
A simple class which implements a automatic looping file. The file needs to be of the class File from...
Definition FileLoop.h:161
A simple class which implements a automatic looping file. In order to support different file implemen...
Definition FileLoop.h:24
size_t size()
Returns the (requested) file size.
Definition FileLoop.h:74
void setLoopCount(int count)
Definition FileLoop.h:85
void setFile(FileType file)
defines the file that is used for looping
Definition FileLoop.h:58
void setStartPos(int pos)
defines the start position after the rewind. E.g. for wav files this should be 44
Definition FileLoop.h:66
FileType & file()
Returns the file.
Definition FileLoop.h:61
void setCallback(void(*cb)(FileLoopT &loop))
You can be notified about a rewind.
Definition FileLoop.h:79
bool isLoopActive()
Definition FileLoop.h:137
void setSize(size_t len)
optionally defines the requested playing size in bytes
Definition FileLoop.h:69
A simple wrapper to provide string functions on existing allocated char*. If the underlying char* is ...
Definition StrView.h:28
virtual bool equals(const char *str)
checks if the string equals indicated parameter string
Definition StrView.h:165
Arduino File support using std::fstream.
Definition VFSFile.h:33
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10