summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/dca/dcaplug.c72
1 files changed, 47 insertions, 25 deletions
diff --git a/plugins/dca/dcaplug.c b/plugins/dca/dcaplug.c
index 3aea033c..4d7d1131 100644
--- a/plugins/dca/dcaplug.c
+++ b/plugins/dca/dcaplug.c
@@ -50,8 +50,8 @@
//#define trace(...) { fprintf (stderr, __VA_ARGS__); }
#define trace(fmt,...)
-static const char * exts[] = { "wav", NULL };
-static const char *filetypes[] = { "DTS WAV", NULL };
+static const char * exts[] = { "wav", "dts", "cpt", NULL };
+static const char *filetypes[] = { "DTS WAV", "DTS", NULL };
enum {
FT_DTSWAV,
@@ -187,7 +187,7 @@ convert_samples (ddb_dca_state_t *state, int flags)
// returns number of frames decoded
static int
-dca_decode_data (ddb_dca_state_t *ddb_state, uint8_t * start, int size)
+dca_decode_data (ddb_dca_state_t *ddb_state, uint8_t * start, int size, int probe)
{
int n_decoded = 0;
uint8_t * end = start + size;
@@ -214,6 +214,9 @@ dca_decode_data (ddb_dca_state_t *ddb_state, uint8_t * start, int size)
}
continue;
}
+ else if (probe) {
+ return length;
+ }
ddb_state->bufpos = ddb_state->buf + length;
}
else {
@@ -360,15 +363,19 @@ dts_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
int totalsamples = -1;
// WAV format
if ((info->offset = dts_open_wav (info->file, &fmt, &totalsamples)) == -1) {
- fprintf (stderr, "dca: unrecognized format in %s\n", it->fname);
- deadbeef->fclose (info->file);
- return -1;
+ // try raw DTS @ 48KHz
+ info->offset = 0;
+ totalsamples = -1;
+ info->wavchannels = 2;
+ _info->bps = 16;
+ }
+ else {
+ _info->bps = fmt.wBitsPerSample;
+ _info->channels = fmt.nChannels;
+ info->wavchannels = fmt.nChannels;
+ _info->samplerate = fmt.nSamplesPerSec;
}
- _info->bps = fmt.wBitsPerSample;
- _info->channels = fmt.nChannels;
- info->wavchannels = fmt.nChannels;
- _info->samplerate = fmt.nSamplesPerSec;
_info->plugin = &plugin;
if (it->endsample > 0) {
@@ -392,11 +399,12 @@ dts_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
// prebuffer 1st piece, and get decoded samplerate and nchannels
uint8_t buffer[BUFFER_SIZE];
size_t rd = deadbeef->fread (buffer, 1, sizeof (buffer), info->file);
- int nsamples = dca_decode_data (info, buffer, rd);
- if (!nsamples) {
- trace ("dca: failed to decode first batch\n");
+ int len = dca_decode_data (info, buffer, rd, 1);
+ if (!len) {
+ trace ("dca: probe failed\n");
return -1;
}
+
_info->channels = channels_multi (info->flags);
_info->samplerate = info->sample_rate;
@@ -421,10 +429,12 @@ dts_free (DB_fileinfo_t *_info) {
static int
dts_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
ddb_dca_state_t *info = (ddb_dca_state_t *)_info;
- if (info->currentsample + size / (2 * _info->channels) > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 2 * _info->channels;
- if (size <= 0) {
- return 0;
+ if (info->endsample >= 0) {
+ if (info->currentsample + size / (2 * _info->channels) > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * 2 * _info->channels;
+ if (size <= 0) {
+ return 0;
+ }
}
}
@@ -459,7 +469,7 @@ dts_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
if (size > 0 && !info->remaining) {
uint8_t buffer[BUFFER_SIZE];
size_t rd = deadbeef->fread (buffer, 1, sizeof (buffer), info->file);
- int nsamples = dca_decode_data (info, buffer, rd);
+ int nsamples = dca_decode_data (info, buffer, rd, 0);
if (!nsamples) {
break;
}
@@ -503,22 +513,27 @@ dts_insert (DB_playItem_t *after, const char *fname) {
fprintf (stderr, "dca: failed to open %s\n", fname);
return NULL;
}
+ int fsize = deadbeef->fgetlength (fp);
wavfmt_t fmt;
int totalsamples = -1;
const char *filetype = NULL;
int offset = 0;
+ double dur = -1;
// WAV format
if ((offset = dts_open_wav (fp, &fmt, &totalsamples)) != -1) {
filetype = filetypes[FT_DTSWAV];
+ dur = (float)totalsamples / fmt.nSamplesPerSec;
}
else {
- fprintf (stderr, "dca: unrecognized format in %s\n", fname);
- goto error;
+ // try raw DTS @ 48KHz
+ offset = 0;
+ filetype = filetypes[FT_DTS];
+ //fprintf (stderr, "dca: unrecognized format in %s\n", fname);
+ //goto error;
}
- double dur = (float)totalsamples / fmt.nSamplesPerSec;
// try to decode piece of file -- that seems to be the only way to check
// it's dts
@@ -534,14 +549,21 @@ dts_insert (DB_playItem_t *after, const char *fname) {
state.gain = 1;
state.bufptr = state.buf;
state.bufpos = state.buf + HEADER_SIZE;
- int dca_frames = dca_decode_data (&state, buffer, size);
+
+ int len = dca_decode_data (&state, buffer, size, 1);
dca_free (state.state);
- trace ("dca: got %d dca frames", dca_frames);
- if (!dca_frames) {
+ if (!len) {
trace ("dca: doesn't seem to be a DTS stream\n");
goto error;
}
+ trace ("dca stream info: len=%d, samplerate=%d, bitrate=%d, framelength=%d\n", len, state.sample_rate, state.bit_rate, state.frame_length);
+
+ // calculate duration
+ if (dur < 0) {
+ totalsamples = fsize / len * state.frame_length;
+ dur = (float)totalsamples / state.sample_rate;
+ }
DB_playItem_t *it = deadbeef->pl_item_alloc ();
it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
@@ -553,7 +575,7 @@ dts_insert (DB_playItem_t *after, const char *fname) {
// embedded cue
DB_playItem_t *cue = NULL;
- cue = deadbeef->pl_insert_cue (after, it, totalsamples, 48000);
+ cue = deadbeef->pl_insert_cue (after, it, totalsamples, state.sample_rate);
if (cue) {
deadbeef->pl_item_unref (it);
deadbeef->pl_item_unref (cue);