文章目录
- 前言
- 一、构造一组声音
- 二、采用FIR滤波器做频率筛选
前言
用生成的一组音频文件举例
一、构造一组声音
模拟钢琴音乐,采用逐渐衰减振荡的正弦波
FFT的频域展示:
源代码:
matlab">function sound_firFs = 1000; % 采样频率freq = [200, 230, 260, 290, 320, 350, 380,410, 440,470]; % 频率数组rythm = 0.5; % 持续时间,单位:秒gap_duration = 0.2; % 间隔时间,单位:秒y = []; % 初始化 ynote_length = numel(freq); % 使用频率的长度% 生成时间向量x = linspace(0, rythm, floor(Fs * rythm));s = zeros(note_length, numel(x)); % 生成每个频率的波形for i = 1:note_lengths(i, :) = sin(2 * pi * freq(i) * x) .* (1 - x / (rythm)); end% 合并音频信号,并添加间隔for i = 1:note_lengthy = [y, s(i, :)]; % 添加当前音符% 添加间隔y = [y, zeros(1, round(Fs * gap_duration))]; % 插入0.2秒间隔endsound(y, Fs); % 播放合成的音频% 做FFT频域变换N = length(y); % 采样点数frequence = fft(y); % 对时域信号进行FFT变换% 幅值修正F2 = (frequence / N);F1 = F2(1:N/2+1); % 选取前半部分F1(2:end-1) = 2 * F1(2:end-1);% 画图f = Fs * (0:(N/2)) / N;% 对其中一段做FFT频域变换N0 = length(s(1, :)); % 采样点数frequence_single = fft(s(1, :)); % 对第一个音符进行FFT变换% 幅值修正F20 = (frequence_single / N0);F10 = F20(1:N0/2+1); % 选取前半部分F10(2:end-1) = 2 * F10(2:end-1);% 绘图f0 = Fs * (0:(N0/2)) / N0;subplot(221);plot(x, s(2, :)); title('单个输入音频的时域信号'); xlabel('时间 (s)'); ylabel('幅度');%可以设置是哪个频率的音频subplot(222);plot(linspace(0, length(y) / Fs, length(y)), y); title('输入音频的时域信号'); xlabel('时间 (s)'); ylabel('幅度');subplot(223);plot(f, abs(F1)); title('全部频域信号'); xlabel('频率 (Hz)'); ylabel('|F1(f)|'); xlim([0 600]);audiowrite('D:\matlab\DSP\sound.wav', y, Fs);student_id = [0 0 0 0 0 0 0 0 0 0 0 0 0];BP_filter = [];% FIR的构造for i = 1:length(student_id)wc = 2 * pi * freq(student_id(i) + 1) / Fs;% 频域函数N1 = 500; % 窗函数长度(阶数)f0 = freq(student_id(i) + 1); % 中心频率 (Hz)bw = 20; % 带宽 (Hz)% 创建频率轴f1 = linspace(0, Fs, N1);% 创建带通滤波器的频率响应BP_filter_row = (abs(f1 - f0) <= bw / 2); % 频率响应BP_filter = [BP_filter; BP_filter_row]; % 按行添加到 BP_filter 中endHBP = sum(BP_filter);subplot(224);for i = 1:length(student_id)plot(f1, BP_filter(i, :)); title('构造的理想滤波器——频域'); xlabel('频率 (Hz)'); ylabel('BP_filter'); xlim([0 900]); ylim([0 2]);hold on; end end
二、采用FIR滤波器做频率筛选
这里采用窗函数构造FIR,将频域上的理想窄带信号,根据IDFT转换为时域的函数,再与汉明窗叠加得到最后的系统函数
matlab"> %FIR的构造hlp=[];fliters=[];for i=1:length(student_id)%时域函数wc=2*pi*freq(student_id(i)+1)/Fs;N=500;nd=(N+1)/2;%群延时为阶数的一半f0 = freq(student_id(i)+1); % 中心频率 (Hz)bw = 20; % 带宽 (Hz)wc1=(wc+pi*bw/Fs);%连续转离散,尺度归一化wc2=(wc-pi*bw/Fs);n = linspace(0,N, N); % 创建n轴,假设滤波器长度为Fshlp_row=(sin(wc1 * (n-nd)) - sin(wc2 * (n - nd))) ./ (pi * (n-nd)); hlp_row(isnan(hlp_row)) = wc / pi; % 处理n=nd时的奇点hlp=[hlp;hlp_row];%窗函数hamming_window = 0.54 - 0.46 * cos(2 * pi * (0:N-1) / (N-1));h = hlp_row .* hamming_window; % 应用窗函数fliters = [fliters;h]; % 存储滤波器end