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);