summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2009-08-18 19:36:42 +0200
committerGravatar waker <wakeroid@gmail.com>2009-08-18 19:36:42 +0200
commit9cededd13631d65ca000bab0af2e03d124cff147 (patch)
tree6bde145ea44fb4469fc522e71ef958ad19b9a7b4
parent3521608a59f6264f1acf0efb69a51ee314795c0d (diff)
mp3/cue works
-rw-r--r--cmp3.c28
-rw-r--r--palsa.c2
-rw-r--r--streamer.c16
-rw-r--r--streamer.h3
4 files changed, 43 insertions, 6 deletions
diff --git a/cmp3.c b/cmp3.c
index 35bd033c..a2c88b87 100644
--- a/cmp3.c
+++ b/cmp3.c
@@ -44,6 +44,10 @@
typedef struct {
FILE *file;
+ // cuesheet info
+ float timestart;
+ float timeend;
+
// input buffer, for MPEG data
mad_timer_t timer;
char input[READBUFFER];
@@ -67,6 +71,7 @@ typedef struct {
int bitspersample;
int channels;
float duration;
+ float trackduration;
int startoffset;
int endoffset;
#if 0
@@ -101,6 +106,7 @@ cmp3_scan_stream (buffer_t *buffer, float position);
int
cmp3_init (struct playItem_s *it) {
+ memset (&buffer, 0, sizeof (buffer));
buffer.file = fopen (it->fname, "rb");
buffer.startoffset = it->startoffset;
buffer.endoffset = it->endoffset;
@@ -115,11 +121,21 @@ cmp3_init (struct playItem_s *it) {
mad_timer_reset(&buffer.timer);
fseek (buffer.file, buffer.startoffset, SEEK_SET);
- it->duration = cmp3_scan_stream (&buffer, -1); // scan entire stream, calc duration
+ if (it->timeend > 0) {
+ buffer.timestart = it->timestart;
+ buffer.timeend = it->timeend;
+ buffer.trackduration = it->duration;
+ printf ("duration: %f\n", it->duration);
+ // that comes from cue, don't calc duration, just seek and play
+ cmp3_scan_stream (&buffer, it->timestart);
+ }
+ else {
+ buffer.trackduration = it->duration = cmp3_scan_stream (&buffer, -1); // scan entire stream, calc duration
+ fseek (buffer.file, buffer.startoffset, SEEK_SET);
+ }
cmp3.info.bitsPerSample = buffer.bitspersample;
cmp3.info.samplesPerSecond = buffer.samplerate;
cmp3.info.channels = buffer.channels;
- fseek (buffer.file, buffer.startoffset, SEEK_SET);
mad_stream_init(&stream);
mad_frame_init(&frame);
@@ -598,11 +614,15 @@ cmp3_read (char *bytes, int size) {
ret += cmp3_decode ();
cmp3.info.readposition = (float)buffer.timer.seconds + (float)buffer.timer.fraction / MAD_TIMER_RESOLUTION;
}
+ if (cmp3.info.readposition >= buffer.trackduration) {
+ return 0;
+ }
return ret;
}
int
cmp3_seek (float time) {
+ time += buffer.timestart;
if (!buffer.file) {
return -1;
}
@@ -625,7 +645,11 @@ cmp3_seek (float time) {
cmp3.info.readposition = 0;
return -1;
}
+ // fixup timer
cmp3.info.readposition = (float)buffer.timer.seconds + (float)buffer.timer.fraction / MAD_TIMER_RESOLUTION;
+ cmp3.info.readposition -= buffer.timestart;
+ buffer.timer.seconds = (int)cmp3.info.readposition;
+ buffer.timer.fraction = (cmp3.info.readposition - buffer.timer.seconds) * MAD_TIMER_RESOLUTION;
return 0;
}
diff --git a/palsa.c b/palsa.c
index b1229e0d..0457bbb7 100644
--- a/palsa.c
+++ b/palsa.c
@@ -342,7 +342,7 @@ palsa_thread (uintptr_t context) {
static void
palsa_callback (char *stream, int len) {
- if (streamer_get_fill () < len) {
+ if (!streamer_ok_to_read (len)) {
memset (stream, 0, len);
return;
}
diff --git a/streamer.c b/streamer.c
index 9d03aa2c..9aa4d68d 100644
--- a/streamer.c
+++ b/streamer.c
@@ -300,10 +300,12 @@ streamer_read_async (char *bytes, int size) {
if (size == 0) {
return initsize;
}
- else {
+ else {
// that means EOF
- bytes_until_next_song = streambuffer_fill;
- pl_nextsong (0);
+ if (bytes_until_next_song == 0) {
+ bytes_until_next_song = streambuffer_fill;
+ pl_nextsong (0);
+ }
break;
}
}
@@ -347,6 +349,14 @@ streamer_get_fill (void) {
}
int
+streamer_ok_to_read (int len) {
+ if (bytes_until_next_song > 0) {
+ return 1;
+ }
+ return streambuffer_fill >= len;
+}
+
+int
streamer_is_buffering (void) {
if (streambuffer_fill < 16384) {
return 1;
diff --git a/streamer.h b/streamer.h
index 9a3fbc1c..34e5fb02 100644
--- a/streamer.h
+++ b/streamer.h
@@ -49,6 +49,9 @@ streamer_set_seek (float pos);
int
streamer_get_fill (void);
+int
+streamer_ok_to_read (int len);
+
float
streamer_get_playpos (void);