33 | 33 |
struct mad_synth synth;
|
34 | 34 |
enum mad_error last_error;
|
35 | 35 |
// for lame gapless processing
|
36 | |
bool checkgapless;
|
|
36 |
int checktags;
|
|
37 |
u32_t consume;
|
37 | 38 |
u32_t skip;
|
38 | 39 |
u64_t samples;
|
39 | 40 |
u32_t padding;
|
|
96 | 97 |
return (s32_t)(sample >> (MAD_F_FRACBITS + 1 - 24)) << 8;
|
97 | 98 |
}
|
98 | 99 |
|
|
100 |
// check for id3.2 tag at start of file - http://id3.org/id3v2.4.0-structure, return length
|
|
101 |
static unsigned _check_id3_tag(size_t bytes) {
|
|
102 |
u8_t *ptr = streambuf->readp;
|
|
103 |
u32_t size = 0;
|
|
104 |
|
|
105 |
if (bytes > 10 && *ptr == 'I' && *(ptr+1) == 'D' && *(ptr+2) == '3') {
|
|
106 |
// size is encoded as syncsafe integer, add 10 if footer present
|
|
107 |
if (*(ptr+6) < 0x80 && *(ptr+7) < 0x80 && *(ptr+8) < 0x80 && *(ptr+9) < 0x80) {
|
|
108 |
size = 10 + (*(ptr+6) << 21) + (*(ptr+7) << 14) + (*(ptr+8) << 7) + *(ptr+9) + ((*(ptr+5) & 0x10) ? 10 : 0);
|
|
109 |
LOG_DEBUG("id3.2 tag len: %u", size);
|
|
110 |
}
|
|
111 |
}
|
|
112 |
|
|
113 |
return size;
|
|
114 |
}
|
|
115 |
|
99 | 116 |
// check for lame gapless params, don't advance streambuf
|
100 | 117 |
static void _check_lame_header(size_t bytes) {
|
101 | 118 |
u8_t *ptr = streambuf->readp;
|
|
149 | 166 |
LOCK_S;
|
150 | 167 |
bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
|
151 | 168 |
|
152 | |
if (m->checkgapless) {
|
153 | |
m->checkgapless = false;
|
154 | |
if (!stream.meta_interval) {
|
155 | |
_check_lame_header(bytes);
|
|
169 |
if (m->checktags) {
|
|
170 |
if (m->checktags == 1) {
|
|
171 |
m->consume = _check_id3_tag(bytes);
|
|
172 |
m->checktags = 2;
|
|
173 |
}
|
|
174 |
if (m->consume) {
|
|
175 |
u32_t consume = min(m->consume, bytes);
|
|
176 |
LOG_DEBUG("consume: %u of %u", consume, m->consume);
|
|
177 |
_buf_inc_readp(streambuf, consume);
|
|
178 |
m->consume -= consume;
|
|
179 |
UNLOCK_S;
|
|
180 |
return DECODE_RUNNING;
|
|
181 |
}
|
|
182 |
if (m->checktags == 2) {
|
|
183 |
if (!stream.meta_interval) {
|
|
184 |
_check_lame_header(bytes);
|
|
185 |
}
|
|
186 |
m->checktags = 0;
|
156 | 187 |
}
|
157 | 188 |
}
|
158 | 189 |
|
|
304 | 335 |
if (!m->readbuf) {
|
305 | 336 |
m->readbuf = malloc(READBUF_SIZE + MAD_BUFFER_GUARD);
|
306 | 337 |
}
|
307 | |
m->checkgapless = true;
|
|
338 |
m->checktags = 1;
|
|
339 |
m->consume = 0;
|
308 | 340 |
m->skip = MAD_DELAY;
|
309 | 341 |
m->samples = 0;
|
310 | 342 |
m->readbuf_len = 0;
|