arduino-audio-tools
AudioSourceSDFAT.h
1 #pragma once
2 
3 #include "AudioConfig.h"
4 
5 #include <SPI.h>
6 #include <SdFat.h>
7 #include "AudioBasic/StrExt.h"
8 #include "AudioLogger.h"
9 #include "AudioTools/AudioSource.h"
10 
11 #define USE_SDFAT
12 #include "AudioLibs/SDDirect.h"
13 
14 
15 // SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
16 // 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
17 #ifndef SD_FAT_TYPE
18 #define SD_FAT_TYPE 1
19 #endif
20 // Try max SPI clock for an SD. Reduce SPI_CLOCK if errors occur. (40?)
21 #define SPI_CLOCK SD_SCK_MHZ(50)
22 
23 #if SD_FAT_TYPE == 0
24  typedef SdFat AudioFs;
25  typedef File AudioFile;
26 #elif SD_FAT_TYPE == 1
27  typedef SdFat32 AudioFs;
28  typedef File32 AudioFile;
29 #elif SD_FAT_TYPE == 2
30  typedef SdExFat AudioFs;
31  typedef ExFile AudioFile;
32 #elif SD_FAT_TYPE == 3
33  typedef SdFs AudioFs;
34  typedef FsFile AudioFile;
35 #endif
36 
37 
38 namespace audio_tools {
48 class AudioSourceSDFAT : public AudioSource {
49 public:
51  AudioSourceSDFAT(const char* startFilePath = "/", const char* ext = ".mp3", int chipSelect = PIN_CS, int speedMHz = 10,int spi_mode=DEDICATED_SPI, bool setupIndex=true) {
52  TRACED();
53  LOGI("SD chipSelect: %d", chipSelect);
54  LOGI("SD speedMHz: %d", speedMHz);
55  LOGI("ext: %s", ext);
56  p_cfg = new SdSpiConfig(chipSelect, spi_mode, SD_SCK_MHZ(speedMHz));
57  owns_cfg = true;
58  start_path = startFilePath;
59  exension = ext;
60  setup_index = setupIndex;
61  }
62 
64  AudioSourceSDFAT(const char* startFilePath, const char* ext, SdSpiConfig &config, bool setupIndex=true) {
65  TRACED();
66  p_cfg = &config;
67  owns_cfg = false;
68  start_path = startFilePath;
69  exension = ext;
70  setup_index = setupIndex;
71  }
72 
73 
74  virtual void begin() override {
75  TRACED();
76  if (!is_sd_setup) {
77  if (!sd.begin(*p_cfg)) {
78  LOGE("sd.begin failed");
79  return;
80  }
81  is_sd_setup = true;
82  }
83  idx.begin(start_path, exension, file_name_pattern);
84  idx_pos = 0;
85  }
86 
87  void end() {
88 #ifdef ESP32
89  sd.end();
90 #endif
91  is_sd_setup = false;
92  }
93 
94 
95  virtual Stream *nextStream(int offset = 1) override {
96  LOGI("nextStream: %d", offset);
97  return selectStream(idx_pos + offset);
98  }
99 
100  virtual Stream *selectStream(int index) override {
101  LOGI("selectStream SDFAT: %d", index);
102  if(index > -1){ //avoid invalid position
103  idx_pos = index;
104  }
105  return selectStream(idx[idx_pos]);
106  }
107 
108  virtual Stream *selectStream(const char *path) override {
109  file.close();
110  if (path==nullptr){
111  LOGE("Filename is null")
112  return nullptr;
113  }
114 
115  AudioFile new_file;
116  if (!new_file.open(path, O_RDONLY)){
117  LOGE("Open error: '%s'", path);
118  }
119 
120  LOGI("-> selectStream: %s", path);
121  strncpy(file_name, path, MAX_FILE_LEN);
122  file = new_file;
123  return &file;
124  }
125 
128  void setFileFilter(const char *filter) { file_name_pattern = filter; }
129 
131  int index() { return idx_pos; }
132 
134  const char *toStr() { return file_name; }
135 
136  // provides default setting go to the next
137  virtual bool isAutoNext() { return true; }
138 
140  virtual void setPath(const char *p) { start_path = p; }
141 
143  long size() { return idx.size();}
144 
145 protected:
146  SdSpiConfig *p_cfg = nullptr;
147  AudioFs sd;
148  AudioFile file;
150  size_t idx_pos = 0;
151  char file_name[MAX_FILE_LEN];
152  const char *exension = nullptr;
153  const char *start_path = nullptr;
154  const char *file_name_pattern = "*";
155  int cs;
156  bool setup_index = true;
157  bool owns_cfg=false;
158  bool is_sd_setup = false;
159 
160  const char* getFileName(AudioFile&file){
161  static char name[MAX_FILE_LEN];
162  file.getName(name,MAX_FILE_LEN);
163  return name;
164  }
165 
166 };
167 
168 } // namespace audio_tools
Abstract Audio Data Source for the AudioPlayer which is used by the Audio Players.
Definition: AudioSource.h:12
ESP32 AudioSource for AudioPlayer using an SD card as data source. This class is based on the Arduino...
Definition: AudioSourceSDFAT.h:48
int index()
Provides the current index position.
Definition: AudioSourceSDFAT.h:131
AudioSourceSDFAT(const char *startFilePath, const char *ext, SdSpiConfig &config, bool setupIndex=true)
Costructor with SdSpiConfig.
Definition: AudioSourceSDFAT.h:64
long size()
Provides the number of files (The max index is size()-1): WARNING this is very slow if you have a lot...
Definition: AudioSourceSDFAT.h:143
const char * toStr()
provides the actual file name
Definition: AudioSourceSDFAT.h:134
AudioSourceSDFAT(const char *startFilePath="/", const char *ext=".mp3", int chipSelect=PIN_CS, int speedMHz=10, int spi_mode=DEDICATED_SPI, bool setupIndex=true)
Default constructor.
Definition: AudioSourceSDFAT.h:51
virtual void begin() override
Reset actual stream and move to root.
Definition: AudioSourceSDFAT.h:74
virtual void setPath(const char *p)
Allows to "correct" the start path if not defined in the constructor.
Definition: AudioSourceSDFAT.h:140
virtual bool isAutoNext()
Returns default setting go to the next.
Definition: AudioSourceSDFAT.h:137
void setFileFilter(const char *filter)
Definition: AudioSourceSDFAT.h:128
virtual Stream * nextStream(int offset=1) override
Returns next audio stream.
Definition: AudioSourceSDFAT.h:95
virtual Stream * selectStream(int index) override
Returns audio stream at the indicated index (the index is zero based, so the first value is 0!...
Definition: AudioSourceSDFAT.h:100
virtual Stream * selectStream(const char *path) override
Returns audio stream by path.
Definition: AudioSourceSDFAT.h:108
long size()
Provides the number of files.
Definition: SDDirect.h:49
Definition: NoArduino.h:125
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AnalogAudio.h:10