Estymacja i redukcja zakłóceń w sygnale mowy
Autorzy: Adam Borowicz
Pliki: rozdzial_13.zip
Przykład 13.1
Przykład (plik przyklad_13_1.m) realizuje uśrednianie wykładnicze widma mocy w ramkach . Argumentami wejściowymi funkcji są: wektor zawierający próbki sygnału, parametr uśredniający oraz indeks próbki częstotliwościowej, dla której są wyświetlane rezultaty. Zasadnicze znaczenie ma tu parametr uśredniający alfa, od którego zależy nie tylko wariancja estymatora, ale również jego obciążenie.function expavg(x, alpha, k)
N = 256;
K = 128;
x = x(:);
l = 1;
Pdd(:,l) = zeros(N,1);
for n = 1:N-K:length(x)-N,
l=l+1;
% krótkookresowe widmo mocy
X2(:,l) = abs(fft(x(n:n+N-1))).^2;
% uśrednianie wykładnicze widma mocy w ramkach
Pdd(:,l) = alpha * Pdd(:,l-1) + (1-alpha) * X2(:,l);
end;
plot(10*log10( X2(k,:)+1e-6), ’b:’), hold on;
plot(10*log10(Pdd(k,:)+1e-6), ’r-’);
Przykład 13.2
Przykład (plik przyklad_13_2.m) przedstawia implementację detektora energetycznego. Ze względu na nieznany początkowy poziom energii szumu algorytm może generować błędy, dlatego też do jego poprawnej pracy jest wymagana początkowa faza adaptacji, umożliwiająca dostrojenie parametrów początkowych do aktualnej charakterystyki zakłóceń.function ym = edet(x, alpha, lambda)
N = 256; % długość ramki
K = 128; % nakładanie się ramek
adpt = 40; % czas adaptacji (liczba ramek)
x = x(:);
m = 0;
for n = 1:N-K:length(x)-N,
m = m + 1;
xw = x(n:n+N-1); % obliczanie energii w m-tej ramce
ex(m) = xw'*xw;
if m > adpt & ex(m) > thr(m-1), % wypowiedź
ym(m) = 1;
thr(m) = thr(m-1);
else % przerwa w wypowiedzi
ym(m) = 0;
if m == 1, ed = ex(m); ed2 = ed^2; end;
ed = alpha*ed + (1-alpha)*ex(m); % est. wartości oczek.
ed2 = alpha*ed2 + (1-alpha)*ex(m)^2; % est. wariancji
thr(m) = ed + lambda*sqrt(abs(ed2 - ed2^2)); % próg decyzyjny
end;
end;
Przykład 13.3
Przykład (plik przyklad_13_3.m) zawiera uproszczony fragment kodu, realizujący mechanizm korekcji błędów przypadkowych.count1 = 0;
count2 = 0;
M = 3;
for m = 1:liczba_ramek,
I = ... % obliczanie decyzji detektora (1 - mowa, 0 - przerwa)
if I == 1,
% korekcja błędów w trakcie wypowiedzi
count2 = 0; count1 = count1 + 1;
if count1 > M, ym(m) = 1; else ym(m) = ym(m-1); end;
else
% korekcja w przerwach
count1 = 0; count2 = count2 + 1;
if count2 > M, ym(m) = 0; else ym(m) = ym(m-1); end;
end;
end;
Przykład 13.4
Przykład (plik przyklad_13_4.m) przedstawia implementację estymatora MCRA w dla l-tej ramki sygnału. Funkcja wymaga przekazania estymaty widmowej mocy sygnału zakłóconego w postaci wektora Pxx. Konieczna jest również inicjalizacja struktury parameters, zawierającej oszacowania parametrów z poprzedniej ramki.function parameters = MCRA_estimation(Pxx, parameters)
alpha = 0.95;
beta = 0.1;
delta = 2.5;
L = 50;
% oszacowania z poprzedniej ramki
pkl = parameters.pkl; % szacunkowe prawdopodob. wypowiedzi
l = parameters.l; % indeks ramki
Pmin = parameters.Pmin; % estymata minimum statystyki
Ptmp = parameters.Ptmp; % wektor pomocniczy
if rem(l,L)==0
Pmin = min(Ptmp,Pxx);
Ptmp = Pxx;
else
Pmin = min(Pmin,Pxx); Ptmp = min(Ptmp,Pxx);
end
Srk = Pxx./Pmin;
Ikl = zeros(length(Srk),1);
Ikl(find(Srk > delta)) = 1;
pkl = beta*pkl + (1-beta) * Ikl; % prawdopodob. wypowiedzi
alpha_t = alpha + (1-alpha)*pkl; % parametr uśredniający
Pdd = alpha_t.*Pdd + (1-alpha_t).*Pxx; % estymacja PSD szumu
% zapis parametrów dla ramki l+1
parameters.pkl = pkl;
parameters.l = l+1;
parameters.Pdd = Pdd;
parameters.Pmin = Pmin;
parameters.Ptmp = Ptmp;
Przykład 13.5
Program w języku MATLAB (plik przyklad_13_5.m), realizujący metodę różnic widmowych. W algorytmie tym przyjęto dla uproszczenia, że początkowe okna sygnału zakłóconego zawierają wyłącznie szum. Widmo szumu jest estymowane dla pierwszych 10 ramek sygnału, z wykorzystaniem średniej arytmetycznej.function y = ss_nr(x)
x = x(:); % wymuszenie notacji kolumnowej
N = 256; % długość ramki (w próbkach), musi być parzysta!
K = 128; % nakładanie się ramek (l. próbek)
W = hann(nw); % funkcja okna analizy
a = 1; % typ metody: 1 - MSS, 2 - PSS
lmbd = 3; % współczynnik kompensacji
N2 = N/2+1;
y = zeros(size(x));
Da = zeros(N2,1);
Xa = zeros(N2,1);
for n = 1:N-K:length(x)-N,
% analiza
sel = n:n+N-1;
X = fft(x(sel).*W);
Xa = abs(X(1:N2)).^a;
% estymacja szumu w oparciu o 10 początkowych ramek
if n < 10, Da = ((n-1)*Da + Xa)/n; end;
% ważenie widmowe
Gss = max(1 - lmbd*(Da./(Xa+eps)), 0).^(1/a);
Y = X(1:N2) .* Gss;
% synteza
Y(N2+1:N) = flipud(conj(Y(2:N2-1))); % odtworzenie symetrii DFT
y(sel) = y(sel)+real(ifft(Y))./max(W); % nakładanie z dodawaniem
end;
subplot(2,1,1);
plot(x);
subplot(2,1,2);
plot(y);
Przykład 13.6
W przykładzie (plik przyklad_13_6.m) przedstawiono implementację estymatora TDC w języku MATLAB. Dla uproszczenia przyjęto założenie, że sygnałem zakłócającym jest szum biały, jednak w ogólnym przypadku należałoby przeprowadzić wstępne wybielanie sygnału zakłóconego. Ponadto w celu przyśpieszenia obliczeń, sąsiadujące ze sobą wektory x(l) są grupowane w kolumnach macierzy trajektorii, po czym przemnażane przez tę samą macierz KLT. Uzyskane współczynniki są modyfikowane przy użyciu diagonalnej macierzy wagowej i transformowane z powrotem do dziedziny czasu. Ramki sygnału uzdatnionego są uzyskiwane z wynikowej macierzy trajektorii poprzez uśrednianie diagonalne.function y = tdc_nr(x)
N = 32; % wymiar przestrzeni sygnału
M = 256; % długość ramki (l. próbek)
K = 128; % nakładanie się ramek (l. próbek)
Lmbd_thr = 3e-3; % parametr progowy dla wartości własnych
mu = 5; % mnożnik Lagrange'a
x = x(:);
y = zeros(size(x));
W = bartlett(M);
% estymacja wariancji szumu na podstawie 1000 pierwszych próbek sygnału x
sigma2_d = var(x(1:1000));
for n = 1:M-K:length(x)-N, % przetwarzanie w ramkach
sel = n:n+M-1;
Xt = buffer(x(sel),N,N-1,’nodelay’); % mac. trajektorii
Cx = (Xt*Xt’)./size(Xt,2); % empiryczna mac. kowariancji
Cy = Cx - sigma2_d*eye(N); % est. mac. kowariancji mowy
[Uy, Lmbd_y] = eig(Cy); % est. mac. KLT i war. własnych
Lmbd_y = diag(Lmbd_y);
I = find(Lmbd_y > Lmbd_thr); % progowanie war. własnych
g_tdc = zeros(N,1);
g_tdc(I) = Lmbd_y(I)./(Lmbd_y(I) + mu*sigma2_d); % wsp. filtru TDC
Yt = Uy * (diag(g_tdc) * (Uy’ * Xt)); % filtracja
% uśrednianie diagonalne (synteza sygnału)
Y = zeros(M,1);
w = zeros(M,1);
i = 1:N;
for m = 1:size(Yt,2),
Y(i) = Y(i) + Yt(:,m);
w(i) = w(i) + 1;
i = i+1;
end;
% nakładanie (uśrednianie) ramek z dodawaniem
y(sel) = y(sel) + (Y./w).*W;
end;
subplot(2,1,1);
plot(x);
subplot(2,1,2);
plot(y);