Wrap up version 1.3.3.
[minidlna.git] / tagutils / tagutils-mp3.c
blobc87a0657c88b01c8845d046804f8658ce0299455
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 free(utf8_text);
238 native_text = id3_field_getfullstring(&pid3frame->fields[3]);
239 if(native_text)
241 utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);
242 if(utf8_text)
244 free(psong->comment);
245 psong->comment = (char*)utf8_text;
249 else
251 free(utf8_text);
256 index++;
259 id3_file_close(pid3file);
260 //DEBUG DPRINTF(E_INFO, L_SCANNER, "Got id3 tag successfully for file=%s\n", file);
261 return 0;
264 // _decode_mp3_frame
265 static int
266 _decode_mp3_frame(unsigned char *frame, struct mp3_frameinfo *pfi)
268 int ver;
269 int layer_index;
270 int sample_index;
271 int bitrate_index;
272 int samplerate_index;
274 if((frame[0] != 0xFF) || (frame[1] < 224))
276 pfi->is_valid = 0;
277 return -1;
280 ver = (frame[1] & 0x18) >> 3;
281 pfi->layer = 4 - ((frame[1] & 0x6) >> 1);
283 layer_index = sample_index = -1;
285 switch(ver)
287 case 0:
288 pfi->mpeg_version = 0x25; // 2.5
289 sample_index = 2;
290 if(pfi->layer == 1)
291 layer_index = 3;
292 if((pfi->layer == 2) || (pfi->layer == 3))
293 layer_index = 4;
294 break;
295 case 2:
296 pfi->mpeg_version = 0x20; // 2.0
297 sample_index = 1;
298 if(pfi->layer == 1)
299 layer_index = 3;
300 if((pfi->layer == 2) || (pfi->layer == 3))
301 layer_index = 4;
302 break;
303 case 3:
304 pfi->mpeg_version = 0x10; // 1.0
305 sample_index = 0;
306 if(pfi->layer == 1)
307 layer_index = 0;
308 if(pfi->layer == 2)
309 layer_index = 1;
310 if(pfi->layer == 3)
311 layer_index = 2;
312 break;
315 if((layer_index < 0) || (layer_index > 4))
317 pfi->is_valid = 0;
318 return -1;
321 if((sample_index < 0) || (sample_index >= 2))
323 pfi->is_valid = 0;
324 return -1;
327 if(pfi->layer == 1) pfi->samples_per_frame = 384;
328 if(pfi->layer == 2) pfi->samples_per_frame = 1152;
329 if(pfi->layer == 3)
331 if(pfi->mpeg_version == 0x10)
332 pfi->samples_per_frame = 1152;
333 else
334 pfi->samples_per_frame = 576;
337 bitrate_index = (frame[2] & 0xF0) >> 4;
338 samplerate_index = (frame[2] & 0x0C) >> 2;
340 if((bitrate_index == 0xF) || (bitrate_index == 0x0))
342 pfi->is_valid = 0;
343 return -1;
346 if(samplerate_index == 3)
348 pfi->is_valid = 0;
349 return -1;
353 pfi->bitrate = bitrate_tbl[layer_index][bitrate_index];
354 pfi->samplerate = sample_rate_tbl[sample_index][samplerate_index];
356 if((frame[3] & 0xC0 >> 6) == 3)
357 pfi->stereo = 0;
358 else
359 pfi->stereo = 1;
361 if(frame[2] & 0x02)
362 pfi->padding = 1;
363 else
364 pfi->padding = 0;
366 if(pfi->mpeg_version == 0x10)
368 if(pfi->stereo)
369 pfi->xing_offset = 32;
370 else
371 pfi->xing_offset = 17;
373 else
375 if(pfi->stereo)
376 pfi->xing_offset = 17;
377 else
378 pfi->xing_offset = 9;
381 pfi->crc_protected = frame[1] & 0xFE;
383 if(pfi->layer == 1)
384 pfi->frame_length = (12 * pfi->bitrate * 1000 / pfi->samplerate + pfi->padding) * 4;
385 else
386 pfi->frame_length = 144 * pfi->bitrate * 1000 / pfi->samplerate + pfi->padding;
388 if((pfi->frame_length > 2880) || (pfi->frame_length <= 0))
390 pfi->is_valid = 0;
391 return -1;
394 pfi->is_valid = 1;
395 return 0;
398 // _mp3_get_average_bitrate
399 // read from midle of file, and estimate
400 static void _mp3_get_average_bitrate(FILE *infile, struct mp3_frameinfo *pfi, const char *fname)
402 off_t file_size;
403 unsigned char frame_buffer[2900];
404 unsigned char header[4];
405 int index = 0;
406 int found = 0;
407 off_t pos;
408 struct mp3_frameinfo fi;
409 int frame_count = 0;
410 int bitrate_total = 0;
412 fseek(infile, 0, SEEK_END);
413 file_size = ftell(infile);
415 pos = file_size >> 1;
417 /* now, find the first frame */
418 fseek(infile, pos, SEEK_SET);
419 if(fread(frame_buffer, 1, sizeof(frame_buffer), infile) != sizeof(frame_buffer))
420 return;
422 while(!found)
424 while((frame_buffer[index] != 0xFF) && (index < (sizeof(frame_buffer) - 4)))
425 index++;
427 if(index >= (sizeof(frame_buffer) - 4)) // max mp3 framesize = 2880
429 DPRINTF(E_DEBUG, L_SCANNER, "Could not find frame for %s\n", basename((char *)fname));
430 return;
433 if(!_decode_mp3_frame(&frame_buffer[index], &fi))
435 /* see if next frame is valid */
436 fseek(infile, pos + index + fi.frame_length, SEEK_SET);
437 if(fread(header, 1, sizeof(header), infile) != sizeof(header))
439 DPRINTF(E_DEBUG, L_SCANNER, "Could not read frame header for %s\n", basename((char *)fname));
440 return;
443 if(!_decode_mp3_frame(header, &fi))
444 found = 1;
447 if(!found)
448 index++;
451 pos += index;
453 // got first frame
454 while(frame_count < 10)
456 fseek(infile, pos, SEEK_SET);
457 if(fread(header, 1, sizeof(header), infile) != sizeof(header))
459 DPRINTF(E_DEBUG, L_SCANNER, "Could not read frame header for %s\n", basename((char *)fname));
460 return;
462 if(_decode_mp3_frame(header, &fi))
464 DPRINTF(E_DEBUG, L_SCANNER, "Invalid frame header while averaging %s\n", basename((char *)fname));
465 return;
468 bitrate_total += fi.bitrate;
469 frame_count++;
470 pos += fi.frame_length;
473 pfi->bitrate = bitrate_total / frame_count;
475 return;
478 // _mp3_get_frame_count
479 // do brute scan
480 static void __attribute__((unused))
481 _mp3_get_frame_count(FILE *infile, struct mp3_frameinfo *pfi)
483 int pos;
484 int frames = 0;
485 unsigned char frame_buffer[4];
486 struct mp3_frameinfo fi;
487 off_t file_size;
488 int err = 0;
489 int cbr = 1;
490 int last_bitrate = 0;
492 fseek(infile, 0, SEEK_END);
493 file_size = ftell(infile);
495 pos = pfi->frame_offset;
497 while(1)
499 err = 1;
501 fseek(infile, pos, SEEK_SET);
502 if(fread(frame_buffer, 1, sizeof(frame_buffer), infile) == sizeof(frame_buffer))
504 // valid frame?
505 if(!_decode_mp3_frame(frame_buffer, &fi))
507 frames++;
508 pos += fi.frame_length;
509 err = 0;
511 if((last_bitrate) && (fi.bitrate != last_bitrate))
512 cbr = 0;
513 last_bitrate = fi.bitrate;
515 // no sense to scan cbr
516 if(cbr && (frames > 100))
518 DPRINTF(E_DEBUG, L_SCANNER, "File appears to be CBR... quitting frame _mp3_get_frame_count()\n");
519 return;
524 if(err)
526 if(pos > (file_size - 4096))
528 pfi->number_of_frames = frames;
529 return;
531 else
533 DPRINTF(E_ERROR, L_SCANNER, "Frame count aborted on error. Pos=%d, Count=%d\n",
534 pos, frames);
535 return;
541 // _get_mp3fileinfo
542 static int
543 _get_mp3fileinfo(char *file, struct song_metadata *psong)
545 FILE *infile;
546 struct id3header *pid3;
547 struct mp3_frameinfo fi;
548 unsigned int size = 0;
549 unsigned int n_read;
550 off_t fp_size = 0;
551 off_t file_size;
552 unsigned char buffer[1024];
553 int index;
555 int xing_flags;
556 int found;
558 int first_check = 0;
559 char frame_buffer[4];
561 char id3v1taghdr[4];
563 if(!(infile = fopen(file, "rb")))
565 DPRINTF(E_ERROR, L_SCANNER, "Could not open %s for reading\n", file);
566 return -1;
569 memset((void*)&fi, 0, sizeof(fi));
571 fseek(infile, 0, SEEK_END);
572 file_size = ftell(infile);
573 fseek(infile, 0, SEEK_SET);
575 if(fread(buffer, 1, sizeof(buffer), infile) != sizeof(buffer))
577 if(ferror(infile))
579 DPRINTF(E_ERROR, L_SCANNER, "Error reading: %s [%s]\n", strerror(errno), file);
581 else
583 DPRINTF(E_WARN, L_SCANNER, "File too small. Probably corrupted. [%s]\n", file);
585 fclose(infile);
586 return -1;
589 pid3 = (struct id3header*)buffer;
591 found = 0;
592 fp_size = 0;
594 if(strncmp((char*)pid3->id, "ID3", 3) == 0)
596 char tagversion[16];
598 /* found an ID3 header... */
599 size = (pid3->size[0] << 21 | pid3->size[1] << 14 |
600 pid3->size[2] << 7 | pid3->size[3]);
601 fp_size = size + sizeof(struct id3header);
602 first_check = 1;
604 snprintf(tagversion, sizeof(tagversion), "ID3v2.%d.%d",
605 pid3->version[0], pid3->version[1]);
606 psong->tagversion = strdup(tagversion);
609 index = 0;
611 /* Here we start the brute-force header seeking. Sure wish there
612 * weren't so many crappy mp3 files out there
615 while(!found)
617 fseek(infile, fp_size, SEEK_SET);
618 if((n_read = fread(buffer, 1, sizeof(buffer), infile)) < 4) // at least mp3 frame header size (i.e. 4 bytes)
620 fclose(infile);
621 return 0;
624 index = 0;
625 while(!found)
627 while((buffer[index] != 0xFF) && (index < (n_read - 50)))
628 index++;
630 if((first_check) && (index))
632 fp_size = 0;
633 first_check = 0;
634 if(n_read < sizeof(buffer))
636 fclose(infile);
637 return 0;
639 break;
642 if(index > (n_read - 50))
644 fp_size += index;
645 if(n_read < sizeof(buffer))
647 fclose(infile);
648 return 0;
650 break;
653 if(!_decode_mp3_frame(&buffer[index], &fi))
655 if(!strncasecmp((char*)&buffer[index + fi.xing_offset + 4], "XING", 4))
657 /* no need to check further... if there is a xing header there,
658 * this is definately a valid frame */
659 found = 1;
660 fp_size += index;
662 else
664 /* No Xing... check for next frame to validate current fram is correct */
665 fseek(infile, fp_size + index + fi.frame_length, SEEK_SET);
666 if(fread(frame_buffer, 1, sizeof(frame_buffer), infile) == sizeof(frame_buffer))
668 if(!_decode_mp3_frame((unsigned char*)frame_buffer, &fi))
670 found = 1;
671 fp_size += index;
674 else
676 DPRINTF(E_ERROR, L_SCANNER, "Could not read frame header: %s\n", file);
677 fclose(infile);
678 return 0;
681 if(!found)
683 // cannot find second frame. Song may be too short. So assume first frame is valid.
684 found = 1;
685 fp_size += index;
690 if(!found)
692 index++;
693 if(first_check)
695 DPRINTF(E_INFO, L_SCANNER, "Bad header... dropping back for full frame search [%s]\n", psong->path);
696 first_check = 0;
697 fp_size = 0;
698 break;
704 fi.frame_offset = fp_size;
706 psong->audio_offset = fp_size;
707 psong->audio_size = file_size - fp_size;
708 // check if last 128 bytes is ID3v1.0 ID3v1.1 tag
709 fseek(infile, file_size - 128, SEEK_SET);
710 if(fread(id3v1taghdr, 1, 4, infile) == 4)
712 if(id3v1taghdr[0] == 'T' && id3v1taghdr[1] == 'A' && id3v1taghdr[2] == 'G')
714 psong->audio_size -= 128;
718 if(_decode_mp3_frame(&buffer[index], &fi))
720 fclose(infile);
721 DPRINTF(E_ERROR, L_SCANNER, "Could not find sync frame: %s\n", file);
722 return 0;
725 /* now check for an XING header */
726 psong->vbr_scale = -1;
727 if(!strncasecmp((char*)&buffer[index + fi.xing_offset + 4], "XING", 4))
729 xing_flags = buffer[index+fi.xing_offset+4+4] << 24 |
730 buffer[index+fi.xing_offset+4+5] << 16 |
731 buffer[index+fi.xing_offset+4+6] << 8 |
732 buffer[index+fi.xing_offset+4+7];
733 psong->vbr_scale = 78;
735 if(xing_flags & 0x1)
737 /* Frames field is valid... */
738 fi.number_of_frames = buffer[index+fi.xing_offset+4+8] << 24 |
739 buffer[index+fi.xing_offset+4+9] << 16 |
740 buffer[index+fi.xing_offset+4+10] << 8 |
741 buffer[index+fi.xing_offset+4+11];
745 if((fi.number_of_frames == 0) && (!psong->song_length))
747 _mp3_get_average_bitrate(infile, &fi, file);
750 psong->bitrate = fi.bitrate * 1000;
751 psong->samplerate = fi.samplerate;
753 if(!psong->song_length)
755 if(fi.number_of_frames)
757 psong->song_length = (int)((double)(fi.number_of_frames * fi.samples_per_frame * 1000.) /
758 (double)fi.samplerate);
759 psong->vbr_scale = 78;
761 else
763 psong->song_length = (int)((double)(file_size - fp_size) * 8. /
764 (double)fi.bitrate);
767 psong->channels = fi.stereo ? 2 : 1;
769 fclose(infile);
770 //DEBUG DPRINTF(E_INFO, L_SCANNER, "Got fileinfo successfully for file=%s song_length=%d\n", file, psong->song_length);
772 psong->blockalignment = 1;
773 xasprintf(&(psong->dlna_pn), "MP3");
775 return 0;