# 第一次作业：一般模拟信号的DFT处理过程详述与演示

## 一、 理论基础
在数字信号处理（DSP）中，我们通常需要利用计算机来分析自然界中的模拟信号。由于计算机只能处理有限长度的离散数字，因此必须将连续时间、连续幅度的模拟信号转换为离散时间、离散幅度的数字信号，然后再使用离散傅里叶变换（DFT）进行频域分析。

一般模拟信号的完整 DFT 处理流程包含以下几个关键步骤：
1. **预滤波（抗混叠滤波）**：限制模拟信号的最高频率成分，防止采样时发生频率混叠。
2. **采样（A/D 转换）**：将时间连续的信号转换为时间离散的序列。
3. **截断与加窗**：由于计算机无法处理无限长的序列，必须从采样后的无限长序列中截取有限长度 $N$ 的数据段，此过程相当于给信号乘上一个“窗函数”。
4. **计算 DFT**：对截断后的有限长序列执行离散傅里叶变换（通常使用快速算法 FFT）。
5. **频谱分析**：根据 DFT 的结果计算并绘制信号的幅度谱、相位谱，提取所需的频率信息。

---

## 二、 处理步骤详述

### 1. 采样与奈奎斯特（Nyquist）定理
设连续模拟信号为 $x_a(t)$，我们以间隔 $T_s$ 对其进行理想采样，得到离散时间序列 $x[n] = x_a(n T_s)$。
- **采样频率** $f_s = 1 / T_s$。
- **Nyquist定理**：为了能够从采样后的离散信号中无失真地恢复出原始模拟信号，采样频率 $f_s$ 必须严格大于模拟信号中最高频率成分 $f_{max}$ 的两倍，即：
  $$ f_s > 2 f_{max} $$
- **混叠误差（Aliasing）**：如果 $f_s < 2 f_{max}$，高于 $f_s/2$（奈奎斯特折叠频率）的频率成分将会“折叠”到低频区间，导致我们无法区分真实的低频信号和折叠下来的高频信号。

### 2. 截断与加窗
实际应用中，信号往往是持续不断的。为了进行 DFT 计算，我们必须截取 $N$ 个采样点，这相当于将信号 $x[n]$ 与一个长度为 $N$ 的窗函数 $w[n]$ 相乘。
- **矩形窗**：最简单的截断就是直接取 $N$ 个点（即矩形窗）。
- **频谱泄漏（Leakage）**：时域上的相乘对应于频域上的卷积。原始信号的频谱与窗函数的频谱（如 Sinc 函数）进行卷积，会导致原始信号单一谱线向两侧扩散，使得能量“泄漏”到其他频率上去。这种现象称为频谱泄漏。为了减轻泄漏，我们常采用汉明窗（Hamming）、海宁窗（Hanning）等旁瓣衰减更快的窗函数。

### 3. DFT 计算与频域参数
对截断后的序列 $x[n]$（$0 \le n \le N-1$）计算 N 点 DFT：
$$ X[k] = \sum_{n=0}^{N-1} x[n] e^{-j\frac{2\pi}{N}nk}, \quad k=0,1,\dots,N-1 $$
- **频率分辨率 $\Delta f$**：DFT 结果中两个相邻频率采样点之间的物理频率间隔为：
  $$ \Delta f = \frac{f_s}{N} $$
  若想提高频率分辨率（即减小 $\Delta f$），在保持采样频率 $f_s$ 不变的情况下，需要增加采样点数 $N$（即延长观测时间）。
- **栅栏效应（Picket-fence effect）**：由于 DFT 是对连续频谱的离散采样，我们只能看到 $k \Delta f$ 处的谱线，就像透过栅栏看风景。如果信号的真实频率刚好落在两个离散频率点之间，我们观察到的峰值就会比实际值小。这可以通过在原序列末尾补零（Zero-padding）来增加频域的插值点，从而减轻视觉上的栅栏效应。

---

## 三、 MATLAB 演示

下面提供了一段 MATLAB 代码 `dft_demo.m`，完整演示了将一个包含 50Hz 和 120Hz 的模拟混合信号，经过采样、截断，并使用 FFT 求其幅度谱的过程。

### MATLAB 演示代码

```matlab
% 一般模拟信号的DFT处理过程演示
clear; clc; close all;

%% 1. 模拟信号参数设置 (构造一个连续信号)
% 构造一个包含 50Hz 和 120Hz 两个频率分量的混合信号
f1 = 50;  % 频率分量1: 50Hz
f2 = 120; % 频率分量2: 120Hz

% 使用极小的时间步长来近似表示“连续”的模拟信号
t_continuous = 0:0.0001:0.1; 
x_continuous = 0.7*sin(2*pi*f1*t_continuous) + sin(2*pi*f2*t_continuous);

%% 2. 采样过程
% 根据奈奎斯特采样定理，采样频率 fs 必须大于信号最高频率的两倍 (fs > 2 * 120 = 240Hz)
fs = 500; % 这里设定采样频率为 500Hz
Ts = 1/fs; % 采样周期

% 取 N 个采样点
N = 256; % 截断长度/DFT点数
t_discrete = (0:N-1)*Ts; % 离散时间序列
x_discrete = 0.7*sin(2*pi*f1*t_discrete) + sin(2*pi*f2*t_discrete); % 理想采样后的离散信号

%% 3. 加窗与截断
% 这里默认使用矩形窗（即直接截断）。如果需要减少频谱泄漏，可以使用汉明窗等。
x_windowed = x_discrete; 

%% 4. DFT (FFT) 计算
% 使用 MATLAB 的快速傅里叶变换(FFT)函数计算DFT
X_k = fft(x_windowed, N);

% 计算双边幅度谱并进行归一化（除以N）
mag_X = abs(X_k) / N; 

% 计算单边幅度谱 (直流分量和奈奎斯特频率除外需乘以2以补偿能量)
mag_X_single = mag_X(1:N/2+1);
mag_X_single(2:end-1) = 2 * mag_X_single(2:end-1);

% 构建频率轴 (分辨率为 fs/N)
f_axis = (0:N/2) * (fs/N);

%% 5. 绘图展示
figure('Name', '一般模拟信号的DFT处理过程演示', 'Position', [100, 100, 800, 600]);

% 子图1：原始连续模拟信号
subplot(3,1,1);
plot(t_continuous, x_continuous, 'b', 'LineWidth', 1.2);
title('步骤1：原始连续模拟信号 (50Hz与120Hz混合)');
xlabel('时间 (s)'); ylabel('幅度');
grid on;

% 子图2：采样后的离散时间信号
subplot(3,1,2);
stem(t_discrete(1:50), x_discrete(1:50), 'r', 'filled'); % 只显示前50个点以便于观察
title('步骤2 & 3：采样并截断后的离散时间信号 (显示前50个点)');
xlabel('时间 (s)'); ylabel('幅度');
grid on;

% 子图3：DFT(FFT) 得到的单边幅度谱
subplot(3,1,3);
plot(f_axis, mag_X_single, 'k', 'LineWidth', 1.5);
hold on;
stem(f_axis, mag_X_single, 'k', 'Marker', 'none'); 
title(['步骤4：DFT得到的单边幅度谱 (N=', num2str(N), ', fs=', num2str(fs), 'Hz)']);
xlabel('频率 (Hz)'); ylabel('幅度');
xlim([0, fs/2]);
grid on;
```

### 演示分析与结论
1. **时域采样**：从图1到图2，我们将连续的模拟波形离散化。由于设定的 $f_s = 500\text{Hz}$ 远大于 $2 \times 120\text{Hz}$，因此在频域上不会发生混叠，满足 Nyquist 定理。
2. **频率分辨率**：本实验中 $N=256$，$f_s=500\text{Hz}$，因此频率分辨率 $\Delta f = 500 / 256 \approx 1.95\text{Hz}$。这意味着我们可以在频域图上清晰地分辨出 50Hz 和 120Hz 两个独立的峰值。
3. **幅度还原**：在单边幅度谱（图3）中，50Hz 处的幅度接近 0.7，120Hz 处的幅度接近 1.0，这与我们在第一步中设定的原始模拟信号 $0.7\sin(2\pi\cdot 50t) + \sin(2\pi\cdot 120t)$ 的真实幅度完美吻合。如果有轻微偏差，那是由**栅栏效应**引起的（因为 50Hz 和 120Hz 并不一定是 $1.95\text{Hz}$ 的整数倍，存在轻微能量泄漏）。
