summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2018-01-02 18:22:53 +0100
committerMax Kellermann <max@musicpd.org>2018-01-02 23:17:25 +0100
commitf6ec43b9ec2a1f64ed09479b60e85bd7d4fdb962 (patch)
tree95f98b40b95984409e2de699efc6abedcc0fb2a4 /src
parent6d0d8cf9cf07a5d0905f715be9a79f5de86e8b37 (diff)
pcm/Resampler: add virtual method Flush()
Wired to Filter::Flush(). Closes #153
Diffstat (limited to 'src')
-rw-r--r--src/filter/plugins/ConvertFilterPlugin.cxx4
-rw-r--r--src/pcm/GlueResampler.cxx6
-rw-r--r--src/pcm/GlueResampler.hxx2
-rw-r--r--src/pcm/PcmConvert.cxx19
-rw-r--r--src/pcm/PcmConvert.hxx6
-rw-r--r--src/pcm/Resampler.hxx8
-rw-r--r--src/pcm/SoxrResampler.cxx21
-rw-r--r--src/pcm/SoxrResampler.hxx1
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