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

相关推荐
kaisun641 小时前
树莓派4B上使用INMP441麦克风进行语音识别:从I2S配置到Python环境搭建全记录
python·语音识别·树莓派
IT猿手12 小时前
基于控制障碍函数的多无人机编队动态避障控制方法研究,MATLAB代码
开发语言·matlab·无人机·openclaw·多无人机动态避障路径规划·无人机编队
Evand J16 小时前
【MATLAB复现RRT(快速随机树)算法】用于二维平面上的无人车路径规划与避障,含性能分析与可视化
算法·matlab·平面·无人车·rrt·避障
s090713616 小时前
【声纳成像】基于滑动子孔径与加权拼接的条带式多子阵SAS连续成像(MATLAB仿真)
开发语言·算法·matlab·合成孔径声呐·后向投影算法·条带拼接
IT猿手19 小时前
基于 ZOH 离散化与增量 PID 的四旋翼无人机轨迹跟踪控制研究,MATLAB代码
开发语言·算法·matlab·无人机·动态路径规划·openclaw
IT猿手19 小时前
基于控制障碍函数(Control Barrier Function, CBF)的无人机编队三维动态避障路径规划,MATLAB代码
开发语言·matlab·无人机·动态路径规划·无人机编队
SugarFreeOixi19 小时前
MATLAB绘图风格记录NP类型
python·matlab·numpy
IT猿手19 小时前
基于 CBF 的多无人机编队动态避障路径规划研究,无人机及障碍物数量可以自定义修改,MATLAB代码
开发语言·matlab·无人机·动态路径规划
开开心心就好20 小时前
绿色版PDF多功能工具,支持编辑转换
人工智能·windows·pdf·ocr·excel·语音识别·harmonyos
IT猿手21 小时前
基于强化学习Q-learning算法的无人机三维路径规划算法原理与实现,MATLAB代码
算法·matlab·无人机·路径规划·动态路径规划