aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-09-19 21:40:22 +0200
committerMax Kellermann <max@duempel.org>2014-09-19 21:44:16 +0200
commitd1a8a4481e81b9c3716e02af8fa245740acfe97b (patch)
treec0fc2ce98445ddc09864395d4be84450ea6182db
parent5921ffaa36483d6c532f9c18db96f2e287b9df81 (diff)
downloadmpd-d1a8a4481e81b9c3716e02af8fa245740acfe97b.tar.gz
mpd-d1a8a4481e81b9c3716e02af8fa245740acfe97b.tar.xz
mpd-d1a8a4481e81b9c3716e02af8fa245740acfe97b.zip
decoder/sndfile: support float and 16 bit samples
Support these PCM formats natively, instead of letting libsndfile convert everything to 32 bit.
-rw-r--r--NEWS2
-rw-r--r--src/decoder/plugins/SndfileDecoderPlugin.cxx36
2 files changed, 34 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index 0a68d3c80..305cc8841 100644
--- a/NEWS
+++ b/NEWS
@@ -50,6 +50,8 @@ ver 0.19 (not yet released)
- dsf: fix noise at end of malformed file
- sndfile: support scanning remote files
- sndfile: support tags "comment", "album", "track", "genre"
+ - sndfile: native floating point playback
+ - sndfile: optimized 16 bit playback
- mp4v2: support playback of MP4 files.
* encoder:
- shine: new encoder plugin
diff --git a/src/decoder/plugins/SndfileDecoderPlugin.cxx b/src/decoder/plugins/SndfileDecoderPlugin.cxx
index 388c2d594..74567cc82 100644
--- a/src/decoder/plugins/SndfileDecoderPlugin.cxx
+++ b/src/decoder/plugins/SndfileDecoderPlugin.cxx
@@ -150,14 +150,41 @@ gcc_pure
static SampleFormat
sndfile_sample_format(const SF_INFO &info)
{
- (void)info;
- return SampleFormat::S32;
+ fprintf(stderr, "SNDFILE format=%d\n", info.format & SF_FORMAT_SUBMASK);
+
+ switch (info.format & SF_FORMAT_SUBMASK) {
+ case SF_FORMAT_PCM_S8:
+ case SF_FORMAT_PCM_U8:
+ case SF_FORMAT_PCM_16:
+ return SampleFormat::S16;
+
+ case SF_FORMAT_FLOAT:
+ case SF_FORMAT_DOUBLE:
+ return SampleFormat::FLOAT;
+
+ default:
+ return SampleFormat::S32;
+ }
}
static sf_count_t
-sndfile_read_frames(SNDFILE *sf, void *buffer, sf_count_t n_frames)
+sndfile_read_frames(SNDFILE *sf, SampleFormat format,
+ void *buffer, sf_count_t n_frames)
{
- return sf_readf_int(sf, (int *)buffer, n_frames);
+ switch (format) {
+ case SampleFormat::S16:
+ return sf_readf_short(sf, (short *)buffer, n_frames);
+
+ case SampleFormat::S32:
+ return sf_readf_int(sf, (int *)buffer, n_frames);
+
+ case SampleFormat::FLOAT:
+ return sf_readf_float(sf, (float *)buffer, n_frames);
+
+ default:
+ assert(false);
+ gcc_unreachable();
+ }
}
static void
@@ -198,6 +225,7 @@ sndfile_stream_decode(Decoder &decoder, InputStream &is)
do {
sf_count_t num_frames =
sndfile_read_frames(sf,
+ audio_format.format,
buffer, read_frames);
if (num_frames <= 0)
break;