1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#ifndef LIB_ADAFRUIT_MP3_H
#define LIB_ADAFRUIT_MP3_H
#include "Arduino.h"
#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
#include "arm_math.h"
#include "mp3dec.h"
//TODO: decide on a reasonable buffer size
#if defined(NRF52)
#define MP3_OUTBUF_SIZE (4 * 1024)
#define MP3_INBUF_SIZE (2 * 1024)
#define BUFFER_LOWER_THRESH (1 * 1024)
#else
#define MP3_OUTBUF_SIZE (4 * 1024)
#define MP3_INBUF_SIZE (2 * 1024)
#define BUFFER_LOWER_THRESH (1 * 1024)
#endif
#define MP3_SAMPLE_RATE_DEFAULT 44100
#if defined(__SAMD51__) // feather/metro m4
#define MP3_TC TC2
#define MP3_IRQn TC2_IRQn
#define MP3_Handler TC2_Handler
#define MP3_GCLK_ID TC2_GCLK_ID
#define MP3_DMA_TRIGGER TC2_DMAC_ID_MC_0
#elif defined(NRF52)
#define MP3_TIMER NRF_TIMER1
#define MP3_IRQn TIMER1_IRQn
#define MP3_Handler TIMER1_IRQHandler
#endif
struct Adafruit_MP3_outbuf {
volatile int count;
int16_t buffer[MP3_OUTBUF_SIZE];
};
class Adafruit_MP3 {
public:
Adafruit_MP3() : hMP3Decoder() { inbufend = (inBuf + MP3_INBUF_SIZE); }
~Adafruit_MP3() { MP3FreeDecoder(hMP3Decoder); };
bool begin();
void setBufferCallback(int (*fun_ptr)(uint8_t *, int));
void setSampleReadyCallback(void (*fun_ptr)(int16_t, int16_t));
void play();
void pause();
void resume();
int tick();
#if defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) // teensy 3.6, 3.5, or 3.1/2
static IntervalTimer _MP3Timer;
static uint32_t currentPeriod;
#endif
static uint8_t numChannels;
protected:
#if defined(__SAMD51__) // feather/metro m4
Tc *_tc;
#endif
HMP3Decoder hMP3Decoder;
volatile int bytesLeft;
uint8_t *readPtr;
uint8_t *writePtr;
uint8_t inBuf[MP3_INBUF_SIZE];
uint8_t *inbufend;
bool playing = false;
int (*bufferCallback)(uint8_t *, int);
int findID3Offset(uint8_t *readPtr);
};
class Adafruit_MP3_DMA : public Adafruit_MP3 {
public:
Adafruit_MP3_DMA() : Adafruit_MP3() {
framebuf = NULL;
decodeCallback = NULL;
}
~Adafruit_MP3_DMA() {
if(framebuf != NULL) free(framebuf);
}
void getBuffers(int16_t **ping, int16_t **pong);
void setDecodeCallback(void (*fun_ptr)(int16_t *, int)) { decodeCallback = fun_ptr; }
void play();
int fill();
private:
int16_t *framebuf, *leftover;
int leftoverSamples;
MP3FrameInfo frameInfo;
void (*decodeCallback)(int16_t *, int);
};
#endif
|