From: Markus Grabner Date: Thu, 16 Sep 2004 10:02:12 +0000 (+0000) Subject: Fix the downsampling noise problem X-Git-Tag: v1.0.7~21 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=3a8bfd43d75efb9a9493dd144398c9676ac4fb32;p=alsa-lib.git 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 --- 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;