summaryrefslogtreecommitdiff
path: root/plugins/flac
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/flac')
-rw-r--r--plugins/flac/flac.c59
1 files changed, 37 insertions, 22 deletions
diff --git a/plugins/flac/flac.c b/plugins/flac/flac.c
index 3e688446..ddf8e02c 100644
--- a/plugins/flac/flac.c
+++ b/plugins/flac/flac.c
@@ -24,6 +24,9 @@
static DB_decoder_t plugin;
static DB_functions_t *deadbeef;
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
+
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
@@ -35,6 +38,7 @@ static float timestart;
static float timeend;
static int startsample;
static int endsample;
+static int currentsample;
typedef struct {
DB_playItem_t *after;
@@ -154,18 +158,23 @@ cflac_init (DB_playItem_t *it) {
cflac_free ();
return -1;
}
- if (timeend > timestart || timeend < 0) {
+ if (it->timeend > 0) {
timestart = it->timestart;
timeend = it->timeend;
startsample = it->startsample;
endsample = it->endsample;
- plugin.seek_sample (0);
+ if (plugin.seek_sample (0) < 0) {
+ cflac_free ();
+ return -1;
+ }
}
else {
timestart = 0;
timeend = it->duration;
startsample = 0;
endsample = cb.totalsamples-1;
+ currentsample = 0;
+ trace ("startsample=%d, endsample=%d\n", startsample, endsample);
}
plugin.info.readpos = 0;
@@ -184,12 +193,22 @@ cflac_free (void) {
static int
cflac_read_int16 (char *bytes, int size) {
int initsize = size;
- int nsamples = size / (plugin.info.channels * plugin.info.bps / 8);
- if (timeend > timestart) {
- if (plugin.info.readpos + timestart > timeend) {
+ if (size / (2 * plugin.info.channels) + currentsample > endsample) {
+ size = (endsample - currentsample + 1) * 2 * plugin.info.channels;
+ trace ("size truncated to %d bytes, cursample=%d, endsample=%d\n", size, currentsample, endsample);
+ if (size <= 0) {
return 0;
}
}
+// int nsamples = size / (plugin.info.channels * plugin.info.bps / 8);
+// if (currentsample + nsamples > endsample) {
+// nsamples = endsample-currentsample+1;
+// }
+// if (timeend > timestart) {
+// if (plugin.info.readpos + timestart > timeend) {
+// return 0;
+// }
+// }
do {
if (remaining) {
int s = size * 2;
@@ -206,12 +225,13 @@ cflac_read_int16 (char *bytes, int size) {
memmove (buffer, &buffer[sz], remaining-sz);
}
remaining -= sz;
+ currentsample += sz / (2 * plugin.info.channels);
plugin.info.readpos += (float)sz / (plugin.info.channels * plugin.info.samplerate * sizeof (float));
- if (timeend > timestart) {
- if (plugin.info.readpos + timestart > timeend) {
- break;
- }
- }
+// if (timeend > timestart) {
+// if (plugin.info.readpos + timestart > timeend) {
+// break;
+// }
+// }
}
if (!size) {
break;
@@ -268,27 +288,22 @@ cflac_read_float32 (char *bytes, int size) {
}
static int
-cflac_seek (float time) {
- time += timestart;
- if (!FLAC__stream_decoder_seek_absolute (decoder, (FLAC__uint64)(time * plugin.info.samplerate))) {
- return -1;
- }
- remaining = 0;
- plugin.info.readpos = time - timestart;
- return 0;
-}
-
-static int
cflac_seek_sample (int sample) {
sample += startsample;
if (!FLAC__stream_decoder_seek_absolute (decoder, (FLAC__uint64)(sample))) {
return -1;
}
remaining = 0;
+ currentsample = sample;
plugin.info.readpos = (float)sample / plugin.info.samplerate - timestart;
return 0;
}
+static int
+cflac_seek (float time) {
+ return cflac_seek_sample (time * plugin.info.samplerate);
+}
+
static FLAC__StreamDecoderWriteStatus
cflac_init_write_callback (const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const inputbuffer[], void *client_data) {
if (frame->header.blocksize == 0 || cflac_init_stop_decoding) {
@@ -492,7 +507,7 @@ static DB_decoder_t plugin = {
.init = cflac_init,
.free = cflac_free,
.read_int16 = cflac_read_int16,
- .read_float32 = cflac_read_float32,
+// .read_float32 = cflac_read_float32,
.seek = cflac_seek,
.seek_sample = cflac_seek_sample,
.insert = cflac_insert,