一、信号的离散化

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. Nova PhoneGap框架 第四章 本地数据库
  2. 【转】oracle中in和exists的区别
  3. Android Studio -修改LogCat的颜色
  4. 网络请求之JSON解析
  5. 后缀数组 POJ 3261 Milk Patterns
  6. DOM节点关系,节点关系
  7. Java高级之虚拟机垃圾回收机制
  8. HDU4277 USACO ORZ(dfs+set)
  9. uva 10306
  10. Android Scroller类的详细分析
  11. C++对象模型--总结
  12. HDU 2414 Chessboard Dance (力模拟)
  13. iptables防火墙详解
  14. 第14章 Linux开机详细流程
  15. ARM开发(3)基于STM32的矩阵键盘控制蜂鸣器
  16. 流行的报表生成工具-JXLS
  17. Pycharm问题:module &#39;pip&#39; has no attribute &#39;main&#39;
  18. asp.net mvc学习(Vs技巧与Httpcontext)
  19. 自动把动态的jsp页面(或静态html)生成PDF文档,并且上传至服务器
  20. tornado 异步

热门文章

  1. [Linux]centOS7下RPM安装Perl
  2. c++ 引用和指针
  3. Tomcat服务器绑定域名的配置
  4. ffmpeg-20160714-git-bin.7z
  5. QT Creator调用动态链接库实例
  6. linux查看系统版本和系统位数
  7. MySQL 获得当前日期时间\时间戳 函数 ( 转自传智播客)
  8. objective-c可变数组
  9. Android笔记:管理所有活动
  10. 3dmax导出3ds具有过多要导出的面超过64k解决方法