diff options
Diffstat (limited to 'firmware/mp3data.c')
-rw-r--r-- | firmware/mp3data.c | 187 |
1 files changed, 84 insertions, 103 deletions
diff --git a/firmware/mp3data.c b/firmware/mp3data.c index 6f4c560578..c2d4cd2c37 100644 --- a/firmware/mp3data.c +++ b/firmware/mp3data.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <stdlib.h> | 31 | #include <stdlib.h> |
32 | #include <string.h> | 32 | #include <string.h> |
33 | #include <stdbool.h> | 33 | #include <stdbool.h> |
34 | #include <limits.h> | ||
34 | #include "debug.h" | 35 | #include "debug.h" |
35 | #include "logf.h" | 36 | #include "logf.h" |
36 | #include "mp3data.h" | 37 | #include "mp3data.h" |
@@ -39,7 +40,7 @@ | |||
39 | 40 | ||
40 | #define DEBUG_VERBOSE | 41 | #define DEBUG_VERBOSE |
41 | 42 | ||
42 | #define BYTES2INT(b1,b2,b3,b4) (((long)(b1 & 0xFF) << (3*8)) | \ | 43 | #define BYTES2INT(b1,b2,b3,b4) (((long)(b1 & 0xFF) << (3*8)) | \ |
43 | ((long)(b2 & 0xFF) << (2*8)) | \ | 44 | ((long)(b2 & 0xFF) << (2*8)) | \ |
44 | ((long)(b3 & 0xFF) << (1*8)) | \ | 45 | ((long)(b3 & 0xFF) << (1*8)) | \ |
45 | ((long)(b4 & 0xFF) << (0*8))) | 46 | ((long)(b4 & 0xFF) << (0*8))) |
@@ -58,37 +59,34 @@ | |||
58 | #define ORIGINAL_MASK (1L << 2) | 59 | #define ORIGINAL_MASK (1L << 2) |
59 | #define EMPHASIS_MASK 3L | 60 | #define EMPHASIS_MASK 3L |
60 | 61 | ||
61 | /* Table of bitrates for MP3 files, all values in kilo. | 62 | /* MPEG Version table, sorted by version index */ |
62 | * Indexed by version, layer and value of bit 15-12 in header. | 63 | static const signed char version_table[4] = { |
63 | */ | 64 | MPEG_VERSION2_5, -1, MPEG_VERSION2, MPEG_VERSION1 |
64 | const int bitrate_table[2][3][16] = | ||
65 | { | ||
66 | { | ||
67 | {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, | ||
68 | {0,32,48,56, 64,80, 96, 112,128,160,192,224,256,320,384,0}, | ||
69 | {0,32,40,48, 56,64, 80, 96, 112,128,160,192,224,256,320,0} | ||
70 | }, | ||
71 | { | ||
72 | {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,0}, | ||
73 | {0, 8,16,24,32,40,48, 56, 64, 80, 96,112,128,144,160,0}, | ||
74 | {0, 8,16,24,32,40,48, 56, 64, 80, 96,112,128,144,160,0} | ||
75 | } | ||
76 | }; | 65 | }; |
77 | 66 | ||
78 | /* Table of samples per frame for MP3 files. | 67 | /* Bitrate table for mpeg audio, indexed by row index and birate index */ |
79 | * Indexed by layer. Multiplied with 1000. | 68 | static const short bitrates[5][16] = { |
80 | */ | 69 | {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, /* V1 L1 */ |
81 | const long bs[3] = {384000, 1152000, 1152000}; | 70 | {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,0}, /* V1 L2 */ |
71 | {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,0}, /* V1 L3 */ | ||
72 | {0,32,48,56, 64, 80, 96,112,128,144,160,176,192,224,256,0}, /* V2 L1 */ | ||
73 | {0, 8,16,24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,0} /* V2 L2+L3 */ | ||
74 | }; | ||
82 | 75 | ||
83 | /* Table of sample frequency for MP3 files. | 76 | /* Bitrate pointer table, indexed by version and layer */ |
84 | * Indexed by version and layer. | 77 | static const short *bitrate_table[3][3] = |
85 | */ | 78 | { |
79 | {bitrates[0], bitrates[1], bitrates[2]}, | ||
80 | {bitrates[3], bitrates[4], bitrates[4]}, | ||
81 | {bitrates[3], bitrates[4], bitrates[4]} | ||
82 | }; | ||
86 | 83 | ||
87 | const int freqtab[][4] = | 84 | /* Sampling frequency table, indexed by version and frequency index */ |
85 | static const long freq_table[3][3] = | ||
88 | { | 86 | { |
89 | {11025, 12000, 8000, 0}, /* MPEG version 2.5 */ | 87 | {44100, 48000, 32000}, /* MPEG Version 1 */ |
90 | {44100, 48000, 32000, 0}, /* MPEG Version 1 */ | 88 | {22050, 24000, 16000}, /* MPEG version 2 */ |
91 | {22050, 24000, 16000, 0}, /* MPEG version 2 */ | 89 | {11025, 12000, 8000}, /* MPEG version 2.5 */ |
92 | }; | 90 | }; |
93 | 91 | ||
94 | /* check if 'head' is a valid mp3 frame header */ | 92 | /* check if 'head' is a valid mp3 frame header */ |
@@ -117,97 +115,77 @@ static bool is_mp3frameheader(unsigned long head) | |||
117 | 115 | ||
118 | static bool mp3headerinfo(struct mp3info *info, unsigned long header) | 116 | static bool mp3headerinfo(struct mp3info *info, unsigned long header) |
119 | { | 117 | { |
120 | int bittable = 0; | 118 | int bitindex, freqindex; |
121 | int bitindex; | 119 | |
122 | int freqindex; | ||
123 | |||
124 | /* MPEG Audio Version */ | 120 | /* MPEG Audio Version */ |
125 | switch((header & VERSION_MASK) >> 19) { | 121 | info->version = version_table[(header & VERSION_MASK) >> 19]; |
126 | case 0: | 122 | if (info->version < 0) |
127 | /* MPEG version 2.5 is not an official standard */ | ||
128 | info->version = MPEG_VERSION2_5; | ||
129 | bittable = MPEG_VERSION2 - 1; /* use the V2 bit rate table */ | ||
130 | break; | ||
131 | |||
132 | case 1: | ||
133 | return false; | 123 | return false; |
134 | 124 | ||
135 | case 2: | 125 | /* Layer */ |
136 | /* MPEG version 2 (ISO/IEC 13818-3) */ | 126 | info->layer = 3 - ((header & LAYER_MASK) >> 17); |
137 | info->version = MPEG_VERSION2; | 127 | if (info->layer == 3) |
138 | bittable = MPEG_VERSION2 - 1; | ||
139 | break; | ||
140 | |||
141 | case 3: | ||
142 | /* MPEG version 1 (ISO/IEC 11172-3) */ | ||
143 | info->version = MPEG_VERSION1; | ||
144 | bittable = MPEG_VERSION1 - 1; | ||
145 | break; | ||
146 | } | ||
147 | |||
148 | switch((header & LAYER_MASK) >> 17) { | ||
149 | case 0: | ||
150 | return false; | 128 | return false; |
151 | case 1: | ||
152 | info->layer = 2; | ||
153 | break; | ||
154 | case 2: | ||
155 | info->layer = 1; | ||
156 | break; | ||
157 | case 3: | ||
158 | info->layer = 0; | ||
159 | break; | ||
160 | } | ||
161 | 129 | ||
162 | info->protection = (header & PROTECTION_MASK)?true:false; | 130 | info->protection = (header & PROTECTION_MASK) ? true : false; |
163 | 131 | ||
164 | /* Bitrate */ | 132 | /* Bitrate */ |
165 | bitindex = (header & 0xf000) >> 12; | 133 | bitindex = (header & BITRATE_MASK) >> 12; |
166 | info->bitrate = bitrate_table[bittable][info->layer][bitindex]; | 134 | info->bitrate = bitrate_table[info->version][info->layer][bitindex]; |
167 | if(info->bitrate == 0) | 135 | if(info->bitrate == 0) |
168 | return false; | 136 | return false; |
169 | 137 | ||
170 | /* Sampling frequency */ | 138 | /* Sampling frequency */ |
171 | freqindex = (header & 0x0C00) >> 10; | 139 | freqindex = (header & SAMPLERATE_MASK) >> 10; |
172 | info->frequency = freqtab[info->version][freqindex]; | 140 | if (freqindex == 3) |
173 | if(info->frequency == 0) | ||
174 | return false; | 141 | return false; |
142 | info->frequency = freq_table[info->version][freqindex]; | ||
175 | 143 | ||
176 | info->padding = (header & 0x0200)?1:0; | 144 | info->padding = (header & PADDING_MASK) ? 1 : 0; |
177 | 145 | ||
178 | /* Calculate number of bytes, calculation depends on layer */ | 146 | /* Calculate number of bytes, calculation depends on layer */ |
179 | switch(info->layer) { | 147 | if (info->layer == 0) { |
180 | case 0: | 148 | info->frame_samples = 384; |
181 | info->frame_size = info->bitrate * 48000; | 149 | info->frame_size = (12000 * info->bitrate / info->frequency |
182 | info->frame_size /= | 150 | + info->padding) * 4; |
183 | freqtab[info->version][freqindex] << bittable; | 151 | } |
184 | break; | 152 | else { |
185 | case 1: | 153 | if ((info->version > MPEG_VERSION1) && (info->layer == 2)) |
186 | case 2: | 154 | info->frame_samples = 576; |
187 | info->frame_size = info->bitrate * 144000; | 155 | else |
188 | info->frame_size /= | 156 | info->frame_samples = 1152; |
189 | freqtab[info->version][freqindex] << bittable; | 157 | info->frame_size = (1000/8) * info->frame_samples * info->bitrate |
190 | break; | 158 | / info->frequency + info->padding; |
191 | default: | ||
192 | info->frame_size = 1; | ||
193 | } | 159 | } |
194 | 160 | ||
195 | info->frame_size += info->padding; | 161 | /* Frametime fraction calculation. |
196 | 162 | This fraction is reduced as far as possible. */ | |
197 | /* Calculate time per frame */ | 163 | if (freqindex != 0) { /* 48/32/24/16/12/8 kHz */ |
198 | info->frame_time = bs[info->layer] / | 164 | /* integer number of milliseconds, denominator == 1 */ |
199 | (freqtab[info->version][freqindex] << bittable); | 165 | info->ft_num = 1000 * info->frame_samples / info->frequency; |
166 | info->ft_den = 1; | ||
167 | } | ||
168 | else { /* 44.1/22.05/11.025 kHz */ | ||
169 | if (info->layer == 0) { | ||
170 | info->ft_num = 147000 * 384 / info->frequency; | ||
171 | info->ft_den = 147; | ||
172 | } | ||
173 | else { | ||
174 | info->ft_num = 49000 * info->frame_samples / info->frequency; | ||
175 | info->ft_den = 49; | ||
176 | } | ||
177 | } | ||
200 | 178 | ||
201 | info->channel_mode = (header & 0xc0) >> 6; | 179 | info->channel_mode = (header & CHANNELMODE_MASK) >> 6; |
202 | info->mode_extension = (header & 0x30) >> 4; | 180 | info->mode_extension = (header & MODE_EXT_MASK) >> 4; |
203 | info->emphasis = header & 3; | 181 | info->emphasis = header & EMPHASIS_MASK; |
204 | 182 | ||
205 | #ifdef DEBUG_VERBOSE | 183 | #ifdef DEBUG_VERBOSE |
206 | DEBUGF( "Header: %08x, Ver %d, lay %d, bitr %d, freq %d, " | 184 | DEBUGF( "Header: %08x, Ver %d, lay %d, bitr %d, freq %ld, " |
207 | "chmode %d, mode_ext %d, emph %d, bytes: %d time: %d\n", | 185 | "chmode %d, mode_ext %d, emph %d, bytes: %d time: %d/%d\n", |
208 | header, info->version, info->layer+1, info->bitrate, | 186 | header, info->version, info->layer+1, info->bitrate, |
209 | info->frequency, info->channel_mode, info->mode_extension, | 187 | info->frequency, info->channel_mode, info->mode_extension, |
210 | info->emphasis, info->frame_size, info->frame_time); | 188 | info->emphasis, info->frame_size, info->ft_num, info->ft_den); |
211 | #endif | 189 | #endif |
212 | return true; | 190 | return true; |
213 | } | 191 | } |
@@ -252,7 +230,7 @@ static unsigned long __find_next_frame(int fd, long *offset, long max_offset, | |||
252 | if(*offset) | 230 | if(*offset) |
253 | DEBUGF("Warning: skipping %d bytes of garbage\n", *offset); | 231 | DEBUGF("Warning: skipping %d bytes of garbage\n", *offset); |
254 | #endif | 232 | #endif |
255 | 233 | ||
256 | return header; | 234 | return header; |
257 | } | 235 | } |
258 | 236 | ||
@@ -380,9 +358,6 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
380 | 358 | ||
381 | memset(info, 0, sizeof(struct mp3info)); | 359 | memset(info, 0, sizeof(struct mp3info)); |
382 | /* These two are needed for proper LAME gapless MP3 playback */ | 360 | /* These two are needed for proper LAME gapless MP3 playback */ |
383 | /* TODO: These can be found in a LAME Info header as well, but currently | ||
384 | they are only looked for in a Xing header. Xing and Info headers have | ||
385 | the exact same format, but Info headers are used for CBR files. */ | ||
386 | info->enc_delay = -1; | 361 | info->enc_delay = -1; |
387 | info->enc_padding = -1; | 362 | info->enc_padding = -1; |
388 | if(!mp3headerinfo(info, header)) | 363 | if(!mp3headerinfo(info, header)) |
@@ -435,7 +410,10 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
435 | { | 410 | { |
436 | info->frame_count = BYTES2INT(vbrheader[i], vbrheader[i+1], | 411 | info->frame_count = BYTES2INT(vbrheader[i], vbrheader[i+1], |
437 | vbrheader[i+2], vbrheader[i+3]); | 412 | vbrheader[i+2], vbrheader[i+3]); |
438 | info->file_time = info->frame_count * info->frame_time; | 413 | if (info->frame_count <= ULONG_MAX / info->ft_num) |
414 | info->file_time = info->frame_count * info->ft_num / info->ft_den; | ||
415 | else | ||
416 | info->file_time = info->frame_count / info->ft_den * info->ft_num; | ||
439 | i += 4; | 417 | i += 4; |
440 | } | 418 | } |
441 | 419 | ||
@@ -510,7 +488,10 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
510 | vbrheader[12], vbrheader[13]); | 488 | vbrheader[12], vbrheader[13]); |
511 | info->frame_count = BYTES2INT(vbrheader[14], vbrheader[15], | 489 | info->frame_count = BYTES2INT(vbrheader[14], vbrheader[15], |
512 | vbrheader[16], vbrheader[17]); | 490 | vbrheader[16], vbrheader[17]); |
513 | info->file_time = info->frame_count * info->frame_time; | 491 | if (info->frame_count <= ULONG_MAX / info->ft_num) |
492 | info->file_time = info->frame_count * info->ft_num / info->ft_den; | ||
493 | else | ||
494 | info->file_time = info->frame_count / info->ft_den * info->ft_num; | ||
514 | info->bitrate = info->byte_count * 8 / info->file_time; | 495 | info->bitrate = info->byte_count * 8 / info->file_time; |
515 | 496 | ||
516 | /* We don't parse the TOC, since we don't yet know how to (FIXME) */ | 497 | /* We don't parse the TOC, since we don't yet know how to (FIXME) */ |