比较conv和filter处理群延迟的效果

背景

在做调制信号经过小波降噪的时候,发现经过余弦滚降后的调制信号有一部分接近于0,并且小波降噪且解调之后的误码率非常高,经常40%左右,所以进行纠错,发现是群延迟导致误码率升高。

使用filter函数

BPSK信号调制

clc, clear, close all;

% 设置参数
M = 2; % BPSK 调制阶数
oversampling_factor = 16; % 上采样倍数
SNR_dB = -5; % 信噪比 (dB)

% 生成数据并调制
data = [1,0,0,1,1,0,0,1,0,0,1,0,0,0,1,1];
txSig = pskmod(data, M); % BPSK调制

根升余弦滤波器(filter在这里使用)

% 应用根升余弦滤波器(脉冲成形)
span = 6; % 滤波器跨度
rolloff = 0.35; % 滚降因子
rctfilt = rcosdesign(rolloff, span, oversampling_factor, 'sqrt');

% 先上采样再滤波
txSig_upsampled = upsample(real(txSig), oversampling_factor); % 上采样
txSig_shaped = filter(rctfilt, 1, txSig_upsampled); % 应用根升余弦滤波器

% 添加噪声以达到指定的信噪比
rxSig_noisy = awgn(txSig_shaped, SNR_dB, 'measured');

小波降噪

% 使用 wpdencmp 函数进行小波包去噪
[thr,sorh,keepapp,crit] = ddencmp('den','wp',rxSig_noisy);
% thr = thselect(rxSig_noisy,'heursure');
[xd3, perf0_3, perfl2_3] = wpdencmp(rxSig_noisy, 's', 4, 'sym8', 'sure', thr, 1);
[xd6, perf0_6, perfl2_6] = wpdencmp(rxSig_noisy, 's', 6, 'sym8', 'sure', thr, 1);

结果可视化

% 可视化结果
figure;
subplot(5, 1, 1);
stem((0:length(data) - 1), data, 'filled');
title('原始基带数据');
xlabel('符号序号');
ylabel('幅度');

subplot(5, 1, 2);
plot(txSig_shaped);
title('原始调制信号(经过脉冲成形)');
xlabel('样本点');
ylabel('幅度');

subplot(5, 1, 3);
plot(rxSig_noisy);
title(['含噪声信号(信噪比 ', num2str(SNR_dB), ' dB)']);
xlabel('样本点');
ylabel('幅度');

subplot(5, 1, 4);
plot(xd3);
title('3层小波包去噪后的信号');
xlabel('样本点');
ylabel('幅度');

subplot(5, 1, 5);
plot(xd6);
title('6层小波包去噪后的信号');
xlabel('样本点');
ylabel('幅度');

解调并计算误码率

% 解调信号前先降采样和匹配滤波
xd3_matched = filter(rctfilt, 1, xd3);
xd6_matched = filter(rctfilt, 1, xd6);

% 降采样回原始符号速率
xd3_downsampled = downsample(xd3_matched, oversampling_factor);
xd6_downsampled = downsample(xd6_matched, oversampling_factor);

% 解调信号
dataOut_3 = pskdemod(xd3_downsampled, M);
dataOut_6 = pskdemod(xd6_downsampled, M);

% 计算误码率
[~, ber_3] = symerr(data, dataOut_3);
[~, ber_6] = symerr(data, dataOut_6);

disp(['3层小波包去噪后误码率: ', num2str(ber_3)]);
disp(['6层小波包去噪后误码率: ', num2str(ber_6)]);

 代码运行结果

可以发现,“原始调制信号(经过脉冲成型)”这个图像,在前35个点都非常接近于0。

尽管此时3层小波去噪信号与原始调制信号比较相像,但是经过解调之后,计算误码率为0.5,误码率较高。

使用conv函数

代码格式与上面相似,将filter更改为conv。

代码片段1

clc, clear, close all;

% 设置参数
M = 2; % BPSK 调制阶数
oversampling_factor = 16; % 上采样倍数
SNR_dB = -5; % 信噪比 (dB)

% 生成数据并调制
data = [1,0,0,1,1,0,0,1,0,0,1,0,0,0,1,1];
txSig = pskmod(data, M); % BPSK调制

% 应用根升余弦滤波器(脉冲成形)
span = 6; % 滤波器跨度
rolloff = 0.35; % 滚降因子
rctfilt = rcosdesign(rolloff, span, oversampling_factor, 'sqrt');

根升余弦滤波器(conv在这里使用) 

% 先上采样再滤波
txSig_upsampled = upsample(real(txSig), oversampling_factor); % 上采样
% txSig_shaped = filter(rctfilt, 1, txSig_upsampled); % 应用根升余弦滤波器
txSig_shaped = conv(txSig_upsampled, rctfilt);
delay = round(mean(grpdelay(rctfilt))); % 计算系统群延迟
txSig = txSig_shaped(delay + 1:end - delay); % 去除滤波器引入的延迟

代码片段2

figure;
subplot(6, 1, 1);
stem(data, 'filled'); % 原始基带数据
title('data');
xlabel('样本点');
ylabel('Amplitude');

subplot(6, 1, 2);
plot(0:length(txSig) - 1,txSig); % 原始调制信号
title('modulated signal');
xlabel('样本点');
ylabel('Amplitude');
xlim([0,255]);
grid on;

% 添加噪声以达到指定的信噪比
rxSig_noisy = awgn(txSig, SNR_dB, 'measured');

% 使用 wpdencmp 函数进行小波包去噪
% 参数解释:
% 's' 表示软阈值处理。
% 'wp' 表示使用wavelet packets
% 'sym8' 是所选的小波基。
% 3 和 6 分别表示分解的层数。
[thr,sorh,keepapp,crit] = ddencmp('den','wp',rxSig_noisy);
% thr = thselect(rxSig_noisy,'heursure');
[xd3, perf0_3, perfl2_3] = wpdencmp(rxSig_noisy, 's', 4, 'sym8', 'sure', thr, 1);
[xd6, perf0_6, perfl2_6] = wpdencmp(rxSig_noisy, 's', 6, 'sym8', 'sure', thr, 1);

subplot(6, 1, 3);
plot(rxSig_noisy);
title(['含噪声信号(信噪比 ', num2str(SNR_dB), ' dB)']);
xlabel('样本点');
ylabel('幅度');
xlim([0,255]);

subplot(6, 1, 4);
plot(xd3);
title('3层小波包去噪后的信号');
xlabel('样本点');
ylabel('幅度');
xlim([0,255]);

subplot(6, 1, 5);
plot(xd6);
title('6层小波包去噪后的信号');
xlabel('样本点');
ylabel('幅度');
xlim([0,255]);

匹配滤波 (conv在这里使用)

% 解调信号前先降采样和匹配滤波
% xd3_matched = filter(rctfilt, 1, xd3);
% xd6_matched = filter(rctfilt, 1, xd6);
% rxSig_noisy = filter(rctfilt, 1, rxSig_noisy);
xd3_matched = conv(rctfilt,xd3);
xd6_matched = conv(rctfilt,xd6);
rxSig_noisy = conv(rctfilt, rxSig_noisy);
xd3_matched = xd3_matched(1 + delay:end - delay);
xd6_matched = xd6_matched(1 + delay:end - delay);
rxSig_noisy = rxSig_noisy(1 + delay:end - delay);

代码片段3

% 降采样回原始符号速率
xd3_downsampled = downsample(xd3_matched, oversampling_factor);
xd6_downsampled = downsample(xd6_matched, oversampling_factor);
% rxSig_noisy1 = downsample(rxSig_noisy1 ,oversampling_factor);
txSig_shaped = downsample(rxSig_noisy, oversampling_factor);
% 解调信号
dataOut_3 = pskdemod(xd3_downsampled, M);
dataOut_6 = pskdemod(xd6_downsampled, M);
dataOut_txSig = pskdemod(txSig_shaped, M);
% 计算误码率
[numErrs_3, ber_3] = symerr(data, dataOut_3);
[numErrs_6, ber_6] = symerr(data, dataOut_6);

subplot(6, 1, 6);
stem(dataOut_3, 'filled');
xlabel('样本点');
ylabel('Amplitude');
title('3层小波降噪解调');

disp(['3层小波包去噪后误码率: ', num2str(ber_3)]);
disp(['6层小波包去噪后误码率: ', num2str(ber_6)]);

代码运行结果

运行以上代码可以发现,基带已调信号的前35个点不再趋近于0,且此时3层小波降噪误码率为0。

filter与conv结果不同的原因

前提

在以上代码片段中,是通过根升余弦滤波器(rcosdesign函数)进行成型滤波的。并且,在matlab里面,rcosdesign函数是自带线性相位的(我验证并且通义千问的结果是这样的)。

对于线性相位滤波器,他的群延迟是(N-1)/2,其中N是滤波器阶数。上面这个例子中N=97,所以群延迟\tau为48。

对于filter

filter:

  • 返回与输入信号相同长度的输出:输入信号txSig_upsampled与输出结果txSig_shaped的length都是1x256。
  • 隐含地考虑了群延迟,但边界样本可能受边界效应影响。(通义千问说考虑了群延迟,但是该代码背景中仍然需要裁剪)

但是因为群延迟\tau为48,所以前面48个数据是不可用的,需要删掉。因此有用数据大小为256-48=208。

因为包含不可用数据,所以会影响BPSK解调,进而提高误码率。

对于conv

conv:

  • 返回一个比输入信号长的结果(长度为 N+M−1),其中 NN是输入信号长度,M 是滤波器长度。xd3为1x256,经过conv之后xd3_matched的大小是97+256-1=352。
  • 需要手动裁剪以匹配滤波器的群延迟效果。

但是因为群延迟,前面48与最后面48个数据点不可用,需要删除。

因此有用数据大小为256。此时全部是有用数据,因此误码率降低。

filter更加详细讲解

在matlab官方文档中给出范例

openExample('signal/CompensateForTheDelayIntroducedByAFilterExample')

经过filter,但是未补偿群延迟,可以发现滤波信号与原始信号之间有明显的延迟。图像如下:

打开该文档之后,我们关注最后一个代码块,即:

plot(tt,sn)
hold on, plot(tt,sf,'-r','linewidth',1.5), hold off
title 'Electrocardiogram'
xlabel('Time (s)'), legend('Original Signal','Filtered Shifted Signal')

补偿群延迟后图像:

可以看出,tt与sf的length都为465,是因为把前面35个无用数据删掉了。

当我们把Original Signal绘制完整,也就是把tt更改为tn,sn更改为xn。此时图像如下:

可以发现filter有用信号只有[1+delay:end]

plot(tn,xn)
hold on, plot(tt,sf,'-r','linewidth',1.5), hold off
title 'Electrocardiogram'
xlabel('Time (s)'), legend('Original Signal','Filtered Shifted Signal')

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值