pcm/Resampler: add virtual method Flush()
Wired to Filter::Flush(). Closes #153
This commit is contained in:
@@ -81,3 +81,9 @@ GluePcmResampler::Resample(ConstBuffer<void> src)
|
||||
|
||||
return resampler->Resample(src);
|
||||
}
|
||||
|
||||
ConstBuffer<void>
|
||||
GluePcmResampler::Flush()
|
||||
{
|
||||
return resampler->Flush();
|
||||
}
|
||||
|
@@ -61,6 +61,8 @@ public:
|
||||
void Reset() noexcept;
|
||||
|
||||
ConstBuffer<void> Resample(ConstBuffer<void> src);
|
||||
|
||||
ConstBuffer<void> Flush();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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 };
|
||||
}
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user