使用overlap-add方法计算两个信号的卷积示例(在频域计算卷积)

之前已经写过一篇使用overlap-add方法计算两个信号的卷积示例

本篇将卷积部分的计算从时域改为频域,基本操作步骤不变

示例代码如下:

import numpy as np


def get_blocks(signal, block_length):
    a_length = len(signal)
    padding_length = block_length - 1
    segments = -(-a_length // block_length)
    result = np.zeros((segments, block_length + padding_length))
    for i in range(segments):
        b = signal[i * block_length: (i + 1) * block_length]
        p = block_length + padding_length - len(b)
        b = np.pad(b, (0, p), 'constant', constant_values=(0, 0))
        result[i] = b
    return result


def fft_H(h, length):
    if len(h) < length:
        h = np.pad(h, (0, length - len(h)), 'constant', constant_values=(0, 0))

    return np.fft.fft(h)


def convolve_blocks(blocks, H):
    '''
    该方法改为了从频域计算
    '''
    result = np.zeros((blocks.shape[0], blocks.shape[1]))
    for i in range(blocks.shape[0]):
        X = np.fft.fft(blocks[i])
        Y = X * H
        y = np.fft.ifft(Y)
        result[i] = y.real
    return result


def convolve_overlap_add(a, h):
    a_length = len(a)
    h_length = len(h)
    o_length = h_length - 1
    blocks = get_blocks(a, h_length)
    length = blocks.shape[1]
    H = fft_H(h, length)
    cb = convolve_blocks(blocks, H)

    result = np.zeros(length * length)
    read_offset = 0
    overlap_add = np.zeros(length)
    for i in range(cb.shape[0]):
        if i == 0:
            result[0:length] = cb[i]
            read_offset = h_length
        else:
            result[read_offset:read_offset + length] = overlap_add + cb[i]
            read_offset = read_offset + h_length
        overlap_add = cb[i][h_length:]
        overlap_add = np.pad(overlap_add, (0, length - len(overlap_add)), 'constant', constant_values=(0, 0))
    return result[:a_length + o_length]


a = np.asarray([1, 3, -1, 2, 5, 3, -2, -4, -2, 1])
h = np.asarray([1, 2, -1])

c1 = convolve_overlap_add(a, h)
print('convolve_overlap_add:', c1)

c2 = np.convolve(a, h)
print('np.convolve:', c2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值