summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deadbeef.h2
-rw-r--r--junklib.c17
-rw-r--r--playlist.c2
-rw-r--r--playlist.h2
-rw-r--r--plugins/mpgmad/mpgmad.c210
5 files changed, 118 insertions, 115 deletions
diff --git a/deadbeef.h b/deadbeef.h
index 05fb499c..d51fb4e4 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -74,8 +74,6 @@ typedef struct {
float timestart; // start time of cue track, or -1
float timeend; // end time of cue track, or -1
float duration; // in seconds
- int startoffset; // offset to seek to skip tags and info-headers
- int endoffset; // offset from end of file where music data ends
int shufflerating; // sort order for shuffle mode
float playtime; // total playtime
time_t started_timestamp; // result of calling time(NULL)
diff --git a/junklib.c b/junklib.c
index 43bf6668..822d9794 100644
--- a/junklib.c
+++ b/junklib.c
@@ -482,9 +482,10 @@ junk_read_id3v1 (playItem_t *it, FILE *fp) {
pl_add_meta (it, "track", s);
}
- if (it->endoffset < 128) {
- it->endoffset = 128;
- }
+// FIXME: that should be accounted for
+// if (it->endoffset < 128) {
+// it->endoffset = 128;
+// }
return 0;
}
@@ -678,11 +679,11 @@ junk_read_id3v2 (playItem_t *it, FILE *fp) {
return -1; // bad header
}
uint32_t size = (header[9] << 0) | (header[8] << 7) | (header[7] << 14) | (header[6] << 21);
- int startoffset = size + 10 + 10 * footerpresent;
- if (startoffset > it->startoffset) {
- it->startoffset = startoffset;
-// fprintf (stderr, "id3v2 end: %x\n", startoffset);
- }
+ // FIXME: that should be accounted for
+// int startoffset = size + 10 + 10 * footerpresent;
+// if (startoffset > it->startoffset) {
+// it->startoffset = startoffset;
+// }
// fprintf (stderr, "tag size: %d\n", size);
diff --git a/playlist.c b/playlist.c
index 080a28b8..238260b2 100644
--- a/playlist.c
+++ b/playlist.c
@@ -605,8 +605,6 @@ pl_item_copy (playItem_t *out, playItem_t *it) {
out->timestart = it->timestart;
out->timeend = it->timeend;
out->duration = it->duration;
- out->startoffset = it->startoffset;
- out->endoffset = it->endoffset;
out->shufflerating = it->shufflerating;
out->filetype = it->filetype;
out->started_timestamp = it->started_timestamp;
diff --git a/playlist.h b/playlist.h
index 21754102..660621ff 100644
--- a/playlist.h
+++ b/playlist.h
@@ -40,8 +40,6 @@ typedef struct playItem_s {
float timestart; // start time of cue track, or -1
float timeend; // end time of cue track, or -1
float duration; // in seconds
- int startoffset; // offset to seek to skip tags and info-headers (mp3)
- int endoffset; // offset from end of file where music data ends (mp3)
int shufflerating; // sort order for shuffle mode
float playtime; // total playtime
time_t started_timestamp; // result of calling time(NULL)
diff --git a/plugins/mpgmad/mpgmad.c b/plugins/mpgmad/mpgmad.c
index c083b2c8..661bfab2 100644
--- a/plugins/mpgmad/mpgmad.c
+++ b/plugins/mpgmad/mpgmad.c
@@ -79,6 +79,8 @@ typedef struct {
float duration;
int startoffset;
int endoffset;
+ int startsample;
+ int endsample;
#if 0
// only for xing/lame header
uint32_t frames;
@@ -106,101 +108,6 @@ static struct mad_synth synth;
static int
cmp3_decode (void);
-static int
-cmp3_scan_stream (buffer_t *buffer, float position);
-
-static int
-cmp3_init (DB_playItem_t *it) {
- memset (&buffer, 0, sizeof (buffer));
- buffer.file = fopen (it->fname, "rb");
- if (!buffer.file) {
- return -1;
- }
- buffer.startoffset = it->startoffset;
- buffer.endoffset = it->endoffset;
- buffer.remaining = 0;
- //buffer.output = NULL;
- buffer.readsize = 0;
- buffer.cachefill = 0;
- buffer.cachepos = 0;
- plugin.info.readpos = 0;
- mad_timer_reset(&buffer.timer);
-
-// fseek (buffer.file, buffer.startoffset, SEEK_SET);
- if (it->timeend > 0) {
- buffer.timestart = it->timestart;
- buffer.timeend = it->timeend;
- // that comes from cue, don't calc duration, just seek and play
- cmp3_scan_stream (&buffer, it->timestart);
- mad_timer_reset(&buffer.timer);
- }
- else {
- it->duration = cmp3_scan_stream (&buffer, -1); // scan entire stream, calc duration
- buffer.timestart = 0;
- buffer.timeend = it->duration;
- fseek (buffer.file, buffer.startoffset, SEEK_SET);
- }
- if (buffer.samplerate == 0) {
- //fprintf (stderr, "bad mpeg file: %f\n", it->fname);
- fclose (buffer.file);
- return -1;
- }
- plugin.info.bps = buffer.bitspersample;
- plugin.info.samplerate = buffer.samplerate;
- plugin.info.channels = buffer.channels;
-
- mad_stream_init(&stream);
- mad_frame_init(&frame);
- mad_synth_init(&synth);
-
- return 0;
-}
-
-/****************************************************************************
- * Converts a sample from libmad's fixed point number format to a signed *
- * short (16 bits). *
- ****************************************************************************/
-static inline int16_t
-MadFixedToSshort(mad_fixed_t Fixed)
-{
- /* A fixed point number is formed of the following bit pattern:
- *
- * SWWWFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- * MSB LSB
- * S ==> Sign (0 is positive, 1 is negative)
- * W ==> Whole part bits
- * F ==> Fractional part bits
- *
- * This pattern contains MAD_F_FRACBITS fractional bits, one
- * should alway use this macro when working on the bits of a fixed
- * point number. It is not guaranteed to be constant over the
- * different platforms supported by libmad.
- *
- * The signed short value is formed, after clipping, by the least
- * significant whole part bit, followed by the 15 most significant
- * fractional part bits. Warning: this is a quick and dirty way to
- * compute the 16-bit number, madplay includes much better
- * algorithms.
- */
-
- /* Clipping */
- if(Fixed>=MAD_F_ONE)
- return(32767);
- if(Fixed<=-MAD_F_ONE)
- return(-32768);
-
- /* Conversion. */
- Fixed=Fixed>>(MAD_F_FRACBITS-15);
- return((signed short)Fixed);
-}
-
-static inline float
-MadFixedToFloat (mad_fixed_t Fixed) {
- return (float)((Fixed) / (float)(1L << MAD_F_FRACBITS));
-}
-
-#define MadErrorString(x) mad_stream_errorstr(x)
-
static uint32_t
extract_i32 (unsigned char *buf)
{
@@ -262,10 +169,13 @@ extract_f32 (unsigned char *buf) {
return f;
}
-// function scans file and calculates duration
-// if position >= 0 -- scanning is stopped after duration is greater than position
+// sample=-1: scan entire stream, calculate precise duration
+// sample=0: read headers/tags, calculate approximate duration
+// sample>0: seek to the frame with the sample, update skipsamples
+// return value: -1 on error
static int
cmp3_scan_stream (buffer_t *buffer, float position) {
+ int totalsamples = 0;
int nframe = 0;
int nskipped = 0;
float duration = 0;
@@ -273,7 +183,7 @@ cmp3_scan_stream (buffer_t *buffer, float position) {
int nseeks = 0;
int pos = ftell (buffer->file);
- if (pos <= 0) {
+ if (pos == 0) {
// try to skip id3v2
int skip = deadbeef->junk_get_leading_size (buffer->file);
if (skip > 0) {
@@ -511,6 +421,103 @@ cmp3_scan_stream (buffer_t *buffer, float position) {
return duration;
}
+
+static int
+cmp3_init (DB_playItem_t *it) {
+ memset (&buffer, 0, sizeof (buffer));
+ buffer.file = fopen (it->fname, "rb");
+ if (!buffer.file) {
+ return -1;
+ }
+ buffer.remaining = 0;
+ //buffer.output = NULL;
+ buffer.readsize = 0;
+ buffer.cachefill = 0;
+ buffer.cachepos = 0;
+ plugin.info.readpos = 0;
+ mad_timer_reset(&buffer.timer);
+
+// fseek (buffer.file, buffer.startoffset, SEEK_SET);
+ if (it->timeend > 0) {
+ buffer.timestart = it->timestart;
+ buffer.timeend = it->timeend;
+ buffer.startsample = it->startsample;
+ buffer.endsample = it->endsample;
+ // that comes from cue, don't calc duration, just seek and play
+ plugin.seek_sample (0);
+// cmp3_scan_stream (&buffer, it->timestart);
+// mad_timer_reset(&buffer.timer);
+ }
+ else {
+ cmp3_scan_stream (&buffer, -1); // scan entire stream, calc duration
+ it->duration = buffer.duration;
+ buffer.timestart = 0;
+ buffer.timeend = it->duration;
+ buffer.startsample = 0;
+ buffer.endsample = it->duration * buffer.samplerate - 1;
+ fseek (buffer.file, buffer.startoffset, SEEK_SET);
+ }
+ if (buffer.samplerate == 0) {
+ //fprintf (stderr, "bad mpeg file: %f\n", it->fname);
+ fclose (buffer.file);
+ return -1;
+ }
+ plugin.info.bps = buffer.bitspersample;
+ plugin.info.samplerate = buffer.samplerate;
+ plugin.info.channels = buffer.channels;
+
+ mad_stream_init(&stream);
+ mad_frame_init(&frame);
+ mad_synth_init(&synth);
+
+ return 0;
+}
+
+/****************************************************************************
+ * Converts a sample from libmad's fixed point number format to a signed *
+ * short (16 bits). *
+ ****************************************************************************/
+static inline int16_t
+MadFixedToSshort(mad_fixed_t Fixed)
+{
+ /* A fixed point number is formed of the following bit pattern:
+ *
+ * SWWWFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ * MSB LSB
+ * S ==> Sign (0 is positive, 1 is negative)
+ * W ==> Whole part bits
+ * F ==> Fractional part bits
+ *
+ * This pattern contains MAD_F_FRACBITS fractional bits, one
+ * should alway use this macro when working on the bits of a fixed
+ * point number. It is not guaranteed to be constant over the
+ * different platforms supported by libmad.
+ *
+ * The signed short value is formed, after clipping, by the least
+ * significant whole part bit, followed by the 15 most significant
+ * fractional part bits. Warning: this is a quick and dirty way to
+ * compute the 16-bit number, madplay includes much better
+ * algorithms.
+ */
+
+ /* Clipping */
+ if(Fixed>=MAD_F_ONE)
+ return(32767);
+ if(Fixed<=-MAD_F_ONE)
+ return(-32768);
+
+ /* Conversion. */
+ Fixed=Fixed>>(MAD_F_FRACBITS-15);
+ return((signed short)Fixed);
+}
+
+static inline float
+MadFixedToFloat (mad_fixed_t Fixed) {
+ return (float)((Fixed) / (float)(1L << MAD_F_FRACBITS));
+}
+
+#define MadErrorString(x) mad_stream_errorstr(x)
+
static int
cmp3_decode (void) {
int eof = 0;
@@ -729,7 +736,10 @@ cmp3_seek (float time) {
mad_synth_finish (&synth);
mad_frame_finish (&frame);
mad_stream_finish (&stream);
- fseek(buffer.file, buffer.startoffset, SEEK_SET);
+ int skip = deadbeef->junk_get_leading_size (buffer.file);
+ if (skip > 0) {
+ fseek(buffer.file, skip, SEEK_SET);
+ }
mad_stream_init(&stream);
mad_frame_init(&frame);
mad_synth_init(&synth);
@@ -975,7 +985,6 @@ cmp3_insert (DB_playItem_t *after, const char *fname) {
}
int apeerr = deadbeef->junk_read_ape (it, fp);
deadbeef->pl_add_meta (it, "title", NULL);
- it->startoffset = buffer.startoffset;
it->duration = buffer.duration;
it->filetype = ftype;
@@ -1001,7 +1010,6 @@ static DB_decoder_t plugin = {
.plugin.website = "http://deadbeef.sf.net",
.init = cmp3_init,
.free = cmp3_free,
-// .read = cmp3_read,
.read_int16 = cmp3_read,
.read_float32 = cmp3_read_float32,
.seek = cmp3_seek,