【发布时间】:2015-01-11 07:40:54
【问题描述】:
要改变信号的采样率,需要先上采样、滤波,然后下采样。天真地这样做意味着在输入信号中插入零,与滤波器的脉冲响应相关,然后丢弃除卷积的每个nth 样本之外的所有样本。
天真的方法的问题是有很多无用的计算。与滤波器进行卷积时,大部分滤波器抽头都乘以零,计算在下采样阶段将丢弃的样本值是无用的。这就是为什么高效的理性重采样使用多相滤波器组,其中只执行需要的计算。
我想知道是否可以使用惰性计算来避免无用的乘法,同时也避免显式构建多相滤波器组。我的理想解决方案类似于简单的方法(上采样,然后关联,然后下采样),但执行与显式多相滤波器方法相同的计算。
下采样很容易,因为不需要的值不会被计算。但我不知道如何避免相关部分中的零乘法。我想出的最好的方法是使用 Maybe 类型并使用 Nothing(而不是零)进行上采样:
upsample n xs = upsample2' n xs 0
where upsample' _ [] _ = []
upsample' _ (x:_) 0 = Just x : upsample' n xs n
upsample' n xs counter = Nothing : upsample' n xs (counter - 1)
correlate xs ys = sum $ catMaybes $ zipWith (fmap . (*)) xs ys
firFilter taps signal = map (correlate taps) (tails signal)
downsample _ [] = []
downsample n (x:xs) = x : downsample n (drop (n-1) xs)
upfirdn up down taps = (downsample down).(fir_filter taps).(upsample up)
upfirdn 函数确实只是简单的方法,下采样中的惰性避免了计算,但我认为处理器仍然需要在相关步骤中检查值是否为Nothing。
有没有办法利用惰性来节省与多相滤波器方法相同的计算量?如果不是,有什么根本原因不能做吗?
【问题讨论】:
标签: haskell signal-processing lazy-evaluation resampling