Arduino VS1053
Loading...
Searching...
No Matches
VS1053Driver.h
Go to the documentation of this file.
1
42#pragma once
43
44
45#include "VS1053Config.h"
46#include "VS1053Logger.h"
47#include "VS1053SPI.h"
48#include "VS1053Recording.h"
49#include "patches/vs1053b-patches.h"
50#include "patches_in/vs1003b-pcm.h"
51#include "patches_in/vs1053b-pcm.h"
52#include "patches_midi/rtmidi1053b.h"
53#include "patches_midi/rtmidi1003b.h"
54
55#ifndef _BV
56#define _BV(bit) (1 << (bit))
57#endif
58
59namespace arduino_vs1053 {
60
61
66 VS1053_I2S_RATE_192_KHZ,
67 VS1053_I2S_RATE_96_KHZ,
68 VS1053_I2S_RATE_48_KHZ
69};
70
73 VS1053_NA,
74 VS1053_OUT,
75 VS1053_IN,
76 VS1053_MIDI,
77};
78
81 VS1053_EARSPEAKER_OFF = 0,
82 VS1053_EARSPEAKER_MIN,
83 VS1053_EARSPEAKER_ON,
84 VS1053_EARSPEAKER_MAX
85};
86
91class VS1053 {
92
96 struct VS1053EquilizerValue {
97 VS1053EquilizerValue(uint8_t limit){
98 this->freq_limit = limit;
99 }
101 uint16_t freq_limit=0;
103 uint8_t amplitude=0;
105 uint16_t scaledAmplitude(){
106 if (amplitude>100) amplitude = 100;
107 return static_cast<float>(amplitude)/100.0*15;
108 }
110 uint16_t scaledFreq(float scale){
111 uint16_t result = static_cast<float>(freq_limit) / scale;
112 if (result>15) result = 15;
113 return result;
114 }
115 };
120 class VS1053Equilizer {
121 protected:
122 VS1053EquilizerValue v_bass{3}; // 30 hz
123 VS1053EquilizerValue v_treble{15}; // 15000 hz
124
125 public:
127 VS1053EquilizerValue &bass() {
128 return v_bass;
129 }
130
132 VS1053EquilizerValue &treble() {
133 return v_treble;
134 }
135
137 uint16_t value() {
138 uint16_t result=0;
139 result |= v_treble.scaledAmplitude() << 12;
140 result |= v_treble.scaledFreq(1000) << 8;
141 result |= v_bass.scaledAmplitude() << 4;
142 result |= v_bass.scaledFreq(10);
143 return result;
144 }
145 };
146
151 class VS1003Clock {
152 public:
153 VS1003Clock() = default;
154
155 int setSampleRate(int sample_rate){
156 int diff_min = sample_rate; // max value for difference
157 int sample_rate_result = -1;
158 multiplier = -1;
159
160 // find the combination with the smallet difference
161 for (int j=0;j<7;j++){
162 for (int div=4;div<=126;div++){
163 float mf = multiplier_factors[j];
164 uint16_t sc_mult = sc_multipliers[j];
165 int sample_rate_eff = getSampleRate(div, mf);
166
167 if (sample_rate_eff < sample_rate){
168 // increasing dividers will make the sample rate just smaller, wo we break
169 break;
170 }
171
172 int diff = abs(sample_rate_eff - sample_rate);
173 VS1053_LOGD("--> div: %d - mult: %f (%x) -> %d", div, mf, sc_mult, sample_rate_eff);
174 if (diff<diff_min){
175 VS1053_LOGD("==> div: %d - mult: %f (%x) -> %d", div, mf, sc_mult, sample_rate_eff);
176 diff_min = diff;
177 this->divider = div;
178 this->multiplier = sc_mult;
179 this->multiplier_factor = mf;
180 sample_rate_result = sample_rate_eff;
181 }
182 // if we found the correct rate we are done
183 if (diff==0) return sample_rate_result;
184 }
185 }
186 return multiplier==-1? -1: sample_rate_result;
187 }
188
189 uint16_t getMultiplierRegisterValue() {
190 return multiplier;
191 }
192
193 float getMultiplier() {
194 return multiplier_factor;
195 }
196
197 int8_t getDivider() {
198 return divider; // 4. If SCI_AICTRL0 contains 0, the default divider value 12 is used.
199 }
200
201 protected:
202 const uint16_t SC_1003_MULT_1 = 0x0000;
203 const uint16_t SC_1003_MULT_2 = 0x2000;
204 const uint16_t SC_1003_MULT_25 = 0x4000;
205 const uint16_t SC_1003_MULT_3 = 0x6000;
206 const uint16_t SC_1003_MULT_35 = 0x8000;
207 const uint16_t SC_1003_MULT_4 = 0xa000;
208 const uint16_t SC_1003_MULT_45 = 0xc000;
209 const uint16_t SC_1003_MULT_5 = 0xe000;
210
211 float clock_rate = 12288000;
212 int divider = -1;
213 int multiplier = -1;
214 const uint16_t sc_multipliers[7] = { SC_1003_MULT_2,SC_1003_MULT_25,SC_1003_MULT_3, SC_1003_MULT_35, SC_1003_MULT_4, SC_1003_MULT_45, SC_1003_MULT_5};
215 float multiplier_factor;
216 const float multiplier_factors[7] = { 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0};
217
218 int getSampleRate(int div, float multiplierValue){
219 return (multiplierValue * clock_rate) / 256 / div;
220 }
221
222 };
223
224
225 public:
226 // SCI Register
227 const uint8_t SCI_MODE = 0x0;
228 const uint8_t SCI_STATUS = 0x1;
229 const uint8_t SCI_BASS = 0x2;
230 const uint8_t SCI_CLOCKF = 0x3;
231 const uint8_t SCI_DECODE_TIME = 0x4; // current decoded time in full seconds
232 const uint8_t SCI_AUDATA = 0x5;
233 const uint8_t SCI_WRAM = 0x6;
234 const uint8_t SCI_WRAMADDR = 0x7;
235 const uint8_t SCI_AIADDR = 0xA;
236 const uint8_t SCI_VOL = 0xB;
237 const uint8_t SCI_AICTRL0 = 0xC;
238 const uint8_t SCI_AICTRL1 = 0xD;
239 const uint8_t SCI_AICTRL2 = 0xE;
240 const uint8_t SCI_AICTRL3 = 0xF;
241 const uint8_t SCI_num_registers = 0xF;
242 // Stream header data
243 const uint8_t SCI_HDAT0 = 0x8; // Stream header data 0
244 const uint8_t SCI_HDAT1 = 0x9; // Stream header data 1
245
246 // SCI_MODE bits
247 const uint8_t SM_SDINEW = 11; // Bitnumber in SCI_MODE always on
248 const uint8_t SM_RESET = 2; // Bitnumber in SCI_MODE soft reset
249 const uint8_t SM_CANCEL = 3; // Bitnumber in SCI_MODE cancel song
250 const uint8_t SM_TESTS = 5; // Bitnumber in SCI_MODE for tests
251 const uint8_t SM_LINE1 = 14; // Bitnumber in SCI_MODE for Line input
252 const uint8_t SM_STREAM = 6; // Bitnumber in SCI_MODE for Streaming Mode
253 const uint8_t SM_ADPCM = 12; // Bitnumber in SCI_MODE for PCM/ADPCM recording active
254
255 const uint16_t ADDR_REG_GPIO_DDR_RW = 0xc017;
256 const uint16_t ADDR_REG_GPIO_VAL_R = 0xc018;
257 const uint16_t ADDR_REG_GPIO_ODATA_RW = 0xc019;
258 const uint16_t ADDR_REG_I2S_CONFIG_RW = 0xc040;
259
260 // Timer settings for VS1053 and VS1063 */
261 const uint16_t INT_ENABLE = 0xC01A;
262 const uint16_t SC_MULT_53_35X = 0x8000;
263 const uint16_t SC_ADD_53_10X = 0x0800;
264
265 const uint16_t SC_EAR_SPEAKER_LO = 0x0010;
266 const uint16_t SC_EAR_SPEAKER_HI = 0x0080;
267
268
270 VS1053(uint8_t _cs_pin, uint8_t _dcs_pin, uint8_t _dreq_pin, uint8_t _reset_pin=-1, VS1053_SPI *_p_spi=nullptr);
271
272#ifdef ARDUINO
274 VS1053(uint8_t _cs_pin, uint8_t _dcs_pin, uint8_t _dreq_pin, uint8_t _reset_pin, SPIClass &_p_spi);
275
276#endif
277
279 bool begin();
280
282 bool beginOutput();
283
285 void startSong();
286
288 void writeAudio(uint8_t*data, size_t len);
289
291 void playChunk(uint8_t *data, size_t len);
292
294 void stopSong();
295
297 void setVolume(uint8_t vol);
298
300 void setBalance(int8_t balance);
301
303 void setTone(uint8_t *rtone);
304
306 uint8_t getVolume();
307
309 int8_t getBalance();
310
312 void printDetails(const char *header);
313
315 void softReset();
316
318 void hardReset();
319
321 bool testComm(const char *header);
322
324 void adjustRate(long ppm2);
325
327 void streamModeOn();
328
330 void streamModeOff();
331
333 void switchToMp3Mode();
334
336 void disableI2sOut();
337
339 void enableI2sOut(VS1053_I2S_RATE i2sRate = VS1053_I2S_RATE_48_KHZ);
340
342 bool isChipConnected();
343
345 uint16_t getChipVersion();
346
348 uint16_t getDecodedTime();
349
351 void clearDecodedTime();
352
354 // For more info about patches see http://www.vlsi.fi/en/support/software/vs10xxpatches.html
355 void loadUserCode(const unsigned short* plugin, unsigned short plugin_size);
356
359
360
362 uint8_t treble();
363
365 void setTreble(uint8_t value);
366
368 uint8_t bass();
369
371 void setBass(uint8_t value);
372
374 void setTrebleFrequencyLimit(uint16_t value);
375
377 void setBassFrequencyLimit(uint16_t value);
378
381
383 void end();
384
386 bool beginMidi();
387
389 void sendMidiMessage(uint8_t cmd, uint8_t data1, uint8_t data2);
390
392 bool beginInput(VS1053Recording &opt);
393
395 size_t available();
396
398 size_t readBytes(uint8_t*data, size_t len);
399
401 // A low level method which lets users access the internals of the VS1053.
402 uint16_t readRegister(uint8_t _reg) const;
403
405 // A low level method which lets users access the internals of the VS1053.
406 void writeRegister(uint8_t _reg, uint16_t _value) const;
407
408
409protected:
410 uint8_t cs_pin; // Pin where CS line is connected
411 uint8_t dcs_pin; // Pin where DCS line is connected
412 uint8_t dreq_pin; // Pin where DREQ line is connected
413 uint8_t curvol; // Current volume setting 0..100%
414 int16_t reset_pin = -1; // Custom Reset Pin (optional)
415 int8_t curbalance = 0; // Current balance setting -100..100
416 // (-100 = right channel silent, 100 = left channel silent)
417 const uint8_t vs1053_chunk_size = 32;
418 VS1053_SPI *p_spi = nullptr; // SPI Driver
419 uint8_t endFillByte; // Byte to send when stopping song
420 VS1053Equilizer equilizer;
421 VS1053_MODE mode;
422 uint16_t chip_version = -1;
423 uint8_t channels_multiplier = 1; // Repeat read values for multiple channels
424
425
426
427protected:
428
429 inline void await_data_request() const {
430 while (!digitalRead(dreq_pin)) {
431 yield(); // Very short delay
432 }
433 }
434
435 inline void control_mode_on() const {
436 p_spi->beginTransaction(); // Prevent other SPI users
437 digitalWrite(dcs_pin, HIGH); // Bring slave in control mode
438 digitalWrite(cs_pin, LOW);
439 }
440
441 inline void control_mode_off() const {
442 digitalWrite(cs_pin, HIGH); // End control mode
443 p_spi->endTransaction(); // Allow other SPI users
444 }
445
446 inline void data_mode_on() const {
447 p_spi->beginTransaction(); // Prevent other SPI users
448 digitalWrite(cs_pin, HIGH); // Bring slave in data mode
449 digitalWrite(dcs_pin, LOW);
450 }
451
452 inline void data_mode_off() const {
453 digitalWrite(dcs_pin, HIGH); // End data mode
454 p_spi->endTransaction(); // Allow other SPI users
455 }
456
457 void sdi_send_buffer(uint8_t *data, size_t len);
458
459 void sdi_send_fillers(size_t length);
460
461 void wram_write(uint16_t address, uint16_t data);
462
463 uint16_t wram_read(uint16_t address);
464
465 bool begin_input_vs1053(VS1053Recording &opt);
466
467 bool begin_input_vs1003(VS1053Recording &opt);
468
469 void set_flag(uint16_t &value, uint16_t flag, bool active);
470};
471
472}
VS1053_EARSPEAKER
Earspeaker settings.
Definition: VS1053Driver.h:80
VS1053_MODE
Actual Mode: Input, Output, Output Streaming Midi.
Definition: VS1053Driver.h:72
VS1053_I2S_RATE
I2S Rate.
Definition: VS1053Driver.h:65
Abstract SPI Driver for VS1053. We support different alternative implementations. Outside of Arduino ...
Definition: VS1053SPI.h:20
Main class for controlling VS1053 and VS1003 modules.
Definition: VS1053Driver.h:91
void setBalance(int8_t balance)
Adjusting the left and right volume balance, higher to enhance the right side, lower to enhance the l...
Definition: VS1053Driver.cpp:255
bool testComm(const char *header)
Test communication with module.
Definition: VS1053Driver.cpp:111
void stopSong()
Finish playing a song. Call this after the last playChunk call.
Definition: VS1053Driver.cpp:294
void clearDecodedTime()
Clears SCI_DECODE_TIME register (sets 0x00)
Definition: VS1053Driver.cpp:474
void setTrebleFrequencyLimit(uint16_t value)
Sets the treble frequency limit in hz (range 0 to 15000)
Definition: VS1053Driver.cpp:566
void startSong()
Prepare to start playing. Call this each time a new song starts.
Definition: VS1053Driver.cpp:284
bool beginOutput()
Prepares for regular output in decoding mode - (note that this method is also is calling begin())
Definition: VS1053Driver.cpp:220
void playChunk(uint8_t *data, size_t len)
Legacy method - Play a chunk of data. Copies the data to the chip. Blocks until complete.
Definition: VS1053Driver.cpp:289
void setBassFrequencyLimit(uint16_t value)
Sets the bass frequency limit in hz (range 0 to 15000)
Definition: VS1053Driver.cpp:572
void setBass(uint8_t value)
Sets the bass amplitude value (range 0 to 100)
Definition: VS1053Driver.cpp:559
void writeAudio(uint8_t *data, size_t len)
Play a chunk of data. Copies the data to the chip. Blocks until complete - also supports serial midi.
Definition: VS1053Driver.cpp:674
void loadUserCode(const unsigned short *plugin, unsigned short plugin_size)
Load a patch or plugin to fix bugs and/or extend functionality.
Definition: VS1053Driver.cpp:508
void streamModeOff()
Default: Streaming Mode Off.
Definition: VS1053Driver.cpp:349
void softReset()
Do a soft reset.
Definition: VS1053Driver.cpp:314
void setTone(uint8_t *rtone)
Set the player baas/treble, 4 nibbles for treble gain/freq and bass gain/freq.
Definition: VS1053Driver.cpp:265
uint16_t getChipVersion()
gets Version of the VLSI chip being used
Definition: VS1053Driver.cpp:436
void writeRegister(uint8_t _reg, uint16_t _value) const
Writes to VS10xx's SCI (serial command interface) SPI bus.
Definition: VS1053Driver.cpp:47
size_t available()
Provides the number of bytes which are available in the read buffer.
Definition: VS1053Driver.cpp:800
bool begin()
Begin operation. Sets pins correctly, and prepares SPI bus.
Definition: VS1053Driver.cpp:151
void loadDefaultVs1053Patches()
Loads the latest generic firmware patch.
Definition: VS1053Driver.cpp:534
void end()
Stops the recording of sound - and resets the module.
Definition: VS1053Driver.cpp:602
uint8_t treble()
Provides the treble amplitude value.
Definition: VS1053Driver.cpp:542
void switchToMp3Mode()
An optional switch preventing the module starting up in MIDI mode.
Definition: VS1053Driver.cpp:380
void streamModeOn()
Streaming Mode On.
Definition: VS1053Driver.cpp:342
bool beginMidi()
Starts the MIDI output processing.
Definition: VS1053Driver.cpp:611
uint16_t getDecodedTime()
Provides SCI_DECODE_TIME register value.
Definition: VS1053Driver.cpp:462
uint16_t readRegister(uint8_t _reg) const
Reads a register value.
Definition: VS1053Driver.cpp:33
void sendMidiMessage(uint8_t cmd, uint8_t data1, uint8_t data2)
performs a MIDI command
Definition: VS1053Driver.cpp:656
uint8_t getVolume()
Get the currenet volume setting, higher is louder.
Definition: VS1053Driver.cpp:276
uint8_t bass()
Provides the Bass amplitude value.
Definition: VS1053Driver.cpp:554
int8_t getBalance()
Get the currenet balance setting (-100..100)
Definition: VS1053Driver.cpp:280
void setVolume(uint8_t vol)
Set the player volume.Level from 0-100, higher is louder.
Definition: VS1053Driver.cpp:232
void setTreble(uint8_t value)
Sets the treble amplitude value (range 0 to 100)
Definition: VS1053Driver.cpp:547
bool isChipConnected()
Checks whether the VS1053 chip is connected and is able to exchange data to the ESP.
Definition: VS1053Driver.cpp:425
void enableI2sOut(VS1053_I2S_RATE i2sRate=VS1053_I2S_RATE_48_KHZ)
enable I2S output (GPIO4=LRCLK/WSEL; GPIO5=MCLK; GPIO6=SCLK/BCLK; GPIO7=SDATA/DOUT)
Definition: VS1053Driver.cpp:397
void disableI2sOut()
disable I2S output; this is the default state
Definition: VS1053Driver.cpp:388
void adjustRate(long ppm2)
Fine tune the data rate.
Definition: VS1053Driver.cpp:482
void hardReset()
Do a hardware reset.
Definition: VS1053Driver.cpp:321
bool beginInput(VS1053Recording &opt)
Starts the recording of sound as WAV data.
Definition: VS1053Driver.cpp:688
bool setEarSpeaker(VS1053_EARSPEAKER value)
Activate the ear speaker mode.
Definition: VS1053Driver.cpp:577
size_t readBytes(uint8_t *data, size_t len)
Provides the audio data as WAV.
Definition: VS1053Driver.cpp:812
void printDetails(const char *header)
Print configuration details to serial output.
Definition: VS1053Driver.cpp:356
Relevant control data for recording audio from the vs1053.
Definition: VS1053Recording.h:19