diff options
author | Max Kellermann <max@musicpd.org> | 2018-01-02 18:22:53 +0100 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2018-01-02 23:17:25 +0100 |
commit | f6ec43b9ec2a1f64ed09479b60e85bd7d4fdb962 (patch) | |
tree | 95f98b40b95984409e2de699efc6abedcc0fb2a4 /src | |
parent | 6d0d8cf9cf07a5d0905f715be9a79f5de86e8b37 (diff) |
pcm/Resampler: add virtual method Flush()
Wired to Filter::Flush().
Closes #153
Diffstat (limited to 'src')
-rw-r--r-- | src/filter/plugins/ConvertFilterPlugin.cxx | 4 | ||||
-rw-r--r-- | src/pcm/GlueResampler.cxx | 6 | ||||
-rw-r--r-- | src/pcm/GlueResampler.hxx | 2 | ||||
-rw-r--r-- | src/pcm/PcmConvert.cxx | 19 | ||||
-rw-r--r-- | src/pcm/PcmConvert.hxx | 6 | ||||
-rw-r--r-- | src/pcm/Resampler.hxx | 8 | ||||
-rw-r--r-- | src/pcm/SoxrResampler.cxx | 21 | ||||
-rw-r--r-- | src/pcm/SoxrResampler.hxx | 1 |
8 files changed, 67 insertions, 0 deletions
diff --git a/src/filter/plugins/ConvertFilterPlugin.cxx b/src/filter/plugins/ConvertFilterPlugin.cxx index 5e640aaa0..8600ea03d 100644 --- a/src/filter/plugins/ConvertFilterPlugin.cxx +++ b/src/filter/plugins/ConvertFilterPlugin.cxx @@ -55,6 +55,10 @@ public: } ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override; + + ConstBuffer<void> Flush() override { + return state.Flush(); + } }; class PreparedConvertFilter final : public PreparedFilter { diff --git a/src/pcm/GlueResampler.cxx b/src/pcm/GlueResampler.cxx index 36ee4648b..78118feff 100644 --- a/src/pcm/GlueResampler.cxx +++ b/src/pcm/GlueResampler.cxx @@ -81,3 +81,9 @@ GluePcmResampler::Resample(ConstBuffer<void> src) return resampler->Resample(src); } + +ConstBuffer<void> +GluePcmResampler::Flush() +{ + return resampler->Flush(); +} diff --git a/src/pcm/GlueResampler.hxx b/src/pcm/GlueResampler.hxx index 6c81d1886..4c5c918a4 100644 --- a/src/pcm/GlueResampler.hxx +++ b/src/pcm/GlueResampler.hxx @@ -61,6 +61,8 @@ public: void Reset() noexcept; ConstBuffer<void> Resample(ConstBuffer<void> src); + + ConstBuffer<void> Flush(); }; #endif diff --git a/src/pcm/PcmConvert.cxx b/src/pcm/PcmConvert.cxx index a63e92a7c..548c5a9d1 100644 --- a/src/pcm/PcmConvert.cxx +++ b/src/pcm/PcmConvert.cxx @@ -152,3 +152,22 @@ PcmConvert::Convert(ConstBuffer<void> buffer) return buffer; } + +ConstBuffer<void> +PcmConvert::Flush() +{ + if (enable_resampler) { + auto buffer = resampler.Flush(); + if (!buffer.IsNull()) { + if (enable_format) + buffer = format_converter.Convert(buffer); + + if (enable_channels) + buffer = channels_converter.Convert(buffer); + + return buffer; + } + } + + return nullptr; +} diff --git a/src/pcm/PcmConvert.hxx b/src/pcm/PcmConvert.hxx index 264179635..60a85b1d8 100644 --- a/src/pcm/PcmConvert.hxx +++ b/src/pcm/PcmConvert.hxx @@ -81,6 +81,12 @@ public: * @return the destination buffer */ ConstBuffer<void> Convert(ConstBuffer<void> src); + + /** + * Flush pending data and return it. This should be called + * repepatedly until it returns nullptr. + */ + ConstBuffer<void> Flush(); }; void diff --git a/src/pcm/Resampler.hxx b/src/pcm/Resampler.hxx index 485450acc..7f2c5ae4c 100644 --- a/src/pcm/Resampler.hxx +++ b/src/pcm/Resampler.hxx @@ -70,6 +70,14 @@ public: * filter_close() or filter_filter()) */ virtual ConstBuffer<void> Resample(ConstBuffer<void> src) = 0; + + /** + * Flush pending data and return it. This should be called + * repepatedly until it returns nullptr. + */ + virtual ConstBuffer<void> Flush() { + return nullptr; + } }; #endif diff --git a/src/pcm/SoxrResampler.cxx b/src/pcm/SoxrResampler.cxx index 0c887cbdd..6dc80f416 100644 --- a/src/pcm/SoxrResampler.cxx +++ b/src/pcm/SoxrResampler.cxx @@ -160,3 +160,24 @@ SoxrPcmResampler::Resample(ConstBuffer<void> src) return { output_buffer, o_done * frame_size }; } + +ConstBuffer<void> +SoxrPcmResampler::Flush() +{ + const size_t frame_size = channels * sizeof(float); + const size_t o_frames = 1024; + + float *output_buffer = (float *)buffer.Get(o_frames * frame_size); + + size_t o_done; + soxr_error_t e = soxr_process(soxr, nullptr, 0, nullptr, + output_buffer, o_frames, &o_done); + if (e != nullptr) + throw FormatRuntimeError("soxr error: %s", e); + + if (o_done == 0) + /* flush complete */ + output_buffer = nullptr; + + return { output_buffer, o_done * frame_size }; +} diff --git a/src/pcm/SoxrResampler.hxx b/src/pcm/SoxrResampler.hxx index ee4b98869..8df36c959 100644 --- a/src/pcm/SoxrResampler.hxx +++ b/src/pcm/SoxrResampler.hxx @@ -42,6 +42,7 @@ public: AudioFormat Open(AudioFormat &af, unsigned new_sample_rate) override; void Close() noexcept override; ConstBuffer<void> Resample(ConstBuffer<void> src) override; + ConstBuffer<void> Flush() override; }; void |