diff options
author | waker <wakeroid@gmail.com> | 2009-08-30 16:25:34 +0200 |
---|---|---|
committer | waker <wakeroid@gmail.com> | 2009-08-30 16:25:34 +0200 |
commit | 37b0ce345c9a7fbc383ef69df4e8600e37216ea0 (patch) | |
tree | 4f5543cfacd23792ffda8d5967ea025a48f3fc48 | |
parent | 17953a07524b17d98ad881efdb307fd8a81588ee (diff) |
added reading of cuesheets from flac vorbiscomments
-rw-r--r-- | cflac.c | 14 | ||||
-rw-r--r-- | deadbeef.h | 3 | ||||
-rw-r--r-- | playlist.c | 96 | ||||
-rw-r--r-- | playlist.h | 5 | ||||
-rw-r--r-- | plugins.c | 1 |
5 files changed, 86 insertions, 33 deletions
@@ -288,6 +288,20 @@ cflac_init_cue_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC_ } #endif // }}} + else if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { + const FLAC__StreamMetadata_VorbisComment *vc = &metadata->data.vorbis_comment; + for (int i = 0; i < vc->num_comments; i++) { + const FLAC__StreamMetadata_VorbisComment_Entry *c = &vc->comments[i]; + if (c->length > 0) { + char s[c->length+1]; + s[c->length] = 0; + memcpy (s, c->entry, c->length); + if (!strncasecmp (s, "cuesheet=", 9)) { + cb->last = deadbeef->pl_insert_cue_from_buffer (cb->after, cb->fname, s+9, c->length-9, &plugin, "FLAC"); + } + } + } + } } static void @@ -144,7 +144,8 @@ typedef struct { void (*pl_add_meta) (DB_playItem_t *it, const char *key, const char *value); const char *(*pl_find_meta) (DB_playItem_t *song, const char *meta); // cuesheet support - DB_playItem_t * (*pl_insert_cue) (DB_playItem_t *after, const char *cuename, struct DB_decoder_s *decoder, const char *ftype); + DB_playItem_t *(*pl_insert_cue_from_buffer) (DB_playItem_t *after, const char *fname, const uint8_t *buffer, int buffersize, struct DB_decoder_s *decoder, const char *ftype); + DB_playItem_t * (*pl_insert_cue) (DB_playItem_t *after, const char *filename, struct DB_decoder_s *decoder, const char *ftype); // volume control void (*volume_set_db) (float dB); float (*volume_get_db) (void); @@ -58,8 +58,8 @@ pl_free (void) { } } -static char * -pl_cue_skipspaces (uint8_t *p) { +static const char * +pl_cue_skipspaces (const uint8_t *p) { while (*p && *p <= ' ') { p++; } @@ -67,7 +67,7 @@ pl_cue_skipspaces (uint8_t *p) { } static void -pl_get_qvalue_from_cue (char *p, char *out) { +pl_get_qvalue_from_cue (const char *p, char *out) { if (*p == 0) { *out = 0; return; @@ -89,7 +89,7 @@ pl_get_qvalue_from_cue (char *p, char *out) { } static void -pl_get_value_from_cue (char *p, char *out) { +pl_get_value_from_cue (const char *p, char *out) { while (*p >= ' ') { *out++ = *p++; } @@ -134,23 +134,7 @@ pl_cue_parse_time (const char *p) { } playItem_t * -pl_insert_cue (playItem_t *after, const char *fname, struct DB_decoder_s *decoder, const char *ftype) { - int len = strlen (fname); - char cuename[len+5]; - strcpy (cuename, fname); - strcpy (cuename+len, ".cue"); - FILE *fp = fopen (cuename, "rt"); - if (!fp) { - char *ptr = cuename + len-1; - while (ptr >= cuename && *ptr != '.') { - ptr--; - } - strcpy (ptr+1, "cue"); - fp = fopen (cuename, "rt"); - if (!fp) { - return NULL; - } - } +pl_insert_cue_from_buffer (playItem_t *after, const char *fname, const uint8_t *buffer, int buffersize, struct DB_decoder_s *decoder, const char *ftype) { char performer[1024]; char albumtitle[1024]; char file[1024]; @@ -158,12 +142,27 @@ pl_insert_cue (playItem_t *after, const char *fname, struct DB_decoder_s *decode char title[1024]; char start[1024]; playItem_t *prev = NULL; - for (;;) { - char str[1024]; - if (!fgets (str, 1024, fp)) { - break; // eof + while (buffersize > 0) { + const uint8_t *p = buffer; + // find end of line + while (p - buffer < buffersize && *p >= 0x20) { + p++; } - char *p = pl_cue_skipspaces (str); + // skip linebreak(s) + while (p - buffer < buffersize && *p < 0x20) { + *p++; + } + if (p-buffer > 2048) { // huge string, ignore + buffer = p; + buffersize -= p-buffer; + continue; + } + char str[p-buffer+1]; + strncpy (str, buffer, p-buffer); + str[p-buffer] = 0; + buffersize -= p-buffer; + buffer = p; + p = pl_cue_skipspaces (str); if (!strncmp (p, "PERFORMER ", 10)) { pl_get_qvalue_from_cue (p + 10, performer); // printf ("got performer: %s\n", performer); @@ -181,10 +180,10 @@ pl_insert_cue (playItem_t *after, const char *fname, struct DB_decoder_s *decode else if (!strncmp (p, "FILE ", 5)) { pl_get_qvalue_from_cue (p + 5, file); // copy directory name - char fname[1024]; - int len = strlen (cuename); - memcpy (fname, cuename, len+1); - char *p = fname + len; + char dirname[1024]; + int len = strlen (fname); + memcpy (dirname, fname, len+1); + char *p = dirname + len; while (*p != '/') { p--; len--; @@ -200,7 +199,7 @@ pl_insert_cue (playItem_t *after, const char *fname, struct DB_decoder_s *decode } strcpy (p, file); // copy full name in place of relative name - strcpy (file, fname); + strcpy (file, dirname); // printf ("ended up as: %s\n", file); } else if (!strncmp (p, "TRACK ", 6)) { @@ -260,11 +259,44 @@ pl_insert_cue (playItem_t *after, const char *fname, struct DB_decoder_s *decode // printf ("got unknown line:\n%s\n", p); } } - fclose (fp); return after; } playItem_t * +pl_insert_cue (playItem_t *after, const char *fname, struct DB_decoder_s *decoder, const char *ftype) { + int len = strlen (fname); + char cuename[len+5]; + strcpy (cuename, fname); + strcpy (cuename+len, ".cue"); + FILE *fp = fopen (cuename, "rb"); + if (!fp) { + char *ptr = cuename + len-1; + while (ptr >= cuename && *ptr != '.') { + ptr--; + } + strcpy (ptr+1, "cue"); + fp = fopen (cuename, "rb"); + if (!fp) { + return NULL; + } + } + fseek (fp, 0, SEEK_END); + size_t sz = ftell (fp); + if (sz == 0) { + fclose (fp); + return NULL; + } + rewind (fp); + uint8_t buf[sz]; + if (fread (buf, 1, sz, fp) != sz) { + fclose (fp); + return NULL; + } + fclose (fp); + return pl_insert_cue_from_buffer (after, fname, buf, sz, decoder, ftype); +} + +playItem_t * pl_insert_file (playItem_t *after, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) { if (!fname) { return NULL; @@ -18,6 +18,8 @@ #ifndef __PLAYLIST_H #define __PLAYLIST_H +#include <stdint.h> + typedef struct metaInfo_s { const char *key; char *value; @@ -100,6 +102,9 @@ int pl_get_idx_of (playItem_t *it); playItem_t * +pl_insert_cue_from_buffer (playItem_t *after, const char *fname, const uint8_t *buffer, int buffersize, struct DB_decoder_s *decoder, const char *ftype); + +playItem_t * pl_insert_cue (playItem_t *after, const char *cuename, struct DB_decoder_s *decoder, const char *ftype); int @@ -77,6 +77,7 @@ DB_functions_t deadbeef_api = { .pl_add_meta = (void (*) (DB_playItem_t *, const char *, const char *))pl_add_meta, .pl_find_meta = (const char *(*) (DB_playItem_t *, const char *))pl_find_meta, // cuesheet support + .pl_insert_cue_from_buffer = (DB_playItem_t *(*) (DB_playItem_t *after, const char *fname, const uint8_t *buffer, int buffersize, struct DB_decoder_s *decoder, const char *ftype))pl_insert_cue_from_buffer, .pl_insert_cue = (DB_playItem_t *(*)(DB_playItem_t *, const char *, struct DB_decoder_s *, const char *))pl_insert_cue, // volume control .volume_set_db = plug_volume_set_db, |