changeset 994:3d2984564cb8 trunk

[svn] Taglib length determination veto by nenolod, reverting. Leaving fileinfo optimizations in place, though.
author chainsaw
date Sun, 30 Apr 2006 18:04:43 -0700
parents a9ac4beb4e15
children e4089d6b0fcf
files Plugins/Input/mpg123/mpg123.c
diffstat 1 files changed, 108 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/Plugins/Input/mpg123/mpg123.c	Sun Apr 30 17:59:55 2006 -0700
+++ b/Plugins/Input/mpg123/mpg123.c	Sun Apr 30 18:04:43 2006 -0700
@@ -263,6 +263,13 @@
     g_strfreev(mpg123_id3_encoding_list);
 }
 
+static guint32
+convert_to_header(guint8 * buf)
+{
+    return (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
+}
+
+
 #if 0
 #define DET_BUF_SIZE 1024
 
@@ -363,6 +370,15 @@
     }
 }
 
+static const char *
+get_id3_genre(unsigned char genre_code)
+{
+    if (genre_code < GENRE_MAX)
+        return gettext(mpg123_id3_genres[genre_code]);
+
+    return "";
+}
+
 guint
 mpg123_strip_spaces(char *src, size_t n)
 {
@@ -410,6 +426,39 @@
     return ext;
 }
 
+/*
+ * Function id3v1_to_id3v2 (v1, v2)
+ *
+ *    Convert ID3v1 tag `v1' to ID3v2 tag `v2'.
+ *
+ */
+void
+mpg123_id3v1_to_id3v2(struct id3v1tag_t *v1, struct id3tag_t *v2)
+{
+    memset(v2, 0, sizeof(struct id3tag_t));
+    strncpy(v2->title, v1->title, 30);
+    strncpy(v2->artist, v1->artist, 30);
+    strncpy(v2->album, v1->album, 30);
+    strncpy(v2->comment, v1->u.v1_0.comment, 30);
+    strncpy(v2->genre, get_id3_genre(v1->genre), sizeof(v2->genre));
+    g_strstrip(v2->title);
+    g_strstrip(v2->artist);
+    g_strstrip(v2->album);
+    g_strstrip(v2->comment);
+    g_strstrip(v2->genre);
+    {
+      char y[5];
+      memcpy(y, v1->year, 4); y[4]=0;
+      v2->year = atoi(y);
+    }
+
+    /* Check for v1.1 tags. */
+    if (v1->u.v1_1.__zero == 0)
+        v2->track_number = v1->u.v1_1.track_number;
+    else
+        v2->track_number = 0;
+}
+
 #define REMOVE_NONEXISTANT_TAG(x)   if (!*x) { x = NULL; }
 
 /*
@@ -492,27 +541,69 @@
     return ret;
 }
 
-static guint
-get_song_time(char *filename)
+static long
+get_song_length(VFSFile * file)
 {
     int len;
+    char tmp[4];
 
-    taglib_file = taglib_file_new(filename);
-    if(taglib_file) {
-      taglib_ap = taglib_file_audioproperties(taglib_file);
-    }
+    vfs_fseek(file, 0, SEEK_END);
+    len = vfs_ftell(file);
+    vfs_fseek(file, -128, SEEK_END);
+    vfs_fread(tmp, 1, 3, file);
+    if (!strncmp(tmp, "TAG", 3))
+        len -= 128;
+    return len;
+}
+
+
+static guint
+get_song_time(VFSFile * file)
+{
+    guint32 head;
+    guchar tmp[4], *buf;
+    struct frame frm;
+    xing_header_t xing_header;
+    double tpf, bpf;
+    guint32 len;
+
+    if (!file)
+        return -1;
 
-    len = taglib_audioproperties_length(taglib_ap);
-   
-    taglib_file_free(taglib_file);
-    taglib_tag_free_strings();
-
-    return len;
+    vfs_fseek(file, 0, SEEK_SET);
+    if (vfs_fread(tmp, 1, 4, file) != 4)
+        return 0;
+    head = convert_to_header(tmp);
+    while (!mpg123_head_check(head)) {
+        head <<= 8;
+        if (vfs_fread(tmp, 1, 1, file) != 1)
+            return 0;
+        head |= tmp[0];
+    }
+    if (mpg123_decode_header(&frm, head)) {
+        buf = g_malloc(frm.framesize + 4);
+        vfs_fseek(file, -4, SEEK_CUR);
+        vfs_fread(buf, 1, frm.framesize + 4, file);
+        tpf = mpg123_compute_tpf(&frm);
+        if (mpg123_get_xing_header(&xing_header, buf)) {
+            g_free(buf);
+            if (xing_header.bytes == 0)
+                xing_header.bytes = get_song_length(file);
+            return (tpf * xing_header.frames * 1000);
+        }
+        g_free(buf);
+        bpf = mpg123_compute_bpf(&frm);
+        len = get_song_length(file);
+        return ((guint) (len / bpf) * tpf * 1000);
+    }
+    return 0;
 }
 
 static void
 get_song_info(char *filename, char **title_real, int *len_real)
 {
+    VFSFile *file;
+
     (*len_real) = -1;
     (*title_real) = NULL;
 
@@ -522,8 +613,11 @@
     if (!strncasecmp(filename, "http://", 7))
         return;
 
-    (*len_real) = get_song_time(filename);
-    (*title_real) = get_song_title(filename);
+    if ((file = vfs_fopen(filename, "rb")) != NULL) {
+        (*len_real) = get_song_time(file);
+        (*title_real) = get_song_title(filename);
+	vfs_fclose(file);
+    }
 }
 
 static int