/*
- * Copyright (C) 2003-2014 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2003 Andre Noll <maan@tuebingen.mpg.de>
*
* Licensed under the GPL v2. For licencing details see COPYING.
*/
static const int frame_size_index[] = {24000, 72000, 72000};
static const char *mode_text[] = {"stereo", "joint stereo", "dual channel", "mono", "invalid"};
-#ifdef HAVE_LIBID3TAG
+#ifdef HAVE_ID3TAG
#include <id3tag.h>
return NULL;
}
-static void mp3_get_id3(__a_unused unsigned char *map,
- __a_unused size_t numbytes, int fd, struct taginfo *tags)
+/* this only sets values which are undefined so far */
+static void parse_frames(struct id3_tag *id3_t, struct taginfo *tags)
{
int i;
- struct id3_tag *id3_t;
- struct id3_file *id3_f = id3_file_fdopen(fd, ID3_FILE_MODE_READONLY);
-
- if (!id3_f)
- return;
- id3_t = id3_file_tag(id3_f);
- if (!id3_t) {
- id3_file_close(id3_f);
- return;
- }
+
for (i = 0; i < id3_t->nframes; i++) {
struct id3_frame *fr = id3_t->frames[i];
if (!strcmp(fr->id, ID3_FRAME_TITLE)) {
continue;
}
}
- id3_file_close(id3_f);
}
-#else /* HAVE_LIBID3TAG */
+static int mp3_get_id3(unsigned char *map, size_t numbytes, __a_unused int fd,
+ struct taginfo *tags)
+{
+ int ret = 0;
+ struct id3_tag *id3_t;
+
+ /* id3v2 tags are usually located at the beginning. */
+ id3_t = id3_tag_parse(map, numbytes);
+ if (id3_t) {
+ parse_frames(id3_t, tags);
+ ret |= 2;
+ id3_tag_delete(id3_t);
+ }
+ /* Also look for an id3v1 tag at the end of the file. */
+ if (numbytes >= 128) {
+ id3_t = id3_tag_parse(map + numbytes - 128, 128);
+ if (id3_t) {
+ parse_frames(id3_t, tags);
+ ret |= 1;
+ id3_tag_delete(id3_t);
+ }
+ }
+ return ret;
+}
+
+#else /* HAVE_ID3TAG */
/*
* Remove trailing whitespace from the end of a string
return string;
}
-static void mp3_get_id3(unsigned char *map, size_t numbytes, __a_unused int fd,
+static int mp3_get_id3(unsigned char *map, size_t numbytes, __a_unused int fd,
struct taginfo *tags)
{
char title[31], artist[31], album[31], year[5], comment[31];
if (numbytes < 128 || strncmp("TAG", (char *)map + numbytes - 128, 3)) {
PARA_DEBUG_LOG("no id3 v1 tag\n");
- return;
+ return 0;
}
fpos = numbytes - 125;
memcpy(title, map + fpos, 30);
tags->year = para_strdup(year);
tags->album = para_strdup(album);
tags->comment = para_strdup(comment);
+ return 1;
}
-#endif /* HAVE_LIBID3TAG */
+#endif /* HAVE_ID3TAG */
static int header_frequency(struct mp3header *h)
{
unsigned chunk_table_size = 1000; /* gets increased on demand */
off_t fpos = 0;
struct mp3header header;
+ const char *tag_versions[] = {"no", "id3v1", "id3v2", "id3v1+id3v2"};
afhi->chunks_total = 0;
afhi->chunk_table = para_malloc(chunk_table_size * sizeof(uint32_t));
tv_divide(afhi->chunks_total, &total_time, &afhi->chunk_tv);
PARA_DEBUG_LOG("%lu chunks, each %lums\n", afhi->chunks_total,
tv2ms(&afhi->chunk_tv));
- afhi->techinfo = make_message("%cbr, %s", vbr? 'v' : 'c',
- header_mode(&header));
- mp3_get_id3(map, numbytes, fd, &afhi->tags);
+ ret = mp3_get_id3(map, numbytes, fd, &afhi->tags);
+ afhi->techinfo = make_message("%cbr, %s, %s tags", vbr? 'v' : 'c',
+ header_mode(&header), tag_versions[ret]);
return 1;
err_out:
PARA_ERROR_LOG("%s\n", para_strerror(-ret));