本博文是信号与系统系列博文的最后一篇,主要针对于“男生、女生声音信号的混合与分离”展开研究。信号与系统系列主要包含三篇博文,基于自己三个不同研究目标的信号与系统实验,欢迎阅读信号与系统系列全部博文。
代码示例:
function [Voice,Fs]=VoiceMix(FileName1,FileName2)
% 注释:
% Input---
% FileName1 FileName2 为混合的两个原声音文件
% Output---
% Voice 混合后的音频时域信号
% Fs 混合后的音频时域信号采样频率
[y,Fs] = audioread(FileName1);
[y2,Fs2] = audioread(FileName2);
% 音频信号可能是多通道的,统一只取一个通道
ft = y(:,1);
ft2=y2(:,1);
% 两个混合音频文件变换为同频率
% resample函数对信号频率进行调整
y3=resample(ft2,Fs,Fs2);
Length=length(y(:,1));
Length2=length(y3(:,1));
if Length>=Length2
% 随机取得一个长度,将短的音频插入到长的音频中去
Start=floor(rand*abs(Length-Length2));
% 音频混合
Voice=y;
Voice(Start+1:Start+Length2)=y3+ft(Start+1:Start+Length2);
else
% 随机取得一个长度,将短的音频插入到长的音频中去
Start=floor(rand*abs(Length2-Length));
% 音频混合
Voice=y3;
Voice(Start+1:Start+Length)=ft+y3(Start+1:Start+Length);
end
代码展示:
function main()
clear;clc;
[voice,Fs]=VoiceMix('data_record.wav','女生.mp3'); % 男生、女生声音信号混合
sound(voice, Fs) % 混合后声音文件播放
pause(5)
% 混合后声音信号的时频域波形
figure(1)
voice = voice(:,1);
voice = voice';
N = length(voice);
t = (0:N-1)/Fs;
y = fft(voice);
f = Fs/N*(0:round(N/2)-1);
subplot(211);
plot(t,voice,'g');%绘制时域波形
xlabel('Time/s');ylabel('Amplitude');
title('信号的波形');
grid;
subplot(212);
plot(f,abs(y(1:round(N/2))));
xlabel('Frequency/Hz');ylabel('Amplitude');
title('信号的频谱');
grid;
% 混合前两段声音信号的时频域波形
figure(3)
[x,Fs]=audioread('data_record.wav');
disp(Fs)
x = x(:,1);
x = x';
N = length(x);
t = (0:N-1)/Fs;
y = fft(x);
f = Fs/N*(0:round(N/2)-1);
subplot(211);
plot(t,x,'g');
xlabel('Time/s');ylabel('Amplitude');
title('信号的波形');
grid;
hold on
subplot(212);
plot(f,abs(y(1:round(N/2))));
xlabel('Frequency/Hz');ylabel('Amplitude');
title('信号的频谱');
grid;
hold on
[x,Fs]=audioread('女生.mp3');
disp(Fs)
x = x(:,1);
x = x';
N = length(x);
t = (0:N-1)/Fs;
y = fft(x);
f = Fs/N*(0:round(N/2)-1);
subplot(211);
plot(t,x,'g');
xlabel('Time/s');ylabel('Amplitude');
title('信号的波形');
grid;
subplot(212);
plot(f,abs(y(1:round(N/2))));
xlabel('Frequency/Hz');ylabel('Amplitude');
title('信号的频谱');
grid;
可视化图形分析:
代码如下(示例):
function Hd = Filter_FIR
%FILTER_FIR Returns a discrete-time filter object.
% MATLAB Code
% Generated by MATLAB(R) 9.7 and Signal Processing Toolbox 8.3.
% Generated on: 22-Jun-2021 12:52:59
% Equiripple Lowpass filter designed using the FIRPM function.
% All frequency values are in Hz.
Fs = 44100; % Sampling Frequency
Fpass = 150; % Passband Frequency
Fstop = 200; % Stopband Frequency
Dpass = 0.057501127785; % Passband Ripple
Dstop = 0.0001; % Stopband Attenuation
dens = 20; % Density Factor
% Calculate the order from the parameters using FIRPMORD.
[N, Fo, Ao, W] = firpmord([Fpass, Fstop]/(Fs/2), [1 0], [Dpass, Dstop]);
% Calculate the coefficients using the FIRPM function.
b = firpm(N, Fo, Ao, W, {dens});
Hd = dfilt.dffir(b);
% [EOF]
本实验中低通滤波器的设计采用matlab自带的Filter Designer进行设计,由分析可知,针对于男生和女生而言,女生声音的频率一般比男生高,因此,为从混合声音中将男生声音分离出来,我们设计低通滤波器,截止频率高于男生频率,低于女生频率,即可从混合声音信号中将男生声音提取出来。 代码如下(示例):
% 利用上步中设计好的滤波器进行声音信号的提取
voice1 = filter(Filter_FIR,voice)
% 声音信号分离可视化代码分析
sound(voice1,Fs)
N = length(voice1);
t = (0:N-1)/Fs;
y = fft(voice1);
f = Fs/N*(0:round(N/2)-1);
subplot(211);
plot(t,voice1,'g');
xlabel('Time/s');ylabel('Amplitude');
title('信号的波形');
grid;
subplot(212);
plot(f,abs(y(1:round(N/2))));
xlabel('Frequency/Hz');ylabel('Amplitude');
title('信号的频谱');
grid;