arduino-audio-tools
Loading...
Searching...
No Matches
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, int startPos = 0) {
29 setLoopCount(count);
30 setRewindPos(rewindPos);
31 setStartPos(startPos);
32 }
33
34 // restarts the file from the beginning
35 bool begin() {
36 TRACEI();
37 // automatic determination of rewind pos
38 if (rewind_pos <= 0){
39 current_file.seek(0);
40 char tmp[5] = {0};
41 current_file.readBytes(tmp, 4);
42 // for wav files remove header
43 rewind_pos = StrView(tmp).equals("RIFF") ? 44 : 0;
44 }
45 current_file.seek(start_pos);
46 size_open = total_size;
47 return current_file;
48 }
49
50 // closes the file
51 void end() {
52 TRACEI();
53 current_file.close();
54 }
55
57 void setFile(FileType file) { this->current_file = file; }
58
60 FileType &file(){
61 return current_file;
62 }
63
65 void setRewindPos(int pos) { rewind_pos = pos; }
66
68 void setStartPos(int pos) { start_pos = pos; }
69
71 void setSize(size_t len) {
72 total_size = len;
73 }
74
76 size_t size() {
77 return total_size == -1 ? current_file.size() : total_size;
78 }
79
81 void setCallback(void (*cb)(FileLoopT &loop)){
82 callback = cb;
83 }
84
87 void setLoopCount(int count) { loop_count = count; }
88
89 int available() override {
90 // if we manage the size, we return the open amount
91 if (total_size!=-1) return size_open;
92 // otherwise we return DEFAULT_BUFFER_SIZE if looping is active
93 return isLoopActive() ? DEFAULT_BUFFER_SIZE : current_file.available();
94 }
95
96 size_t readBytes(uint8_t *data, size_t len) override {
97 LOGD("FileLoopT::readBytes %d at %d", (int)len, (int)current_file.position());
98 if (!current_file)
99 return 0;
100
101 // limit the copy size if necessary
102 int copy_len = len;
103 if (total_size!=-1){
104 copy_len = min((int)len, size_open);
105 }
106
107 // read step 1;
108 int result1 = current_file.readBytes((READTYPE *)data, copy_len);
109 int result2 = 0;
110 int open = copy_len - result1;
111 if (isLoopActive() && open > 0) {
112 if (rewind_pos < 0) rewind_pos = 0;
113 LOGI("seek %d", rewind_pos);
114 // looping logic -> rewind to beginning: read step 2
115 current_file.seek(rewind_pos);
116 // notify user
117 if (callback!=nullptr){
118 callback(*this);
119 }
120 result1 = current_file.readBytes((READTYPE*)data + result1, open);
121 if (loop_count>0)
122 loop_count--;
123 }
124 // determine the result size
125 int result = result1 + result2;
126 // calculate the size_open if necessary
127 if (total_size!=-1){
128 size_open -= result;
129 }
130 return result;
131 }
132
133 // Returns the bool of the current file
134 operator bool() {
135 return current_file;
136 }
137
139 bool isLoopActive() { return loop_count > 0 || loop_count == -1; }
140
141 size_t write(const uint8_t* data, size_t len) { return current_file.write(data, len);}
142
143protected:
144 int rewind_pos = -1;
145 int start_pos = 0;
146 int loop_count = -1;
147 int size_open = -1;
148 int total_size = -1;
149 void (*callback)(FileLoopT &loop) = nullptr;
150 FileType current_file;
151};
152
164class FileLoop : public FileLoopT<File> {
165public:
166 FileLoop() = default;
167 FileLoop(File file, int count = -1, int rewindPos = 0)
168 : FileLoopT<File>(file, count, rewindPos) {}
169};
170
171} // 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:164
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:76
void setLoopCount(int count)
Definition FileLoop.h:87
void setRewindPos(int pos)
defines the start position after the rewind. E.g. for wav files this should be 44
Definition FileLoop.h:65
void setFile(FileType file)
defines the file that is used for looping
Definition FileLoop.h:57
void setStartPos(int pos)
defines the start position at the beginning
Definition FileLoop.h:68
FileType & file()
Returns the file.
Definition FileLoop.h:60
void setCallback(void(*cb)(FileLoopT &loop))
You can be notified about a rewind.
Definition FileLoop.h:81
bool isLoopActive()
Definition FileLoop.h:139
void setSize(size_t len)
optionally defines the requested playing size in bytes
Definition FileLoop.h:71
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