VS1053  1.03.00
Arduino Library for VS10xx shield
vs1053_SdFat.cpp
Go to the documentation of this file.
1 
9 #include <vs1053_SdFat.h>
10 // inslude the SPI library:
11 #include "SPI.h"
12 //avr pgmspace library for storing the LUT in program flash instead of sram
13 #include <avr/pgmspace.h>
14 
25 static const uint16_t bitrate_table[15][6] PROGMEM = {
26  { 0, 0, 0, 0, 0, 0}, //0000
27  { 32, 32, 32, 32, 8, 8}, //0001
28  { 64, 48, 40, 48, 16, 16}, //0010
29  { 96, 56, 48, 56, 24, 24}, //0011
30  {128, 64, 56, 64, 32, 32}, //0100
31  {160, 80, 64, 80, 40, 40}, //0101
32  {192, 96, 80, 96, 48, 48}, //0110
33  {224,112, 96,112, 56, 56}, //0111
34  {256,128,112,128, 64, 64}, //1000
35  {288,160,128,144, 80, 80}, //1001
36  {320,192,160,160, 96, 69}, //1010
37  {352,224,192,176,112,112}, //1011
38  {384,256,224,192,128,128}, //1100
39  {416,320,256,224,144,144}, //1101
40  {448,384,320,256,160,160} //1110
41  };
42 
43 /*
44  * Format of a MIDI file into a char arrar. Simply one note on and then off.
45 */
46 // MIDI Event Specifics
47 #define MIDI_NOTE_ON 9
48 #define MIDI_NOTE_OFF 8
49 
50 // MIDI File structure
51 // Header Chunk
52 #define MIDI_HDR_CHUNK_ID 0x4D, 0x54, 0x68, 0x64 // const for MIDI
53 #define MIDI_CHUNKSIZE 0, 0, 0, 6
54 #define MIDI_FORMAT 0, 0 // VSdsp only support Format 0!
55 #define MIDI_NUMBER_OF_TRACKS 0, 1 // ergo must be 1 track
56 #define MIDI_TIME_DIVISION 0, 96
57 // Track Chunk
58 #define MIDI_TRACK_CHUNK_ID 0x4D, 0x54, 0x72, 0x6B // const for MIDI
59 #define MIDI_CHUNK_SIZE 0, 0, 0, sizeof(MIDI_EVENT_NOTE_ON) + sizeof(MIDI_EVENT_NOTE_OFF) + sizeof(MIDI_END_OF_TRACK) // hard coded with zero padded
60 // Events
61 #define MIDI_EVENT_NOTE_ON 0, (MIDI_NOTE_ON<<4) + MIDI_CHANNEL, MIDI_NOTE_NUMBER, MIDI_INTENSITY
62 #define MIDI_EVENT_NOTE_OFF MIDI_NOTE_DURATION, (MIDI_NOTE_OFF<<4) + MIDI_CHANNEL, MIDI_NOTE_NUMBER, MIDI_INTENSITY
63 //
64 #define MIDI_END_OF_TRACK 0, 0xFF, 0x2F, 0
65 
83 
84 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
85 /* Initialize static classes and variables
86  */
87 
91 SdFile vs1053::track;
92 
97 
101 uint16_t vs1053::spi_Read_Rate;
102 uint16_t vs1053::spi_Write_Rate;
103 
104 // only needed for specific means of refilling
105 #if defined(USE_MP3_REFILL_MEANS) && USE_MP3_REFILL_MEANS == USE_MP3_SimpleTimer
106  SimpleTimer timer;
107  int timerId_mp3;
108 #endif
109 
110 //buffer for music
111 uint8_t vs1053::mp3DataBuffer[32];
112 
113 //------------------------------------------------------------------------------
132 uint8_t vs1053::begin() {
133 
134 /*
135  This test is to assit in the migration from versions prior to 1.01.00.
136  It is not really needed, simply prints an easy error, to better assist.
137  If you are using SdFat objects other than "sd" the below may be omitted.
138  or whant to save 222 bytes of Flash space.
139  */
140 #if (1)
141 if (int8_t(sd.vol()->fatType()) == 0) {
142  Serial.println(F("If you get this error, you likely do not have a sd.begin in the main sketch, See Trouble Shooting Guide!"));
143  Serial.println(F("http://mpflaga.github.com/Sparkfun-MP3-Player-Shield-Arduino-Library/#Troubleshooting"));
144 }
145 #endif
146 
147  pinMode(MP3_DREQ, INPUT);
148  pinMode(MP3_XCS, OUTPUT);
149  pinMode(MP3_XDCS, OUTPUT);
150  pinMode(MP3_RESET, OUTPUT);
151 
152 #if PERF_MON_PIN != -1
153  pinMode(PERF_MON_PIN, OUTPUT);
154  digitalWrite(PERF_MON_PIN,HIGH);
155 #endif
156 
157  cs_high(); //MP3_XCS, Init Control Select to deselected
158  dcs_high(); //MP3_XDCS, Init Data Select to deselected
159  digitalWrite(MP3_RESET, LOW); //Put VS1053 into hardware reset
160 
162 
163  uint8_t result = vs_init();
164  if(result) {
165  return result;
166  }
167 
168 #if defined(USE_MP3_REFILL_MEANS) && USE_MP3_REFILL_MEANS == USE_MP3_Timer1
169  Timer1.initialize(MP3_REFILL_PERIOD);
170 #elif defined(USE_MP3_REFILL_MEANS) && USE_MP3_REFILL_MEANS == USE_MP3_SimpleTimer
171  timerId_mp3 = timer.setInterval(MP3_REFILL_PERIOD, refill);
172  timer.disable(timerId_mp3);
173 #endif
174 
175  return 0;
176 }
177 
187 void vs1053::end() {
188 
189  stopTrack(); // Stop and CLOSE any open tracks.
190  disableRefill(); // shut down specific interrupts
191  cs_high(); //MP3_XCS, Init Control Select to deselected
192  dcs_high(); //MP3_XDCS, Init Data Select to deselected
193 
194  // most importantly...
195  digitalWrite(MP3_RESET, LOW); //Put VS1053 into hardware reset
196 
198 }
199 
200 //------------------------------------------------------------------------------
220 uint8_t vs1053::vs_init() {
221 
222  //Initialize VS1053 chip
223 
224  //Reset if not already
225  delay(100); // keep clear of anything prior
226  digitalWrite(MP3_RESET, LOW); //Shut down VS1053
227  delay(100);
228 
229  //Bring out of reset
230  digitalWrite(MP3_RESET, HIGH); //Bring up VS1053
231 
232  //From section 7.6 of datasheet, max SCI reads are CLKI/7.
233  //Assuming CLKI = 12.288MgHz for Shield and 16.0MgHz for Arduino
234  //The VS1053's internal clock multiplier SCI_CLOCKF:SC_MULT is 1.0x after power up.
235  //For a maximum SPI rate of 1.8MgHz = (CLKI/7) = (12.288/7) the VS1053's default.
236 
237  //Warning:
238  //Note that spi transfers interleave between SdCard and VS10xx.
239  //Where Sd2Card.cpp sets SPCR & SPSR each and every transfer
240 
241  //The SDfatlib using SPI_FULL_SPEED results in an 8MHz spi clock rate,
242  //faster than initial allowed spi rate of 1.8MgHz.
243 
244  // set initial mp3's spi to safe rate
245  spi_Read_Rate = SPI_CLOCK_DIV16;
246  spi_Write_Rate = SPI_CLOCK_DIV16;
247  delay(10);
248 
249  //Let's check the status of the VS1053
250  int MP3Mode = Mp3ReadRegister(SCI_MODE);
251 
252 /*
253  Serial.print(F("SCI_Mode (0x4800) = 0x"));
254  Serial.println(MP3Mode, HEX);
255 
256  int MP3Status = Mp3ReadRegister(SCI_Status);
257  Serial.print(F("SCI_Status (0x48) = 0x"));
258  Serial.println(MP3Status, HEX);
259 
260  int MP3Clock = Mp3ReadRegister(SCI_CLOCKF);
261  Serial.print(F("SCI_ClockF = 0x"));
262  Serial.println(MP3Clock, HEX);
263  */
264 
265  if(MP3Mode != (SM_LINE1 | SM_SDINEW)) return 4;
266 
267  //Now that we have the VS1053 up and running, increase the internal clock multiplier and up our SPI rate
268  Mp3WriteRegister(SCI_CLOCKF, 0x6000); //Set multiplier to 3.0x
269  //Internal clock multiplier is now 3x.
270  //Therefore, max SPI speed is 52MgHz.
271 
272 #if (F_CPU == 16000000 )
273  spi_Read_Rate = SPI_CLOCK_DIV4; //use safe SPI rate of (16MHz / 4 = 4MHz)
274  spi_Write_Rate = SPI_CLOCK_DIV2; //use safe SPI rate of (16MHz / 2 = 8MHz)
275 #else
276  // must be 8000000
277  spi_Read_Rate = SPI_CLOCK_DIV2; //use safe SPI rate of (8MHz / 2 = 4MHz)
278  spi_Write_Rate = SPI_CLOCK_DIV2; //use safe SPI rate of (8MHz / 2 = 4MHz)
279 #endif
280 
281  delay(10); // settle time
282 
283  //test reading after data rate change
284  int MP3Clock = Mp3ReadRegister(SCI_CLOCKF);
285  if(MP3Clock != 0x6000) return 5;
286 
287  setVolume(40, 40);
288  // one would think the following patch would over write the volume.
289  // But the SCI_VOL register space is not in the VSdsp's WRAM space.
290  // Note to keep an eye on it for future patches.
291 
292  if(VSLoadUserCode("patches.053")) return 6;
293 
294  delay(100); // just a good idea to let settle.
295 
296  return 0; // indicating all was good.
297 }
298 
299 //------------------------------------------------------------------------------
327 uint8_t vs1053::VSLoadUserCode(char* fileName){
328 
329  union twobyte val;
330  union twobyte addr;
331  union twobyte n;
332 
333  if(!digitalRead(MP3_RESET)) return 3;
334  if(isPlaying()) return 1;
335  if(!digitalRead(MP3_RESET)) return 3;
336 
337  //Open the file in read mode.
338  if(!track.open(fileName, O_READ)) return 2;
339  //playing_state = loading;
340  //while(i<size_of_Plugin/sizeof(Plugin[0])) {
341  while(1) {
342  //addr = Plugin[i++];
343  if(!track.read(addr.byte, 2)) break;
344  //n = Plugin[i++];
345  if(!track.read(n.byte, 2)) break;
346  if(n.word & 0x8000U) { /* RLE run, replicate n samples */
347  n.word &= 0x7FFF;
348  //val = Plugin[i++];
349  if(!track.read(val.byte, 2)) break;
350  while(n.word--) {
351  Mp3WriteRegister(addr.word, val.word);
352  }
353  } else { /* Copy run, copy n samples */
354  while(n.word--) {
355  //val = Plugin[i++];
356  if(!track.read(val.byte, 2)) break;
357  Mp3WriteRegister(addr.word, val.word);
358  }
359  }
360  }
361  track.close(); //Close out this track
362  //playing_state = ready;
363  return 0;
364 }
365 
366 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
367 // @{
368 // SelfTest_Group
369 
370 //------------------------------------------------------------------------------
389 uint8_t vs1053::enableTestSineWave(uint8_t freq) {
390 
391  if(isPlaying() || !digitalRead(MP3_RESET)) {
392  Serial.println(F("Warning Tests are not available."));
393  return -1;
394  }
395 
396  uint16_t MP3SCI_MODE = Mp3ReadRegister(SCI_MODE);
397  if(MP3SCI_MODE & SM_TESTS) {
398  return 2;
399  }
400 
401  Mp3WriteRegister(SCI_MODE, MP3SCI_MODE | SM_TESTS);
402 
403  for(int y = 0 ; y <= 1 ; y++) { // need to do it twice if it was already done once before
404  //Wait for DREQ to go high indicating IC is available
405  while(!digitalRead(MP3_DREQ)) ;
406  //Select control
407  dcs_low();
408  //SCI consists of instruction byte, address byte, and 16-bit data word.
409  SPI.transfer(0x53);
410  SPI.transfer(0xEF);
411  SPI.transfer(0x6E);
412  SPI.transfer(freq);
413  SPI.transfer(0x00);
414  SPI.transfer(0x00);
415  SPI.transfer(0x00);
416  SPI.transfer(0x00);
417  while(!digitalRead(MP3_DREQ)) ; //Wait for DREQ to go high indicating command is complete
418  dcs_high(); //Deselect Control
419  }
420 
422  return 1;
423 }
424 
425 //------------------------------------------------------------------------------
441 
442  if(isPlaying() || !digitalRead(MP3_RESET)) {
443  Serial.println(F("Warning Tests are not available."));
444  return -1;
445  }
446 
447  uint16_t MP3SCI_MODE = Mp3ReadRegister(SCI_MODE);
448  if(!(MP3SCI_MODE & SM_TESTS)) {
449  return 0;
450  }
451 
452  //Wait for DREQ to go high indicating IC is available
453  while(!digitalRead(MP3_DREQ)) ;
454 
455  //Select SPI Control channel
456  dcs_low();
457 
458  //SDI consists of instruction byte, address byte, and 16-bit data word.
459  SPI.transfer(0x45);
460  SPI.transfer(0x78);
461  SPI.transfer(0x69);
462  SPI.transfer(0x74);
463  SPI.transfer(0x00);
464  SPI.transfer(0x00);
465  SPI.transfer(0x00);
466  SPI.transfer(0x00);
467  while(!digitalRead(MP3_DREQ)) ; //Wait for DREQ to go high indicating command is complete
468 
469  //Deselect SPI Control channel
470  dcs_high();
471 
472  // turn test mode bit off
474 
476  return 0;
477 }
478 
479 //------------------------------------------------------------------------------
495 uint16_t vs1053::memoryTest() {
496 
497  if(isPlaying() || !digitalRead(MP3_RESET)) {
498  Serial.println(F("Warning Tests are not available."));
499  return -1;
500  }
501 
503 
504  vs_init();
505 
506  uint16_t MP3SCI_MODE = Mp3ReadRegister(SCI_MODE);
507  if(MP3SCI_MODE & SM_TESTS) {
509  return 2;
510  }
511 
512  Mp3WriteRegister(SCI_MODE, MP3SCI_MODE | SM_TESTS);
513 
514 // for(int y = 0 ; y <= 1 ; y++) { // need to do it twice if it was already done once before
515  //Wait for DREQ to go high indicating IC is available
516  while(!digitalRead(MP3_DREQ)) ;
517 
518  //Select SPI Control channel
519  dcs_low();
520 
521  //SCI consists of instruction byte, address byte, and 16-bit data word.
522  SPI.transfer(0x4D);
523  SPI.transfer(0xEA);
524  SPI.transfer(0x6D);
525  SPI.transfer(0x54);
526  SPI.transfer(0x00);
527  SPI.transfer(0x00);
528  SPI.transfer(0x00);
529  SPI.transfer(0x00);
530  while(!digitalRead(MP3_DREQ)) ; //Wait for DREQ to go high indicating command is complete
531 
532  //Deselect SPI Control channel
533  dcs_high();
534 // }
535  delay(250);
536 
537  uint16_t MP3SCI_HDAT0 = Mp3ReadRegister(SCI_HDAT0);
538 
540 
541  vs_init();
542 
544  return MP3SCI_HDAT0;
545 }
546 // @}
547 // SelfTest_Group
548 
549 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
550 // @{
551 // Volume_Group
552 
553 //------------------------------------------------------------------------------
564 void vs1053::setVolume(uint16_t data) {
565  union twobyte val;
566  val.word = data;
567  setVolume(val.byte[1], val.byte[0]);
568 }
569 
570 //------------------------------------------------------------------------------
581 void vs1053::setVolume(uint8_t data) {
582  setVolume(data, data);
583 }
584 
585 //------------------------------------------------------------------------------
598 void vs1053::setVolume(uint8_t leftchannel, uint8_t rightchannel){
599 
600  VolL = leftchannel;
601  VolR = rightchannel;
602  Mp3WriteRegister(SCI_VOL, leftchannel, rightchannel);
603 }
604 
605 //------------------------------------------------------------------------------
620 uint16_t vs1053::getVolume() {
621  uint16_t MP3SCI_VOL = Mp3ReadRegister(SCI_VOL);
622  return MP3SCI_VOL;
623 }
624 // @}
625 // Volume_Group
626 
627 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
628 // @{
629 // Base_Treble_Group
630 
631 //------------------------------------------------------------------------------
639 {
640  union sci_bass_m sci_base_value;
641  sci_base_value.word = Mp3ReadRegister(SCI_BASS);
642  return (sci_base_value.nibble.Treble_Freqlimt * 1000);
643 }
644 
645 //------------------------------------------------------------------------------
653 {
654  union sci_bass_m sci_base_value;
655  sci_base_value.word = Mp3ReadRegister(SCI_BASS);
656  return (sci_base_value.nibble.Treble_Amplitude);
657 }
658 //------------------------------------------------------------------------------
666 {
667  union sci_bass_m sci_base_value;
668  sci_base_value.word = Mp3ReadRegister(SCI_BASS);
669  return (sci_base_value.nibble.Bass_Freqlimt * 10);
670 }
671 
672 //------------------------------------------------------------------------------
684 {
685  union sci_bass_m sci_base_value;
686  sci_base_value.word = Mp3ReadRegister(SCI_BASS);
687  return (sci_base_value.nibble.Bass_Amplitude);
688 }
689 //------------------------------------------------------------------------------
697 void vs1053::setTrebleFrequency(uint16_t frequency)
698 {
699  union sci_bass_m sci_base_value;
700 
701  frequency /= 1000;
702 
703  if(frequency < 1)
704  {
705  frequency = 1;
706  }
707  else if(frequency > 15)
708  {
709  frequency = 15;
710  }
711 
712  sci_base_value.word = Mp3ReadRegister(SCI_BASS);
713  sci_base_value.nibble.Treble_Freqlimt = frequency;
714  Mp3WriteRegister(SCI_BASS, sci_base_value.word);
715 }
716 
717 //------------------------------------------------------------------------------
725 void vs1053::setTrebleAmplitude(int8_t amplitude)
726 {
727  union sci_bass_m sci_base_value;
728 
729 
730  if(amplitude < -8)
731  {
732  amplitude = -8;
733  }
734  else if(amplitude > 7)
735  {
736  amplitude = 7;
737  }
738 
739  sci_base_value.word = Mp3ReadRegister(SCI_BASS);
740  sci_base_value.nibble.Treble_Amplitude = amplitude;
741  Mp3WriteRegister(SCI_BASS, sci_base_value.word);
742 }
743 
744 //------------------------------------------------------------------------------
752 void vs1053::setBassFrequency(uint16_t frequency)
753 {
754  union sci_bass_m sci_base_value;
755 
756  frequency /= 10;
757 
758  if(frequency < 2)
759  {
760  frequency = 2;
761  }
762  else if(frequency > 15)
763  {
764  frequency = 15;
765  }
766 
767  sci_base_value.word = Mp3ReadRegister(SCI_BASS);
768  sci_base_value.nibble.Bass_Freqlimt = frequency;
769  Mp3WriteRegister(SCI_BASS, sci_base_value.word);
770 }
771 
772 //------------------------------------------------------------------------------
784 void vs1053::setBassAmplitude(uint8_t amplitude)
785 {
786  union sci_bass_m sci_base_value;
787 
788  if(amplitude < 0)
789  {
790  amplitude = 0;
791  }
792  else if(amplitude > 15)
793  {
794  amplitude = 15;
795  }
796 
797  sci_base_value.word = Mp3ReadRegister(SCI_BASS);
798  sci_base_value.nibble.Bass_Amplitude = amplitude;
799  Mp3WriteRegister(SCI_BASS, sci_base_value.word);
800 }
801 // @}
802 // Base_Treble_Group
803 
804 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
805 // @{
806 // PlaySpeed_Group
807 
808 //------------------------------------------------------------------------------
825  uint16_t MP3playspeed = Mp3ReadWRAM(para_playSpeed);
826  return MP3playspeed;
827 }
828 
829 //------------------------------------------------------------------------------
844 void vs1053::setPlaySpeed(uint16_t data) {
846 }
847 // @}
848 //PlaySpeed_Group
849 
850 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
851 // @{
852 // EarSpeaker_Group
853 
854 //------------------------------------------------------------------------------
865  uint8_t result = 0;
866  uint16_t MP3SCI_MODE = Mp3ReadRegister(SCI_MODE);
867 
868  // SM_EARSPEAKER bits are not adjacent hence need to add them together
869  if(MP3SCI_MODE & SM_EARSPEAKER_LO) {
870  result += 0b01;
871  }
872  if(MP3SCI_MODE & SM_EARSPEAKER_HI) {
873  result += 0b10;
874  }
875  return result;
876 }
877 
878 //------------------------------------------------------------------------------
888 void vs1053::setEarSpeaker(uint16_t EarSpeaker) {
889  uint16_t MP3SCI_MODE = Mp3ReadRegister(SCI_MODE);
890 
891  // SM_EARSPEAKER bits are not adjacent hence need to add them individually
892  if(EarSpeaker & 0b01) {
893  MP3SCI_MODE |= SM_EARSPEAKER_LO;
894  } else {
895  MP3SCI_MODE &= ~SM_EARSPEAKER_LO;
896  }
897 
898  if(EarSpeaker & 0b10) {
899  MP3SCI_MODE |= SM_EARSPEAKER_HI;
900  } else {
901  MP3SCI_MODE &= ~SM_EARSPEAKER_HI;
902  }
903  Mp3WriteRegister(SCI_MODE, MP3SCI_MODE);
904 }
905 // @}
906 // EarSpeaker_Group
907 
908 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
909 // @{
910 // Differential_Output_Mode_Group
911 
912 //------------------------------------------------------------------------------
929  uint8_t result = 0;
930  uint16_t MP3SCI_MODE = Mp3ReadRegister(SCI_MODE);
931 
932  if(MP3SCI_MODE & SM_DIFF) {
933  result = 1;
934  }
935  return result;
936 }
937 
938 //------------------------------------------------------------------------------
952 void vs1053::setDifferentialOutput(uint16_t DiffMode) {
953  uint16_t MP3SCI_MODE = Mp3ReadRegister(SCI_MODE);
954 
955  if(DiffMode) {
956  MP3SCI_MODE |= SM_DIFF;
957  } else {
958  MP3SCI_MODE &= ~SM_DIFF;
959  }
960  Mp3WriteRegister(SCI_MODE, MP3SCI_MODE);
961 }
962 // @}
963 // Differential_Output_Mode_Group
964 
965 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
966 // @{
967 // Stereo_Group
968 
969 //------------------------------------------------------------------------------
983  uint16_t result = (Mp3ReadWRAM(para_MonoOutput) & 0x0001);
984  return result;
985 }
986 
987 //------------------------------------------------------------------------------
998 void vs1053::setMonoMode(uint16_t StereoMode) {
999  uint16_t data = (Mp3ReadWRAM(para_MonoOutput) & ~0x0001); // preserve other bits
1000  Mp3WriteWRAM(0x1e09, (StereoMode | (data & 0x0001)));
1001 }
1002 // @}
1003 // Stereo_Group
1004 
1005 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1006 // @{
1007 // Play_Control_Group
1008 
1009 //------------------------------------------------------------------------------
1025 uint8_t vs1053::playTrack(uint8_t trackNo){
1026 
1027  //a storage place for track names
1028  char trackName[] = "track001.mp3";
1029  uint8_t trackNumber = 1;
1030 
1031  //tack the number onto the rest of the filename
1032  sprintf(trackName, "track%03d.mp3", trackNo);
1033 
1034  //play the file
1035  return playMP3(trackName);
1036 }
1037 
1038 //------------------------------------------------------------------------------
1066 uint8_t vs1053::playMP3(char* fileName, uint32_t timecode) {
1067 
1068  if(isPlaying()) return 1;
1069  if(!digitalRead(MP3_RESET)) return 3;
1070 
1071  //Open the file in read mode.
1072  if(!track.open(fileName, O_READ)) return 2;
1073 
1074  // find length of arrary at pointer
1075  int fileNamefileName_length = 0;
1076  while(*(fileName + fileNamefileName_length))
1077  fileNamefileName_length++;
1078 
1079  // Only know how to read bitrate from MP3 file. ignore the rest.
1080  // Note bitrate may get updated later by getAudioInfo()
1081  if(strstr(strlwr(fileName), "mp3") ) {
1082  getBitRateFromMP3File(fileName);
1083  if (timecode > 0) {
1084  track.seekSet(timecode * bitrate + start_of_music); // skip to X ms.
1085  }
1086  }
1087 
1089 
1090  Mp3WriteRegister(SCI_DECODE_TIME, 0); // Reset the Decode and bitrate from previous play back.
1091  delay(100); // experimentally found that we need to let this settle before sending data.
1092 
1093  //gotta start feeding that hungry mp3 chip
1094  refill();
1095 
1096  //attach refill interrupt off DREQ line, pin 2
1097  enableRefill();
1098 
1099  return 0;
1100 }
1101 
1102 //------------------------------------------------------------------------------
1111 
1112  if(((playing_state != playback) && (playing_state != paused_playback)) || !digitalRead(MP3_RESET))
1113  return;
1114 
1115  //cancel external interrupt
1116  disableRefill();
1117  playing_state = ready;
1118 
1119  track.close(); //Close out this track
1120 
1121  flush_cancel(pre); //possible mode of "none" for faster response.
1122 
1123  //Serial.println(F("Track is done!"));
1124 
1125 }
1126 
1127 //------------------------------------------------------------------------------
1139  uint8_t result;
1140 
1141  if(!digitalRead(MP3_RESET))
1142  result = 3;
1143  else if(getState() == playback)
1144  result = 1;
1145  else if(getState() == paused_playback)
1146  result = 1;
1147  else
1148  result = 0;
1149 
1150  return result;
1151 }
1152 
1162  return playing_state;
1163 }
1164 
1165 //------------------------------------------------------------------------------
1172 
1173  //cancel external interrupt
1174  if((playing_state == playback) && digitalRead(MP3_RESET))
1175  {
1176  disableRefill();
1178  }
1179 }
1180 
1181 //------------------------------------------------------------------------------
1189 
1190  if((playing_state == paused_playback) && digitalRead(MP3_RESET)) {
1191  //see if it is already ready for more
1192  refill();
1193 
1195  //attach refill interrupt off DREQ line, pin 2
1196  enableRefill();
1197  }
1198 }
1199 
1200 //------------------------------------------------------------------------------
1210  pauseDataStream();
1211 }
1212 
1213 //------------------------------------------------------------------------------
1229 uint8_t vs1053::resumeMusic(uint32_t timecode) {
1230  if((playing_state == paused_playback) && digitalRead(MP3_RESET)) {
1231 
1232  if(!track.seekSet(((timecode * Mp3ReadWRAM(para_byteRate))/1000) + start_of_music)) //if(!track.seekCur((uint32_t(timecode/1000 * Mp3ReadWRAM(para_byteRate)))))
1233  return 2;
1234 
1235  resumeDataStream();
1236  return 0;
1237  }
1238  return 1;
1239 }
1240 
1241 //------------------------------------------------------------------------------
1255  if((playing_state == paused_playback) && digitalRead(MP3_RESET)) {
1256  resumeDataStream();
1257  return 0;
1258  }
1259  return 1;
1260 }
1261 
1262 //------------------------------------------------------------------------------
1278 uint8_t vs1053::skip(int32_t timecode){
1279 
1280  if(isPlaying() && digitalRead(MP3_RESET)) {
1281 
1282  //stop interupt for now
1283  disableRefill();
1285 
1286  // try to set the files position to current position + offset(in bytes)
1287  // as calculated from current byte rate, as per VSdsp.
1288  if(!track.seekCur((uint32_t(timecode/1000 * Mp3ReadWRAM(para_byteRate))))) // skip next X ms.
1289  return 2;
1290 
1291  Mp3WriteRegister(SCI_VOL, 0xFE, 0xFE);
1292  //seeked successfully
1293 
1294  flush_cancel(pre); //possible mode of "none" for faster response.
1295 
1296  //gotta start feeding that hungry mp3 chip
1297  refill();
1298 
1299  //again, I'm being bad and not following the spec sheet.
1300  //I already turned the volume down, so when the MP3 chip gets upset at me
1301  //for just slammin in new bits of the file, you won't hear it.
1302  //so we'll wait a bit, and restore the volume to previous level
1303  delay(50);
1304 
1305  //one of these days I'll come back and try to do it the right way.
1306  setVolume(VolL,VolR);
1307 
1309  //attach refill interrupt off DREQ line, pin 2
1310  enableRefill();
1311 
1312  return 0;
1313  }
1314 
1315  return 1;
1316 }
1317 
1318 //------------------------------------------------------------------------------
1334 uint8_t vs1053::skipTo(uint32_t timecode){
1335 
1336  if(isPlaying() && digitalRead(MP3_RESET)) {
1337 
1338  //stop interupt for now
1339  disableRefill();
1341 
1342  // try to set the files position to current position + offset(in bytes)
1343  // as calculated from current byte rate, as per VSdsp.
1344  if(!track.seekSet(((timecode * Mp3ReadWRAM(para_byteRate))/1000) + start_of_music)) // skip to X ms.
1345  //if(!track.seekCur((uint32_t(timecode/1000 * Mp3ReadWRAM(para_byteRate))))) // skip next X ms.
1346  return 2;
1347 
1348  Mp3WriteRegister(SCI_VOL, 0xFE, 0xFE);
1349  //seeked successfully
1350 
1351  flush_cancel(pre); //possible mode of "none" for faster response.
1352 
1353  //gotta start feeding that hungry mp3 chip
1354  refill();
1355 
1356  //again, I'm being bad and not following the spec sheet.
1357  //I already turned the volume down, so when the MP3 chip gets upset at me
1358  //for just slammin in new bits of the file, you won't hear it.
1359  //so we'll wait a bit, and restore the volume to previous level
1360  delay(50);
1361 
1362  //one of these days I'll come back and try to do it the right way.
1363  setVolume(VolL,VolR);
1364 
1366  //attach refill interrupt off DREQ line, pin 2
1367  enableRefill();
1368 
1369  return 0;
1370  }
1371 
1372  return 1;
1373 }
1374 
1375 //------------------------------------------------------------------------------
1391 
1392  return(Mp3ReadRegister(SCI_DECODE_TIME) << 10); // multiply by 1024 to convert to milliseconds.
1393 }
1394 
1395 // @}
1396 // Play_Control_Group
1397 
1398 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1399 // @{
1400 // Audio_Information_Group
1401 
1402 //------------------------------------------------------------------------------
1414 void vs1053::trackArtist(char* infobuffer){
1415  getTrackInfo(TRACK_ARTIST, infobuffer);
1416 }
1417 
1418 //------------------------------------------------------------------------------
1430 void vs1053::trackTitle(char* infobuffer){
1431  getTrackInfo(TRACK_TITLE, infobuffer);
1432 }
1433 
1434 //------------------------------------------------------------------------------
1446 void vs1053::trackAlbum(char* infobuffer){
1447  getTrackInfo(TRACK_ALBUM, infobuffer);
1448 }
1449 
1450 //------------------------------------------------------------------------------
1463 void vs1053::getTrackInfo(uint8_t offset, char* infobuffer){
1464 
1465  //disable interupts
1466  if(playing_state == playback) {
1467  disableRefill();
1468  }
1469 
1470  //record current file position
1471  uint32_t currentPos = track.curPosition();
1472 
1473  //skip to end
1474  track.seekEnd((-128 + offset));
1475 
1476  //read 30 bytes of tag informat at -128 + offset
1477  track.read(infobuffer, 30);
1478  infobuffer = strip_nonalpha_inplace(infobuffer);
1479 
1480  //seek back to saved file position
1481  track.seekSet(currentPos);
1482 
1483  //renable interupt
1484  if(playing_state == playback) {
1485  enableRefill();
1486  }
1487 
1488 }
1489 
1490 //------------------------------------------------------------------------------
1503 
1504  //disable interupts
1505  // already disabled in Mp3ReadRegister function
1506  //pauseDataStream();
1507 
1508  Serial.print(F("HDAT1"));
1509  Serial.print(F("\tHDAT0"));
1510  Serial.print(F("\tVOL"));
1511  Serial.print(F("\tMode"));
1512  Serial.print(F("\tStatus"));
1513  Serial.print(F("\tClockF"));
1514  Serial.print(F("\tpversion"));
1515  Serial.print(F("\t[Bytes/S]"));
1516  Serial.print(F("\t[KBits/S]"));
1517  Serial.print(F("\tPlaySpeed"));
1518  Serial.print(F("\tDECODE_TIME"));
1519  Serial.print(F("\tCurrentPos"));
1520  Serial.println();
1521 
1522 
1523  uint16_t MP3HDAT1 = Mp3ReadRegister(SCI_HDAT1);
1524  Serial.print(F("0x"));
1525  Serial.print(MP3HDAT1, HEX);
1526 
1527  uint16_t MP3HDAT0 = Mp3ReadRegister(SCI_HDAT0);
1528  Serial.print(F("\t0x"));
1529  Serial.print(MP3HDAT0, HEX);
1530 
1531  uint16_t MP3SCI_VOL = Mp3ReadRegister(SCI_VOL);
1532  Serial.print(F("\t0x"));
1533  Serial.print(MP3SCI_VOL, HEX);
1534 
1535  uint16_t MP3Mode = Mp3ReadRegister(SCI_MODE);
1536  Serial.print(F("\t0x"));
1537  Serial.print(MP3Mode, HEX);
1538 
1539  uint16_t MP3Status = Mp3ReadRegister(SCI_STATUS);
1540  Serial.print(F("\t0x"));
1541  Serial.print(MP3Status, HEX);
1542 
1543  uint16_t MP3Clock = Mp3ReadRegister(SCI_CLOCKF);
1544  Serial.print(F("\t0x"));
1545  Serial.print(MP3Clock, HEX);
1546 
1547  uint16_t MP3para_version = Mp3ReadWRAM(para_version);
1548  Serial.print(F("\t0x"));
1549  Serial.print(MP3para_version, HEX);
1550 
1551  uint16_t MP3ByteRate = Mp3ReadWRAM(para_byteRate);
1552  Serial.print(F("\t\t"));
1553  Serial.print(MP3ByteRate, HEX);
1554 
1555  Serial.print(F("\t\t"));
1556  Serial.print((MP3ByteRate>>7), DEC); // shift 7 is the same as *8/1024, and easier math.
1557 
1558  uint16_t MP3playSpeed = Mp3ReadWRAM(para_playSpeed);
1559  Serial.print(F("\t\t"));
1560  Serial.print(MP3playSpeed, HEX);
1561 
1562  uint16_t MP3SCI_DECODE_TIME = Mp3ReadRegister(SCI_DECODE_TIME);
1563  Serial.print(F("\t\t"));
1564  Serial.print(MP3SCI_DECODE_TIME, DEC);
1565 
1566  Serial.print(F("\t\t"));
1567  Serial.print(currentPosition(), DEC);
1568 
1569  Serial.println();
1570 }
1571 
1572 //------------------------------------------------------------------------------
1587 void vs1053::getBitRateFromMP3File(char* fileName) {
1588  //look for first MP3 frame (11 1's)
1589  bitrate = 0;
1590  uint8_t temp = 0;
1591  uint8_t row_num =0;
1592 
1593  for(uint16_t i = 0; i<65535; i++) {
1594  if(track.read() == 0xFF) {
1595 
1596  temp = track.read();
1597 
1598  if(((temp & 0b11100000) == 0b11100000) && ((temp & 0b00000110) != 0b00000000)) {
1599 
1600  //found the 11 1's
1601  //parse version, layer and bitrate out and save bitrate
1602  if(!(temp & 0b00001000)) {
1603  row_num = 3;
1604  }
1605  else if((temp & 0b00000110) == 0b00000100) { //true if layer 2, false if layer 1 or 3
1606  row_num += 1;
1607  }
1608  else if((temp & 0b00000110) == 0b00000010) { //true if layer 3, false if layer 2 or 1
1609  row_num += 2;
1610  } else {
1611  continue; // Not found, need to skip the rest and continue looking.
1612  // \warning But this can lead to a dead end and file end of file.
1613  }
1614 
1615  //parse bitrate code from next byte
1616  temp = track.read();
1617  temp = temp>>4;
1618 
1619  //lookup bitrate
1620  bitrate = pgm_read_word_near ( &(bitrate_table[temp][row_num]) );
1621 
1622  //convert kbps to Bytes per mS
1623  bitrate /= 8;
1624 
1625  //record file position
1626  track.seekCur(-3);
1627  start_of_music = track.curPosition();
1628 
1629 // Serial.print(F("POS: "));
1630 // Serial.println(start_of_music);
1631 
1632 // Serial.print(F("Bitrate: "));
1633 // Serial.println(bitrate);
1634 
1635  //break out of for loop
1636  break;
1637 
1638  }
1639  }
1640  }
1641  }
1642 
1643 //------------------------------------------------------------------------------
1655  return 1;
1656  }
1657  return 0;
1658  }
1659 
1660 //------------------------------------------------------------------------------
1673 int8_t vs1053::setVUmeter(int8_t enable) {
1674  uint16_t MP3Status = Mp3ReadRegister(SCI_STATUS);
1675 
1676  if(enable) {
1678  } else {
1679  Mp3WriteRegister(SCI_STATUS, MP3Status & ~SS_VU_ENABLE);
1680  }
1681  return 1; // in future return if not available, if patch not applied.
1682  }
1683 
1684 //------------------------------------------------------------------------------
1697  return Mp3ReadRegister(SCI_AICTRL3);
1698 }
1699 
1700 // @}
1701 // Audio_Information_Group
1702 
1703 //------------------------------------------------------------------------------
1712 void vs1053::setBitRate(uint16_t bitr){
1713 
1714  bitrate = bitr;
1715  return;
1716 }
1717 
1718 //------------------------------------------------------------------------------
1728  //Set SPI bus for write
1729  SPI.setBitOrder(MSBFIRST);
1730  SPI.setDataMode(SPI_MODE0);
1731  SPI.setClockDivider(spi_Write_Rate);
1732 }
1733 
1734 //------------------------------------------------------------------------------
1745  spiInit();
1746  digitalWrite(MP3_XCS, LOW);
1747 }
1748 
1749 //------------------------------------------------------------------------------
1757  digitalWrite(MP3_XCS, HIGH);
1758 }
1759 
1760 //------------------------------------------------------------------------------
1771  spiInit();
1772  digitalWrite(MP3_XDCS, LOW);
1773 }
1774 
1775 //------------------------------------------------------------------------------
1783  digitalWrite(MP3_XDCS, HIGH);
1784 }
1785 
1786 //------------------------------------------------------------------------------
1796 void vs1053::Mp3WriteRegister(uint8_t addressbyte, uint16_t data) {
1797  union twobyte val;
1798  val.word = data;
1799  Mp3WriteRegister(addressbyte, val.byte[1], val.byte[0]);
1800 }
1801 
1802 //------------------------------------------------------------------------------
1813 void vs1053::Mp3WriteRegister(uint8_t addressbyte, uint8_t highbyte, uint8_t lowbyte) {
1814 
1815  // skip if the chip is in reset.
1816  if(!digitalRead(MP3_RESET)) return;
1817 
1818  //cancel interrupt if playing
1819  if(playing_state == playback)
1820  disableRefill();
1821 
1822  //Wait for DREQ to go high indicating IC is available
1823  while(!digitalRead(MP3_DREQ)) ;
1824 
1825  cs_low(); //Select control
1826 
1827  //SCI consists of instruction byte, address byte, and 16-bit data word.
1828  SPI.transfer(0x02); //Write instruction
1829  SPI.transfer(addressbyte);
1830  SPI.transfer(highbyte);
1831  SPI.transfer(lowbyte);
1832  while(!digitalRead(MP3_DREQ)) ; //Wait for DREQ to go high indicating command is complete
1833  cs_high(); //Deselect Control
1834 
1835  //resume interrupt if playing.
1836  if(playing_state == playback) {
1837  //see if it is already ready for more
1838  refill();
1839 
1840  //attach refill interrupt off DREQ line, pin 2
1841  enableRefill();
1842  }
1843 
1844 }
1845 
1846 //------------------------------------------------------------------------------
1856 uint16_t vs1053::Mp3ReadRegister (uint8_t addressbyte){
1857 
1858  union twobyte resultvalue;
1859 
1860  // skip if the chip is in reset.
1861  if(!digitalRead(MP3_RESET)) return 0;
1862 
1863  //cancel interrupt if playing
1864  if(playing_state == playback)
1865  disableRefill();
1866 
1867  while(!digitalRead(MP3_DREQ)) ; //Wait for DREQ to go high indicating IC is available
1868 
1869  cs_low(); //Select control
1870  SPI.setClockDivider(spi_Read_Rate); // correct the clock speed as from cs_low()
1871 
1872  //SCI consists of instruction byte, address byte, and 16-bit data word.
1873  SPI.transfer(0x03); //Read instruction
1874  SPI.transfer(addressbyte);
1875 
1876  resultvalue.byte[1] = SPI.transfer(0xFF); //Read the first byte
1877  while(!digitalRead(MP3_DREQ)) ; //Wait for DREQ to go high indicating command is complete
1878  resultvalue.byte[0] = SPI.transfer(0xFF); //Read the second byte
1879  while(!digitalRead(MP3_DREQ)) ; //Wait for DREQ to go high indicating command is complete
1880 
1881  cs_high(); //Deselect Control
1882 
1883  //resume interrupt if playing.
1884  if(playing_state == playback) {
1885  //see if it is already ready for more
1886  refill();
1887 
1888  //attach refill interrupt off DREQ line, pin 2
1889  enableRefill();
1890  }
1891  return resultvalue.word;
1892 }
1893 
1894 //------------------------------------------------------------------------------
1904 uint16_t vs1053::Mp3ReadWRAM (uint16_t addressbyte){
1905 
1906  unsigned short int tmp1,tmp2;
1907 
1908  //Set SPI bus for write
1909  spiInit();
1910  SPI.setClockDivider(spi_Read_Rate);
1911 
1912  Mp3WriteRegister(SCI_WRAMADDR, addressbyte);
1913  tmp1 = Mp3ReadRegister(SCI_WRAM);
1914 
1915  Mp3WriteRegister(SCI_WRAMADDR, addressbyte);
1916  tmp2 = Mp3ReadRegister(SCI_WRAM);
1917 
1918  if(tmp1==tmp2) return tmp1;
1919  Mp3WriteRegister(SCI_WRAMADDR, addressbyte);
1920  tmp2 = Mp3ReadRegister(SCI_WRAM);
1921 
1922  if(tmp1==tmp2) return tmp1;
1923  Mp3WriteRegister(SCI_WRAMADDR, addressbyte);
1924  tmp2 = Mp3ReadRegister(SCI_WRAM);
1925 
1926  if(tmp1==tmp2) return tmp1;
1927  return tmp1;
1928 }
1929 
1930 //------------------------------------------------------------------------------
1939 //Write the 16-bit value of a VS10xx WRAM location
1940 void vs1053::Mp3WriteWRAM(uint16_t addressbyte, uint16_t data){
1941 
1942  Mp3WriteRegister(SCI_WRAMADDR, addressbyte);
1943  Mp3WriteRegister(SCI_WRAM, data);
1944 }
1945 
1946 //------------------------------------------------------------------------------
1954 #if defined(USE_MP3_REFILL_MEANS) && USE_MP3_REFILL_MEANS == USE_MP3_SimpleTimer
1955  timer.run();
1956 #elif defined(USE_MP3_REFILL_MEANS) && USE_MP3_REFILL_MEANS == USE_MP3_Polled
1957  refill();
1958 #endif
1959 }
1960 
1961 //------------------------------------------------------------------------------
1976 
1977  //Serial.println(F("filling"));
1978 #if PERF_MON_PIN != -1
1979  digitalWrite(PERF_MON_PIN,LOW);
1980 #endif
1981 
1982  // no need to keep interrupts blocked, allow other ISR such as timer0 to continue
1983 #if !defined(USE_MP3_REFILL_MEANS) || USE_MP3_REFILL_MEANS == USE_MP3_INTx
1984  sei();
1985 #endif
1986 
1987  while(digitalRead(MP3_DREQ)) {
1988 
1989  if(!track.read(mp3DataBuffer, sizeof(mp3DataBuffer))) { //Go out to SD card and try reading 32 new bytes of the song
1990  track.close(); //Close out this track
1991  playing_state = ready;
1992 
1993  //cancel external interrupt
1994  disableRefill();
1995 
1996  flush_cancel(post); //possible mode of "none" for faster response.
1997 
1998  //Oh no! There is no data left to read!
1999  //Time to exit
2000  break;
2001  }
2002 
2003 
2004  //Once DREQ is released (high) we now feed 32 bytes of data to the VS1053 from our SD read buffer
2005 #if !defined(USE_MP3_REFILL_MEANS) || USE_MP3_REFILL_MEANS == USE_MP3_INTx
2006  cli(); // allow transfer to occur with out interruption.
2007 #endif
2008  dcs_low(); //Select Data
2009  for(uint8_t y = 0 ; y < sizeof(mp3DataBuffer) ; y++) {
2010  //while(!digitalRead(MP3_DREQ)); // wait until DREQ is or goes high // turns out it is not needed.
2011  SPI.transfer(mp3DataBuffer[y]); // Send SPI byte
2012  }
2013 
2014  dcs_high(); //Deselect Data
2015  //We've just dumped 32 bytes into VS1053 so our SD read buffer is empty. go get more data
2016 #if !defined(USE_MP3_REFILL_MEANS) || USE_MP3_REFILL_MEANS == USE_MP3_INTx
2017  sei();
2018 #endif
2019  }
2020 
2021 #if PERF_MON_PIN != -1
2022  digitalWrite(PERF_MON_PIN,HIGH);
2023 #endif
2024 }
2025 
2026 //------------------------------------------------------------------------------
2037 
2038  if(!digitalRead(MP3_RESET))
2039  return;
2040 
2041  //cancel and store current state to restore after
2042  disableRefill();
2043  state_m prv_state = playing_state;
2045 
2046  // need to quickly purge the exiting formate of decoder.
2047  flush_cancel(none);
2048 
2049  // wait for VS1053 to be available.
2050  while(!digitalRead(MP3_DREQ));
2051 
2052 #if !defined(USE_MP3_REFILL_MEANS) || USE_MP3_REFILL_MEANS == USE_MP3_INTx
2053  cli(); // allow transfer to occur with out interruption.
2054 #endif
2055 
2056  dcs_low(); //Select Data
2057  for(uint8_t y = 0 ; y < sizeof(SingleMIDInoteFile) ; y++) { // sizeof(mp3DataBuffer)
2058  // Every 32 check if not ready for next buffer chunk.
2059  if ( !(y % 32) ) {
2060  while(!digitalRead(MP3_DREQ));
2061  }
2062  SPI.transfer( pgm_read_byte_near( &(SingleMIDInoteFile[y]))); // Send next byte
2063  }
2064  dcs_high(); //Deselect Data
2065 
2066 #if !defined(USE_MP3_REFILL_MEANS) || USE_MP3_REFILL_MEANS == USE_MP3_INTx
2067  sei(); // renable interrupts for other processes
2068 #endif
2069 
2070  flush_cancel(none); // need to quickly purge the exiting format of decoder.
2071  playing_state = prv_state;
2072  enableRefill();
2073 }
2074 
2075 //------------------------------------------------------------------------------
2083  if(playing_state == playback) {
2084  #if defined(USE_MP3_REFILL_MEANS) && USE_MP3_REFILL_MEANS == USE_MP3_Timer1
2085  Timer1.attachInterrupt( refill );
2086  #elif defined(USE_MP3_REFILL_MEANS) && USE_MP3_REFILL_MEANS == USE_MP3_SimpleTimer
2087  timer.enable(timerId_mp3);
2088  #elif !defined(USE_MP3_REFILL_MEANS) || USE_MP3_REFILL_MEANS == USE_MP3_INTx
2089  attachInterrupt(MP3_DREQINT, refill, RISING);
2090  #endif
2091  }
2092 }
2093 
2094 //------------------------------------------------------------------------------
2102 #if defined(USE_MP3_REFILL_MEANS) && USE_MP3_REFILL_MEANS == USE_MP3_Timer1
2103  Timer1.detachInterrupt();
2104 #elif defined(USE_MP3_REFILL_MEANS) && USE_MP3_REFILL_MEANS == USE_MP3_SimpleTimer
2105  timer.disable(timerId_mp3);
2106 #elif !defined(USE_MP3_REFILL_MEANS) || USE_MP3_REFILL_MEANS == USE_MP3_INTx
2107  detachInterrupt(MP3_DREQINT);
2108 #endif
2109 }
2110 
2111 //------------------------------------------------------------------------------
2129  int8_t endFillByte = (int8_t) (Mp3ReadWRAM(para_endFillByte) & 0xFF);
2130 
2131  if((mode == post) || (mode == both)) {
2132 
2133  dcs_low(); //Select Data
2134  for(int y = 0 ; y < 2052 ; y++) {
2135  while(!digitalRead(MP3_DREQ)); // wait until DREQ is or goes high
2136  SPI.transfer(endFillByte); // Send SPI byte
2137  }
2138  dcs_high(); //Deselect Data
2139  }
2140 
2141  for (int n = 0; n < 64 ; n++)
2142  {
2143 // Mp3WriteRegister(SCI_MODE, SM_LINE1 | SM_SDINEW | SM_CANCEL); // old way of SCI_MODE WRITE.
2145 
2146  dcs_low(); //Select Data
2147  for(int y = 0 ; y < 32 ; y++) {
2148  while(!digitalRead(MP3_DREQ)); // wait until DREQ is or goes high
2149  SPI.transfer(endFillByte); // Send SPI byte
2150  }
2151  dcs_high(); //Deselect Data
2152 
2153  int cancel = Mp3ReadRegister(SCI_MODE) & SM_CANCEL;
2154  if(cancel == 0) {
2155  // Cancel has succeeded.
2156  if((mode == pre) || (mode == both)) {
2157  dcs_low(); //Select Data
2158  for(int y = 0 ; y < 2052 ; y++) {
2159  while(!digitalRead(MP3_DREQ)); // wait until DREQ is or goes high
2160  SPI.transfer(endFillByte); // Send SPI byte
2161  }
2162  dcs_high(); //Deselect Data
2163  }
2164  return;
2165  }
2166  }
2167  // Cancel has not succeeded.
2168  //Serial.println(F("Warning: VS10XX chip did not cancel, reseting chip!"));
2169 // Mp3WriteRegister(SCI_MODE, SM_LINE1 | SM_SDINEW | SM_RESET); // old way of SCI_MODE WRITE.
2170  Mp3WriteRegister(SCI_MODE, (Mp3ReadRegister(SCI_MODE) | SM_RESET)); // software reset. but vs_init will HW reset anyways.
2171 // vs_init(); // perform hardware reset followed by re-initializing.
2172  //vs_init(); // however, vs1053::begin() is member function that does not exist statically.
2173 }
2174 
2175 
2176 //------------------------------------------------------------------------------
2198 uint8_t vs1053::ADMixerLoad(char* fileName){
2199 
2200  if(!digitalRead(MP3_RESET)) return 3;
2201  if(isPlaying() != FALSE)
2202  return 1;
2203 
2205  if(VSLoadUserCode(fileName)) {
2206  playing_state = ready;
2207  return 2;
2208  // Serial.print(F("Error: ")); Serial.print(fileName); Serial.println(F(", file not found, skipping."));
2209  }
2210 
2211  // Set Input Mode to either Line1 or Microphone.
2212 #if defined(VS_LINE1_MODE)
2214 #else
2216 #endif
2217  playing_state = ready;
2218  return 0;
2219 }
2220 
2221 //------------------------------------------------------------------------------
2235 void vs1053::ADMixerVol(int8_t ADM_volume){
2236  union twobyte MP3AIADDR;
2237  union twobyte MP3AICTRL0;
2238 
2239  MP3AIADDR.word = Mp3ReadRegister(SCI_AIADDR);
2240 
2241  if((ADM_volume > -3) || (-31 > ADM_volume)) {
2242  // Disable Mixer Patch
2243  MP3AIADDR.word = 0x0F01;
2244  Mp3WriteRegister(SCI_AIADDR, MP3AIADDR.word);
2245  } else {
2246  // Set Volume
2247  //MP3AICTRL0.word = Mp3ReadRegister(SCI_AICTRL0);
2248  MP3AICTRL0.byte[1] = (uint8_t) ADM_volume; // upper byte appears to have no affect
2249  MP3AICTRL0.byte[0] = (uint8_t) ADM_volume;
2250  Mp3WriteRegister(SCI_AICTRL0, MP3AICTRL0.word);
2251 
2252  // Enable Mixer Patch
2253  MP3AIADDR.word = 0x0F00;
2254  Mp3WriteRegister(SCI_AIADDR, MP3AIADDR.word);
2255  }
2256 }
2257 
2258 
2259 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2260 // Global Function
2261 
2269 char* strip_nonalpha_inplace(char *s) {
2270  for ( ; *s && !isalpha(*s); ++s)
2271  ; // skip leading non-alpha chars
2272  if(*s == '\0')
2273  return s; // there are no alpha characters
2274 
2275  char *tail = s + strlen(s);
2276  for ( ; !isalpha(*tail); --tail)
2277  ; // skip trailing non-alpha chars
2278  *++tail = '\0'; // truncate after the last alpha
2279 
2280  return s;
2281 }
2282 
2291 bool isFnMusic(char* filename) {
2292  int8_t len = strlen(filename);
2293  bool result;
2294  if ( strstr(strlwr(filename + (len - 4)), ".mp3")
2295  || strstr(strlwr(filename + (len - 4)), ".aac")
2296  || strstr(strlwr(filename + (len - 4)), ".wma")
2297  || strstr(strlwr(filename + (len - 4)), ".wav")
2298  || strstr(strlwr(filename + (len - 4)), ".fla")
2299  || strstr(strlwr(filename + (len - 4)), ".mid")
2300  ) {
2301  result = true;
2302  } else {
2303  result = false;
2304  }
2305  return result;
2306 }
#define para_MonoOutput
A macro of the WRAM para_MonoOutput register&#39;s address (R/W)
Definition: vs1053_SdFat.h:575
bool isFnMusic(char *filename)
is the filename music
#define para_playSpeed
A macro of the WRAM para_playSpeed register&#39;s address (R/W)
Definition: vs1053_SdFat.h:532
void setEarSpeaker(uint16_t)
Set the current Spatial EarSpeaker setting of the VS10xx chip.
uint16_t memoryTest()
Perform Memory Test.
#define SCI_AICTRL3
A macro of the SCI AICTRL[x] register (R/W)
Definition: vs1053_SdFat.h:269
uint8_t VolL
contains a local value of the VSdsp&#39;s master volume left channels
Definition: vs1053_SdFat.h:759
uint8_t playTrack(uint8_t)
Begin playing a mp3 file, just with a number.
#define TRACK_TITLE
A macro of the offset for the track&#39;s Title.
Definition: vs1053_SdFat.h:637
#define SM_CANCEL
A macro of the SM_DIFF bit mask of the SCI_MODE register.
Definition: vs1053_SdFat.h:313
#define MP3_XCS
A macro to configure the XCS pin.
uint8_t bitrate
contains a local value of the beleived current bit-rate.
Definition: vs1053_SdFat.h:753
Don&#39;t Flush.
Definition: vs1053_SdFat.h:81
static const uint16_t bitrate_table [15][6] PROGMEM
bitrate lookup table
#define SCI_WRAMADDR
A macro of the SCI WRAMADDR register (W)
Definition: vs1053_SdFat.h:186
uint16_t word
whole word value
Definition: vs1053_SdFat.h:777
state_m getState()
Get the current state of the device.
void trackArtist(char *)
Get Track&#39;s Artist.
#define MIDI_TRACK_CHUNK_ID
SdFat sd
SdFat sd;.
#define SCI_AIADDR
A macro of the SCI AIADDR register&#39;s address (R/W)
Definition: vs1053_SdFat.h:223
uint8_t getDifferentialOutput()
Get the current SM_DIFF setting from the VS10xx chip.
#define MIDI_CHUNK_SIZE
void SendSingleMIDInote()
Play hardcoded MIDI file.
struct vs1053::sci_bass_m::@0 nibble
individual Nibbles
static state_m playing_state
Boolean flag indicating if filehandle is streaming.
Definition: vs1053_SdFat.h:743
void setBassAmplitude(uint8_t)
Set the current Bass Boost amplitude in VS10xx chip.
static void available()
Public interface of refill.
uint8_t skip(int32_t)
Skips to a duration in the track.
void setBassFrequency(uint16_t)
Set the current Bass Boost Frequency limit cutoff in VS10xx chip.
void getTrackInfo(uint8_t, char *)
Fetch ID3 Tag information.
PROGMEM const uint8_t SingleMIDInoteFile[]
a MIDI File of one Note
#define para_endFillByte
A macro of the WRAM para_endFillByte register&#39;s address (R/W)
Definition: vs1053_SdFat.h:561
void setMonoMode(uint16_t)
Set the current Stereo/Mono setting of the VS10xx output.
uint16_t word
whole word value
Definition: vs1053_SdFat.h:826
uint16_t getTrebleFrequency()
Get the current Treble Frequency limit from the VS10xx chip.
#define FALSE
Definition: vs1053_SdFat.h:621
#define SM_TESTS
A macro of the SM_TESTS bit mask of the SCI_MODE register.
Definition: vs1053_SdFat.h:335
uint16_t getVolume()
Get the current volume from the VS10xx chip.
#define MIDI_FORMAT
static void disableRefill()
Disable the Interrupts for refill.
static uint16_t Mp3ReadWRAM(uint16_t)
Read a VS10xx WRAM Location.
flush_m
How to flush the VSdsp&#39;s buffer.
Definition: vs1053_SdFat.h:53
#define SCI_WRAM
A macro of the SCI WRAM register&#39;s address (R/W)
Definition: vs1053_SdFat.h:178
int8_t setVUmeter(int8_t)
enable VSdsp VU Meter
void setTrebleAmplitude(int8_t)
Set the current Treble Amplitude in VS10xx chip.
uint8_t vs_init()
Initialize the VS10xx Audio Decoder Chip.
#define MIDI_NUMBER_OF_TRACKS
uint8_t skipTo(uint32_t)
Skips to a certain point in the track.
int16_t getVUlevel()
get current measured VU Meter
#define SM_LINE1
A macro of the SM_LINE1 bit mask of the SCI_MODE register.
Definition: vs1053_SdFat.h:423
uint16_t getPlaySpeed()
Get the current playSpeed from the VS10xx chip.
uint32_t currentPosition()
Current timecode in ms.
uint8_t enableTestSineWave(uint8_t)
Generate Test Sine wave.
#define SCI_DECODE_TIME
A macro of the SCI Decode Time register&#39;s address (R/W)
Definition: vs1053_SdFat.h:155
void setPlaySpeed(uint16_t)
Set the current playSpeed of the VS10xx chip.
#define SM_EARSPEAKER_HI
A macro of the SM_EARSPEAKER_HI bit mask of the SCI_MODE register.
Definition: vs1053_SdFat.h:354
#define MIDI_EVENT_NOTE_OFF
static void dcs_high()
Deselect Data Channel.
void setBitRate(uint16_t)
Force bit rate.
#define SCI_MODE
A macro of the SCI MODE register&#39;s address (R/W)
Definition: vs1053_SdFat.h:117
Flush First.
Definition: vs1053_SdFat.h:67
#define SCI_STATUS
A macro of the SCI STATUS register&#39;s address (R/W)
Definition: vs1053_SdFat.h:125
static void dcs_low()
Select Data Channel.
uint32_t start_of_music
contains a filehandles offset to the begining of the current file.
Definition: vs1053_SdFat.h:756
int8_t getVUmeter()
get the status of the VSdsp VU Meter
#define PERF_MON_PIN
A macro to configure a Pin to analyze performance.
state_m
State of the vs1053 device.
Definition: vs1053_SdFat.h:33
static uint16_t spi_Read_Rate
Rate of the SPI to be used with communicating to the VSdsp.
Definition: vs1053_SdFat.h:746
static void spiInit()
Initialize the SPI for VS10xx use.
void resumeDataStream()
Unpause streaming data to the VSdsp.
Flush After.
Definition: vs1053_SdFat.h:60
void getBitRateFromMP3File(char *)
Read the Bit-Rate from the current track&#39;s filehandle.
#define para_byteRate
A macro of the WRAM para_byteRate register&#39;s address (R/W)
Definition: vs1053_SdFat.h:546
uint8_t VSLoadUserCode(char *)
load VS1xxx with patch or plugin from file on SDcard.
static uint16_t Mp3ReadRegister(uint8_t)
Read a VS10xx register.
#define SCI_HDAT1
A macro of the SCI HDAT1 register&#39;s address (R/W)
Definition: vs1053_SdFat.h:211
#define SM_RESET
A macro of the SM_DIFF bit mask of the SM_RESET register.
Definition: vs1053_SdFat.h:303
uint8_t VolR
contains a local value of the VSdsp&#39;s master volume Right channels
Definition: vs1053_SdFat.h:762
uint8_t isPlaying()
Inidicate if a song is playing?
uint8_t disableTestSineWave()
Disable Test Sine wave.
static void cs_low()
Select Control Channel.
#define SCI_AICTRL0
A macro of the SCI AICTRL[x] register&#39;s address (R/W)
Definition: vs1053_SdFat.h:245
void pauseDataStream()
Pause streaming data to the VSdsp.
static uint8_t mp3DataBuffer[32]
Buffer for moving data between Filehandle and VSdsp.
Definition: vs1053_SdFat.h:750
#define MIDI_TIME_DIVISION
Flush both First and After.
Definition: vs1053_SdFat.h:74
void ADMixerVol(int8_t)
Set ADMixer&#39;s attenuation of input to between -3 and -31 dB otherwise disable.
static void enableRefill()
Enable the Interrupts for refill.
#define para_version
A macro of the WRAM para_version register&#39;s address (R/W)
Definition: vs1053_SdFat.h:510
void setTrebleFrequency(uint16_t)
Set the current treble frequency limit in VS10xx chip.
uint16_t getMonoMode()
Get the current Stereo/Mono setting of the VS10xx output.
#define MIDI_EVENT_NOTE_ON
void end()
Disables the MP3 Player shield.
char * strip_nonalpha_inplace(char *s)
chomp non printable characters out of string.
void getAudioInfo()
Display various Audio information from the VSdsp.
#define SM_EARSPEAKER_LO
A macro of the SM_EARSPEAKER_LO bit mask of the SCI_MODE register.
Definition: vs1053_SdFat.h:324
bool resumeMusic()
Resume music from where it was paused.
static void Mp3WriteWRAM(uint16_t, uint16_t)
Write a VS10xx WRAM Location.
#define MP3_DREQINT
A macro to configure the DREQINT pin.
static void cs_high()
Deselect Control Channel.
static void flush_cancel(flush_m)
flush the VSdsp buffer and cancel
int8_t getTrebleAmplitude()
Get the current Treble Amplitude from the VS10xx chip.
A handler for accessing bytes of a word.
Definition: vs1053_SdFat.h:819
#define MP3_RESET
A macro to configure the RESET pin.
#define MIDI_CHUNKSIZE
#define MIDI_HDR_CHUNK_ID
#define SS_VU_ENABLE
A macro of the SS_VU_ENABLE bit mask of the SCI_STATUS register.
Definition: vs1053_SdFat.h:468
#define SCI_BASS
A macro of the SCI BASS register&#39;s address (R/W)
Definition: vs1053_SdFat.h:134
void trackTitle(char *)
Get Track&#39;s Title.
static SdFile track
Initializer for the instance of the SdCard&#39;s static member.
Definition: vs1053_SdFat.h:721
uint8_t byte[2]
individual bytes
Definition: vs1053_SdFat.h:834
#define SM_DIFF
A macro of the SM_DIFF bit mask of the SCI_MODE register.
Definition: vs1053_SdFat.h:287
uint8_t playMP3(char *, uint32_t timecode=0)
Begin playing a mp3 file by its filename.
static uint16_t spi_Write_Rate
Definition: vs1053_SdFat.h:747
#define MP3_XDCS
A macro to configure the XDCS pin.
uint8_t getEarSpeaker()
Get the current Spatial EarSpeaker setting from the VS10xx chip.
#define TRACK_ALBUM
A macro of the offset for the track&#39;s Album.
Definition: vs1053_SdFat.h:655
#define MIDI_END_OF_TRACK
void trackAlbum(char *)
Get Track&#39;s Album.
static void Mp3WriteRegister(uint8_t, uint8_t, uint8_t)
Write a value a VSDsp&#39;s register.
void pauseMusic()
Pause music.
#define SM_SDINEW
A macro of the SM_SDINEW bit mask of the SCI_MODE register.
Definition: vs1053_SdFat.h:393
uint8_t ADMixerLoad(char *)
Initially load ADMixer patch and configure line/mic mode.
#define SCI_VOL
A macro of the SCI VOL register&#39;s address (R/W)
Definition: vs1053_SdFat.h:237
void setVolume(uint8_t, uint8_t)
Store and Push member volume to VS10xx chip.
static void refill()
Refill the VS10xx buffer with new data.
void stopTrack()
Gracefully close track and cancel refill.
int8_t getBassAmplitude()
Get the current Bass boost amplitude from the VS10xx chip.
uint8_t begin()
Initialize the MP3 Player shield.
#define TRACK_ARTIST
A macro of the offset for the track&#39;s Artist.
Definition: vs1053_SdFat.h:646
#define MP3_DREQ
A macro to configure the DREQ pin.
uint16_t getBassFrequency()
Get the current Bass Frequency limit from the VS10xx chip.
A handler for accessing nibbles of the SCI_BASS word.
Definition: vs1053_SdFat.h:770
#define SCI_CLOCKF
A macro of the SCI CLOCKF register&#39;s address (R/W)
Definition: vs1053_SdFat.h:141
void setDifferentialOutput(uint16_t)
Set the current SM_DIFF setting of the VS10xx chip.
#define SCI_HDAT0
A macro of the SCI HDAT0 register&#39;s address (R/W)
Definition: vs1053_SdFat.h:199