\documentclass{book}

\usepackage[polish]{babel}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{color}
\usepackage[usenames,dvipsnames,svgnames]{xcolor}
\usepackage{hyperref}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning}
\usetikzlibrary{trees}

\begin{document}


\begin{titlepage}
\today

\vspace{5cm}
\Huge
\begin{center}

Instrukcja użytkowania systemu rozpoznawania mowy w projekcie SYNAT

\Large
\vspace{2cm}
wersja 2\_20140325

\large
\vspace{2cm}
Danijel Kor\v{z}inek, Polsko-Japońska Wyższa Szkoła Technik Komputerowych

\url{danijel@pjwstk.edu.pl}
\end{center}
\end{titlepage}

\tableofcontents

\chapter{Wprowadzenie}

Dokument ten ma za zadanie opisanie procedury instalacji i użytkowania systemu
rozpoznawania mowy robionego w ramach projektu SYNAT przez Polsko-Japońską
Wyższą Szkołę Technik Komputerowych.

Dokument składa się z dwóch części: najpierw jest opisana wersja systemu
stworzona w roku 2013. oparta o dekoder Julius, a póżniej jest opisana wersja
systemu z 2014. roku oparta o dekoder Kaldi.

\section{Struktura katalogów}

\tikzstyle{every node}=[anchor=west]
\begin{tikzpicture}[
  grow via three points={one child at (0.5,-0.7) and
  two children at (0.5,-0.7) and (0.5,-1.4)},
  edge from parent path={(\tikzparentnode.south) |- (\tikzchildnode.west)}]
\node {\texttt{speech-recognition-pjwstk}}
    child { node {\texttt{apps}}
    	child { node {\texttt{ffmpeg} - dekoder multimedialny}}
    	child { node {\texttt{julius4} - system rozpoznawania mowy}}
    	child { node {\texttt{shout} - program do VAD}}
    	child { node {\texttt{SynatASRTools} - program z przydatnymi narzędziami}}
    	child { node {\texttt{kaldi-trunk} - nowy, lepszy system rozpoznawania
    	mowy}} }
    child [missing] {}					
    child [missing] {}				
    child [missing] {}				
    child [missing] {}
    child [missing] {}		
    child { node {\texttt{conf}}
    	child { node {\texttt{dictionary.dic} - słownik fonetyczny}}  
    	child { node {\texttt{julius.jconf} - plik konfiguracyjny Juliusa}}  
    	child { node {\texttt{triphones.mmf} - model akustyczny}}
    	child { node {\texttt{hcopy.conf} - plik konfiguracyjny z parametryzacją sygnału}}      
    	child { node {\texttt{model.jlm} - model języka}}     
    	child { node {\texttt{triphone\_tied.list} - lista modeli akustycznych}}
    	child { node {\texttt{final.mdl} - model akustyczny dla systemu KALDI}}
    	child { node {\texttt{HCLG.fst} - model FST dla systemu KALDI }}
    	child { node {\texttt{word\_boundary.int} - lista cech granicznych fonemów
    	KALDI}} 
    	child { node {\texttt{words.txt} - lista wyrazów dla KALDI}} }
    child [missing] {}
    child [missing] {} 
    child [missing] {} 
    child [missing] {} 
    child [missing] {}  
    child [missing] {}				
    child [missing] {}				
    child [missing] {}				
    child [missing] {}
    child [missing] {}
    child { node {\texttt{doc} - dokumentacja projektu}}
    child { node {\texttt{demo} - pliki testowe}};
\end{tikzpicture}

\chapter{Pierwsza wersja systemu - Julius}

System ten opracowano na podstawie wymagań projektu SYNAT we wrześniu 2013.
roku.

\section{Architektura systemu}

System wymaga 3 różnych komponentów:
\begin{enumerate}
  \item dekodera plików multimedialnych - media decoder
  \item systemu detekcji mowy - VAD\footnote{VAD - voice activity detection}
  \item systemu rozpoznawania mowy - ASR\footnote{ASR - automatic speech recognition}
\end{enumerate}
oraz kilku programów pomocniczych wspomagających komunikację powyższych
komponentów i interpretację ich wyników.

\begin{figure}[h]
\begin{center}
\begin{tikzpicture}[thick]

\node (f) {media file};
\node[draw,rectangle,right=of f] (a) {Media decoder};
\node[draw,rectangle,right=of a] (b) {VAD};
\node[draw,rectangle,right=of b] (c) {ASR};
\node[right=of c] (o) {result};

\draw[->] (f) to (a);
\draw[->] (a) to (b);
\draw[->] (b) to (c);
\draw[->] (c) to (o);

\end{tikzpicture}
\end{center}
\caption{Ilustracja architektury systemu.}
\end{figure}

\subsection{Użyte narzędzia}

Jako dekodera multimedialnego użyto popularnego oprogramowania typu opensource
FFMPEG jaki można ściągnąć ze strony \url{http://ffmpeg.org/}.

Do detekcji mowy użyto jednego narzędzia zawartego w systemie rozpoznawania mowy
SHOUT, ze strony \url{http://shout-toolkit.sourceforge.net/}.

Jako główny system rozpoznawania mowy, użyto otwartego silnika rozpoznawania
mowy Julius. Można go znaleźć pod adresem:

\url{http://julius.sourceforge.jp/en_index.php?q=index-en.html}

\subsection{Licencje}

\label{sec:lic1}

FFMPEG jest opublikowany przeważnie na licencji LGPLv2.1, a częściowo na GPLv2.
Istnieje potencjalne ryzyko związane z użyciem opatentowanych kodeków, ale jest
ono raczej nikłe. Więcej informacji na ten temat można znaleźć pod adresem:

\url{http://ffmpeg.org/legal.html}

Według dokumentu załączonego do kodu źródłowego SHOUT jest licenjonowany na
licencji GPLv2.

Julius posiada dosyć wolną licencję i jako taki może być używany zarówno
komercyjnie jak i w dowolny inny sposób. Licencja dostępna pod adresem:

\url{http://julius.sourceforge.jp/LICENSE.txt}

Pozostałe pliki (w tym przede wszystkim modele statystyczne) zostały całkowicie
stowrzone w Polsko-Japońskiej Wyższej Szkole Technik Komputerowych na potrzeby
projektu SYNAT i nie mogą być używane do żadnego innego celu bez zgody autorów.

\section{Instalacja}

\subsection{Kompilacja FFMPEG}

\label{sec:inst1:ffmpeg}

\textcolor{red}{UWAGA: Jeśli system posiada już zainstalowany program ``ffmpeg'', 
albo istnieje inny sposób na jego zainstalowanie, można bezpiecznie pominąć ten krok!}

Program ściągnięto według instrukcji ze strony projektu: 

\url{http://ffmpeg.org/download.html} 

Wywołądno polecenie:
\begin{verbatim}
git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
\end{verbatim}
(Data ściągnięcia: 9. stycznia 2013)

Kompilacja programu ffmpeg jest rzeczą powszechnie znaną. Jest to zestaw
narzędzi i bibliotek umożliwiający kodowanie/dekodowanie i odtwarzanie wielu z
znanych (większości?) formatów plików multimedialnych (filmów czy muzyki).

FFMPEG nie wymaga żadnych dodatkowych bibliotek oprócz standardowego kompilatora
i assemblera (\texttt{yasm} - koniecznie sparwdzić czy jest zainstalowany!),
aczkowlwiek doisntalowanie niektórych dodatkowych bibliotek może poszerzyć jego
funkcjonalność o dodatkowe kodeki. W tej instrukcji zakładamy, że nie są
instalowane dodatkowe biblioteki.

Do kompilacji wystarczy użyć standardowych poleceń \texttt{./configure} i
\texttt{make}. Wywołanie polecenia \verb|./configure --help| zwróci listę opcji
jakich można użyć podczas kompilacji. Dla nas większe znaczenia ma polecenie:
\begin{verbatim}
./configure --list-decoders
\end{verbatim} 
żeby zobaczyć jakie formaty plików obsługujemy na wejściu programu. Poniżej jest
lista kilku zalecanych opcji:

\begin{verbatim}
./configure --enable-gpl --enable-version3 --enable-nonfree 
    --disable-ffplay --disable-ffprobe --disable-ffserver 
    --disable-doc
\end{verbatim}

Pierwsze 3 opcje umożliwią kompilowanie większej ilości funkcji, ale
uniemożliwią redystrybucję skompilowanych binarek (co zresztą nie jest dla nas
potrzebne). Kolejne opcje wyłączają kompilowanie komponentów zbędnych dla
obecnego projektu - nas właściwie interesuje tylko i wyłącznie program
\texttt{ffmpeg}.

W wyniku wywołania powyższych poleceń w katalogu z kodem źródłowym, zostanie
utowrzony program \texttt{ffmpeg} i umieszczony w tym samym katalogu gdzie
znajduje się plik \texttt{configure}.

Nie jest wymagane uruchamianie \verb|make install| gdyż możemy się odwołać
bezpośrednio do pliku wykonywalnego znajdującego się w katalogu źródłowym. W
razie potrzeby, można go przenieść do innego katalogu.

Uruchomienie polecenia \texttt{./ffmpeg} bez argumentów pokazuje opcje
kompilacji i prostą instrukcję obsługi.

\subsection{Kompilacja SHOUT}

Narzędzie ściągnięto ze strony:

\url{http://shout-toolkit.sourceforge.net/download.html} 

w wersji 0.3 i ściągnięto również model statystyczny do VAD (shout.sad) z tej
samej strony.

Do kompilacji programów SHOUT, należy mieć zainstalowane środowisko
\texttt{automake} (czyli \texttt{autoconf},\texttt{autotool},itp.) Oprócz tego
nie są wymagane żadne niestandardowe biblioteki.

Żeby skompilować programy, wystarczy uruchomić w głównym katalogu kodu
źródłowego skrypt:

\begin{verbatim}
./configure-make.sh
\end{verbatim}

Jeśli wszystko pójdzie dobrze, programy się powinny pojawić w podkatalogu
\texttt{./release/src} głównego katalogu źródłowego. Nas interesuje tylko
program o nazwie \texttt{shout\_segment} i plik \texttt{shout.sad} (model
statystyczny do VAD) obecny w głównym katalogu źródłowym.

Uruchomienie polecenia \texttt{shout\_segment} pokazuje prostą instrukcję obsługi
programu.

\subsection{Kompilacja Juliusa}

Program ściągnięto według instrukcji na stronie
\url{http://julius.sourceforge.jp/en_index.php?q=index-en.html} wywołując
polecenie:
\begin{verbatim}
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.jp:/cvsroot/julius 
    co julius4
\end{verbatim}
(Data ściągnięcia: 9. stycznia 2013)

Julius również nie wymaga żadnych zewnętrznych bibliotek. Konfiguruje się go
standardowym poleceniem \texttt{./configure}, ale koniecznie jest potrzebna
następująca opcja:

\begin{verbatim}
 ./configure --enable-words-int
\end{verbatim}

Umożliwia ona użycie słownika o ilości wyrazów większej niż 65k (to dla nas ma
dosyć duże znaczenie).

\textcolor{red}{UWAGA:} Istnieje jedna ważna zmiana w kodzie źródłowym, która
może okazać się konieczna do poprawnego funkcjonowania programu. W poniższym
pliku:
\begin{verbatim}
.\libsent\include\sent\speech.h
\end{verbatim}

istnieją dwie makrodefinicje warte uwagi. \texttt{MAXSEQNM} określa maksymalną
długość wypowiedzi (w wyrazach) jaką system może zwrócić w jednym ciągłym
fragmnecie mowy (ciągły w sensie braku przerw w wymowie). \texttt{MAXSPEECHLEN}
jest długość tego samego fragmentu w próbkach sygnału podawanego do analizy.
Czasami, podczas analizy długich nagrań, program może wyjść z krytycznym błędem
informującym o jednej z tych wartości. Obydwie wartości można zwiększyć według
potrzeby nawet dziesięcio- albo stokrotnie, pamiętając oczywiście o zwiększonej
ilości wymaganej pamięci. Według opisu na stronie internetowej, Julius normalnie
zajmuje <64 MB, więc zwiększenie tej wartości nie powinno być dużym kłopotem.


Po tych zmianach wystarczy wywołać \texttt{make} i poczekać na ukończenie procesu
kompilacji. Program o nazwie \texttt{julius} powinien się znajdować w
podkatalogu \texttt{julius} głównego katalogu źródłowego.
 
Tak jak w przypadku FFMPEG, nie jest potrzebny \verb|make install|, bo wystarczy
nam jeden plik wykonywalny. W razie potrzeby, można go przenieść do innego
katalogu.

Uruchomienie polecenia \texttt{./julius} bez argumentów pokazuje prostą
instrukcję obsługi, a \verb|./julius -setting| pokazuje opcję kompilacji
programu.

\section{Użytkowanie}

\subsection{Konwersja plików wejściowych}
\label{sect:konw_wej}

Zanim rozpoczniemy rozpoznawanie mowy, musimy przekonwertować wejściowy plik
multimedialny (plik audio albo wideo) na format rozpoznawalny przez system
reozpoznawania mowy - plik audio o określonej częstotliwości próbkowania (16000
Hz), głębi 16 bitów i jednyn kanale (mono).

Na szczęście, mając odpowiednie narzędzia, zadanie to wcale nie musi być trudne.
Biblioteka FFMPEG jest jedną z najbardziej popularnych dekoderów używanych w
wielu aplikacjach w sieci. Obsługuje ona większość znanych formatów plików
multimedialnych. Standardowo, otrzymujemy z nią kilka prostych programów do
konwersji, odtwarzania i streamingu plików multimedialnych. Nas interesuje tylko
program \texttt{ffmpeg} służący do konwersji plików multimedialnych.

Aby skonwertować dowolny plik multimedialny do formatu jaki potrabujemy,
wystarczy wywołać polecenie:
\begin{verbatim}
./<sciezka_do>/ffmpeg -i <plik_wejsciowy> -ar 16000 -ac 1 <plik_wyjsciowy.wav>
\end{verbatim}

Czyli, na przykład:
\begin{verbatim}
~/synat_asr/apps/ffmpeg/ffmpeg -i input.mp3 -ar 16000 -ac 1 output.wav
\end{verbatim}

W trakcie kodowania powinniśmy otrzymać informacje podobne do następujących:
\begin{verbatim}
Input #0, mp3, from '../input.mp3':
  Duration: 00:00:48.20, start: 0.000000, bitrate: 108 kb/s
    Stream #0:0: Audio: mp3, 16000 Hz, mono, s16p, 112 kb/s
Output #0, wav, to 'out.wav':
  Metadata:
    ISFT            : Lavf54.59.106
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 
          16000 Hz, mono, s16, 256 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (mp3 -> pcm_s16le)
Press [q] to stop, [?] for help
size=    1504kB time=00:00:48.20 bitrate= 255.6kbits/s
video:0kB audio:1504kB subtitle:0 global headers:0kB muxing 
    overhead 0.005194%
\end{verbatim}

Program do segmentacji pracuje niestety tylko z formatem RAW więc należy
dodatkowo przygotować plik następującym poleceniem:
\begin{verbatim}
./<sciezka_do>/ffmpeg -i <plik.wav> -f s16le -acodec pcm_s16le <plik.raw>
\end{verbatim}

Albo inaczej:
\begin{verbatim}
~/synat_asr/apps/ffmpeg/ffmpeg -i output.wav -f s16le -acodec pcm_s16le output.raw
\end{verbatim}

\subsection{Detekcja mowy}
\label{sec:vad}

Program do detekcji mowy nazywa się \texttt{shout\_segment}. Wywołujemy go poleceniem:
\begin{verbatim}
./<sciezka_do>/shout_segment -a <plik_audio.raw> -ams <model_vad.sad> 
    -mo <plik_wyjsciowy.vad>
\end{verbatim}

Czyli:
\begin{verbatim}
~/synat_asr/apps/shout/release/src/shout_segment -a out.raw 
    -ams ~/synat_asr/apps/shout/shout.sad -mo out.vad
\end{verbatim}


\subsection{Wycinanie nie-mowy}

Czasami nagrania zawierają dużo szumów i innych zawartości, które nie są mową
(np. hałasy, efekty specjalne, czy muzyka). Chciaż w wielu przypadkach system
rozpoznawania mowy poprawnie zaklasyfikuje takie fragmenty jako \texttt{<UNK>},
jeśli tych szumów jest dostatecznie dużo, mogą one zostać rozpoznane jako
wyrazy.

Rozwiązaniem jest właśnie zastosowanie VAD w celu wykrycia fragmentów, które są
mową i pominięcie w procesie dekodowania wszystkich innych fragmentów. Żeby
zachować ``dopasowanie'' wyniku rozpoznawania i oryginalnego nagrania, nic nie
jest na siłę wycinane, tylko wyciszane (zastępowane zerami).

\textcolor{red}{UWGA: } Stosowanie wycinania według VAD może również obniżyć
skuteczność systemu rozpoznawania mowy, gdyż wycinanie fragmentów sygnału może
popsuć kontekst wyrazów. Jeśli nagranie nie zawiera dużej ilości szumów/muzyki,
warto nie wykonywać tego kroku! Dokładne sktutki działania tej procedury muszą
jeszcze być dokłądniej zbadane!

Żeby dokonać wycięcia sygnału nie-mowy z pliku WAV, należy użyć następującego
polecenia:
\begin{verbatim}
 java -jar ../apps/SynatASRTools/SynatASRTools.jar -V -i output.wav 
     -o output_speech.wav -v output.vad -w 0.1
\end{verbatim}

Pierwszy argument to tryb pracy programu. Parametry \texttt{-i} i \texttt{-o}
określają po prostu plik wejściowy i wyjściowy. Parametr \texttt{-v} to plik
uzyskany z poprzedniego kroku (rozdział \ref{sec:vad}). Parametr \texttt{-w} to
ilość sekund usuwana z lewej i prawej strony wycinanego fragmentu, po to żeby
zachować więcej sygnału mowy. Robione jest to ponieważ detekcja nowy działa
czasami zbyt agresywnie i lepiej jest dodać trochę nie-mowy do sygnału, niż
wyciąć kawałek mowy.

\subsection{Podział długiego pliku}

Za pomocą informacji uzyskanej z rozdziału \ref{sec:vad} można dokonać
``bezpiecznego'' podziału pliku na więcej części. Jest to przydatne, jeśli plik
jest bardzo długi i przeanalizowanie go naraz w systemie rozpoznawania mowy jest
niewykonalne.

\textcolor{red}{FUNKCJA TA NIE JEST JESZCZE ZAIMPLEMENTOWANA!}

\subsection{Rozpoznawanie mowy}

Do rozpoznawania korzystamy z programu \texttt{julius}. Do poprawnego działania
programu, potrzebne jest też kilka plików: model akustyczny, model języka i
słownik. Potrzebny jest też plik konfiguracyjny opisujący wszystkie opcję
programu. Argumenty konfiguracji można podać albo w pliku konfiguracyjnym, albo
jako argumenty na linii poleceń.

Wszystkie potrzebne pliki są powiązane w pliku konfiguracyjnym. Ścieżki względne
są ustawione jako względne wobec pliku konfiguracyjnego \texttt{julius.jconf}.
Jednym z ważnych plików podanych w konfiguracji jest plik \texttt{-filelist}.
Zawiera on listę plików jakie system ma przetworzyć. Ścieżki względne w pliku z
listą plików audio są względne wobec miejsca gdzie uruchomiono polecenie.

Gdy ustawimy zawartość pliku \texttt{-filelist}, wystarczy uruchomić
rozpoznawanie poleceniem:
\begin{verbatim}
./<sciezka-do>/julius -C ./<sciezka_do>/julius.jconf 
    -filelist ./<sciezka-do>/lista.scp
\end{verbatim}

Program dla każdego wejściowego pliku WAV wygeneruje plik z rozszerzeniem OUT.

\subsection{Interpretacja wyników rozpoznawania}
\label{sect:interp}

Pliki jakie zwraca julius zaweirają mnóstwo pożytecznych informacji, ale nie
muszą być zbyt wygodne w przetwarzaniu. Stworzyliśmy zatem program, który
zamienia pliki wyjściowe Juliusa na łatwiejszy w obsłudze plik XML.

Dodatkową funkcją tego programu jest możliwość wygenerowania pliku TextGrid do
łatwego sprawdzenia wyniku rozpoznawania. Plik TextGrid można otworzyć w
programie Praat (\url{http://www.praat.org/}). Należy w głównym oknie programu
najpierw otworzyć plik WAV (poleceniem Open/Read from file\ldots) i tym samym
poleceniem otworzyć plik TextGrid. Potem należy zaznaczyć na liście objektów
zarówno dźwięk jak i TextGrid i wybrać opcję ``Edit''. Odtwarzać można klikając
na przyciski ``Total duration'', ``Visible part'', itp. Odtwarzanie przerwać
można klawiszem Esc.

Żeby wygenerować pliki XML i TextGrid, wystarczy odpalić polecenie:
\begin{verbatim}
 java -jar ../apps/SynatASRTools/SynatASRTools.jar -J -i output.out 
     -o output.xml -g output.TextGrid
\end{verbatim}

Format pliku XML jest do ustalenia\ldots

\section{Demo}

Oto krótki przykład pokazujący działanie programu. Należy po kolei wywoływać
następujące polecenia:
\begin{enumerate}
  \item cd ./<sciezka-do-projektu>/demo
  \item ../apps/ffmpeg/ffmpeg  -i input.mp3 -ar 16000 -ac 1 output.wav
  \item ../apps/ffmpeg/ffmpeg -i output.wav -f s16le -acodec pcm\_s16le output.raw
  \item ../apps/shout/release/src/shout\_segment -a output.raw -ams ../apps/shout/shout.sad -mo output.vad
  \item java -jar ../apps/SynatASRTools/SynatASRTools.jar -V -i output.wav -o output\_speech.wav -v output.vad -w 0.1
  \item echo ``output\_speech.wav'' > file.scp
  \item ../apps/julius4/julius/julius -C ../conf/julius.jconf -filelist file.scp
  \item java -jar ../apps/SynatASRTools/SynatASRTools.jar -J -i output\_speech.out -o output.xml -g output.TextGrid
 \end{enumerate}

Opis poleceń:
\begin{enumerate}
  \item wchodzimy do katalogu demo
  \item tworzymy plik wav z pliku wejściowego MP3 (tutaj dla przykładu - powinno działać z dowolnym plikiem audio/wideo)
  \item tworzymy plik RAW z pliku WAV (dla programu shout\_segment)
  \item uruchamiamy program shout\_segment zeby otrzymać podział pliku na segmenty mowa/nie-mowa
  \item wykorzystujemy plik z poprzedniego kroku do wyciszenia fragmenów z nie-mową
  \item tworzymy plik z listą plików podlegających rozpoznawaniu
  \item uruchamiamy rozpoznawanie mowy
  \item konwertujemy plik wyjściowy Juliusa na plik XML i TextGrid 
\end{enumerate}

\chapter{Druga wersja systemu - Kaldi}

Kaldi jest nowoczesnym systemem rozpoznawania mowy opartym o
WFST\footnote{Weighted Finite State Transducer} posiadający wiele mechanizmów
modelowania mowy uważanych w obecnej chwili za ``state-of-the-art''. Jako taki,
system ten jest bardziej kompletny i wymaga mniej dodatkowych narzędzi niż
w poprzedniej wersji systemu.

\section{Architektura systemu}

Z ogólnej architektury, wyrzuocny zostanie VAD jako osobny blok, ponieważ jest
on zawarty w Kaldi'm. FFMPEG jest nadal potrzebny, do konwersji z szeregu
różnych rodzajów plików na potrzebny nam format.

\begin{figure}[h]
\begin{center}
\begin{tikzpicture}[thick]

\node (f) {media file};
\node[draw,rectangle,right=of f] (a) {FFMPEG};
\node[draw,rectangle,right=of b] (c) {KALDI};
\node[right=of c] (o) {result};

\draw[->] (f) to (a);
\draw[->] (a) to (c);
\draw[->] (c) to (o);

\end{tikzpicture}
\end{center}
\caption{Ilustracja architektury nowego systemu opratego o Kaldi.}
\end{figure}

\subsection{Licencje}

W sprawie licencji do FFMPEG proszę zajrzeć do rozdziału \ref{sec:lic1}.

Kaldi został opublikowany na licencji Apache w wersji 2.0. Wykorzystuje on
jednak szereg bibliotek które mogą wymagać innych licencji. Główne
wykorzystane biblioteki to OpenFST (na Apache) oraz Atlas (na BSD), więc raczej
żadne nie powinny przeszkadzać w użyciu, aczkolwiek warto się upewnić. Wiele z
nich jest też dostępne w standardowych dytrybucjach, więc to dodatkowo ułatwia
ich zastosowanie.

\section{Instalacja}

\subsection{Kompilacja FFMPEG}

Na temat instalacji FFMPEG, proszę zajrzeć do rozdziału \ref{sec:inst1:ffmpeg}.

\subsection{Kompilacja Kaldi}

Kaldi ściągnięto z repozytorium projektu Kladi poleceniem (data ściągnięcia
28.3.2014):

\begin{verbatim}
svn co https://svn.code.sf.net/p/kaldi/code/trunk kaldi-trunk
\end{verbatim}

Kompilacja systemu jest robiona w dwóch krokach. Najpierw należy przygotować
wszystkie wymagane biblioteki, a potem można skompilować sam program. Aby
ułatwić to zadanie, autorzy przygotowali specjalny skrypt do kompilowania
wymaganych bibliotek. Należy najpierw wejść do katalogu \texttt{tools} i tam
wykonać polecenie \texttt{make}. Ponieważ potrzebujemy również pewne dodwtkowe
programy które wymagają biblioteki do nagrywania dźwięku, należy ręcznie
skompilować bibliotekę ``portaudio'' uruchamiając załączony skrypt:

\texttt{./install\_portaudio.sh}.

Kolejny krok to kompilacja samego systemu. Należy zatem wejść do katalogu
\texttt{src} i tam wykonać najpierw \texttt{configure}, potem \texttt{make} i na
samym końcu \texttt{make ext} żeby skompilować dodatkowe programy wymagane do
realizacji projektu.

W trakcie wykonywania powyższych poleceń, można dostać informację o tym że
barkuje jakiejś biblioteki albo narzędzia w systemie. W tym dokumencie nie są
opisane wszystkie takie przypadki, gdzyż trudno jest to przewidzieć dla każdego
systemu, ale autor nie miał problemu z tym w systemach Debian i
Ubuntu podczas wieloktrotnej instalacji na różnych komputerach. Na pewno przed
uruchomieniem polecenia configure warto zainstalować biblioteki libatlas-dev i
libatlas-base-dev.

\section{Użytkowanie}

\subsection{Konwersja plików wejściowych}

Opis kowersji plików jest taki sam jak w przypadku Juliusa i można go znaleźć w
rozdziale \ref{sect:konw_wej}. Jedyny wymagany plik do systemu Kaldi to plik WAV
z jednym kanałem (MONO) i częstotliwością próbkwania 16 kHz.

\subsection{Rozpoznawanie mowy w systemie Kaldi}

Kaldi został stworzony jako program do badań na wielkich korpusach danych, więc
większość jego narzędzi jest podporządkowane temu zastosowaniu. Niemniej jednak,
posiada on również programy, które mogą być użyte w projektach takich jak Synat.

Domyślnie, Kladi posiada mnóstwo programów wykonujących małe, cząstkowe
procedury. Przykład takiej procedury woknywującej proste rozpoznawanie mowy
wykorzystywałoby kolejno następujące programy: \texttt{compute-mfcc-feats},
\texttt{compute-mfcc-feats}, \texttt{apply-cmvn}, \texttt{add-deltas},
\texttt{gmm-decode-faster}, \texttt{copy-int-vector}. Chociaż można w ten sposób
wykonywać wszystko co umożliwia Kaldi, główna wada tego rozwiązania jest, że
każde wywołanie polecenia dekodowania (\texttt{gmm-decode-faster}) wymaga
kosztownego wczytywania modelu FST trwającego czasami ponad minutę.

Dlatego Kaldi posiada kilka programów do dekodowania ``online''. Program taki
się uruchamia jednorazowo, a on czeka na zlecenia i ropoznaje je kiedy
nadchodzą. Więcej informacji o tym można znaleźć tutaj:
\url{http://kaldi.sourceforge.net/online_programs.html}

Jedno alternatywne zastosowanie polega na skompilowaniu i uruchomieniu Kaldi
jako wtyczki do systemu GStreamer. W niektórych sytuacjach może to działać
całkiem skutecznie, ale my nie mamy z tym zbytnio doświadczenia, więc nie wiemy
czy można to polecić.

My polecamy korzystania z programu ``online-audio-server-decode-faster''. Jest
to server, który nasłuchuje na porcie TCP/IP i przyjmuje klientów wysyłających
sygnał audio w postaci RAW. W Kaldi'm jest kilka implementacji klientów tego
servera: w C++ i w Javie. Wypisują one wynik w formatch HTK i WebVTT, ale my
zmodyfikowaliśmy klient w Javie, żeby również wypisywał format w XML, taki jak w
rozdziale \ref{sect:interp}.

Żeby uruchomić serwer należy użyć następującego polecenia (z punktu widzenia
katalogu ``demo''):

\begin{verbatim}
../apps/kaldi-trunk/src/onlinebin/online-audio-server-decode-faster 
--rt-min=0.5 --rt-max=3.0 --max-active=6000 --beam=72.0 
--acoustic-scale=0.083333 ../conf/final.mdl ../conf/HCLG.fst 
../conf/words.txt '1:2:3:4:5' 5555 ../conf/word_boundary.int 
../conf/final.mat
\end{verbatim}

Poszczególne argumenty to:
\begin{itemize}
  \item \verb|--rt-min| $-$ minimalna wartość realtime, czyli najwolniej jak
  dekoder powinien pracować
  \item \verb|--rt-max| $-$ maksymalna wartość realtime, czyli najszybciej jak
  dekoder powinien pracować
  \item \verb|--max-active| $-$ maksymalna ilość badanych hipotez (wpływa na
  zajętość pamięci)
  \item  \verb|--beam| $-$ próg prawdopodobieństwa badanych hipotez (to samo co
  wyżej, ale zamiast ilości jest inny rodzaj parametru)
  \item  \verb|--acoustic-scale| $-$ waga ustalona empirycznie (należy ją
  zostawić tak jak jest dla danego modelu akustycznego)
  \item \verb|final.mdl| $-$ model akustyczny
  \item \verb|HCLG.fst| $-$ model FST (zawiera model języka, leksykon i parę
  innych rzeczy)
  \item \verb|words.txt| $-$ lista wyrazów (i ich numerów ID), bo dekoder
  pracuje tylko na numerach ID i potrzebujemy ten plik żeby to skonwertować z
  powrotem na tekst
  \item \verb|'1:2:3:4:5'| $-$ ID fonemów modelu akustycznego dla ciszy
  \item \verb|5555| $-$ port na jaki ma nasłuchiwać program
  \item \verb|word_boundary.int| $-$ lista cech granicznych fonemów (czyli
  informacja czy dany fonem jest fonemem granicznym, czy wewnętrznym)
  \item \item \verb|final.mat| $-$ macierz LDA do konwersji cech
\end{itemize}

Po pełnym uruchomieniu serwera dostaniemy infromację ``Waiting for client...'' i
możemy się na serwer podłączyć klientem jaki został dodany do programu
SynatASRTools:

\begin{verbatim}
 java -jar ../apps/SynatASRTools/SynatASRTools.jar -K -i euronews.wav 
     -o output.xml -g output.TextGrid -k localhost:5555
\end{verbatim}

\chapter{Zmiany dokumentu}
\begin{itemize}
  \item 1\_20130901 -- Początek dokumentu
  \item 2\_20140325 -- Opis drugiej wersji systemu
\end{itemize}


\end{document}
