summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cflac.c14
-rw-r--r--deadbeef.h3
-rw-r--r--playlist.c96
-rw-r--r--playlist.h5
-rw-r--r--plugins.c1
5 files changed, 86 insertions, 33 deletions
diff --git a/cflac.c b/cflac.c
index 67fdba98..8f309f8f 100644
--- a/cflac.c
+++ b/cflac.c
@@ -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
diff --git a/deadbeef.h b/deadbeef.h
index 03e83d87..d8460cdc 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -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);
diff --git a/playlist.c b/playlist.c
index ed391de3..e53ccc2c 100644
--- a/playlist.c
+++ b/playlist.c
@@ -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;
diff --git a/playlist.h b/playlist.h
index 1d007aa2..1c57de16 100644
--- a/playlist.h
+++ b/playlist.h
@@ -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
diff --git a/plugins.c b/plugins.c
index 2e9df7b8..bc5d3f42 100644
--- a/plugins.c
+++ b/plugins.c
@@ -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,