summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/export/mpeg.h2
-rw-r--r--firmware/mpeg.c148
2 files changed, 85 insertions, 65 deletions
diff --git a/firmware/export/mpeg.h b/firmware/export/mpeg.h
index 51932c5090..bf16a2ac73 100644
--- a/firmware/export/mpeg.h
+++ b/firmware/export/mpeg.h
@@ -92,6 +92,8 @@ void mpeg_get_debugdata(struct mpeg_debug *dbgdata);
92void mpeg_set_buffer_margin(int seconds); 92void mpeg_set_buffer_margin(int seconds);
93unsigned int mpeg_error(void); 93unsigned int mpeg_error(void);
94void mpeg_error_clear(void); 94void mpeg_error_clear(void);
95int mpeg_get_file_pos(void);
96unsigned long mpeg_get_last_header(void);
95 97
96/* in order to keep the recording here, I have to expose this */ 98/* in order to keep the recording here, I have to expose this */
97void rec_tick(void); 99void rec_tick(void);
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index a54866e0c2..377427260a 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -257,6 +257,84 @@ static void set_elapsed(struct mp3entry* id3)
257 id3->elapsed = id3->offset / id3->bpf * id3->tpf; 257 id3->elapsed = id3->offset / id3->bpf * id3->tpf;
258} 258}
259 259
260int mpeg_get_file_pos(void)
261{
262 int pos = -1;
263 struct mp3entry *id3 = mpeg_current_track();
264
265 if (id3->vbr)
266 {
267 if (id3->has_toc)
268 {
269 /* Use the TOC to find the new position */
270 unsigned int percent, remainder;
271 int curtoc, nexttoc, plen;
272
273 percent = (id3->elapsed*100)/id3->length;
274 if (percent > 99)
275 percent = 99;
276
277 curtoc = id3->toc[percent];
278
279 if (percent < 99)
280 nexttoc = id3->toc[percent+1];
281 else
282 nexttoc = 256;
283
284 pos = (id3->filesize/256)*curtoc;
285
286 /* Use the remainder to get a more accurate position */
287 remainder = (id3->elapsed*100)%id3->length;
288 remainder = (remainder*100)/id3->length;
289 plen = (nexttoc - curtoc)*(id3->filesize/256);
290 pos += (plen/100)*remainder;
291 }
292 else
293 {
294 /* No TOC exists, estimate the new position */
295 pos = (id3->filesize / (id3->length / 1000)) *
296 (id3->elapsed / 1000);
297 }
298 }
299 else if (id3->bpf && id3->tpf)
300 pos = (id3->elapsed/id3->tpf)*id3->bpf;
301 else
302 {
303 return -1;
304 }
305
306 if (pos >= (int)(id3->filesize - id3->id3v1len))
307 {
308 /* Don't seek right to the end of the file so that we can
309 transition properly to the next song */
310 pos = id3->filesize - id3->id3v1len - 1;
311 }
312 else if (pos < (int)id3->first_frame_offset)
313 {
314 /* skip past id3v2 tag and other leading garbage */
315 pos = id3->first_frame_offset;
316 }
317 return pos;
318}
319
320unsigned long mpeg_get_last_header(void)
321{
322#ifdef SIMULATOR
323 return 0;
324#else
325 unsigned long tmp[2];
326
327 /* Read the frame data from the MAS and reconstruct it with the
328 frame sync and all */
329#ifdef HAVE_MAS3587F
330 mas_readmem(MAS_BANK_D0, 0xfd1, tmp, 2);
331#else
332 mas_readmem(MAS_BANK_D0, 0x301, tmp, 2);
333#endif
334 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
335#endif
336}
337
260static bool paused; /* playback is paused */ 338static bool paused; /* playback is paused */
261 339
262static unsigned int mpeg_errno; 340static unsigned int mpeg_errno;
@@ -960,18 +1038,6 @@ static const unsigned char empty_id3_header[] =
960 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */ 1038 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
961}; 1039};
962 1040
963#ifdef HAVE_MAS3587F
964static unsigned long get_last_recorded_header(void)
965{
966 unsigned long tmp[2];
967
968 /* Read the frame data from the MAS and reconstruct it with the
969 frame sync and all */
970 mas_readmem(MAS_BANK_D0, 0xfd1, tmp, 2);
971 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
972}
973#endif /* #ifdef HAVE_MAS3587F */
974
975static void mpeg_thread(void) 1041static void mpeg_thread(void)
976{ 1042{
977 static int pause_tick = 0; 1043 static int pause_tick = 0;
@@ -1230,61 +1296,13 @@ static void mpeg_thread(void)
1230 1296
1231 id3->elapsed = newtime; 1297 id3->elapsed = newtime;
1232 1298
1233 if (id3->vbr) 1299 newpos = mpeg_get_file_pos();
1234 { 1300 if(newpos < 0)
1235 if (id3->has_toc)
1236 {
1237 /* Use the TOC to find the new position */
1238 unsigned int percent, remainder;
1239 int curtoc, nexttoc, plen;
1240
1241 percent = (newtime*100)/id3->length;
1242 if (percent > 99)
1243 percent = 99;
1244
1245 curtoc = id3->toc[percent];
1246
1247 if (percent < 99)
1248 nexttoc = id3->toc[percent+1];
1249 else
1250 nexttoc = 256;
1251
1252 newpos = (id3->filesize/256)*curtoc;
1253
1254 /* Use the remainder to get a more accurate position */
1255 remainder = (newtime*100)%id3->length;
1256 remainder = (remainder*100)/id3->length;
1257 plen = (nexttoc - curtoc)*(id3->filesize/256);
1258 newpos += (plen/100)*remainder;
1259 }
1260 else
1261 {
1262 /* No TOC exists, estimate the new position */
1263 newpos = (id3->filesize / (id3->length / 1000)) *
1264 (newtime / 1000);
1265 }
1266 }
1267 else if (id3->bpf && id3->tpf)
1268 newpos = (newtime/id3->tpf)*id3->bpf;
1269 else
1270 { 1301 {
1271 /* Not enough information to FF/Rewind */
1272 id3->elapsed = oldtime; 1302 id3->elapsed = oldtime;
1273 break; 1303 break;
1274 } 1304 }
1275 1305
1276 if (newpos >= (int)(id3->filesize - id3->id3v1len))
1277 {
1278 /* Don't seek right to the end of the file so that we can
1279 transition properly to the next song */
1280 newpos = id3->filesize - id3->id3v1len - 1;
1281 }
1282 else if (newpos < (int)id3->first_frame_offset)
1283 {
1284 /* skip past id3v2 tag and other leading garbage */
1285 newpos = id3->first_frame_offset;
1286 }
1287
1288 if (mpeg_file >= 0) 1306 if (mpeg_file >= 0)
1289 curpos = lseek(mpeg_file, 0, SEEK_CUR); 1307 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1290 else 1308 else
@@ -1601,7 +1619,7 @@ static void mpeg_thread(void)
1601 DEBUGF("Start looking at address %x (%x)\n", 1619 DEBUGF("Start looking at address %x (%x)\n",
1602 mp3buf+startpos, startpos); 1620 mp3buf+startpos, startpos);
1603 1621
1604 saved_header = get_last_recorded_header(); 1622 saved_header = mpeg_get_last_header();
1605 1623
1606 mem_find_next_frame(startpos, &offset, 5000, 1624 mem_find_next_frame(startpos, &offset, 5000,
1607 saved_header); 1625 saved_header);
@@ -1668,7 +1686,7 @@ static void mpeg_thread(void)
1668 frame header, for later use by the Xing header 1686 frame header, for later use by the Xing header
1669 generation */ 1687 generation */
1670 sleep(HZ/10); 1688 sleep(HZ/10);
1671 saved_header = get_last_recorded_header(); 1689 saved_header = mpeg_get_last_header();
1672 1690
1673 /* delayed until buffer is saved, don't open yet */ 1691 /* delayed until buffer is saved, don't open yet */
1674 strcpy(delayed_filename, recording_filename); 1692 strcpy(delayed_filename, recording_filename);