diff options
author | Max Kellermann <max@duempel.org> | 2014-09-19 21:40:22 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2014-09-19 21:44:16 +0200 |
commit | d1a8a4481e81b9c3716e02af8fa245740acfe97b (patch) | |
tree | c0fc2ce98445ddc09864395d4be84450ea6182db | |
parent | 5921ffaa36483d6c532f9c18db96f2e287b9df81 (diff) | |
download | mpd-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-- | NEWS | 2 | ||||
-rw-r--r-- | src/decoder/plugins/SndfileDecoderPlugin.cxx | 36 |
2 files changed, 34 insertions, 4 deletions
@@ -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; |