- Fixed issues with Teensy support - The code NVIC_DisableIRQ(MP3_IRQn); applies only to the feather and metro m4 but was applied to all boards which resulted in MP3\_IRQn being undefined. (Adafruit\_MP3.cpp)

- Added support for Teensy 3.5 - Added `defined(__MK64FX512__)` wherever `defined(__MK66FX1M0__)` was found
- Added/modified comments on compiler directives for Teensy boards
- Included test.mp3 sample file (58.3 KB)
- Fix applied to library and the "play_from_SD.ino" example only. *(Other examples may have the same errors so use the above notes to fix other examples if needed.)*

This release was tested with the Teensy 3.5 only. It is expected that it will work with all other supported boards. *(At least as supported as the previous version.)*
This commit is contained in:
Richard Teel 2018-10-06 13:12:45 -04:00
parent 7f42556958
commit 09f62caff9
7 changed files with 53 additions and 18 deletions

View file

@ -2,3 +2,41 @@
This library sets up and performs *native* MP3 audio decoding on various Arduino-compatible platforms including Metro/Feather M4 (SAMD51 chip), teensy 3.6, teensy 3.2, and teensy 3.1. Audio output via the DAC pins. Uses Helix as underlying decoding. On the SAMD51 boards, TC2 is used to create the sample timer (usually 44.1khz or 48khz). Uses a decent chunk of RAM at this time!
See [documentation](https://adafruit.github.io/Adafruit_MP3/classAdafruit__mp3.html).
## UPDATE 6 October 2018 ##
- Fixed issues with Teensy support - The code `NVIC_DisableIRQ(MP3_IRQn);` applies only to the feather and metro m4 but was applied to all boards which resulted in MP3\_IRQn being undefined. (Adafruit\_MP3.cpp)
- Added support for Teensy 3.5 - Added `defined(__MK64FX512__)` wherever `defined(__MK66FX1M0__)` was found
- Added/modified comments on compiler directives for Teensy boards
- Included test.mp3 sample file (58.3 KB)
- Fix applied to library and the "play_from_SD.ino" example only. *(Other examples may have the same errors so use the above notes to fix other examples if needed.)*
This release was tested with the Teensy 3.5 only. It is expected that it will work with all other supported boards. *(At least as supported as the previous version.)*
### Some notes regarding audio file format ###
The tutorial posted on [https://learn.adafruit.com/native-mp3-decoding-on-arduino](https://learn.adafruit.com/native-mp3-decoding-on-arduino "https://learn.adafruit.com/native-mp3-decoding-on-arduino") states:
> This function is called from an interrupt, so it should be short and sweet. It's getting called 44,100 to 48,000 times per second for most MP3 files.
This means that the MP3 files should be encoded within this range. The code is written for stereo MP3 files so if you have a mono MP3 file, it will not play back using this code as is.
Best practice for producing playable MP3 files
- Encode at constant 40kbps with a sample rate of 44,100 kHz
- Stereo only
Resources for encoding audio
- Online converter to strip audio from video or convert audio to MP3 or change bitrate - [https://online-audio-converter.com/](https://online-audio-converter.com/ "https://online-audio-converter.com/")
- Desktop software for conversion - [https://www.audacityteam.org/](https://www.audacityteam.org/ "Audacity")
- How to use Audacity to convert mono to stereo - [https://www.wikihow.com/Change-a-Mono-Track-Into-Stereo-Track-Using-Audacity](https://www.wikihow.com/Change-a-Mono-Track-Into-Stereo-Track-Using-Audacity)
Other notes
- SD Cards (at least on Teensy 3.5 & 3.6 need to be formatted with FAT32 file system. If a small card is used with FAT formatting, it will not work.
- If you receive errors with Teensy 3.5 & 3.6 code regarding the parameters for SD card initialization, look for warnings regarding the SD library. Most likely you have multiple libraries installed and the Teensy SD library is being skipped/ignored. If this is the case, you will need to move or remove the one being used, at least temporarily, so that the Teensy library is used by the Arduino IDE.

View file

@ -5,7 +5,7 @@
//set this to a value between 0 and 4095 to raise/lower volume
#define VOLUME_MAX 1023
#if defined(__MK66FX1M0__) // teensy 3.6
#if defined(__MK66FX1M0__) || defined(__MK64FX512__) // teensy 3.6 or 3.5
const int chipSelect = BUILTIN_SDCARD ;
#elif defined(__MK20DX256__) //teensy 3.1
const int chipSelect = 10;
@ -23,7 +23,7 @@ void writeDacs(int16_t l, int16_t r){
#if defined(__SAMD51__) // feather/metro m4
analogWrite(A0, vall);
analogWrite(A1, valr);
#elif defined(__MK66FX1M0__) // teensy 3.6
#elif defined(__MK66FX1M0__) || defined(__MK64FX512__) // teensy 3.6 or 3.5
analogWrite(A21, vall);
analogWrite(A22, valr);
#elif defined(NRF52)
@ -53,16 +53,11 @@ void setup() {
; // wait for serial port to connect. Needed for native USB port only
}
#if defined(__SAMD51__)
analogWrite(A0, 2048);
analogWrite(A1, 2048);
#endif
Serial.println("Native MP3 decoding!");
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
#if defined(__MK66FX1M0__) || defined(__MK20DX256__) // teensy 3.6 or 3.1/2
#if defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) // teensy 3.6, 3.5, or 3.1/2
analogWriteResolution(12);
while (!SD.begin(chipSelect)) {
#else

BIN
examples/test.mp3 Normal file

Binary file not shown.

View file

@ -5,7 +5,7 @@
#define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.SYNCBUSY.bit.ENABLE);
#elif defined(__MK66FX1M0__) || defined(__MK20DX256__) // teensy 3.6
#elif defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) // teensy 3.6, 3.5. or 3.1/2
IntervalTimer Adafruit_MP3::_MP3Timer;
uint32_t Adafruit_MP3::currentPeriod;
@ -30,7 +30,7 @@ static inline void enableTimer()
#if defined(__SAMD51__) // feather/metro m4
MP3_TC->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;
WAIT_TC16_REGS_SYNC(MP3_TC)
#elif defined(__MK66FX1M0__) || defined(__MK20DX256__) // teensy 3.6
#elif defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) // teensy 3.6, 3.5. or 3.1/2
Adafruit_MP3::_MP3Timer.begin(MP3_Handler, Adafruit_MP3::currentPeriod);
#elif defined(NRF52)
@ -49,7 +49,7 @@ static inline void disableTimer()
#if defined(__SAMD51__) // feather/metro m4
MP3_TC->COUNT16.CTRLA.bit.ENABLE = 0;
WAIT_TC16_REGS_SYNC(MP3_TC)
#elif defined(__MK66FX1M0__) || defined(__MK20DX256__) // teensy 3.6
#elif defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) // teensy 3.6, 3.5. or 3.1/2
Adafruit_MP3::_MP3Timer.end();
#elif defined(NRF52)
MP3_TIMER->TASKS_STOP = 1;
@ -118,7 +118,7 @@ static inline void configureTimer()
MP3_TIMER->INTENSET = (1UL << 16); //enable compare 0 interrupt
#elif defined(__MK66FX1M0__) || defined(__MK20DX256__) // teensy 3.6
#elif defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) // teensy 3.6, 3.5. or 3.1/2
float sec = 1.0 / (float)MP3_SAMPLE_RATE_DEFAULT;
Adafruit_MP3::currentPeriod = sec * 1000000UL;
#endif
@ -144,7 +144,7 @@ static inline void updateTimerFreq(uint32_t freq)
#if defined(__SAMD51__) // feather/metro m4
MP3_TC->COUNT16.CC[0].reg = (uint16_t)( (SystemCoreClock >> 2) / freq);
WAIT_TC16_REGS_SYNC(MP3_TC);
#elif defined(__MK66FX1M0__) || defined(__MK20DX256__) // teensy 3.6
#elif defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) // teensy 3.6, 3.5. or 3.1/2
float sec = 1.0 / (float)freq;
Adafruit_MP3::currentPeriod = sec * 1000000UL;
@ -241,7 +241,9 @@ void Adafruit_MP3_DMA::play()
MP3_TC->COUNT16.INTENCLR.bit.MC0 = 1;
#endif
Adafruit_MP3::play();
#if defined(__SAMD51__) || defined(NRF52) // feather/metro m4
NVIC_DisableIRQ(MP3_IRQn); //we don't need the interrupt
#endif
leftoverSamples = 0;
//fill both buffers

View file

@ -3,7 +3,7 @@
#include "Arduino.h"
#if defined(__MK66FX1M0__) || defined(__MK20DX256__)|| defined(NRF52)
#if defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__)|| defined(NRF52) // teensy 3.6, 3.5, 3.1/2, or Adafruit Feather nRF52
#define ARM_MATH_CM4
#endif
@ -60,7 +60,7 @@ public:
int tick();
#if defined(__MK66FX1M0__) || defined(__MK20DX256__) // teensy 3.6
#if defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) // teensy 3.6, 3.5, or 3.1/2
static IntervalTimer _MP3Timer;
static uint32_t currentPeriod;
#endif

View file

@ -382,7 +382,7 @@ __attribute__((__always_inline__)) static __inline Word64 SAR64(Word64 x, int n)
return( x );
}
#elif (defined(__CORTEX_M) && __CORTEX_M == 0x04U) || defined(__MK66FX1M0__) || defined(__MK20DX256__)
#elif (defined(__CORTEX_M) && __CORTEX_M == 0x04U) || defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) /* teensy 3.6, 3.5, or 3.1/2 */
/* ARM cortex m4 */
@ -420,7 +420,7 @@ static __inline int FASTABS(int x)
static __inline int CLZ(int x)
{
#if defined(__MK66FX1M0__) || defined(__MK20DX256__)
#if defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) /* teensy 3.6, 3.5, or 3.1/2 */
return __builtin_clz(x);
#else
return __CLZ(x);

View file

@ -66,7 +66,7 @@
#
#elif defined(__CORTEX_M) && __CORTEX_M == 0x04U
#
#elif defined(__MK66FX1M0__) || defined(__MK20DX256__)
#elif defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) /* teensy 3.6, 3.5, or 3.1/2 */
#
#else
#error No platform defined. See valid options in mp3dec.h