软件无线电1-MATLAB实现FM调制解调

1、MATLAB读取语音文件

准备一段wav的语音文件,我用笔记本自带的录音机录制了一段自己的语音"爱福皮的姐.wav",MATLAB读取语音文件,并获取采样率信息。

Matlab 复制代码
clc;
clear all;
%% ***************read file*************************************
filename ='./data_source/爱福皮的姐.wav';
[m,fm]= audioread(filename);% fm = 48e3; %音频的采样率
sound(m,fm);
figure(1);
plot(m);title('原始的语音信号');

这段原始语音采样率48kHz,时域波形如图1所示,

2、FM调制

根据FM调制数学表达式:

生成FM信号。

2.1相关参数设置和语音数据源初处理

我是用的载波频率192kHz,载波采样率1.92MHz,代码里类似这些参数大家可以根据自己的需求修改。FM宽带调制最大频偏75kHz,FM窄带调制最大频偏5kHz。因为FM调制是用基带信号控制载波的频率,即与载波信号数据相乘,所以在这之前,我们需要将基带信号的采样率和长度进行处理,使其与载波信号采样率和长度保持一致,处理代码如下:

Matlab 复制代码
fs = 1.92e6; %采样率 载波的采样率
fc = 192e3; %载波中心频率
df = 75e3; %最大频偏  宽带75khz   窄带时5khz
kf = (df*2^32/fs)/32767;
AC= 1024;%幅度
dt=1/fs;
m_len=length(m)*fs/fm;%按照载波采样率的长度计算
m_t=zeros(1,m_len);
for i=1:length(m)
    for j=1:fix(fs/fm)
        m_t((i-1)*fix(fs/fm)+j)=m(i); 
    end
end

2.2基带信号FM调制生成基带IQ信号

查表法实现信号发生器,MATLAB产生DDS,代码如下:

Matlab 复制代码
%************************* FM调制 ********************
n=0:1/1024:1023/1024;
s_rom=sin(2*pi*n);
c_rom=cos(2*pi*n);
w_r=0;%相位累加器
rrom_addr=0;%
dac_i=zeros(1,m_len);%I路信号 
dac_q=zeros(1,m_len);%Q路信号
for i=1:m_len
    w_r = w_r + kf*m_t(i);
    if(w_r > 2^32) % 做32位累加器的溢出判断
        w_r= w_r - 2^32;
    elseif(w_r <0)
        w_r = w_r + 2^32; % 负的溢出时
    end
    
    rrom_addr=round(w_r/2^22);%读查找表的地址
    if rrom_addr == 0
        rrom_addr =1;
    end
    dac_q(i)=AC*s_rom(rrom_addr);
    dac_i(i)=AC*c_rom(rrom_addr);
end

2.3 生成载波IQ信号

查表法实现信号发生器,MATLAB产生DDS,代码如下:

Matlab 复制代码
%*****************************载波信号 *********************************
w=fc*2^32/fs; %频率控制字,32位的相位累加器, f_out  = fs*w/2^N :
n=0:1/1024:1023/1024;
s_rom=sin(2*pi*n);
c_rom=cos(2*pi*n);
%接下来产生载波地址,
w_r=0;%相位累加器
rrom_addr=0;%
cw_sin=zeros(1,m_len);%这个相当于是我们的查找表,一个周期的正弦波
cw_cos=zeros(1,m_len);
for i=1:m_len
    w_r = w_r + w;
    if(w_r > 2^32) % 做32位累加器的溢出判断
        w_r= w_r - 2^32;
    end
    rrom_addr=round(w_r/2^22);%读查找表的地址
    if rrom_addr == 0%matlab计数时从1开始计数
        rrom_addr =1;
    end
    cw_sin(i)=s_rom(rrom_addr);%载波完成
    cw_cos(i)=c_rom(rrom_addr);%载波
end
figure(2);
subplot(2,1,1);plot(cw_sin(1:3000),'r');title('sin载波信号');
subplot(2,1,2);plot(cw_cos(1:3000),'b');title('cos载波信号');

载波信号时域波形如图2所示。

图2 载波信号时域波形

2.4 生成FM信号

基带IQ信号分别和载波IQ信号相乘,之后相加,得到FM信号。

Matlab 复制代码
%******************* FM信号 *******************
s_t=zeros(1,m_len);
for i=1:m_len
    s_t(i) = dac_i(i)*cw_cos(i) + dac_q(i)*cw_sin(i)*(-1);
end
figure(3);
subplot(2,1,1);plot(s_t);title('FM信号');
subplot(2,1,2);psd(s_t,fs);title('FM信号频谱');

FM窄带调制生成的FM信号时域波形和频谱如图3所示。

图3 FM窄带调制生成的FM信号时域波形和频谱

FM宽带调制生成的FM信号时域波形和频谱如图4所示。

图4 FM宽带调制生成的FM信号时域波形和频谱

3 FM相干解调

3.1 去除高频分量

相干解调首先将FM信号与载波信号IQ信号相乘,然后经过低通滤波器,滤除高频分量。

Matlab 复制代码
%% 解调方法一   %*******************相干解调 ok*******************
%%%%%%%%%%%%正交解调%%%%%%%%%%%%%%%%
i_data = zeros(1,m_len);
q_data = zeros(1,m_len);
for i = 1 : m_len
	i_data(i) = s_t(i) * cw_cos(i);
	q_data(i) = (-1)* s_t(i) * cw_sin(i);
end 
%%%%%%%%%%%%%%进行低通滤波%%%%%%%%%%%%%%%%
%滤波器系数
f20k= [-4.49340747782e-05,0.00010035338004,0.00018271359187,0.000333071475,......];
adc_i=filter(f20k,1,i_data);
adc_q=filter(f20k,1,q_data);

滤波器系数获取步骤:

步骤1:使用MATLAB自带的滤波器设计工具,即fdatool获取滤波器系数。在MATLAB命令窗口输入fdatool回车,弹出滤波器设计工具

步骤2:滤波器参数设置。

选择低通滤波器,然后设置采样率、通带、阻带等参数后,最后点击设计滤波器,等待结束,生成滤波器,如图5所示:

图5 滤波器参数设置

步骤3:导出滤波器系数。

滤波器设计工具右上角"file"下拉选择"Export",设置导出系数的名称,覆盖原数据,导出如图6所示,在MATLAB工作区找到刚刚取的名称。

图6 导出滤波器系数

3.2 FM解调

根据如下FM解调公式,得到我们需要的数据源基带信号。

Matlab 复制代码
%%%%%%%%%%%%%FM解调%%%%%%%%%%%%%%%%%%%%%%
c_len = length(adc_i);
cr = zeros(1,c_len);
cj = zeros(1,c_len);
for i = 2: c_len %必须从2开始,因为有I-1 
	cr(i) = adc_i(i)*adc_i(i) +adc_q(i)*adc_q(i);
	cj(i)  = adc_i(i-1) * adc_q(i) -  adc_i(i)* adc_q(i-1);%I(n-1)*Q(n) -I(n)*Q(n-1)
end
angle = zeros(1,c_len);
for i = 1:c_len
	if cr(i) == 0
		angle(i) = 0;
	else 
        angle(i) = (cj(i)/cr(i)); 
	end
end

3.3 降采样率处理

上面得到的基带信号采样率依然是1.92MHz,我们使用MATLAB自带的函数resample函数进行40倍抽取处理,将基带信号的采样率降到48kHz,为了MATLAB播放出来效果更好,将信号幅值乘10处理后播放,我们可以将原语音数据播放效果和解调后的语音数据进行比较,解调后的语音听起来效果还可以,非常清晰。

Matlab 复制代码
%%%%%%%%%%%%%降采样%%%%%%%%%%%%%%%%%%%%%%%%%
data_out1 = resample(angle,1,40);
sound(data_out1*10,fm);
figure(4);
plot(data_out1(100:end)*10);title('FM解调信号');

FM解调信号时域波形如图7所示。

图7 FM解调信号1

4 FM非相干解调

非相干解调不需要提取载波信息,将接收到的FM信号经过微分器,然后经过希尔伯特变换和包络检波,最后去偏置,得到的基带信号采样率1.92Mhz,同样使用MATLAB自带的函数resample进行40倍抽取处理,将基带信号的采样率降到48kHz,为了MATLAB播放出来效果更好,将信号幅值除以30处理后播放,我们可以将原语音数据播放效果和解调后的语音数据进行比较,非相干解调后的语音听起来也非常清晰。

Matlab 复制代码
%% 解调方法二  %*******************非相干解调 ok*******************
for i=1:m_len-1
    diff_sfm(i)=(s_t(i+1)-s_t(i))/dt;%微分器,将调频波变换成调幅调频波
end
diff_sfm=abs(hilbert(diff_sfm));      %希尔伯特变换移相,然后包络检波
diff_sfm=(diff_sfm/AC-2*pi*fc)/kf;    %去偏置
data_out2 = resample(diff_sfm,1,40);
sound(data_out2/30,fm);
figure(4);
plot(data_out1(100:end)*10);title('FM解调信号');

FM解调信号时域波形如图8所示。

图8 FM解调信号2

5 MATLAB里FM相关库函数实现FM调制解调

MATLAB软件自带了很多库函数,可以直接调用。FM调制我们可以使用fmmod函数,FM解调使用demod函数,代码如下,同样也进行了降采样率处理后,播放最终处理的结果数据,解调后的语音听起来也非常清晰。

Matlab 复制代码
%% 解调方法三   
%*******************matlab 库函数调制解调 ok*******************
y=fmmod(m_t,fc,fs,10);
so = demod(y,fc,fs,'fm'); %FM解调
data_out3 = resample(so,1,40);
sound(data_out3,fm);
figure(6);
subplot(2,1,1);plot(y,'b');title('FM信号');
subplot(2,1,2);plot(so,'r');title('FM解调信号');

FM信号和解调信号时域波形如图9所示。

图9 FM调制信号和解调信号

相关推荐
机器学习之心3 小时前
MATLAB基于改进云物元的模拟机协同训练质量评价
matlab·改进云物元
ytttr8733 小时前
MATLAB实现经验模态分解(EMD)与希尔伯特变换获取能量谱
人工智能·python·matlab
t198751285 小时前
基于多假设跟踪(MHT)算法的MATLAB实现
开发语言·matlab
机器学习之心8 小时前
MATLAB多子种群混沌自适应哈里斯鹰算法优化BP神经网络回归预测
神经网络·算法·matlab
力江9 小时前
攻克维吾尔语识别的技术实践(多语言智能识别系统)
人工智能·python·自然语言处理·语音识别·unicode·维吾尔语
π同学12 小时前
基于Matlab的递推最小二乘法参数估计
matlab·最小二乘法
小喵要摸鱼19 小时前
【MATLBA】使用教程
matlab
listhi5201 天前
基于空时阵列最佳旋转角度的卫星导航抗干扰信号处理的完整MATLAB仿真
开发语言·matlab·信号处理
88号技师1 天前
2025年7月一区SCI优化算法-Logistic-Gauss Circle optimizer-附Matlab免费代码
开发语言·算法·数学建模·matlab·优化算法
ZEGO即构开发者1 天前
【ZEGO即构开发者日报】Soul AI Lab开源播客语音合成模型;腾讯混元推出国内首个交互式AI播客;ChatGPT Go向用户免费开放一年......
人工智能·aigc·语音识别·实时音视频