From d23c4131888e026b1366cb3e4f3331b4850fd3e3 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Mon, 8 Dec 2014 19:07:45 +0100 Subject: [PATCH] Interpolating resampler: un-break it. The interpolation was performed only on the samples in a buffer, without "linking" with the previous one. This can't work. * Remember the last sample from a buffer to be able to use it when interpolating the first samples of the next one * Adjust the kernel to properly loop over all samples in the buffer Fixes #9438. --- .../media/media-add-ons/mixer/Interpolate.cpp | 15 +++++++++------ .../media/media-add-ons/mixer/Interpolate.h | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp b/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp index de4ab75cdd..17bbbb21f2 100644 --- a/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp +++ b/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp @@ -43,13 +43,14 @@ kernel(Resampler* object, const void *_src, int32 srcSampleOffset, return; } - register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1); + register float delta = float(srcSampleCount) / float(destSampleCount); register float current = 0.0f; + float oldSample = ((Interpolate*)object)->fOldSample; - #define SRC(n) *(const inType*)(src + n * srcSampleOffset) + #define SRC *(const inType*)(src) - while (--count) { - float tmp = (gain * (SRC(0) + (SRC(1) - SRC(0)) * current) + offset); + while (count--) { + float tmp = (gain * (oldSample + (SRC - oldSample) * current) + offset); if (tmp < min) tmp = min; if (tmp > max) tmp = max; *(outType *)dest = (outType)tmp; @@ -59,17 +60,19 @@ kernel(Resampler* object, const void *_src, int32 srcSampleOffset, if (current >= 1.0f) { double ipart; current = modf(current, &ipart); + oldSample = SRC; src += srcSampleOffset * (int)ipart; } } - *(outType*)dest = (outType)(SRC(0) * gain + offset); + ((Interpolate*)object)->fOldSample = oldSample; } Interpolate::Interpolate(uint32 src_format, uint32 dst_format) : - Resampler() + Resampler(), + fOldSample(0) { if (dst_format == media_raw_audio_format::B_AUDIO_FLOAT) { switch (src_format) { diff --git a/src/add-ons/media/media-add-ons/mixer/Interpolate.h b/src/add-ons/media/media-add-ons/mixer/Interpolate.h index 2d08632bba..fb4dddb000 100644 --- a/src/add-ons/media/media-add-ons/mixer/Interpolate.h +++ b/src/add-ons/media/media-add-ons/mixer/Interpolate.h @@ -13,8 +13,8 @@ class Interpolate: public Resampler { public: Interpolate(uint32 sourceFormat, uint32 destFormat); -private: + float fOldSample; };