Truly read the ID3 info from the files.
authorNicolas Pennequin <nicolas.pennequin@free.fr>
Tue, 14 Aug 2007 17:06:57 +0000 (14 19:06 +0200)
committerNicolas Pennequin <nicolas.pennequin@free.fr>
Tue, 14 Aug 2007 17:06:57 +0000 (14 19:06 +0200)
Call get_metadata to obtain the struct mp3entry with the file's metadata.
We need to use special functions to copy ot move the struct mp3entry because
it has pointers to an internal buffer.
The bufopen thread needs a bigger stack for this.

Tested successfully on sim and on the gigabeat.

testplugin.c

index 41a248a..ab6168c 100644 (file)
@@ -404,6 +404,14 @@ static void free_buffer(int handle_id)
         h->data = RINGBUF_ADD(h->data, delta);
         h->ridx = RINGBUF_ADD(h->ridx, delta);
         h->widx = RINGBUF_ADD(h->widx, delta);
+
+        /* when moving a struct mp3entry we need to readjust its pointers. */
+        if (h->type == TYPE_ID3 && h->filesize == sizeof(struct mp3entry)) {
+            rb->adjust_mp3entry((struct mp3entry *)&buffer[h->data],
+                                (void *)&buffer[h->data],
+                                (void *)&buffer[RINGBUF_SUB(h->data, delta)]);
+        }
+
         DEBUGF("free_buffer(%d): metadata, moved by %ld bytes\n",
                handle_id, delta);
     }
@@ -578,8 +586,15 @@ int bufalloc(void *src, size_t size, enum data_type type)
     if (!h || allocsize != size)
         return -2;
 
-    if (src)
-        rb->memcpy(&buffer[buf_widx], src, size);
+    if (src) {
+        if (type == TYPE_ID3 && size == sizeof(struct mp3entry)) {
+            /* specially take care of struct mp3entry */
+            rb->copy_mp3entry((struct mp3entry *)&buffer[buf_widx],
+                              (struct mp3entry *)src);
+        } else {
+            rb->memcpy(&buffer[buf_widx], src, size);
+        }
+    }
 
     h->fd = -1;
     *h->path = 0;
@@ -899,38 +914,15 @@ void print_progress(size_t amount, int file, int numfiles)
 void print_metadata(int handle_id)
 {
     ssize_t ret;
-    char *artist, *title;
-    unsigned char *buf;
+    struct mp3entry *id3;
 
-    ret = bufgetdata(handle_id, 0, &buf);
+    ret = bufgetdata(handle_id, 0, (unsigned char **)&id3);
 
     if (ret < 0)
         return;
 
-    artist = buf;
-    title = artist + rb->strlen(artist) + 1;
-
-    rb->lcd_puts(0, 3, artist);
-    rb->lcd_puts(0, 4, title);
-}
-
-int read_metadata(char *filename, char *buf, int bufsize)
-{
-    int ret;
-    char *newline;
-    int fd = rb->open(filename, O_RDONLY);
-    if (fd < 0)
-        return -1;
-
-    ret = rb->read(fd, buf, bufsize);
-    newline = rb->strchr(buf, '\n');
-    *newline = '\0';
-    newline = rb->strchr(newline + 1, '\n');
-    *newline = '\0';
-
-    rb->close(fd);
-
-    return ret;
+    rb->lcd_puts(0, 3, id3->artist);
+    rb->lcd_puts(0, 4, id3->title);
 }
 
 bool buffer_init(void)
@@ -969,7 +961,7 @@ THREADING CODE
 static long codec_stack[4*DEFAULT_STACK_SIZE/sizeof(long)];
 static struct thread_entry* codecthread_id;
 
-static long bufopen_stack[2*DEFAULT_STACK_SIZE/sizeof(long)];
+static long bufopen_stack[4*DEFAULT_STACK_SIZE/sizeof(long)];
 static struct thread_entry* bufopenthread_id;
 
 bool done_playing = false;
@@ -1057,25 +1049,27 @@ void codec_thread(void)
 
 void bufopen_thread(void)
 {
-    int idx = 0, ret;
-    char filename[MAX_PATH];
-    char buf[MAX_PATH];
-    int meta_len;
+    int idx = 0, ret, fd;
+    struct mp3entry id3;
+    bool meta_loaded;
 
     while (idx < num_files)
     {
         if (meta_handles[idx] <= 0)
         {
-            /* read the metadata file */
-            rb->snprintf(filename, MAX_PATH, "/meta%s.txt", files[idx]);
-            meta_len = read_metadata(filename, buf, MAX_PATH);
+            /* read the metadata */
+            fd = rb->open(files[idx], O_RDONLY);
+            meta_loaded = rb->get_metadata(&id3, fd, files[idx], false);
 
             /* copy the metadata to a new handle */
-            if (meta_len > 0)
-                meta_handles[idx] = bufalloc(buf, meta_len, TYPE_ID3);
+            if (meta_loaded)
+                meta_handles[idx] = bufalloc(&id3, sizeof(struct mp3entry),
+                                             TYPE_ID3);
+
+            rb->close(fd);
         }
 
-        if (meta_handles[idx] > 0)
+        if (meta_handles[idx] > 0 || !meta_loaded)
         {
             /* open the audio file */
             ret = bufopen(files[idx], 0, TYPE_AUDIO);
@@ -1083,7 +1077,10 @@ void bufopen_thread(void)
                 handles[idx++] = ret;
             } else {
                 /* couldn't open the audio file, close the metadata handle */
-                bufclose(meta_handles[idx]);
+                if (meta_handles[idx] > 0) {
+                    bufclose(meta_handles[idx]);
+                    meta_handles[idx] = -1;
+                }
             }
         }
         rb->sleep(HZ*2);