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

news2024/11/16 9:48:31

1、MATLAB读取语音文件

      准备一段wav的语音文件,我用笔记本自带的录音机录制了一段自己的语音“爱福皮的姐.wav“,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调制是用基带信号控制载波的频率,即与载波信号数据相乘,所以在这之前,我们需要将基带信号的采样率和长度进行处理,使其与载波信号采样率和长度保持一致,处理代码如下:

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,代码如下:

%************************* 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,代码如下:

%*****************************载波信号 *********************************
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信号。

%******************* 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信号相乘,然后经过低通滤波器,滤除高频分量。

%% 解调方法一   %*******************相干解调 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解调公式,得到我们需要的数据源基带信号。

f\left(n\right)=\frac{X_I\left(n\right)\ast X_Q\left(n-1\right)-X_I\left(n-1\right)\ast X_Q\left(n\right)}{X_I\left(n\right)\ast X_I\left(n\right)+X_Q\left(n\right)\ast X_Q\left(n\right)}

%%%%%%%%%%%%%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处理后播放,我们可以将原语音数据播放效果和解调后的语音数据进行比较,解调后的语音听起来效果还可以,非常清晰。

%%%%%%%%%%%%%降采样%%%%%%%%%%%%%%%%%%%%%%%%%
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处理后播放,我们可以将原语音数据播放效果和解调后的语音数据进行比较,非相干解调后的语音听起来也非常清晰。

%% 解调方法二  %*******************非相干解调 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 库函数调制解调 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调制信号和解调信号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2126773.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【困难】 猿人学web第一届 第18题 jsvmp 洞察先机

文章目录 数据接口分析还原加密参数插桩调试分析日志插桩补充 python 代码 数据接口分析 数据接口 https://match.yuanrenxue.cn/match/18data 请求参数 {page: 页码, t: 时间戳, v: 加密值} 请求第一页不需要携带 t, v 参数 cookie 只需要携带 sessionid 只要 还原加密字段…

深入理解Java反射技术及其应用

什么是反射技术&#xff1f; Java反射机制是一种强大的特性&#xff0c;它允许程序在运行时动态加载类并获取类或对象的属性和方法。其核心在于JVM通过获得class对象进行反编译&#xff0c;从而获取对象的各种信息。 反射机制的基本特点 动态性 Java是一种先编译后运行的语言…

【电子通识】规格书上的%FS和%RD具体指什么?

在仪器仪表类的手册上&#xff0c;常见的精度表达规格显示方式&#xff1a;%FS 和%RD 究竟如何解读呢&#xff1f; 术语解说 %RD(Reading)&#xff1a;用于表示对比显示值(读值)存在多少(%)的误差 %FS(Full Scale)&#xff1a;用于表示对比全量程存在多少(%)的误差 %SP(Set Poi…

基于vue框架的城市体育运动交流平台15s43(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,赛事类型,近期赛事,比赛报名,器材类型,器材信息,自由约战,运动队伍 开题报告内容 基于Vue框架的城市体育运动交流平台开题报告 一、项目背景与意义 随着城市化进程的加速和居民健康意识的提升&#xff0c;城市体育运动已成为现代…

思维导图神器!四款高效工具助你职场逆袭

在如今这个信息爆炸的时代&#xff0c;如何高效地整理和呈现思维&#xff0c;成为了一个重要的能力&#xff1b;思维导图作为一种有效的思维工具&#xff0c;被广泛应用于工作、学习和生活中&#xff1b;今天&#xff0c;我将为大家介绍四款常用的思维导图软件并分享一下它们的…

win10任务栏透明如何调整?——详解Windows任务栏设置与优化技巧

在这个数字化时代&#xff0c;电脑已经成为我们日常办公和生活中的。关于win10任务栏透明的设置方法&#xff0c;身边很多同事都在咨询。 本文就来简单介绍下关于电脑任务栏个性化设置的方法&#xff0c;毕竟任务栏影响着用户体验。这时&#xff0c;一款优秀的任务栏优化工具就…

模拟实现string类: clear函数、流提取(<<)和流插入(>>)运算符重载、>、<、==、<=、>=、!=的运算符重载、赋值运算符(=)重载等的介绍

文章目录 前言一、 clear函数二、流提取(<<)和流插入(>>)运算符重载三、 >、<、、<、>、!的运算符重载四、赋值运算符&#xff08;&#xff09;重载总结 前言 模拟实现string类: clear函数、流提取(<<)和流插入(>>)运算符重载、>、<…

[论文笔记]ChatQA: Surpassing GPT-4 on Conversational QA and RAG

引言 今天来看一下上篇论文笔记中反复介绍的 ChatQA: Surpassing GPT-4 on Conversational QA and RAG。 为了简单&#xff0c;下文中以翻译的口吻记录&#xff0c;比如替换"作者"为"我们"。 我们介绍了 ChatQA&#xff0c;这是一个模型套件&#xff0c;一…

机器学习和深度学习的常见概念总结(面试用,多原创图和公式)

目录 使用说明一、未分类损失函数&#xff08;Loss Function&#xff09;1. **损失函数的作用**2. **常见的损失函数**2.1. **均方误差&#xff08;MSE, Mean Squared Error&#xff09;**2.2. **均方根误差&#xff08;RMSE, Root Mean Squared Error&#xff09;**2.3. **平均…

1. 运动控制指令概要(omron 机器自动化控制器)

机器自动化控制器——第一章 运动控制指令概要 1-1 运动控制指令PLCopen运动控制用功能块运动控制指令概要▶ 运动控制指令的种类▶ 状态变化▶ 运动控制指令的启动和状态▶ 异常处理▶ 执行运动控制指令时输入变量的变更(指令重启)▶ 通过选择缓存模式执行指令多重启动▶ 通过…

四川锦程消费金融有限责任公司2024年(第一批次)催收机构选型入库采购公告

四川锦程消费金融有限责任公司2024年&#xff08;第一批次&#xff09;催收机构选型入库采购公告 根据需要&#xff0c; 四川锦程消费金融有限责任公司决定对外公 开选型采购催收代理合作的催收机构&#xff0c;欢迎符合条件的催收 机构参与采购。具体公告如下&#xff1a; 一…

Redisson分布式锁实现及原理详解

随着技术快速发展&#xff0c;数据规模增大&#xff0c;分布式系统越来越普及&#xff0c;一个应用往往会部署在多台机器上&#xff08;多节点&#xff09;&#xff0c;在有些场景中&#xff0c;为了保证数据不重复&#xff0c;要求在同一时刻&#xff0c;同一任务只在一个节点…

Makefile中的override

若对变量进行赋值一部分需要由命令行&#xff08;注意命令行只能使用/:/进行赋值&#xff0c;不能使用&#xff1f;进行赋值&#xff09;输入完成&#xff0c;一部分需要写在Makefile文件里&#xff0c;Makefile规则默认会让命令行的赋值覆盖文件里的赋值。要想解决这个问题&am…

【源码+文档+调试讲解】高校研招信息共享系统

摘 要 近年来&#xff0c;科技飞速发展&#xff0c;在经济全球化的背景之下&#xff0c;互联网技术将进一步提高社会综合发展的效率和速度&#xff0c;互联网技术也会涉及到各个领域&#xff0c;而高校研招信息共享系统在网络背景下有着无法忽视的作用。信息管理系统的开发是…

log4j靶场,反弹shell

1.用vulhub靶场搭建&#xff0c;首先进入目录CVE-2021-44228中&#xff0c;docker启动命令 2.发现端口是8983&#xff0c;浏览器访问http://172.16.1.18:8983/ 3.用dnslog平台检测dns回显&#xff0c;看看有没有漏洞存在 4.反弹shell到kali&#xff08;ip为172.16.1.18&#xf…

【白话Spring】三级缓存

快速导航 一、Spring的三级缓存是什么&#xff1f;三级缓存SpringBean 的生命周期&#xff1a;BeanFactory关于Bean初始化注释&#xff1a;分析&#xff1a;Bean的创建过程&#xff1a;Bean的销毁过程&#xff1a; Spring Bean创建的核心逻辑&#xff1a; 二、Spring的三级缓存…

CentOS7 使用yum报错:[Errno 14] HTTP Error 404 - Not Found 正在尝试其它镜像。

CentOS7 使用yum报错&#xff1a;[Errno 14] HTTP Error 404 - Not Found 正在尝试其它镜像。 CentOS镜像下载、VM虚拟机下载 下载地址&#xff1a;www.macfxb.cn 一、问题描述 安装完CentOS7 后 使用yum报错 如下图 二、解决方案 1.查看自己的系统架构 我的是aarch64 uname …

【MySQL】查询语句之inner、left、right、full join 的区别

前言&#xff1a; INNER JOIN 和 OUTER JOIN 是SQL中常用的两种连接方式&#xff0c;用于从两表活多表中提取相关的数据。两者区别主要在于返回的 结果集 如何处理 匹配 与 不匹配 的行。 目录 1、INNER JOIN 2、OUTER JOIN 3、总结 1、INNER JOIN 称为内连接&#xff0c;只…

ComfyUI-AdvancedLivePortrait:实时编辑人脸让图像动起来

经常使用Stable Diffiusion的朋友都知道&#xff0c;webUI和comfyUI底层都是Stable Diffiusion&#xff0c;但是它们的显示界面有非常大的区别&#xff1a;webUI界面简洁&#xff0c;新手比较容易上手&#xff1b;而ComfyUI 是采用基于节点的图形界面&#xff0c;通过连接不同的…

面向 NetworkX 用户的加速生产就绪型图形分析

目录 借助 NetworkX 轻松进行图形分析 使用 cuGraph 加速图形分析 使用 ArangoDB 进行生产就绪型图形分析 借助 cuGraph 和 ArangoDB 实现 GPU 加速分析 实施示例 测试环境 下载数据 创建 NetworkX 图形 在不使用 ArangoDB 的情况下运行 cuGraph 算法 将 NetworkX 图…