Skip to content

Commit 78ae0e2

Browse files
Play files from a mounted file system (#35)
Tested with SD library but should also work with SD_MMC library
1 parent fc7d16a commit 78ae0e2

File tree

3 files changed

+202
-121
lines changed

3 files changed

+202
-121
lines changed

README.md

Lines changed: 72 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
A streaming library for esp32, esp32-wrover, esp32-s2 and esp32-s3 with a separate VS1053 codec chip.<br>
66
This library plays mp3, ogg, aac, aac+ and <strike>flac</strike> files and streams and uses [ESP_VS1053_Library](https://github.com/baldram/ESP_VS1053_Library) to communicate with the decoder.
77

8-
Supports http, https (insecure mode) and chunked audio streams.
8+
This library plays http, https (insecure mode) and chunked audio files and streams.
9+
Also plays mp3 and ogg files from sdcard.
910

1011
Visit [eStreamPlayer32_VS1053 for PIO](https://github.com/CelliesProjects/eStreamplayer32-vs1053-pio) to see a [PlatformIO](https://platformio.org/platformio) project using this library.
1112

@@ -15,12 +16,13 @@ Install [ESP_VS1053_Library](https://github.com/baldram/ESP_VS1053_Library) and
1516

1617
Take care to install the master branch of the VS1053 library or at least a version from commit [ba1803f](https://github.com/baldram/ESP_VS1053_Library/commit/ba1803f75722a36f3e9f539129e885bea3c60f71) or later because the `getChipVersion()` call that is needed is not included in the latest release.<br>See https://github.com/CelliesProjects/ESP32_VS1053_Stream/issues/23
1718

18-
Use [the latest Arduino ESP32 core version](https://github.com/espressif/arduino-esp32/releases/latest).
19+
Use the [2.0.17 Arduino ESP32 core version](https://github.com/espressif/arduino-esp32/releases/tag/2.0.17).
1920

2021
## Example code
2122

2223
```c++
2324
#include <Arduino.h>
25+
#include <SD.h>
2426
#include <VS1053.h> /* https://github.com/baldram/ESP_VS1053_Library */
2527
#include <ESP32_VS1053_Stream.h>
2628

@@ -32,50 +34,86 @@ Use [the latest Arduino ESP32 core version](https://github.com/espressif/arduino
3234
#define VS1053_DCS 21
3335
#define VS1053_DREQ 22
3436

37+
#define SDREADER_CS 26
38+
3539
ESP32_VS1053_Stream stream;
3640

3741
const char* SSID = "xxx";
3842
const char* PSK = "xxx";
3943

40-
void setup() {
41-
#if defined(CONFIG_IDF_TARGET_ESP32S2) && ARDUHAL_LOG_LEVEL != ARDUHAL_LOG_LEVEL_NONE
42-
delay(3000);
43-
Serial.setDebugOutput(true);
44-
#endif
44+
bool mountSDcard()
45+
{
46+
if (!SD.begin(SDREADER_CS))
47+
{
48+
Serial.println("Card Mount Failed");
49+
return false;
50+
}
51+
uint8_t cardType = SD.cardType();
52+
53+
if (cardType == CARD_NONE)
54+
{
55+
Serial.println("No SD card attached");
56+
return false;
57+
}
4558

59+
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
60+
Serial.println("SD Card Size: %lluMB\n", cardSize);
61+
return true;
62+
}
63+
64+
void setup() {
4665
Serial.begin(115200);
66+
Serial.println("\n\nsimple vs1053 streaming example.\n");
4767

48-
WiFi.begin(SSID, PSK);
49-
50-
WiFi.setSleep(false);
51-
/* important to set this right! See issue #15 */
68+
Serial.printf("connecting to wifi network %s\n", SSID);
5269

53-
Serial.println("\n\nSimple vs1053 Streaming example.");
70+
WiFi.begin(SSID, PSK);
71+
WiFi.setSleep(false); /* important to set this right! See issue #15 */
5472

5573
while (!WiFi.isConnected())
5674
delay(10);
57-
Serial.println("wifi connected - starting decoder");
75+
76+
Serial.println("wifi connected - starting spi bus");
5877

5978
SPI.setHwCs(true);
60-
SPI.begin(SPI_CLK_PIN, SPI_MISO_PIN, SPI_MOSI_PIN); /* start SPI before starting decoder */
79+
SPI.begin(SPI_CLK_PIN, SPI_MISO_PIN, SPI_MOSI_PIN); /* start SPI before starting decoder or sdcard*/
80+
81+
Serial.println("spi running - mounting sd card");
82+
83+
if (!mountSDcard())
84+
{
85+
Serial.println("sdcard not mounted - system halted");
86+
while (1)
87+
delay(100);
88+
}
89+
90+
Serial.println("card mounted - starting vs1053");
6191

6292
if (!stream.startDecoder(VS1053_CS, VS1053_DCS, VS1053_DREQ) || !stream.isChipConnected())
6393
{
64-
Serial.println("Decoder not running");
65-
while (1) delay(100);
66-
};
94+
Serial.println("Decoder not running - system halted");
95+
while (1)
96+
delay(100);
97+
}
6798

68-
Serial.println("decoder running - starting stream");
99+
Serial.println("vs1053 running - starting playback");
69100

70-
stream.connecttohost("http://icecast.omroep.nl/radio6-bb-mp3");
101+
//stream.connecttohost("http://icecast.omroep.nl/radio6-bb-mp3");
102+
stream.connecttofile(SD, "/test.mp3");
103+
104+
if (!stream.isRunning())
105+
{
106+
Serial.println("no stream running - system halted");
107+
while (1)
108+
delay(100);
109+
}
71110

72111
Serial.print("codec: ");
73112
Serial.println(stream.currentCodec());
74113

75114
Serial.print("bitrate: ");
76115
Serial.print(stream.bitrate());
77116
Serial.println("kbps");
78-
79117
}
80118

81119
void loop() {
@@ -96,6 +134,8 @@ void audio_eof_stream(const char* info) {
96134
Serial.printf("eof: %s\n", info);
97135
}
98136
```
137+
## Known issues
138+
Ogg files can not be started with an offset without first playing a couple of seconds from the start of the file.
99139
100140
## Tips for troublefree streaming
101141
@@ -110,8 +150,6 @@ WiFi.setSleep(false);
110150
...
111151
```
112152

113-
<hr>
114-
115153
### Prevent reboots while playing
116154
Early version of the esp32 have issues with the external psram cache, resulting in reboots.<br>Workarounds are possible depending on the hardware revision.
117155

@@ -139,161 +177,103 @@ Source: [esp-idf api guide on external ram](https://docs.espressif.com/projects/
139177
In PIO you can find out what hardware revision you have by running `esptool.py flash_id` in a terminal.
140178

141179
In Arduino IDE go to `File->Preferences` and find the `Show verbose output during` option. Check the box marked `upload`.<br>You can now see the hardware revision when you upload a sketch.
142-
<hr>
143180

144181
# Functions
145-
146182
### Initialize the VS1053 codec
147183

148184
```c++
149185
bool startDecoder(CS, DCS, DREQ)
150186
```
151-
152-
<hr>
153-
154187
### Check if VS1053 is responding
155-
156188
```c++
157189
bool isChipConnected()
158190
```
159-
160-
<hr>
161-
162191
### Start or resume a stream
163192

164193
```c++
165194
bool connecttohost(url)
166195
```
167-
168196
```c++
169197
bool connecttohost(url, offset)
170198
```
171-
172199
```c++
173200
bool connecttohost(url, user, pwd)
174201
```
175-
176202
```c++
177203
bool connecttohost(url, user, pwd, offset)
178204
```
179-
180-
<hr>
181-
182-
### Stop a stream
183-
205+
### Start or resume a local file
206+
```c++
207+
bool connecttofile(filesystem, filename)
208+
```
209+
```c++
210+
bool connecttofile(filesystem, filename, offset)
211+
```
212+
### Stop a running stream
184213
```c++
185214
void stopSong()
186215
```
187-
188-
<hr>
189-
190216
### Feed the decoder
191-
192217
```c++
193218
void loop()
194219
```
195-
196220
This function has to called every couple of ms to feed the decoder with data.<br>For bitrates up to 320kbps somewhere between 5-25 ms is about right.
197-
198-
<hr>
199-
200221
### Check if stream is running
201-
202222
```c++
203223
bool isRunning()
204224
```
205-
206-
<hr>
207-
208225
### Get the current volume
209-
210226
```c++
211227
uint8_t getVolume()
212228
```
213-
214-
<hr>
215-
216229
### Set the volume
217-
218230
```c++
219231
void setVolume(uint8_t volume)
220232
```
221-
222233
Value should be between 0-100.
223-
224-
<hr>
225-
226234
### Set bass and treble
227-
228235
```c++
229236
uint8_t rtone[4] = {toneha, tonehf, tonela, tonelf};
230237
void setTone(rtone)
231238
```
232-
233239
Values for `rtone`:
234-
235240
```c++
236241
toneha = <0..15> // Setting treble gain (0 off, 1.5dB steps)
237242
tonehf = <0..15> // Setting treble frequency lower limit x 1000 Hz
238243
tonela = <0..15> // Setting bass gain (0 = off, 1dB steps)
239244
tonelf = <0..15> // Setting bass frequency lower limit x 10 Hz
240245
```
241-
242-
<hr>
243-
244246
### Get the current used codec
245-
246247
```c++
247248
const char* currentCodec()
248249
```
249-
250250
Returns `STOPPED` if no stream is running.
251-
252-
<hr>
253-
254251
### Get the current stream url
255-
256252
```c++
257253
const char* lastUrl()
258254
```
259-
260255
The current stream url might differ from the request url if the request url points to a playlist.
261-
262-
<hr>
263-
264256
### Get the filesize
265-
266257
```c++
267258
size_t size()
268259
```
269260
Returns `0` if the stream is a radio stream.
270-
271-
<hr>
272-
273261
### Get the current position in the file
274262
```c++
275263
size_t position()
276264
```
277265
Returns `0` if the stream is a radio stream.
278-
279-
<hr>
280-
281266
### Get the buffer fill status
282267
```c++
283268
const char *bufferStatus()
284269
```
285-
286270
Returns `0/0` if there is no buffer.<br>Otherwise returns something like `4096/65536` which means 4kB waiting in a 64kB buffer.
287-
288271
```c++
289272
void bufferStatus(size_t &used, size_t &capacity)
290273
```
274+
This version takes two `size_t` variables by reference.<br>Works the same as the `const char *` version.
291275
292-
There is also a version that takes two `size_t` variables by reference.<br>Works the same as the `const char *` version.
293-
294-
A buffer will only be allocated if there is enough free psram.
295-
296-
<hr>
276+
NOTE: A buffer will only be allocated if there is enough free psram.
297277
298278
# Event callbacks
299279
@@ -302,28 +282,19 @@ A buffer will only be allocated if there is enough free psram.
302282
```c++
303283
void audio_showstation(const char* info)
304284
```
305-
<hr>
306-
307285
### Stream information callback.
308286

309287
```c++
310288
void audio_showstreamtitle(const char* info)
311289
```
312-
313-
<hr>
314-
315290
### End of file callback.
316291
317292
```c++
318293
void audio_eof_stream(const char* info)
319294
```
295+
Returns the eof url or path.<br>Also called if a stream or file times out/errors.
320296

321-
Returns the eof url.<br>Also called if a stream times out/errors.
322-
323-
Handy function for coding a playlist.<br>You can use `connecttohost()` inside this function to start the next item.
324-
325-
<hr>
326-
297+
You can use this function for coding a playlist.<br>Use `connecttohost()` or `connecttofile()` inside this function to start the next item.
327298
## License
328299

329300
MIT License

0 commit comments

Comments
 (0)