summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2009-08-04 17:49:03 +0200
committerGravatar waker <wakeroid@gmail.com>2009-08-04 17:49:03 +0200
commit7bccab7d4a27e554259637f4ed23356519433549 (patch)
tree02fc9b9b7349053be3935f9a1b19e4e9906dc4e7
parentb3826e69941ff69f9da91679d087e6964bbc41f6 (diff)
playlist insertion WIP
-rw-r--r--cdumb.c12
-rw-r--r--cflac.c27
-rw-r--r--cgme.c10
-rw-r--r--cmp3.c12
-rw-r--r--codec.h5
-rw-r--r--common.h12
-rw-r--r--csid.cpp22
-rw-r--r--cvorbis.c14
-rw-r--r--playlist.c195
-rw-r--r--playlist.h21
-rw-r--r--psdl.c11
11 files changed, 252 insertions, 89 deletions
diff --git a/cdumb.c b/cdumb.c
index dc4062e9..8a6680e8 100644
--- a/cdumb.c
+++ b/cdumb.c
@@ -656,8 +656,8 @@ static DUH * open_module(const char *fname, const char *ext, int *start_order, i
return duh;
}
-int
-cdumb_add (const char *fname) {
+playItem_t *
+cdumb_insert (playItem_t *after, const char *fname) {
const char *ext = fname + strlen (fname) - 1;
while (*ext != '.' && ext > fname) {
ext--;
@@ -669,7 +669,7 @@ cdumb_add (const char *fname) {
dumb_register_stdfiles ();
DUH* duh = open_module(fname, ext, &start_order, &is_it, &is_dos);
if (!duh) {
- return -1;
+ return NULL;
}
unload_duh (duh);
playItem_t *it = malloc (sizeof (playItem_t));
@@ -679,9 +679,9 @@ cdumb_add (const char *fname) {
it->tracknum = 0;
it->timestart = 0;
it->timeend = 0;
- ps_append_item (it);
+ after = ps_insert_item (after, it);
- return 0;
+ return after;
}
const char **cdumb_getexts (void) {
@@ -693,7 +693,7 @@ codec_t cdumb = {
.free = cdumb_free,
.read = cdumb_read,
.seek = cdumb_seek,
- .add = cdumb_add,
+ .insert = cdumb_insert,
.getexts = cdumb_getexts
};
diff --git a/cflac.c b/cflac.c
index eb95f8ac..0c6ea3c5 100644
--- a/cflac.c
+++ b/cflac.c
@@ -181,22 +181,23 @@ cflac_init_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__Str
*psr = metadata->data.stream_info.sample_rate;
}
-int
-cflac_add (const char *fname) {
+playItem_t *
+cflac_insert (playItem_t *after, const char *fname) {
// try cue
char cuename[1024];
snprintf (cuename, 1024, "%s.cue", fname);
// printf ("loading %s\n", cuename);
- if (!ps_add_cue (cuename)) {
- return 0;
+ playItem_t *cue_after;
+ if ((cue_after = ps_insert_cue (after, cuename)) != NULL) {
+ return cue_after;
}
int n = strlen (fname) - 4;
if (n > 0) {
strncpy (cuename, fname, n);
strcpy (cuename + n, "cue");
// printf ("loading %s\n", cuename);
- if (!ps_add_cue (cuename)) {
- return 0;
+ if ((cue_after = ps_insert_cue (after, cuename)) != NULL) {
+ return cue_after;
}
}
@@ -205,22 +206,22 @@ cflac_add (const char *fname) {
decoder = FLAC__stream_decoder_new();
if (!decoder) {
printf ("FLAC__stream_decoder_new failed\n");
- return -1;
+ return NULL;
}
FLAC__stream_decoder_set_md5_checking(decoder, 0);
int samplerate = -1;
status = FLAC__stream_decoder_init_file(decoder, fname, cflac_init_write_callback, cflac_init_metadata_callback, cflac_error_callback, &samplerate);
if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
FLAC__stream_decoder_delete(decoder);
- return -1;
+ return NULL;
}
if (!FLAC__stream_decoder_process_until_end_of_metadata (decoder)) {
FLAC__stream_decoder_delete(decoder);
- return -1;
+ return NULL;
}
if (samplerate == -1) { // not a FLAC stream
FLAC__stream_decoder_delete(decoder);
- return -1;
+ return NULL;
}
FLAC__stream_decoder_delete(decoder);
playItem_t *it = malloc (sizeof (playItem_t));
@@ -230,8 +231,8 @@ cflac_add (const char *fname) {
it->tracknum = 0;
it->timestart = 0;
it->timeend = 0;
- ps_append_item (it);
- return 0;
+ after = ps_insert_item (after, it);
+ return after;
}
static const char * exts[]=
@@ -248,6 +249,6 @@ codec_t cflac = {
.free = cflac_free,
.read = cflac_read,
.seek = cflac_seek,
- .add = cflac_add,
+ .insert = cflac_insert,
.getexts = cflac_getexts
};
diff --git a/cgme.c b/cgme.c
index 72193c29..74a7e6e2 100644
--- a/cgme.c
+++ b/cgme.c
@@ -89,8 +89,8 @@ cgme_seek (float time) {
return 0;
}
-int
-cgme_add (const char *fname) {
+playItem_t *
+cgme_insert (playItem_t *after, const char *fname) {
// printf ("adding %s chiptune\n", fname);
Music_Emu *emu;
if (!gme_open_file (fname, &emu, gme_info_only)) {
@@ -123,7 +123,7 @@ cgme_add (const char *fname) {
char trk[10];
snprintf (trk, 10, "%d", i+1);
ps_add_meta (it, "track", trk);
- ps_append_item (it);
+ after = ps_insert_item (after, it);
}
else {
printf ("gme error: %s\n", ret);
@@ -136,7 +136,7 @@ cgme_add (const char *fname) {
else {
printf ("error adding %s\n", fname);
}
- return 0;
+ return after;
}
static const char * exts[]=
@@ -170,7 +170,7 @@ codec_t cgme = {
.free = cgme_free,
.read = cgme_read,
.seek = cgme_seek,
- .add = cgme_add,
+ .insert = cgme_insert,
.getexts = cgme_getexts,
.numvoices = cgme_numvoices,
.mutevoice = cgme_mutevoice
diff --git a/cmp3.c b/cmp3.c
index c7349445..9338b447 100644
--- a/cmp3.c
+++ b/cmp3.c
@@ -916,11 +916,11 @@ cmp3_read_id3v2 (playItem_t *it, FILE *fp) {
return 0;
}
-int
-cmp3_add (const char *fname) {
+playItem_t *
+cmp3_insert (playItem_t *after, const char *fname) {
FILE *fp = fopen (fname, "rb");
if (!fp) {
- return -1;
+ return NULL;
}
playItem_t *it = malloc (sizeof (playItem_t));
memset (it, 0, sizeof (playItem_t));
@@ -933,8 +933,8 @@ cmp3_add (const char *fname) {
it->tracknum = 0;
it->timestart = 0;
it->timeend = 0;
- ps_append_item (it);
- return 0;
+ after = ps_insert_item (after, it);
+ return after;
}
static const char * exts[]=
@@ -951,7 +951,7 @@ codec_t cmp3 = {
.free = cmp3_free,
.read = cmp3_read,
.seek = cmp3_seek,
- .add = cmp3_add,
+ .insert = cmp3_insert,
.getexts = cmp3_getexts
};
diff --git a/codec.h b/codec.h
index 5e86cb78..68f29e54 100644
--- a/codec.h
+++ b/codec.h
@@ -2,6 +2,7 @@
#define __CODEC_H
#include <stdint.h>
+//#include "playlist.h"
typedef struct {
int bitsPerSample;
@@ -11,13 +12,15 @@ typedef struct {
float position;
} fileinfo_t;
+struct playItem_s;
+
typedef struct codec_s {
int (*init) (const char *fname, int track, float start, float end);
void (*free) (void);
// player is responsible for starting next song if -1 is returned
int (*read) (char *bytes, int size);
int (*seek) (float time);
- int (*add) (const char *fname);
+ struct playItem_s * (*insert) (struct playItem_s *after, const char *fname); // after==NULL means "prepend to beginning"
const char ** (*getexts) (void);
int (*numvoices) (void);
void (*mutevoice) (int voice, int mute);
diff --git a/common.h b/common.h
index 0cefcb8d..63f0f010 100644
--- a/common.h
+++ b/common.h
@@ -4,16 +4,4 @@
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
-inline void
-le_int16 (int16_t in, char *out) {
- char *pin = (char *)&in;
-#if !BIGENDIAN
- out[0] = pin[0];
- out[1] = pin[1];
-#else
- out[1] = pin[0];
- out[0] = pin[1];
-#endif
-}
-
#endif // __COMMON_H
diff --git a/csid.cpp b/csid.cpp
index 76394b16..e0f36605 100644
--- a/csid.cpp
+++ b/csid.cpp
@@ -12,6 +12,18 @@ extern "C" {
#include "common.h"
}
+static inline void
+le_int16 (int16_t in, char *out) {
+ char *pin = (char *)&in;
+#if !BIGENDIAN
+ out[0] = pin[0];
+ out[1] = pin[1];
+#else
+ out[1] = pin[0];
+ out[0] = pin[1];
+#endif
+}
+
static sidplay2 *sidplay;
static ReSIDBuilder *resid;
static SidTune *tune;
@@ -346,8 +358,8 @@ convstr (const char* str) {
return out;
}
-extern "C" int
-csid_add (const char *fname) {
+extern "C" playItem_t *
+csid_insert (playItem_t *after, const char *fname) {
sldb_load(sldb_fname);
SidTune *tune;
tune = new SidTune (fname);
@@ -384,11 +396,11 @@ csid_add (const char *fname) {
char trk[10];
snprintf (trk, 10, "%d", s+1);
ps_add_meta (it, "track", trk);
- ps_append_item (it);
+ after = ps_insert_item (after, it);
}
}
delete tune;
- return 0;
+ return after;
}
static const char *exts[]=
@@ -428,7 +440,7 @@ codec_t csid = {
csid_free,
csid_read,
csid_seek,
- csid_add,
+ csid_insert,
csid_getexts,
csid_numvoices,
csid_mutevoice
diff --git a/cvorbis.c b/cvorbis.c
index f45194f7..2d801113 100644
--- a/cvorbis.c
+++ b/cvorbis.c
@@ -97,19 +97,19 @@ cvorbis_seek (float time) {
return 0;
}
-int
-cvorbis_add (const char *fname) {
+playItem_t *
+cvorbis_insert (playItem_t *after, const char *fname) {
// check for validity
FILE *fp = fopen (fname, "rb");
if (!fp) {
- return -1;
+ return NULL;
}
OggVorbis_File vorbis_file;
vorbis_info *vi;
ov_open (fp, &vorbis_file, NULL, 0);
vi = ov_info (&vorbis_file, -1);
if (!vi) { // not a vorbis stream
- return -1;
+ return NULL;
}
playItem_t *it = malloc (sizeof (playItem_t));
memset (it, 0, sizeof (playItem_t));
@@ -136,8 +136,8 @@ cvorbis_add (const char *fname) {
}
}
ov_clear (&vorbis_file);
- ps_append_item (it);
- return 0;
+ after = ps_insert_item (after, it);
+ return after;
}
static const char * exts[]=
@@ -154,7 +154,7 @@ codec_t cvorbis = {
.free = cvorbis_free,
.read = cvorbis_read,
.seek = cvorbis_seek,
- .add = cvorbis_add,
+ .insert = cvorbis_insert,
.getexts = cvorbis_getexts
};
diff --git a/playlist.c b/playlist.c
index 07a175d8..d91af9cf 100644
--- a/playlist.c
+++ b/playlist.c
@@ -110,8 +110,131 @@ ps_cue_parse_time (const char *p) {
return mins * 60 + sec;
}
+playItem_t *
+ps_insert_cue (playItem_t *after, const char *cuename) {
+ FILE *fp = fopen (cuename, "rt");
+ if (!fp) {
+ return NULL;
+ }
+ char performer[1024];
+ char albumtitle[1024];
+ char file[1024];
+ char track[1024];
+ char title[1024];
+ char start[1024];
+ playItem_t *prev = NULL;
+ for (;;) {
+ char str[1024];
+ if (!fgets (str, 1024, fp)) {
+ break; // eof
+ }
+ char *p = ps_cue_skipspaces (str);
+ if (!strncmp (p, "PERFORMER ", 10)) {
+ ps_get_qvalue_from_cue (p + 10, performer);
+// printf ("got performer: %s\n", performer);
+ }
+ else if (!strncmp (p, "TITLE ", 6)) {
+ if (str[0] > ' ') {
+ ps_get_qvalue_from_cue (p + 6, albumtitle);
+// printf ("got albumtitle: %s\n", albumtitle);
+ }
+ else {
+ ps_get_qvalue_from_cue (p + 6, title);
+// printf ("got title: %s\n", title);
+ }
+ }
+ else if (!strncmp (p, "FILE ", 5)) {
+ ps_get_qvalue_from_cue (p + 5, file);
+// printf ("got filename: %s\n", file);
+ // copy directory name
+ char fname[1024];
+ int len = strlen (cuename);
+ memcpy (fname, cuename, len+1);
+ char *p = fname + len;
+ while (*p != '/') {
+ p--;
+ len--;
+ }
+ p++;
+ len++;
+ // add file name
+ int flen = strlen (file);
+ // ensure fullname fills in buffer
+ if (flen + len >= 1024) {
+// printf ("cue file name is too long");
+ return NULL;
+ }
+ strcpy (p, file);
+ // copy full name in place of relative name
+ strcpy (file, fname);
+// printf ("ended up as: %s\n", file);
+ }
+ else if (!strncmp (p, "TRACK ", 6)) {
+ ps_get_value_from_cue (p + 6, track);
+// printf ("got track: %s\n", track);
+ }
+// else if (!strncmp (p, "PERFORMER ", 10)) {
+// ps_get_qvalue_from_cue (p + 10, performer);
+// }
+ else if (!strncmp (p, "INDEX 00 ", 9) || !strncmp (p, "INDEX 01 ", 9)) {
+ if (!track[0]) {
+ continue;
+ }
+#if SKIP_BLANK_CUE_TRACKS
+ if (!title[0])
+ continue;
+#endif
+ ps_get_value_from_cue (p + 9, start);
+// printf ("got index0: %s\n", start);
+ char *p = track;
+ while (*p && isdigit (*p)) {
+ p++;
+ }
+ *p = 0;
+ // check that indexes have valid timestamps
+ float tstart = ps_cue_parse_time (start);
+ if (tstart < 0) {
+// printf ("cue file %s has bad timestamp(s)\n", cuename);
+ continue;
+ }
+ if (prev) {
+ prev->timeend = tstart;
+// printf ("end time for prev track (%x): %f\n", prev, tstart);
+ }
+ // add this track
+ char str[1024];
+ snprintf (str, 1024, "%d. %s - %s", atoi (track), performer, title[0] ? title : "?", start, tstart);
+// printf ("adding %s\n", str);
+ playItem_t *it = malloc (sizeof (playItem_t));
+ memset (it, 0, sizeof (playItem_t));
+ it->codec = &cflac;
+ it->fname = strdup (file);
+ it->tracknum = atoi (track);
+ it->timestart = tstart;
+ it->timeend = -1; // will be filled by next read, or by codec
+ after = ps_insert_item (after, it);
+// ps_append_item (it);
+// printf ("added item %x\n", it);
+ prev = it;
+ track[0] = 0;
+ }
+ else {
+// printf ("got unknown line:\n%s\n", p);
+ }
+ }
+ fclose (fp);
+ return after;
+}
+
int
ps_add_cue (const char *cuename) {
+ playItem_t *it = ps_insert_cue (playlist_tail, cuename);
+ if (!it) {
+ return -1;
+ }
+ return 0;
+// {{{ hide old cue code
+#if 0
FILE *fp = fopen (cuename, "rt");
if (!fp) {
return -1;
@@ -223,6 +346,16 @@ ps_add_cue (const char *cuename) {
}
fclose (fp);
return 0;
+#endif
+// }}}
+}
+
+playItem_t *
+ps_insert_file (playItem_t *after, const char *fname) {
+}
+
+playItem_t *
+ps_insert_dir (playItem_t *after, const char *dirname) {
}
int
@@ -242,13 +375,15 @@ ps_add_file (const char *fname) {
codec_t *codecs[] = {
&cdumb, &cvorbis, &cflac, &cgme, &cmp3, &csid, NULL
};
+ playItem_t *after = playlist_tail;
for (int i = 0; codecs[i]; i++) {
- if (codecs[i]->getexts && codecs[i]->add) {
+ if (codecs[i]->getexts && codecs[i]->insert) {
const char **exts = codecs[i]->getexts ();
if (exts) {
for (int e = 0; exts[e]; e++) {
if (!strcasecmp (exts[e], eol)) {
- if (!codecs[i]->add (fname)) {
+ playItem_t *inserted = NULL;
+ if ((inserted = codecs[i]->insert (after, fname)) != NULL) {
return 0;
}
}
@@ -258,35 +393,6 @@ ps_add_file (const char *fname) {
}
return -1;
-#if 0
- // add by extension (temporary hack)
-// else if (!strcasecmp (eol, "wav")) {
-// codec = &cwav;
-// }
- if (!strcasecmp (eol, "mp3")) {
- codec = &cmp3;
- }
- else {
- return -1;
- }
- // copy string
- playItem_t *it = malloc (sizeof (playItem_t));
- memset (it, 0, sizeof (playItem_t));
- it->codec = codec;
- it->fname = strdup (fname);
- // find 1st slash from end
- while (eol > fname && *eol != '/') {
- eol--;
- }
- if (*eol=='/') {
- eol++;
- }
-
- it->timestart = -1;
- it->timeend = -1;
-
- ps_append_item (it);
-#endif
}
int
@@ -406,6 +512,33 @@ ps_append_item (playItem_t *it) {
ps_count++;
}
+playItem_t *
+ps_insert_item (playItem_t *after, playItem_t *it) {
+ if (!after) {
+ it->next = playlist_head;
+ it->prev = NULL;
+ if (playlist_head) {
+ playlist_head->prev = it;
+ }
+ else {
+ playlist_tail = it;
+ }
+ playlist_head = it;
+ }
+ else {
+ it->next = after;
+ it->prev = after->prev;
+ if (after->prev) {
+ after->prev->next = it;
+ }
+ after->prev = it;
+ if (after == playlist_tail) {
+ playlist_tail = it;
+ }
+ }
+ return it;
+}
+
void
ps_item_copy (playItem_t *out, playItem_t *it) {
out->fname = strdup (it->fname);
diff --git a/playlist.h b/playlist.h
index d649b416..681bf2bc 100644
--- a/playlist.h
+++ b/playlist.h
@@ -25,13 +25,22 @@ extern playItem_t *playlist_current_ptr; // pointer to a real current playlist i
extern playItem_t playlist_current; // copy of playlist item being played (stays in memory even if removed from playlist)
int
-ps_add_file (const char *fname);
+ps_add_dir (const char *dirname);
int
-ps_append_item (playItem_t *it);
+ps_add_file (const char *fname);
+
+playItem_t *
+ps_insert_dir (playItem_t *after, const char *dirname);
+
+playItem_t *
+ps_insert_file (playItem_t *after, const char *fname);
+
+playItem_t *
+ps_insert_item (playItem_t *after, playItem_t *it);
int
-ps_add_dir (const char *dirname);
+ps_append_item (playItem_t *it);
int
ps_remove (playItem_t *i);
@@ -57,6 +66,12 @@ ps_get_idx_of (playItem_t *it);
int
ps_add_cue (const char *cuename);
+playItem_t *
+ps_insert_cue (playItem_t *after, const char *cuename);
+
+playItem_t *
+ps_insert_cue (playItem_t *after, const char *cuename);
+
int
ps_set_current (playItem_t *it);
diff --git a/psdl.c b/psdl.c
index 1ffa21ca..72305b7e 100644
--- a/psdl.c
+++ b/psdl.c
@@ -9,6 +9,17 @@ static SDL_AudioSpec spec;
static void psdl_callback (void *userdata, Uint8 *stream, int len);
static float sdl_volume = 1;
+static inline void
+le_int16 (int16_t in, char *out) {
+ char *pin = (char *)&in;
+#if !BIGENDIAN
+ out[0] = pin[0];
+ out[1] = pin[1];
+#else
+ out[1] = pin[0];
+ out[0] = pin[1];
+#endif
+}
int
psdl_init (void) {
SDL_AudioSpec obt;