Updates to Tomato RAF including NGINX && PHP
[tomato.git] / release / src / router / minidlna / tagutils / tagutils-mp3.c
blob770f231b39976a92303fabcb0b4076cafcae71b0
1 //=========================================================================
2 // FILENAME : tagutils-mp3.c
3 // DESCRIPTION : MP3 metadata reader
4 //=========================================================================
5 // Copyright (c) 2008- NETGEAR, Inc. All Rights Reserved.
6 //=========================================================================
8 /*
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 * This file is derived from mt-daap project.
27 static int
28 _get_mp3tags(char *file, struct song_metadata *psong)
30 struct id3_file *pid3file;
31 struct id3_tag *pid3tag;
32 struct id3_frame *pid3frame;
33 int err;
34 int index;
35 int used;
36 unsigned char *utf8_text;
37 int genre = WINAMP_GENRE_UNKNOWN;
38 int have_utf8;
39 int have_text;
40 id3_ucs4_t const *native_text;
41 char *tmp;
42 int got_numeric_genre;
43 id3_byte_t const *image;
44 id3_length_t image_size = 0;
46 pid3file = id3_file_open(file, ID3_FILE_MODE_READONLY);
47 if(!pid3file)
49 DPRINTF(E_ERROR, L_SCANNER, "Cannot open %s\n", file);
50 return -1;
53 pid3tag = id3_file_tag(pid3file);
55 if(!pid3tag)
57 err = errno;
58 id3_file_close(pid3file);
59 errno = err;
60 DPRINTF(E_WARN, L_SCANNER, "Cannot get ID3 tag for %s\n", file);
61 return -1;
64 index = 0;
65 while((pid3frame = id3_tag_findframe(pid3tag, "", index)))
67 used = 0;
68 utf8_text = NULL;
69 native_text = NULL;
70 have_utf8 = 0;
71 have_text = 0;
73 if(!strcmp(pid3frame->id, "YTCP")) /* for id3v2.2 */
75 psong->compilation = 1;
76 DPRINTF(E_DEBUG, L_SCANNER, "Compilation: %d [%s]\n", psong->compilation, basename(file));
78 else if(!strcmp(pid3frame->id, "APIC") && !image_size)
80 if( (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "image/jpeg") == 0) ||
81 (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "image/jpg") == 0) ||
82 (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "jpeg") == 0) )
84 image = id3_field_getbinarydata(&pid3frame->fields[4], &image_size);
85 if( image_size )
87 psong->image = malloc(image_size);
88 memcpy(psong->image, image, image_size);
89 psong->image_size = image_size;
90 //DEBUG DPRINTF(E_DEBUG, L_SCANNER, "Found thumbnail: %d\n", psong->image_size);
95 if(((pid3frame->id[0] == 'T') || (strcmp(pid3frame->id, "COMM") == 0)) &&
96 (id3_field_getnstrings(&pid3frame->fields[1])))
97 have_text = 1;
99 if(have_text)
101 native_text = id3_field_getstrings(&pid3frame->fields[1], 0);
103 if(native_text)
105 have_utf8 = 1;
106 if(lang_index >= 0)
107 utf8_text = _get_utf8_text(native_text); // through iconv
108 else
109 utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);
111 if(!strcmp(pid3frame->id, "TIT2"))
113 used = 1;
114 psong->title = (char*)utf8_text;
116 else if(!strcmp(pid3frame->id, "TPE1"))
118 used = 1;
119 psong->contributor[ROLE_ARTIST] = (char*)utf8_text;
121 else if(!strcmp(pid3frame->id, "TALB"))
123 used = 1;
124 psong->album = (char*)utf8_text;
126 else if(!strcmp(pid3frame->id, "TCOM"))
128 used = 1;
129 psong->contributor[ROLE_COMPOSER] = (char*)utf8_text;
131 else if(!strcmp(pid3frame->id, "TIT1"))
133 used = 1;
134 psong->grouping = (char*)utf8_text;
136 else if(!strcmp(pid3frame->id, "TPE2"))
138 used = 1;
139 psong->contributor[ROLE_BAND] = (char*)utf8_text;
141 else if(!strcmp(pid3frame->id, "TPE3"))
143 used = 1;
144 psong->contributor[ROLE_CONDUCTOR] = (char*)utf8_text;
146 else if(!strcmp(pid3frame->id, "TCON"))
148 used = 1;
149 psong->genre = (char*)utf8_text;
150 got_numeric_genre = 0;
151 if(psong->genre)
153 if(!strlen(psong->genre))
155 genre = WINAMP_GENRE_UNKNOWN;
156 got_numeric_genre = 1;
158 else if(isdigit(psong->genre[0]))
160 genre = atoi(psong->genre);
161 got_numeric_genre = 1;
163 else if((psong->genre[0] == '(') && (isdigit(psong->genre[1])))
165 genre = atoi((char*)&psong->genre[1]);
166 got_numeric_genre = 1;
169 if(got_numeric_genre)
171 if((genre < 0) || (genre > WINAMP_GENRE_UNKNOWN))
172 genre = WINAMP_GENRE_UNKNOWN;
173 free(psong->genre);
174 psong->genre = strdup(winamp_genre[genre]);
178 else if(!strcmp(pid3frame->id, "COMM"))
180 used = 1;
181 psong->comment = (char*)utf8_text;
183 else if(!strcmp(pid3frame->id, "TPOS"))
185 tmp = (char*)utf8_text;
186 strsep(&tmp, "/");
187 if(tmp)
189 psong->total_discs = atoi(tmp);
191 psong->disc = atoi((char*)utf8_text);
193 else if(!strcmp(pid3frame->id, "TRCK"))
195 tmp = (char*)utf8_text;
196 strsep(&tmp, "/");
197 if(tmp)
199 psong->total_tracks = atoi(tmp);
201 psong->track = atoi((char*)utf8_text);
203 else if(!strcmp(pid3frame->id, "TDRC"))
205 psong->year = atoi((char*)utf8_text);
207 else if(!strcmp(pid3frame->id, "TLEN"))
209 psong->song_length = atoi((char*)utf8_text);
211 else if(!strcmp(pid3frame->id, "TBPM"))
213 psong->bpm = atoi((char*)utf8_text);
215 else if(!strcmp(pid3frame->id, "TCMP"))
217 psong->compilation = (char)atoi((char*)utf8_text);
222 // check if text tag
223 if((!used) && (have_utf8) && (utf8_text))
224 free(utf8_text);
226 // v2 COMM
227 if((!strcmp(pid3frame->id, "COMM")) && (pid3frame->nfields == 4))
229 native_text = id3_field_getstring(&pid3frame->fields[2]);
230 if(native_text)
232 utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);
233 if((utf8_text) && (strncasecmp((char*)utf8_text, "iTun", 4) != 0))
235 // read comment
236 if(utf8_text)
237 free(utf8_text);
239 native_text = id3_field_getfullstring(&pid3frame->fields[3]);
240 if(native_text)
242 utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);
243 if(utf8_text)
245 if (psong->comment)
246 free(psong->comment);
247 psong->comment = (char*)utf8_text;
251 else
253 if(utf8_text)
254 free(utf8_text);
259 index++;
262 id3_file_close(pid3file);
263 //DEBUG DPRINTF(E_INFO, L_SCANNER, "Got id3 tag successfully for file=%s\n", file);
264 return 0;
267 // _decode_mp3_frame
268 static int
269 _decode_mp3_frame(unsigned char *frame, struct mp3_frameinfo *pfi)
271 int ver;
272 int layer_index;
273 int sample_index;
274 int bitrate_index;
275 int samplerate_index;
277 if((frame[0] != 0xFF) || (frame[1] < 224))
279 pfi->is_valid = 0;
280 return -1;
283 ver = (frame[1] & 0x18) >> 3;
284 pfi->layer = 4 - ((frame[1] & 0x6) >> 1);
286 layer_index = sample_index = -1;
288 switch(ver)
290 case 0:
291 pfi->mpeg_version = 0x25; // 2.5
292 sample_index = 2;
293 if(pfi->layer == 1)
294 layer_index = 3;
295 if((pfi->layer == 2) || (pfi->layer == 3))
296 layer_index = 4;
297 break;
298 case 2:
299 pfi->mpeg_version = 0x20; // 2.0
300 sample_index = 1;
301 if(pfi->layer == 1)
302 layer_index = 3;
303 if((pfi->layer == 2) || (pfi->layer == 3))
304 layer_index = 4;
305 break;
306 case 3:
307 pfi->mpeg_version = 0x10; // 1.0
308 sample_index = 0;
309 if(pfi->layer == 1)
310 layer_index = 0;
311 if(pfi->layer == 2)
312 layer_index = 1;
313 if(pfi->layer == 3)
314 layer_index = 2;
315 break;
318 if((layer_index < 0) || (layer_index > 4))
320 pfi->is_valid = 0;
321 return -1;
324 if((sample_index < 0) || (sample_index >= 2))
326 pfi->is_valid = 0;
327 return -1;
330 if(pfi->layer == 1) pfi->samples_per_frame = 384;
331 if(pfi->layer == 2) pfi->samples_per_frame = 1152;
332 if(pfi->layer == 3)
334 if(pfi->mpeg_version == 0x10)
335 pfi->samples_per_frame = 1152;
336 else
337 pfi->samples_per_frame = 576;
340 bitrate_index = (frame[2] & 0xF0) >> 4;
341 samplerate_index = (frame[2] & 0x0C) >> 2;
343 if((bitrate_index == 0xF) || (bitrate_index == 0x0))
345 pfi->is_valid = 0;
346 return -1;
349 if(samplerate_index == 3)
351 pfi->is_valid = 0;
352 return -1;
356 pfi->bitrate = bitrate_tbl[layer_index][bitrate_index];
357 pfi->samplerate = sample_rate_tbl[sample_index][samplerate_index];
359 if((frame[3] & 0xC0 >> 6) == 3)
360 pfi->stereo = 0;
361 else
362 pfi->stereo = 1;
364 if(frame[2] & 0x02)
365 pfi->padding = 1;
366 else
367 pfi->padding = 0;
369 if(pfi->mpeg_version == 0x10)
371 if(pfi->stereo)
372 pfi->xing_offset = 32;
373 else
374 pfi->xing_offset = 17;
376 else
378 if(pfi->stereo)
379 pfi->xing_offset = 17;
380 else
381 pfi->xing_offset = 9;
384 pfi->crc_protected = frame[1] & 0xFE;
386 if(pfi->layer == 1)
387 pfi->frame_length = (12 * pfi->bitrate * 1000 / pfi->samplerate + pfi->padding) * 4;
388 else
389 pfi->frame_length = 144 * pfi->bitrate * 1000 / pfi->samplerate + pfi->padding;
391 if((pfi->frame_length > 2880) || (pfi->frame_length <= 0))
393 pfi->is_valid = 0;
394 return -1;
397 pfi->is_valid = 1;
398 return 0;
401 // _mp3_get_average_bitrate
402 // read from midle of file, and estimate
403 static void _mp3_get_average_bitrate(FILE *infile, struct mp3_frameinfo *pfi, const char *fname)
405 off_t file_size;
406 unsigned char frame_buffer[2900];
407 unsigned char header[4];
408 int index = 0;
409 int found = 0;
410 off_t pos;
411 struct mp3_frameinfo fi;
412 int frame_count = 0;
413 int bitrate_total = 0;
415 fseek(infile, 0, SEEK_END);
416 file_size = ftell(infile);
418 pos = file_size >> 1;
420 /* now, find the first frame */
421 fseek(infile, pos, SEEK_SET);
422 if(fread(frame_buffer, 1, sizeof(frame_buffer), infile) != sizeof(frame_buffer))
423 return;
425 while(!found)
427 while((frame_buffer[index] != 0xFF) && (index < (sizeof(frame_buffer) - 4)))
428 index++;
430 if(index >= (sizeof(frame_buffer) - 4)) // max mp3 framesize = 2880
432 DPRINTF(E_DEBUG, L_SCANNER, "Could not find frame for %s\n", basename((char *)fname));
433 return;
436 if(!_decode_mp3_frame(&frame_buffer[index], &fi))
438 /* see if next frame is valid */
439 fseek(infile, pos + index + fi.frame_length, SEEK_SET);
440 if(fread(header, 1, sizeof(header), infile) != sizeof(header))
442 DPRINTF(E_DEBUG, L_SCANNER, "Could not read frame header for %s\n", basename((char *)fname));
443 return;
446 if(!_decode_mp3_frame(header, &fi))
447 found = 1;
450 if(!found)
451 index++;
454 pos += index;
456 // got first frame
457 while(frame_count < 10)
459 fseek(infile, pos, SEEK_SET);
460 if(fread(header, 1, sizeof(header), infile) != sizeof(header))
462 DPRINTF(E_DEBUG, L_SCANNER, "Could not read frame header for %s\n", basename((char *)fname));
463 return;
465 if(_decode_mp3_frame(header, &fi))
467 DPRINTF(E_DEBUG, L_SCANNER, "Invalid frame header while averaging %s\n", basename((char *)fname));
468 return;
471 bitrate_total += fi.bitrate;
472 frame_count++;
473 pos += fi.frame_length;
476 pfi->bitrate = bitrate_total / frame_count;
478 return;
481 // _mp3_get_frame_count
482 // do brute scan
483 static void __attribute__((unused))
484 _mp3_get_frame_count(FILE *infile, struct mp3_frameinfo *pfi)
486 int pos;
487 int frames = 0;
488 unsigned char frame_buffer[4];
489 struct mp3_frameinfo fi;
490 off_t file_size;
491 int err = 0;
492 int cbr = 1;
493 int last_bitrate = 0;
495 fseek(infile, 0, SEEK_END);
496 file_size = ftell(infile);
498 pos = pfi->frame_offset;
500 while(1)
502 err = 1;
504 fseek(infile, pos, SEEK_SET);
505 if(fread(frame_buffer, 1, sizeof(frame_buffer), infile) == sizeof(frame_buffer))
507 // valid frame?
508 if(!_decode_mp3_frame(frame_buffer, &fi))
510 frames++;
511 pos += fi.frame_length;
512 err = 0;
514 if((last_bitrate) && (fi.bitrate != last_bitrate))
515 cbr = 0;
516 last_bitrate = fi.bitrate;
518 // no sense to scan cbr
519 if(cbr && (frames > 100))
521 DPRINTF(E_DEBUG, L_SCANNER, "File appears to be CBR... quitting frame _mp3_get_frame_count()\n");
522 return;
527 if(err)
529 if(pos > (file_size - 4096))
531 pfi->number_of_frames = frames;
532 return;
534 else
536 DPRINTF(E_ERROR, L_SCANNER, "Frame count aborted on error. Pos=%d, Count=%d\n",
537 pos, frames);
538 return;
544 // _get_mp3fileinfo
545 static int
546 _get_mp3fileinfo(char *file, struct song_metadata *psong)
548 FILE *infile;
549 struct id3header *pid3;
550 struct mp3_frameinfo fi;
551 unsigned int size = 0;
552 unsigned int n_read;
553 off_t fp_size = 0;
554 off_t file_size;
555 unsigned char buffer[1024];
556 int index;
558 int xing_flags;
559 int found;
561 int first_check = 0;
562 char frame_buffer[4];
564 char id3v1taghdr[4];
566 if(!(infile = fopen(file, "rb")))
568 DPRINTF(E_ERROR, L_SCANNER, "Could not open %s for reading\n", file);
569 return -1;
572 memset((void*)&fi, 0, sizeof(fi));
574 fseek(infile, 0, SEEK_END);
575 file_size = ftell(infile);
576 fseek(infile, 0, SEEK_SET);
578 if(fread(buffer, 1, sizeof(buffer), infile) != sizeof(buffer))
580 if(ferror(infile))
582 DPRINTF(E_ERROR, L_SCANNER, "Error reading: %s [%s]\n", strerror(errno), file);
584 else
586 DPRINTF(E_WARN, L_SCANNER, "File too small. Probably corrupted. [%s]\n", file);
588 fclose(infile);
589 return -1;
592 pid3 = (struct id3header*)buffer;
594 found = 0;
595 fp_size = 0;
597 if(strncmp((char*)pid3->id, "ID3", 3) == 0)
599 char tagversion[16];
601 /* found an ID3 header... */
602 size = (pid3->size[0] << 21 | pid3->size[1] << 14 |
603 pid3->size[2] << 7 | pid3->size[3]);
604 fp_size = size + sizeof(struct id3header);
605 first_check = 1;
607 snprintf(tagversion, sizeof(tagversion), "ID3v2.%d.%d",
608 pid3->version[0], pid3->version[1]);
609 psong->tagversion = strdup(tagversion);
612 index = 0;
614 /* Here we start the brute-force header seeking. Sure wish there
615 * weren't so many crappy mp3 files out there
618 while(!found)
620 fseek(infile, fp_size, SEEK_SET);
621 if((n_read = fread(buffer, 1, sizeof(buffer), infile)) < 4) // at least mp3 frame header size (i.e. 4 bytes)
623 fclose(infile);
624 return 0;
627 index = 0;
628 while(!found)
630 while((buffer[index] != 0xFF) && (index < (n_read - 50)))
631 index++;
633 if((first_check) && (index))
635 fp_size = 0;
636 first_check = 0;
637 if(n_read < sizeof(buffer))
639 fclose(infile);
640 return 0;
642 break;
645 if(index > (n_read - 50))
647 fp_size += index;
648 if(n_read < sizeof(buffer))
650 fclose(infile);
651 return 0;
653 break;
656 if(!_decode_mp3_frame(&buffer[index], &fi))
658 if(!strncasecmp((char*)&buffer[index + fi.xing_offset + 4], "XING", 4))
660 /* no need to check further... if there is a xing header there,
661 * this is definately a valid frame */
662 found = 1;
663 fp_size += index;
665 else
667 /* No Xing... check for next frame to validate current fram is correct */
668 fseek(infile, fp_size + index + fi.frame_length, SEEK_SET);
669 if(fread(frame_buffer, 1, sizeof(frame_buffer), infile) == sizeof(frame_buffer))
671 if(!_decode_mp3_frame((unsigned char*)frame_buffer, &fi))
673 found = 1;
674 fp_size += index;
677 else
679 DPRINTF(E_ERROR, L_SCANNER, "Could not read frame header: %s\n", file);
680 fclose(infile);
681 return 0;
684 if(!found)
686 // cannot find second frame. Song may be too short. So assume first frame is valid.
687 found = 1;
688 fp_size += index;
693 if(!found)
695 index++;
696 if(first_check)
698 DPRINTF(E_INFO, L_SCANNER, "Bad header... dropping back for full frame search [%s]\n", psong->path);
699 first_check = 0;
700 fp_size = 0;
701 break;
707 fi.frame_offset = fp_size;
709 psong->audio_offset = fp_size;
710 psong->audio_size = file_size - fp_size;
711 // check if last 128 bytes is ID3v1.0 ID3v1.1 tag
712 fseek(infile, file_size - 128, SEEK_SET);
713 if(fread(id3v1taghdr, 1, 4, infile) == 4)
715 if(id3v1taghdr[0] == 'T' && id3v1taghdr[1] == 'A' && id3v1taghdr[2] == 'G')
717 psong->audio_size -= 128;
721 if(_decode_mp3_frame(&buffer[index], &fi))
723 fclose(infile);
724 DPRINTF(E_ERROR, L_SCANNER, "Could not find sync frame: %s\n", file);
725 return 0;
728 /* now check for an XING header */
729 psong->vbr_scale = -1;
730 if(!strncasecmp((char*)&buffer[index + fi.xing_offset + 4], "XING", 4))
732 xing_flags = buffer[index+fi.xing_offset+4+4] << 24 |
733 buffer[index+fi.xing_offset+4+5] << 16 |
734 buffer[index+fi.xing_offset+4+6] << 8 |
735 buffer[index+fi.xing_offset+4+7];
736 psong->vbr_scale = 78;
738 if(xing_flags & 0x1)
740 /* Frames field is valid... */
741 fi.number_of_frames = buffer[index+fi.xing_offset+4+8] << 24 |
742 buffer[index+fi.xing_offset+4+9] << 16 |
743 buffer[index+fi.xing_offset+4+10] << 8 |
744 buffer[index+fi.xing_offset+4+11];
748 if((fi.number_of_frames == 0) && (!psong->song_length))
750 _mp3_get_average_bitrate(infile, &fi, file);
753 psong->bitrate = fi.bitrate * 1000;
754 psong->samplerate = fi.samplerate;
756 if(!psong->song_length)
758 if(fi.number_of_frames)
760 psong->song_length = (int)((double)(fi.number_of_frames * fi.samples_per_frame * 1000.) /
761 (double)fi.samplerate);
762 psong->vbr_scale = 78;
764 else
766 psong->song_length = (int)((double)(file_size - fp_size) * 8. /
767 (double)fi.bitrate);
770 psong->channels = fi.stereo ? 2 : 1;
772 fclose(infile);
773 //DEBUG DPRINTF(E_INFO, L_SCANNER, "Got fileinfo successfully for file=%s song_length=%d\n", file, psong->song_length);
775 psong->blockalignment = 1;
776 asprintf(&(psong->dlna_pn), "MP3");
778 return 0;