Advertisement

语音信号处理基础(四)—语音编辑

阅读量:

语音信号处理基础(四)—语音编辑

文章目录

  • 语音信号处理基础(四)—语音编辑
    • 实验目的
    • 实验原理
      • 1.信号的叠加
      • 2.信号的卷积
      • 3.信号采样频率的变换

实验目的

1.掌握语音信号线性叠加的方法,实现非等长语音信号的叠加

2.熟悉语音信号卷积原理,实现两语音卷积。

3.熟悉语音信号升采样/降采样方法。

实验原理

1.信号的叠加

两个信号X1和X2,通过短时信号的补零,使两语音信号有相同的长度,叠加信号为
X_{new}=X_1+X_2
叠加白噪声通过生成随机信号的方法来实现

举例

在一个音频信号上叠加一个信噪比为10dB的高斯白噪声,并播放声音对比

实现代码

复制代码
    %语音信号叠加
    clc
    clear all
    [x,fs]=audioread('C2_2_y.wav');
    s=1:length(x);
    t=s/fs;
    xmax=max(abs(x));               %归一化处理
    x=x/xmax;                      
    y=awgn(x,10);        %在原始信号上叠加信噪比为10dB的高斯白噪声
    ymax=max(abs(y));
    y1=y/ymax;
    
    subplot(211) 
    plot(t,x);                      %画出原始信号的幅度谱
    xlabel('时间/s');
    ylabel('归一化幅值');
    title('(a)原始信号');
    subplot(212)
    plot(t,y1);                 %画出加10dB高斯白噪声后归一化的幅度谱
    xlabel('时间/s');
    ylabel('归一化幅值');
    title('(b)随机序列');
    
    sound(x);             %播放原始语音
    pause(7);
    sound(y1);            %播放加10dB高斯白噪声后的语音
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

运行结果
在这里插入图片描述

2.信号的卷积

两序列卷积的定义为
y(n)=\sum_{k=-\infty}^{\infty} x_{1}(k) x_{2}(n-k)=x_{1}(n) * x_{2}(n)
注意:产生的序列y(n)长度为两序列长度之和减1

MATLAB中自带的卷积函数为conv()

语法

复制代码
    w=conv(u,v)
    
    
      
    

此函数将矢量u和v进行卷积运算。从代数上讲,卷积是与多项式相乘。这此多项式的系数就是u和v中的元素。

例 一个语音信号与等长的随机序列进行卷积

实现代码

复制代码
    %:语音信号卷积
    clc 
    clear all
    [x,fs]=audioread('C2_2_y.wav');
    s=1:length(x);
    t=s/fs;
    xmax=max(abs(x));            %归一化
    x=x/xmax;                    
    y=randn(size(x));            %产生同x相同长度的随机序列
    ymax=max(abs(y));            %归一化
    y=y/ymax;                     
    z=conv(x,y);
    zmax=max(abs(z));
    z=z/zmax;
    t2=(1:length(z))/fs;
    figure(1)
    subplot(311)
    plot(t,x);                   %画出原始信号
    xlabel('时间/s');
    ylabel('归一化幅值');
    title('(a)原始信号');
    subplot(312)
    plot(t,y);                   %画出随机序列
    xlabel('时间/s');
    ylabel('归一化幅值');
    title('(b)随机序列');
    subplot(313)
    plot(t2,z);                  %画出卷积结果
    xlabel('时间/s');
    ylabel('归一化幅值');
    title('(c)信号卷积');
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

运行结果
在这里插入图片描述
自己编写卷积函数与上面的结果对比

实现代码

复制代码
    %不调用conv()函数,实现语音信号的卷积
    clc 
    clear all
    [x,fs]=audioread('C2_2_y.wav');%读取语音信号
    s=1:length(x);
    t=s/fs;
    xmax=max(abs(x));            %归一化
    x=x/xmax;       
    y=randn(size(x));            %产生同x相同长度的随机序列
    ymax=max(abs(y));            %归一化
    y=y/ymax;  
    z = my_conv(x,y);      %计算卷积
    zmax=max(abs(z));      %归一化
    z=z/zmax;
    t2=(1:length(z))/fs;
    subplot(311)
    plot(t,x);             %画出原始信号
    xlabel('时间/s');
    ylabel('归一化幅值');
    title('(a)原始信号');
    subplot(312)
    plot(t,y);             %画出随机序列
    xlabel('时间/s');
    ylabel('归一化幅值');
    title('(b)随机序列');
    subplot(313)
    plot(t2,z);            %画出卷积结果
    xlabel('时间/s');
    ylabel('归一化幅值');
    title('(c)信号卷积');
    
    function a=my_conv(b,c) %定义自卷积函数
    bs=size(b);             %求b和c的大小
    cs=size(c);
    i=any(bs-cs);           %判断b和c的大小是否相等
    if i                    %如果相等
    error('error')
    end
    i=any(~(bs-1));
    if ~i                   %如果不相等
    error('error')
    end
    ko=0;
    if bs(1)>bs(2)          %调整b中的元素,使其按从小到大排序,并转置
    b=b';
    c=c';
    ko=1;
    end
    bs=size(b);
    cs=size(c);
    ss=2*bs(2)-1;
    a=zeros(1,ss);
    for i=1:cs(2)           %相乘后再相加
    q=zeros(1,i-1);
    p=zeros(1,ss-cs(2)+1-i);
    ba=[q,c,p];
    ma=b(i)*ba;
    a=a+ma;
    end
    if ko                   %如果元素排好序后,取转置
    a=a';
    end
    end 
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

运行结果
在这里插入图片描述

3.信号采样频率的变换

采样率变换是多采样率信号处理的基础,主要由两个操作组成:抽取和内插。

抽取就是把原采样序列x(n)每隔D-1点取一个值,形成一个新的序列:
x_{D}(m)=x(m D)
其中,D为正整数。

注:为了避免抽取序列频谱的混叠,通常需要在抽取前,将信号通过一个抗混叠滤波器。 ( 抗混叠滤波器是ADC之前为了消除模拟信号中频率高于奈奎斯特采样频率的信号成份,以让系统过去正确的低频信号,本质上,抗混叠滤波器是低通滤波器。)

内插器和抽取器作用相反,它在两个原始序列的样点之间插入I-1个值。设原始序列为x(n),则内插后的序列x_I(m)为:
x_{1}(m)=\left\{\begin{array}{ll}{x\left(\frac{m}{I}\right),} & {m=0, \pm I, \pm 2 I \cdots} \\ {0,} & {\text { others }}\end{array}\right.
注:内插之后还要通过低通滤波器,抑制混叠信号

MATLAB中自带函数**resample()**能实现采样率的变换

语法

复制代码
    y = resample(x,p,q)
    
    
      
    

-采用多相滤波器 对时间序列进行重采样,得到的序列y的长度为原来的序列x的长度的p/q倍,p和q都为正整数.此时,默认采用使用FIR方法设计的抗混叠的低通滤波器.

复制代码
    y = resample(x,p,q,n)
    
    
      
    

采用chebyshev IIR型低通滤波器 对时间序列进行重采样,滤波器的长度与n成比例,n默认值为10

例:

对简单的线性序列进行为原采样率3/2倍的重采样

实现代码

复制代码
    %语音信号采样频率变换
    clc
    clear all
    [x,fs]=audioread('C2_2_y.wav');  %读取音频文件
    s=1:length(x);            %采样长度
    t=s/fs;                   %采样时间
    xmax=max(abs(x));         %归一化处理
    x=x/xmax;
    
    figure(1)
    subplot(311)           
    axis([0 5 -1 1]);       %设定x轴与y轴的显示范围
    plot(t,x);              %画出原始信号的幅度谱
    xlabel('时间/s');
    ylabel('归一化幅值');
    title('(a)原始信号');
    
    p=2;q=1;                %设定初始值
    x1=resample(x,p,q);     %采样率变换,得到的序列y的长度为原来的序列x的长度的p/q倍
    x1max=max(abs(x1));     %归一化
    x1=x1/x1max;
    fs1=fs*p/q;             %得到原始采样频率2倍的采样频率
    t1=(1:length(x1))/fs1;  %得到在新的采样频率对应的采样时间
    subplot(312);   
    axis([0 5 -1 1]);       %设定x轴与y轴的显示范围
    plot(t1,x1);            %画出2倍采样频率下的幅度谱
    xlabel('时间/s');
    ylabel('归一化幅值');
    title('(b)2倍采样率');
    
    p=1;q=2;                 %设定初始值
    x2=resample(x,p,q);      %采样率变换,得到的序列y的长度为原来的序列x的长度的p/q倍
    x2max=max(abs(x2));      %归一化
    x2=x2/x2max;
    fs2=fs*p/q;               %得到原始采样频率1/2倍的采样频率
    t2=(1:length(x2))/fs2;
    subplot(313);
    axis([0 5 -1 1]);         %设定x轴与y轴的显示范围
    plot(t2,x2);              %画出1/2倍采样频率下的幅度谱
    xlabel('时间/s');
    ylabel('归一化幅值');
    title('(c)1/2采样率');
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

运行结果
在这里插入图片描述
可以通过播放采集到的音频信号,分辨他们的效果

实现代码

复制代码
    %语音信号采样频率变换
    clc
    clear all
    [x,fs]=audioread('C2_2_y.wav');  %读取音频文件
    s=1:length(x);            %采样长度
    t=s/fs;                   %采样时间
    xmax=max(abs(x));         %归一化处理
    x=x/xmax;
    
    p=2;q=1;                %设定初始值
    x1=resample(x,p,q);     %得到的序列y的长度为原来的序列x的长度的p/q倍
    x1max=max(abs(x1));     %归一化
    x1=x1/x1max;
    fs1=fs*p/q;             %得到原始采样频率2倍的采样频率
    t1=(1:length(x1))/fs1;  %得到在新的采样频率对应的采样时间
    
    p=1;q=2;                 %设定初始值
    x2=resample(x,p,q);      %得到的序列y的长度为原来的序列x的长度的p/q倍
    x2max=max(abs(x2));      %归一化
    x2=x2/x2max;
    fs2=fs*p/q;              %得到原始采样频率1/2倍的采样频率
    t2=(1:length(x2))/fs2;
    
    sound(x,fs);          %播放以初始采样率采样后的声音
    pause(5)              %暂停4s,与后面的声音分开
    sound(x1,fs1);        %播放以1/2倍采样率采样后的声音
    pause(5)              %暂停4s,与后面的声音分开
    sound(x2,fs2);        %播放以2倍采样率采样后的声音
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

全部评论 (0)

还没有任何评论哟~