summaryrefslogtreecommitdiff
path: root/plugins/flac
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2010-11-24 22:52:07 +0100
committerGravatar waker <wakeroid@gmail.com>2010-11-24 22:52:07 +0100
commit6ca06a612a349229bc61cc811284fd51cadfe7bf (patch)
tree4a9ce0a18bb36968a5589bafeef81be517e1e24d /plugins/flac
parent9aa1f87dbdd01832e7e4d65fecb72222f8e890d4 (diff)
ported flac plugin to new API
Diffstat (limited to 'plugins/flac')
-rw-r--r--plugins/flac/flac.c134
1 files changed, 74 insertions, 60 deletions
diff --git a/plugins/flac/flac.c b/plugins/flac/flac.c
index 1de1f443..f427ef1c 100644
--- a/plugins/flac/flac.c
+++ b/plugins/flac/flac.c
@@ -104,24 +104,52 @@ cflac_write_callback (const FLAC__StreamDecoder *decoder, const FLAC__Frame *fra
if (info->bitrate > 0) {
deadbeef->streamer_set_bitrate (info->bitrate);
}
+ int samplesize = _info->fmt.channels * _info->fmt.bps / 8;
int bufsize = BUFFERSIZE - info->remaining;
- int bufsamples = bufsize / (_info->channels * _info->bps / 8);
+ int bufsamples = bufsize / samplesize;
int nsamples = min (bufsamples, frame->header.blocksize);
char *bufptr = &info->buffer[info->remaining];
- float mul = 1.f/ ((1 << (_info->bps-1))-1);
- int channels = _info->channels;
- if (channels > 2) {
- channels = 2;
- }
- int readbytes = frame->header.blocksize * channels * _info->bps / 8;
+ int readbytes = frame->header.blocksize * samplesize;
- for (int i = 0; i < nsamples; i++) {
- for (int c = 0; c < channels; c++) {
- int32_t sample = inputbuffer[c][i];
- *((float*)bufptr) = sample * mul;
- bufptr += sizeof (float);
- info->remaining += sizeof (float);
+ if (_info->fmt.bps == 32) {
+ for (int i = 0; i < nsamples; i++) {
+ for (int c = 0; c < _info->fmt.channels; c++) {
+ int32_t sample = inputbuffer[c][i];
+ *((int32_t*)bufptr) = sample;
+ bufptr += 4;
+ info->remaining += 4;
+ }
+ }
+ }
+ else if (_info->fmt.bps == 24) {
+ for (int i = 0; i < nsamples; i++) {
+ for (int c = 0; c < _info->fmt.channels; c++) {
+ int32_t sample = inputbuffer[c][i];
+ *bufptr++ = sample&0xff;
+ *bufptr++ = (sample&0xff00)>>8;
+ *bufptr++ = (sample&0xff0000)>>16;
+ info->remaining += 3;
+ }
+ }
+ }
+ else if (_info->fmt.bps == 16) {
+ for (int i = 0; i < nsamples; i++) {
+ for (int c = 0; c < _info->fmt.channels; c++) {
+ int32_t sample = inputbuffer[c][i];
+ *bufptr++ = sample&0xff;
+ *bufptr++ = (sample&0xff00)>>8;
+ info->remaining += 2;
+ }
+ }
+ }
+ else if (_info->fmt.bps == 8) {
+ for (int i = 0; i < nsamples; i++) {
+ for (int c = 0; c < _info->fmt.channels; c++) {
+ int32_t sample = inputbuffer[c][i];
+ *bufptr++ = sample&0xff;
+ info->remaining += 1;
+ }
}
}
if (readbytes > bufsize) {
@@ -136,9 +164,10 @@ cflac_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMe
DB_fileinfo_t *_info = (DB_fileinfo_t *)client_data;
flac_info_t *info = (flac_info_t *)_info;
info->totalsamples = metadata->data.stream_info.total_samples;
- _info->samplerate = metadata->data.stream_info.sample_rate;
- _info->channels = metadata->data.stream_info.channels;
- _info->bps = metadata->data.stream_info.bits_per_sample;
+ _info->fmt.samplerate = metadata->data.stream_info.sample_rate;
+ _info->fmt.channels = metadata->data.stream_info.channels;
+ _info->fmt.bps = metadata->data.stream_info.bits_per_sample;
+ _info->fmt.channelmask = _info->fmt.channels == 1 ? DDB_SPEAKER_FRONT_LEFT : (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT);
}
@@ -164,7 +193,7 @@ cflac_init_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecode
}
static DB_fileinfo_t *
-cflac_open (void) {
+cflac_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (flac_info_t));
memset (_info, 0, sizeof (flac_info_t));
return _info;
@@ -237,7 +266,7 @@ cflac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
trace ("cflac_init bad decoder status\n");
return -1;
}
- //_info->samplerate = -1;
+ //_info->fmt.samplerate = -1;
if (!FLAC__stream_decoder_process_until_end_of_metadata (info->decoder)) {
trace ("cflac_init metadata failed\n");
return -1;
@@ -247,7 +276,7 @@ cflac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
_info->plugin = &plugin;
_info->readpos = 0;
- if (_info->samplerate <= 0) { // not a FLAC stream
+ if (_info->fmt.samplerate <= 0) { // not a FLAC stream
fprintf (stderr, "corrupted/invalid flac stream\n");
return -1;
}
@@ -260,7 +289,7 @@ cflac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
fsize -= position;
}
FLAC__uint64 flac_totalsamples = FLAC__stream_decoder_get_total_samples (info->decoder);
- float sec = flac_totalsamples / _info->samplerate;
+ float sec = flac_totalsamples / _info->fmt.samplerate;
if (sec > 0) {
info->bitrate = fsize / sec * 8 / 1000;
}
@@ -309,48 +338,31 @@ cflac_free (DB_fileinfo_t *_info) {
}
static int
-cflac_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+cflac_read (DB_fileinfo_t *_info, char *bytes, int size) {
flac_info_t *info = (flac_info_t *)_info;
- if (size / (2 * _info->channels) + info->currentsample > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 2 * _info->channels;
+ int samplesize = _info->fmt.channels * _info->fmt.bps / 8;
+ if (size / samplesize + info->currentsample > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * samplesize;
trace ("size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample);
if (size <= 0) {
return 0;
}
}
- int n_output_channels = _info->channels;
- if (n_output_channels > 2) {
- n_output_channels = 2;
- }
int initsize = size;
do {
if (info->remaining) {
- int n_input_frames = info->remaining / sizeof (float) / n_output_channels;
- int n_output_frames = size / n_output_channels / sizeof (int16_t);
- int n = min (n_input_frames, n_output_frames);
+ int sz = min(size, info->remaining);
+ memcpy (bytes, info->buffer, sz);
-// trace ("flac: [1] if=%d, of=%d, n=%d, rem=%d, size=%d\n", n_input_frames, n_output_frames, n, info->remaining, size);
- // convert from float to int16
- float *in = (float *)info->buffer;
- for (int i = 0; i < n; i++) {
- *((int16_t *)bytes) = (int16_t)((*in) * 0x7fff);
- size -= sizeof (int16_t);
- bytes += sizeof (int16_t);
- if (n_output_channels == 2) {
- *((int16_t *)bytes) = (int16_t)((*(in+1)) * 0x7fff);
- size -= sizeof (int16_t);
- bytes += sizeof (int16_t);
- }
- in += n_output_channels;
- }
- int sz = n * sizeof (float) * n_output_channels;
+ size -= sz;
+ bytes += sz;
if (sz < info->remaining) {
memmove (info->buffer, &info->buffer[sz], info->remaining - sz);
}
info->remaining -= sz;
- info->currentsample += n;
- _info->readpos += (float)n / _info->samplerate;
-// trace ("flac: [2] if=%d, of=%d, n=%d, rem=%d, size=%d\n", n_input_frames, n_output_frames, n, info->remaining, size);
+ int n = sz / samplesize;
+ info->currentsample += sz / samplesize;
+ _info->readpos += (float)n / _info->fmt.samplerate;
}
if (!size) {
break;
@@ -372,17 +384,18 @@ cflac_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
return initsize - size;
}
+#if 0
static int
cflac_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) {
flac_info_t *info = (flac_info_t *)_info;
- if (size / (4 * _info->channels) + info->currentsample > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 4 * _info->channels;
+ if (size / (4 * _info->fmt.channels) + info->currentsample > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * 4 * _info->fmt.channels;
trace ("size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample);
if (size <= 0) {
return 0;
}
}
- int n_output_channels = _info->channels;
+ int n_output_channels = _info->fmt.channels;
if (n_output_channels > 2) {
n_output_channels = 2;
}
@@ -411,7 +424,7 @@ cflac_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) {
}
info->remaining -= sz;
info->currentsample += n;
- _info->readpos += (float)n / _info->samplerate;
+ _info->readpos += (float)n / _info->fmt.samplerate;
}
if (!size) {
break;
@@ -432,6 +445,7 @@ cflac_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) {
return initsize - size;
}
+#endif
static int
cflac_seek_sample (DB_fileinfo_t *_info, int sample) {
@@ -442,13 +456,13 @@ cflac_seek_sample (DB_fileinfo_t *_info, int sample) {
if (!FLAC__stream_decoder_seek_absolute (info->decoder, (FLAC__uint64)(sample))) {
return -1;
}
- _info->readpos = (float)(sample - info->startsample)/ _info->samplerate;
+ _info->readpos = (float)(sample - info->startsample)/ _info->fmt.samplerate;
return 0;
}
static int
cflac_seek (DB_fileinfo_t *_info, float time) {
- return cflac_seek_sample (_info, time * _info->samplerate);
+ return cflac_seek_sample (_info, time * _info->fmt.samplerate);
}
static FLAC__StreamDecoderWriteStatus
@@ -509,8 +523,8 @@ cflac_init_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__Str
//it->tracknum = 0;
if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
trace ("flac: samplerate=%d, channels=%d\n", metadata->data.stream_info.sample_rate, metadata->data.stream_info.channels);
- _info->samplerate = metadata->data.stream_info.sample_rate;
- _info->channels = metadata->data.stream_info.channels;
+ _info->fmt.samplerate = metadata->data.stream_info.sample_rate;
+ _info->fmt.channels = metadata->data.stream_info.channels;
info->totalsamples = metadata->data.stream_info.total_samples;
deadbeef->pl_set_item_duration (it, metadata->data.stream_info.total_samples / (float)metadata->data.stream_info.sample_rate);
}
@@ -653,7 +667,7 @@ cflac_insert (DB_playItem_t *after, const char *fname) {
// try embedded cue
const char *cuesheet = deadbeef->pl_find_meta (it, "cuesheet");
if (cuesheet) {
- DB_playItem_t *last = deadbeef->pl_insert_cue_from_buffer (after, it, cuesheet, strlen (cuesheet), info.totalsamples, info.info.samplerate);
+ DB_playItem_t *last = deadbeef->pl_insert_cue_from_buffer (after, it, cuesheet, strlen (cuesheet), info.totalsamples, info.info.fmt.samplerate);
if (last) {
deadbeef->pl_item_unref (it);
deadbeef->pl_item_unref (last);
@@ -662,7 +676,7 @@ cflac_insert (DB_playItem_t *after, const char *fname) {
}
// try external cue
- DB_playItem_t *cue_after = deadbeef->pl_insert_cue (after, it, info.totalsamples, info.info.samplerate);
+ DB_playItem_t *cue_after = deadbeef->pl_insert_cue (after, it, info.totalsamples, info.info.fmt.samplerate);
if (cue_after) {
if (info.file) {
deadbeef->fclose (info.file);
@@ -849,8 +863,8 @@ static DB_decoder_t plugin = {
.open = cflac_open,
.init = cflac_init,
.free = cflac_free,
- .read_int16 = cflac_read_int16,
- .read_float32 = cflac_read_float32,
+ .read = cflac_read,
+// .read_float32 = cflac_read_float32,
.seek = cflac_seek,
.seek_sample = cflac_seek_sample,
.insert = cflac_insert,