Uprzejmator - aktualizacja

Rozpoznawanie płci mówcy na podstawie dźwięku głosu

Projekt uprzejmator, który zrealizowałem kilka miesięcy temu, dotyczył małego elektronicznego awatara, którego przeznaczeniem było uprzejme wysłuchiwanie kierowanych do właściciela słów (w jego zastępstwie). Uprzejmator potrafi skierować głowę w stronę źródła dźwięku i podtrzymać „konwersację” losową, lecz uprzejmą uwagą. W zasadzie działa to dobrze. Pomyślałem jednak, że może warto by było rozwinąć nieco projekt – uwagi kierowane do rozmówcy mogą być nieco bardziej zróżnicowane, na przykład ze względu na płeć. Nie chodzi tu o żadną planowaną dyskryminację, po prostu wydaje mi się, że wypowiedzenie do mężczyzny słów „świetna fryzura” może mieć inne efekty niż w przypadku skierowania tych samych słów do kobiety. Jeśli kogoś to nie przekonuje, to jest jeszcze jeden argument – szacunek dla języka polskiego. Zasady deklinacji wymuszają na nas stosowanie odmiennych końcówek wyrazów w zdaniach kierowanych do mężczyzn i kobiet. Cokolwiek by nie było motywacją, problem jest jeden: jak sprawić, by maszyna rozpoznała płeć rozmówcy.

Analiza częstotliwościowa

Jeśli „przyglądnąć” się temu, jak wygląda ta sama kwestia („MATLAB i Simulink”) wypowiedziana przez kobietę i przez mężczyznę, to ze znalezieniem istotnych różnic może być problem.

[data1, Fs] = audioread('bernadeta.wav');
data2 = audioread('maciej.wav');

t = 0:1/Fs:2-1/Fs;
subplot(2,1,1); plot(t, data1);ylim([-0.5 0.5]); title('Bernadeta'); xlabel('czas [s]');
subplot(2,1,2); plot(t, data2); ylim([-0.5 0.5]); title('Maciej'); xlabel('czas [s]')

Oczywiście, przyglądanie się wyłącznie przebiegom czasowym bardzo rzadko wystarczy w jakiejkolwiek analizie sygnałów. W tym wypadku wykonanie zwykłego fft, lub nawet metody pwelch na pobranych próbkach dźwięku może nie wystarczyć. Można mniej więcej stwierdzić, dla jakich częstotliwości pojawia się coś istotnego, jednak gdyby sygnał składał się z mniejszej ilości próbek, ustalenie wyraźnego progu byłoby trudne.

[D1, f] = pwelch(data1, 256,64,256, Fs); xlim([0 0.5]); title('Agnieszka')
D2 = pwelch(data2, 256,64,256, Fs);xlim([0 0.5]); title('Maciej')
D3 = pwelch(data3, 256,64,256, Fs);xlim([0 0.5]);title('Jaromir')
D4 = pwelch(data4, 256,64,256, Fs);xlim([0 0.5]);title('Bernadeta')

subplot(2,2,1); plot(f, D1); title('Agnieszka'); xlim([0 500]); xlabel('Częstotliwość [Hz]');
subplot(2,2,2); plot(f, D2); title('Maciej'); xlim([0 500]);xlabel('Częstotliwość [Hz]');
subplot(2,2,3); plot(f, D3); title('Jaromir');xlim([0 500]);xlabel('Częstotliwość [Hz]');
subplot(2,2,4); plot(f, D4); title('Bernadeta');xlim([0 500]);xlabel('Częstotliwość [Hz]');

Analiza korelacyjna

Każdy wypowiedziany przez człowieka wyraz składa się z głosek dźwięcznych i bezdźwięcznych. Istnieje, zdaje się, dokładniejszy podział, jednak z całą pewnością można wyróżnić głoski, które „dźwięczą”, ponieważ podczas wyrzucania ich w przestrzeń drgają struny głosowe, i takie, których tworzenie oparte jest na innych właściwościach toru głosowego. U kobiet będzie dźwięczało trochę wyżej niż u mężczyzn. W związku z tym pomysł na wykrycie płci mówcy może polegać na wyszukaniu w sygnale mowy tych dźwięczących fragmentów i określenie „częstotliwości podstawowej” właśnie na ich podstawie. Wykrycie dźwięczących fragmentów można zrealizować korzystając z funkcji autokorelacji. Jeśli w danym fragmencie dźwięku funkcja autokorelacji wykryje okresowość, można wyznaczyć okres i co za tym idzie częstotliwość dominującą dla danego fragmentu. Jeśli analizowany fragment nie zdradza żadnych objawów okresowości, (bo na przykład „szu” szumi), możn go po prostu pominąć.

N = length(data);
Mlen=256; % długość okna
Mstep=192; % liczba próbek, o które przesuwane jest okno
Nramek=floor((N-Mlen)/Mstep+1);	% liczba fragmentów (ramek) do przetworzenia
ramki = zeros(Mlen, Nramek); %przygotowanie miejsca na fragmenty sygnału
Xr = zeros(Mlen * 2 - 1, Nramek); % przygotowanie miejsca na autokorelacje
for i=0:Nramek-1
    ramki(:, i+1) = data(1 + i*Mstep : i*Mstep + Mlen);
    ramki(:, i+1) = ramki(:,i+1) - mean(ramki(:, i+1)); % usunięcie wartości średniej dla każdej z ramek
    [Xr(:,i+1), lags] = xcorr(ramki(:, i+1));  %wyznaczanie funkcji autokorelacji dla fragmentu
end
% poszukiwanie maksimum funkcji autokorelacji
% przy górnym ograniczeniu częstotliwości wynoszącym 400 Hz (lags > 20 dla fp = 8000))
offset = 20;
[XrMax, idxMax] = max(Xr(lags > offset,:));
idxVoiced = XrMax > 0.35*Xr(lags == 0); % wyszukanie fragmentów potencjalnie dźwięcznych
lags = lags(lags > offset);
lags = lags(idxMax(idxVoiced));
T = mean(lags) / Fs;
fpod = Fs/mean(lags)

Dzięki temu można wyznaczyć, że dla Agnieszki „częstotliwość podstawowa” wynosi 202 Hz, a dla Macieja 105 Hz.
Teraz wystarczy zaadaptować algorytm na rzecz uprzejmatora, będzie jeszcze uprzejmiej 🙂

(Visited 109 times, 1 visits today)

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *