通信原理实践(一)——音频信号处理
一、信号的离散化
1、采样定理:
–如果信号是带限的,并且采样频率fs超过信号最高频率的两倍,那么,原来的连续信号可以从采样样本中完全重建出来。
因此在仿真过程中,采样率(fs)是一个非常重要的参数。必须满足fs大于信号最高频率的两倍。
e.g:产生一段长度为1000的100Hz的正弦波
N = 1000; % 长度
fs = 8e3; % 采样率
fc = 100; % 正弦波频率
t = (0:N-1)’/fs; % 时间t
y = sin(2*pi*fc*t); % 产生的信号
plot(t, y, ‘b’); % t-y绘图
xlabel(‘time’);
ylabel(‘amplitude’);

二、利用声卡重现信号
1、原理:
声卡中含有一个DA转换器,可以将数字信号转为模拟信号
2、MatLab提供的函数
(1)首先:构建一个SoundCardDAC对象,并指定采样率fs。其中采样率通常位于5000~96000Hz之间,典型值为8kHz、16kHz、22.05kHz、44.1kHz、48kHz、64kHz。
dac = SoundCardDAC(fs);
(2)而后注册其善后方法(需要在函数内调用,不能用脚本)
onCleanup(@dac.delete);
(3)使用tx()或者tx_once()进行数模转换,信号幅度应落在[-1,1]之间(函数区别见m文件说明)
dac.tx(signal);
Ps:附上声卡封装好的对象函数代码
classdef SoundCardDAC < handle
% SoundCardDAC 利用声卡将数字信号转为模拟波形
% 利用obj=SoundCardDAC(fs)构造对象,其中fs为采样率,单位Hz
% 类方法: (1) tx(signal) 将信号signal添加到声卡缓存并进行播放,该函数可产生连续的信号输出
% (2) tx_once(signal) 直接播放信号signal,该函数仅产生一段突发的信号
% (3) delete 释放占用的资源,可在主函数中利用onCleanup调用 properties (SetAccess = private, GetAccess = private)
m_ao = 0;
m_fs = 44100;
m_state = 0; % 0: uninitialize, 1: ready, 2: runing
end methods
function obj = SoundCardDAC(fs)
obj.m_fs = fs;
obj.m_ao = analogoutput('winsound');
addchannel(obj.m_ao,1);
set (obj.m_ao, 'SampleRate', obj.m_fs);
obj.m_state = 1;
fprintf(1,'Info: Create soundCardDAC object, fs=%d.\n', fs);
end function tx(obj, signal)
sample_th1 = obj.m_fs * 0.4; % 保证声卡中至少有0.4s左右长度的数据
sample_th2 = obj.m_fs * 0.6; % 通常声卡缓冲区数据也不用太长 signal = reshape(signal, length(signal), 1); % 转为列向量 if obj.m_state == 0 % not allowed
error('Error: SoundCard does not be initialized.\n');
return;
end putdata(obj.m_ao, signal);
sample_av = get(obj.m_ao, 'SamplesAvailable'); if obj.m_state == 1 % ready
if sample_av > sample_th1
obj.m_state = 2;
start(obj.m_ao);
fprintf(1,'Info: Starting DAC...\n');
end
elseif obj.m_state == 2 % running
if sample_av < sample_th1 % 缓冲区数据量小于阈值,预示有可能程序实时性不够
fprintf(1,'Warning: Program efficiency may be too low.\n');
elseif sample_av > sample_th2 % 数据太快,让程序停顿一会儿
time_pause = (sample_av-sample_th2)/obj.m_fs;
pause(time_pause);
end
else
error('Error: Unknown error occured.\n');
end
end function tx_once(obj, signal)
signal = reshape(signal, length(signal), 1); % 转为列向量 if obj.m_state == 0 % not allowed
error('Error: SoundCard does not be initialized.\n');
elseif obj.m_state == 1 % ready
putdata(obj.m_ao, signal);
sample_av = get(obj.m_ao, 'SamplesAvailable');
start(obj.m_ao);
time_pause = sample_av/obj.m_fs + 0.2;
pause(time_pause);
stop(obj.m_ao);
elseif obj.m_state == 2
error('Error: Do not call tx() and tx_once() simultaneously.\n');
else
error('Error: Unknown error occured.\n');
end
end function delete(obj)
if obj.m_ao ~= 0
stop(obj.m_ao);
delete(obj.m_ao);
obj.m_ao = 0;
obj.m_state = 0;
fprintf(1,'Info: Destory soundCardDAC object.\n');
end
end
end end
使用这个面向对象的demo:(注意要保证相位连续)
function sine_gen
N = 5000; % 每一次产生的长度
fs = 16e3; % 采样率16kHz
fc = 400; % 正弦波频率 dac = SoundCardDAC(fs); %构造dac对象
onCleanup(@dac.delete); %注册善后函数 while 1
t = (0:N)'/ fs; % 时间t
y = sin(2*pi*fc*t); % 产生的信号
dac.tx(y);
end
end
通信原理实践(一)——音频信号处理的更多相关文章
- 通信原理实践(二)——幅度调制
一.幅度调制,并画出时域和频域波形 1.代码如下: function [ p_n ] = AM_func( N,fs,fm,Am,fc,Ac,Ma ) %UNTITLED 此处显示有关此函数的摘要 % ...
- 通信原理实践(六)——基带传输
一.基带传输引入 1.从数字带通传输说起 以上系统可以等价为: 这里"等价"的假设条件是 •信号通过滤波器不失真 •不存在码间串扰 意义:可以通过评估基带传输系统来获得数字带通传输 ...
- 通信原理实践(五)——2PSK 与2DPSK 通信系统
一.一些Matlab函数 二.2PSK调制解调,性能分析 1.2PSK调制 (1)图示 (2)Matlab代码 function [ s_t ,bb_t,bits] = psk2_module( nS ...
- 通信原理实践(四)——模拟通信系统性能分析
一.模拟通信系统性能分析 1.系统框图 2.信噪比定义 (1)输入信噪比: (2)输出信噪比: (3)调制制度增益: 3.模拟通信系统分析等价模型 即自己产生一个高斯白噪声,加入到调制信号,然后在送入 ...
- 通信原理实践(三)——FM调制
一.FM调制 1.代码如下: clc,clear; fm = ; % 调制信号频率(Hz) Am = 0.5; % 调制信号幅度 fc = 5e3; % 载波频率(Hz) Ac = ; % 载波幅度 ...
- Java网络编程UDP通信原理
前言 继续今天我们的Java网络编程--TCP和UDP通信 一.TCP和UDP概述 传输层通常以TCP和UDP协议来控制端点与端点的通信 TCP UDP 协议名称 传输控制协议 用户数据包协议 是 ...
- 基于web的IM软件通信原理分析
关于IM(InstantMessaging)即时通信类软件(如微信,QQ),大多数都是桌面应用程序或者native应用较为流行,而网上关于原生IM或桌面IM软件类的通信原理介绍也较多,此处不再赘述.而 ...
- Socket 通信原理(Android客户端和服务器以TCP&&UDP方式互通)
转载地址:http://blog.csdn.net/mad1989/article/details/9147661 ZERO.前言 有关通信原理内容是在网上或百科整理得到,代码部分为本人所写,如果不当 ...
- SSL 通信原理及Tomcat SSL 配置
SSL 通信原理及Tomcat SSL 双向配置 目录1 参考资料 .................................................................. ...
随机推荐
- Delphi操作Excel大全
Delphi操作Excel大全 DELPHI操作excel(转)(一) 使用动态创建的方法 首先创建 Excel 对象,使用ComObj:var ExcelApp: Variant;ExcelApp ...
- 3.nodejs权威指南--文件
1. 文件 1.1 读写整个文件 1.1.1 读 var fs = require('fs'); fs.readFile('./test.txt',function(err,data){ if(err ...
- Django~Settings.py
配置 数据库 默认sqlite, 支持Mysql,postgresql,oracle 更改时区 查看表结构 .schema (SQLite), display the tables Django cr ...
- IP子网划分
CIDR值: 1.掩码255.0.0.0:/8(A类地址默认掩码) 2.掩码255.128.0.0:/9 3.掩码255.192.0.0:/10 4.掩码255.224.0.0:/11 5.掩码255 ...
- 【数据结构】DFS求有向图的强连通分量
用十字链表结构写的,根据数据结构书上的描述和自己的理解实现.但理解的不透彻,所以不知道有没有错误.但实验了几个都ok. #include <iostream> #include <v ...
- python if __name__ == '__main__'解析
废话不多说,正题: python中所有的模块都有一个内置属性 __name__,一个模块的 __name__ 的值取决于如何应用模块.如果 import 一个模块,那么模块__name__ 的值通常为 ...
- 【XLL API 函数】xlUDF
调用用户定义函数,这个函数允许DLL 调用 VBA 中的用户定义函数,XLM 宏语言函数,以及在其它 add-ins 中注册的函数. 原型 Excel12(xlUDF, LPXLOPER12 pxRe ...
- VB.NET 注册表基本操作
''' <summary> ''' 注册表设置值 ''' </summary> ''' <param name="strKey"></pa ...
- 群内大神与你交流WEB经验 业内专家指点就职技巧
就知道你是一个有理想要抱负的人,不会满足于做一个初级的前端开发工程师.在接下来的这个阶段,我们将走上前端开发的进阶之路,将自己的能力再往上拔高一个等级.同样,薪资也会往上升一个等级!但是,如果你是一个 ...
- 模拟赛1030d2
他[问题描述]一张长度为N的纸带, 我们可以从左至右编号为0 − N( 纸带最左端标号为0). 现在有M次操作, 每次将纸带沿着某个位置进行折叠, 问所有操作之后纸带的长度是多少.[输入格式]第一行两 ...