Speex中的近端信号去直流和预加重操作

speex_echo_cancellation中收到的近端信号,首先进行了去直流和预加重的操作。

Speex中的近端信号去直流和预加重操作_第1张图片
近端信号预处理

去直流
/* Apply a notch filter to make sure DC doesn't end up causing problems */
        filter_dc_notch16(in + chan, 
                          st->notch_radius, 
                          st->input + chan*st->frame_size, 
                          st->frame_size, 
                          st->notch_mem + 2*chan, 
                          C);

其中in中保存的是原始的近端信号,st->input中保存的是去直流之后的信号。
利用matlab进行频域分析,


Speex中的近端信号去直流和预加重操作_第2张图片
去直流频域分析

预加重操作

/* Copy input data to buffer and apply pre-emphasis */
        /* Copy input data to buffer */
        for (i = 0; i < st->frame_size; i++)
        {
            spx_word32_t tmp32;
            /* FIXME: This core has changed a bit, need to merge properly */
            tmp32 = SUB32(EXTEND32(st->input[chan*st->frame_size+i]), 
                          EXTEND32(MULT16_16_P15(st->preemph, st->memD[chan])));

#ifdef FIXED_POINT
            if (tmp32 > 32767)
            {
                tmp32 = 32767;
                if (st->saturated == 0)
                    st->saturated = 1;
            }      
            if (tmp32 < -32767)
            {
                tmp32 = -32767;
                if (st->saturated == 0)
                    st->saturated = 1;
            }
#endif
            st->memD[chan] = st->input[chan*st->frame_size+i];
            st->input[chan*st->frame_size+i] = EXTRACT16(tmp32);
        }

用matlab进行频谱分析,


Speex中的近端信号去直流和预加重操作_第3张图片
预加重之后频谱分析

matlab代码如下:

clear
Fs = 48000;       % 采样频率
T  = 1/Fs;       % 采样时间
L  = 480;        % 信号长度
t  = (0:L-1)*T; % 时间
y  = textread('fp_TIME_near_001.txt');
y2 = textread('fp_TIME_near002_after_filter_dc.txt');
y3 = textread('fp_TIME_near003_after_pre-emphasis.txt');

N = 2^nextpow2(L); %采样点数,采样点数越大,分辨的频率越精确,N>=L,超出的部分信号补为0

% y
Y = fft(y,N)/N*2;   %除以N乘以2才是真实幅值,N越大,幅值精度越高
f = Fs/N*(0:1:N-1); %频率
A = abs(Y);     %幅值
P = angle(Y);   %相值

% y2
Y2 = fft(y2,N)/N*2;   %除以N乘以2才是真实幅值,N越大,幅值精度越高
f2 = Fs/N*(0:1:N-1); %频率
A2 = abs(Y2);     %幅值
P2 = angle(Y2);   %相值

% y3
Y3 = fft(y3,N)/N*2;   %除以N乘以2才是真实幅值,N越大,幅值精度越高
f3 = Fs/N*(0:1:N-1); %频率
A3 = abs(Y3);     %幅值
P3 = angle(Y3);   %相值

figure;
subplot(411);
%plot(t, y, 'k')
hold on
plot(t, y2, 'r')
hold on 
plot(t, y3, 'b')

legend('2: 去直流后','3: 预加重后') %为图片添加图例

title('时域信号')
xlabel('时间(s)')


subplot(412); 
%plot(f(1:N/2), A(1:N/2),'k');   %函数fft返回值的数据结构具有对称性,因此我们只取前一半
hold on
plot(f2(1:N/2), A2(1:N/2), 'r');   
hold on
plot(f3(1:N/2), A3(1:N/2), 'b');   

title('幅值频谱(前半部分)')
xlabel('频率(Hz)')
ylabel('幅值')

subplot(413); 
%plot(f(1:10), A(1:10),'k');  
hold on
plot(f2(1:20), A2(1:20), 'r');   
hold on
plot(f3(1:20), A3(1:20), 'b');  

title('幅值频谱(放大最前部分)')
xlabel('频率(Hz)')
ylabel('幅值')

subplot(414); 
%plot(f(1:10), A(1:10),'k');   
hold on
plot(f2(21:240), A2(21:240), 'r');   
hold on
plot(f3(21:240), A3(21:240), 'b');   

title('幅值频谱(放大最后部分)')
xlabel('频率(Hz)')
ylabel('幅值')

你可能感兴趣的:(Speex中的近端信号去直流和预加重操作)