summaryrefslogtreecommitdiff
path: root/plugins/sndfile
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-08-14 09:34:19 +0200
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-08-14 09:34:19 +0200
commit38b7d3e6b6cd94486f1354cfd514f696a86b1a49 (patch)
tree1f78f20fda97181bbc1274068889fd3b8fa1c70a /plugins/sndfile
parent93f6591c6f471c5b0c84abefeb2be2d8034c8855 (diff)
fixed multichannel decoding in sndfile plugin
Diffstat (limited to 'plugins/sndfile')
-rw-r--r--plugins/sndfile/sndfile.c54
1 files changed, 44 insertions, 10 deletions
diff --git a/plugins/sndfile/sndfile.c b/plugins/sndfile/sndfile.c
index 0cb48675..90390603 100644
--- a/plugins/sndfile/sndfile.c
+++ b/plugins/sndfile/sndfile.c
@@ -174,16 +174,34 @@ sndfile_free (DB_fileinfo_t *_info) {
static int
sndfile_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
sndfile_info_t *info = (sndfile_info_t*)_info;
- if (size / (2 * _info->channels) + info->currentsample > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 2 * _info->channels;
- trace ("wv: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample);
+ int out_ch = min (_info->channels, 2);
+ if (size / (2 * out_ch) + info->currentsample > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * 2 * out_ch;
+ trace ("sndfile: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample);
if (size <= 0) {
return 0;
}
}
- int n = sf_readf_short (info->ctx, (short *)bytes, size/(2*_info->channels));
+
+ int n = 0;
+ if (out_ch != _info->channels) {
+ // read into temp buffer, and downmix
+ int nframes = size / out_ch / 2;
+ int16_t buf[nframes * _info->channels];
+ n = sf_readf_short (info->ctx, buf, nframes);
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < out_ch; j++) {
+ ((int16_t *)bytes)[i * out_ch + j] = buf[i * _info->channels + j];
+ }
+ }
+ }
+ else {
+ n = sf_readf_short (info->ctx, (short *)bytes, size/(2*_info->channels));
+ }
info->currentsample += n;
- size = n * 2 * _info->channels;
+
+
+ size = n * 2 * out_ch;
_info->readpos = (float)(info->currentsample-info->startsample)/_info->samplerate;
if (info->bitrate > 0) {
deadbeef->streamer_set_bitrate (info->bitrate);
@@ -194,16 +212,32 @@ sndfile_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
static int
sndfile_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) {
sndfile_info_t *info = (sndfile_info_t*)_info;
- if (size / (4 * _info->channels) + info->currentsample > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 4 * _info->channels;
- trace ("wv: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample);
+ int out_ch = min (_info->channels, 2);
+ if (size / (4 * out_ch) + info->currentsample > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * 4 * out_ch;
+ trace ("sndfile: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample);
if (size <= 0) {
return 0;
}
}
- int n = sf_readf_float (info->ctx, (float *)bytes, size/(4*_info->channels));
+ int n = 0;
+ if (out_ch != _info->channels) {
+ // read into temp buffer, and downmix
+ int nframes = size / out_ch / 4;
+ float buf[nframes * _info->channels];
+ n = sf_readf_float (info->ctx, buf, nframes);
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < out_ch; j++) {
+ ((float *)bytes)[i * out_ch + j] = buf[i * _info->channels + j];
+ }
+ }
+ }
+ else {
+ n = sf_readf_float (info->ctx, (float *)bytes, size/(4*_info->channels));
+ }
+
info->currentsample += n;
- size = n * 4 * _info->channels;
+ size = n * 4 * out_ch;
_info->readpos = (float)(info->currentsample-info->startsample)/_info->samplerate;
if (info->bitrate > 0) {
deadbeef->streamer_set_bitrate (info->bitrate);