diff options
-rw-r--r-- | firmware/export/mp3data.h | 10 | ||||
-rw-r--r-- | firmware/mp3data.c | 24 |
2 files changed, 29 insertions, 5 deletions
diff --git a/firmware/export/mp3data.h b/firmware/export/mp3data.h index c031cc20ce..a7f2e3d7f0 100644 --- a/firmware/export/mp3data.h +++ b/firmware/export/mp3data.h | |||
@@ -47,13 +47,15 @@ struct mp3info { | |||
47 | long byte_count; /* File size in bytes */ | 47 | long byte_count; /* File size in bytes */ |
48 | long file_time; /* Length of the whole file in milliseconds */ | 48 | long file_time; /* Length of the whole file in milliseconds */ |
49 | int vbr_header_pos; | 49 | int vbr_header_pos; |
50 | int enc_delay; /* Encoder delay, fetched from LAME header */ | ||
51 | int enc_padding; /* Padded samples added to last frame. LAME header */ | ||
50 | }; | 52 | }; |
51 | 53 | ||
52 | /* Xing header information */ | 54 | /* Xing header information */ |
53 | #define VBR_FRAMES_FLAG 0x01 | 55 | #define VBR_FRAMES_FLAG 0x01 |
54 | #define VBR_BYTES_FLAG 0x02 | 56 | #define VBR_BYTES_FLAG 0x02 |
55 | #define VBR_TOC_FLAG 0x04 | 57 | #define VBR_TOC_FLAG 0x04 |
56 | 58 | #define VBR_QUALITY_FLAG 0x08 | |
57 | 59 | ||
58 | unsigned long find_next_frame(int fd, long *offset, long max_offset, unsigned long last_header); | 60 | unsigned long find_next_frame(int fd, long *offset, long max_offset, unsigned long last_header); |
59 | unsigned long mem_find_next_frame(int startpos, long *offset, long max_offset, | 61 | unsigned long mem_find_next_frame(int startpos, long *offset, long max_offset, |
diff --git a/firmware/mp3data.c b/firmware/mp3data.c index 32b3be4ffc..2b58710715 100644 --- a/firmware/mp3data.c +++ b/firmware/mp3data.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <string.h> | 32 | #include <string.h> |
33 | #include <stdbool.h> | 33 | #include <stdbool.h> |
34 | #include "debug.h" | 34 | #include "debug.h" |
35 | #include "logf.h" | ||
35 | #include "mp3data.h" | 36 | #include "mp3data.h" |
36 | #include "file.h" | 37 | #include "file.h" |
37 | #include "buffer.h" | 38 | #include "buffer.h" |
@@ -379,6 +380,12 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
379 | return -1; | 380 | return -1; |
380 | 381 | ||
381 | memset(info, 0, sizeof(struct mp3info)); | 382 | memset(info, 0, sizeof(struct mp3info)); |
383 | /* These two are needed for proper LAME gapless MP3 playback */ | ||
384 | /* TODO: These can be found in a LAME Info header as well, but currently | ||
385 | they are only looked for in a Xing header. Xing and Info headers have | ||
386 | the exact same format, but Info headers are used for CBR files. */ | ||
387 | info->enc_delay = -1; | ||
388 | info->enc_padding = -1; | ||
382 | if(!mp3headerinfo(info, header)) | 389 | if(!mp3headerinfo(info, header)) |
383 | return -2; | 390 | return -2; |
384 | 391 | ||
@@ -448,6 +455,22 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
448 | if(vbrheader[7] & VBR_TOC_FLAG) /* Is table-of-contents there? */ | 455 | if(vbrheader[7] & VBR_TOC_FLAG) /* Is table-of-contents there? */ |
449 | { | 456 | { |
450 | memcpy( info->toc, vbrheader+i, 100 ); | 457 | memcpy( info->toc, vbrheader+i, 100 ); |
458 | i += 100; | ||
459 | } | ||
460 | if (vbrheader[7] & VBR_QUALITY_FLAG) | ||
461 | { | ||
462 | /* We don't care about this, but need to skip it */ | ||
463 | i += 4; | ||
464 | } | ||
465 | i += 21; | ||
466 | info->enc_delay = (vbrheader[i] << 4) | (vbrheader[i + 1] >> 4); | ||
467 | info->enc_padding = ((vbrheader[i + 1] & 0x0f) << 8) | vbrheader[i + 2]; | ||
468 | if (!(info->enc_delay >= 0 && info->enc_delay <= 1152 && | ||
469 | info->enc_padding >= 0 && info->enc_padding <= 2*1152)) | ||
470 | { | ||
471 | /* Invalid data */ | ||
472 | info->enc_delay = -1; | ||
473 | info->enc_padding = -1; | ||
451 | } | 474 | } |
452 | } | 475 | } |
453 | 476 | ||
@@ -488,7 +511,6 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
488 | vbrheader[12], vbrheader[13]); | 511 | vbrheader[12], vbrheader[13]); |
489 | info->frame_count = BYTES2INT(vbrheader[14], vbrheader[15], | 512 | info->frame_count = BYTES2INT(vbrheader[14], vbrheader[15], |
490 | vbrheader[16], vbrheader[17]); | 513 | vbrheader[16], vbrheader[17]); |
491 | |||
492 | info->file_time = info->frame_count * info->frame_time; | 514 | info->file_time = info->frame_count * info->frame_time; |
493 | info->bitrate = info->byte_count * 8 / info->file_time; | 515 | info->bitrate = info->byte_count * 8 / info->file_time; |
494 | 516 | ||