From 3a8bfd43d75efb9a9493dd144398c9676ac4fb32 Mon Sep 17 00:00:00 2001 From: Markus Grabner Date: Thu, 16 Sep 2004 10:02:12 +0000 Subject: [PATCH] Fix the downsampling noise problem Description: The patch replaces the nearest neighbor downsampling method in the sample rate conversion plugin by linear interpolation of the closest two samples, thus significantly reducing the resampling noise. Signed-off-by: Markus Grabner --- src/pcm/pcm_rate.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c index a6bc6443..27fe4aa5 100644 --- a/src/pcm/pcm_rate.c +++ b/src/pcm/pcm_rate.c @@ -45,7 +45,8 @@ const char *_snd_module_pcm_rate = ""; #ifndef DOC_HIDDEN /* LINEAR_DIV needs to be large enough to handle resampling from 192000 -> 8000 */ -#define LINEAR_DIV (1<<19) +#define LINEAR_DIV_SHIFT 19 +#define LINEAR_DIV (1<u.linear.sum; //int16_t old_sample = states->u.linear.old_sample; - pos = LINEAR_DIV/2; /* Start at 0.5 */ + pos = LINEAR_DIV - get_increment; /* Force first sample to be copied */ states->u.linear.init = 0; src = snd_pcm_channel_area_addr(src_area, src_offset); dst = snd_pcm_channel_area_addr(dst_area, dst_offset); @@ -223,11 +227,15 @@ static void snd_pcm_rate_shrink(const snd_pcm_channel_area_t *dst_areas, #include "plugin_ops.h" #undef GET16_END after_get: + new_sample = sample; src += src_step; src_frames1++; pos += get_increment; if (pos >= LINEAR_DIV) { pos -= LINEAR_DIV; + old_weight = (pos << (32 - LINEAR_DIV_SHIFT)) / (get_increment >> (LINEAR_DIV_SHIFT - 16)); + new_weight = 0x10000 - old_weight; + sample = (old_sample * old_weight + new_sample * new_weight) >> 16; goto *put; #define PUT16_END after_put #include "plugin_ops.h" @@ -237,6 +245,7 @@ static void snd_pcm_rate_shrink(const snd_pcm_channel_area_t *dst_areas, dst_frames1++; assert(dst_frames1 <= dst_frames); } + old_sample = new_sample; } states->u.linear.sum = sum; -- 2.47.1