码迷,mamicode.com
首页 > 其他好文 > 详细

通信原理实践(一)——音频信号处理

时间:2015-10-02 17:22:54      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:

一、信号的离散化

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

通信原理实践(一)——音频信号处理

标签:

原文地址:http://www.cnblogs.com/BlueMountain-HaggenDazs/p/4852343.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!