软件无线电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调制信号和解调信号

相关推荐
liangbm32 小时前
MATLAB系列07:输入/输入函数
开发语言·数据库·笔记·matlab·函数·自定义函数·matlab函数
梦里花乡17 小时前
Matlab 的.m 文件批量转成py文件
开发语言·matlab
天飓1 天前
树莓派智能语音助手实现音乐播放
人工智能·python·语音识别·树莓派·rasa·sounddevice
Winner13001 天前
【MATLAB GUI 设计第一篇 】
开发语言·matlab
MATLAB代码顾问1 天前
如何用MATLAB计算多边形的几何中心
算法·机器学习·matlab
中式代码美式咖啡1 天前
记录开发一个英语听力训练网站
java·spring boot·bootstrap·音视频·语音识别
tsumikistep2 天前
【matlab】生成 GIF 的函数(已封装可直接调用)
前端·数据库·matlab
黄卷青灯772 天前
matlab fid = fopen(file_nav,‘rt‘);语句解释
开发语言·matlab·rt·fopen
bu_shuo2 天前
Simulink仿真理想二极管模型
matlab·simulink·二极管
思茂信息2 天前
5G毫米波阵列天线仿真——CDF计算(手动AC远场)
linux·服务器·网络·数据库·5g·matlab