/* 
 * File:   dictionary.h
 * Author: elenar
 *
 * Created on 25. únor 2011, 10:40
 */

#ifndef DICTIONARY_H
#define	DICTIONARY_H

#define DICTIONARY_DEBUG

#include "dictionary_data.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "matrix.h"
#include "element.h"
#include "cell.h"
#include "list.h"
#include "mlp.h"
#include "detector.h"
#include "signal_processing.h"
#include "somp.h"

#define SENTENCE_BASE_WIN 0.032
#define SENTENCE_BASE_INC 0.016

/* * * * * * * * * * *
 * DICTIONARY CLASS  *
 * * * * * * * * * * */

/*
 * Alokuje slovni tridu o poctu slov N promluv.
 */
dictionary_class *dictionary_class_alloc(unsigned int n);

/*
 * Uvolni z pameti slovnik DICT se vsemi jeho slovy.
 */
void dictionary_class_free(dictionary_class *dict);

/*
 * Klonuje slovni tridu DCL.
 */
dictionary_class *dictionary_class_clone(dictionary_class *dcl);

/*
 * Nastavi slovni tride nazev slova NAME.
 */
void dictionary_class_set_name(dictionary_class *dcl, char *name);

/*
 * Nastavi I-tou promluvu FEATURES slovni tride DCL.
 */
void dictionary_class_set_features(dictionary_class *dcl, unsigned int i, matrix *features);

/*
 * Nastavi fonetickou transkripci PHONEMES tridy DCL.
 */
void dictionary_class_set_phonemes(dictionary_class *dcl, cell *phonemes);

/*
 * Vrati nazev slova slovni tridy DCL.
 */
char *dictionary_class_get_name(dictionary_class *dcl);

/*
 * Vrati nazev slova slovni tridy DCL.
 */
matrix *dictionary_class_get_features(dictionary_class *dcl, unsigned int i);

/*
 * Vrati fonetickou transkripci slovni tridy DCL.
 */
cell *dictionary_class_get_phonemes(dictionary_class *dcl);

/*
 * vrati prumernou delku ulozenych promluv ve slovni tride DCL.
 */
double dictionary_class_mean_length(dictionary_class *dcl);

/*
 * Vrati smerodatnou odchylku ulozenych promluv ve slovni tride DCL.
 */
double dictionary_class_std_length(dictionary_class *dcl);

/* * * * * * * *
 * DICTIONARY  *
 * * * * * * * */

/*
 * Alokuje slovnik o N slovnich tridach.
 */
dictionary *dictionary_alloc(unsigned int n);

/*
 * Uvolni slovnik.
 */
void dictionary_free(dictionary *dict);

/*
 * Nastavi I-tou slovni tridu ve slovniku DICT.
 * DCL - nastavovana slovni trida.
 */
int dictionary_set(dictionary *dict, unsigned int i, dictionary_class *dcl);

/*
 * Vrati I-tou slovni tridu ze slovniku DICT.
 */
dictionary_class *dictionary_get(dictionary *dict, unsigned int i);

/*
 * Vrati strukturu priznaku I-teho slova ze slovniku DICT.
 */
cell *dictionary_get_features(dictionary *dict, unsigned int i);

/*
 * Vrati nazev slova ze slovniku DICT.
 */
char *dictionary_get_name(dictionary *dict, unsigned int i);

/*
 * Vrati fonetickou transkripci slova ze slovniku DICT.
 */
cell *dictionary_get_phonemes(dictionary *dict, unsigned int i);

/*
 * Vrati prumernou delku i-teho slova
 */
double dictionary_get_mean(dictionary *dict, unsigned int i);

/*
 * Vrati vyfiltrovany slovnik.
 * DICT - slovnik z ktereho bude funkce cerpat
 * WORDS - seznam slov ktere chceme vyfiltorvat z DICT.
 */
dictionary *dictionary_filter_words(dictionary *dict, list *words);

/*
 * Spoji pole slovniku DICT_ARRAY v jeden.
 */
dictionary *dictionary_cat(dictionary **dict_array, unsigned int n);

/*
 * Ulozi slovnik.
 */
void dictionary_save(char *filename, dictionary *dict);

/*
 * Nacte fonemovou transkripci z retezce STR.
 */
cell *dictionary_phoneme_parse(char *str);

/*
 * Nacte slovnik.
 */
dictionary *dictionary_load(char *filename);

/*
 * Navrhne matici vah pro jednotliva slova jako gausovou funkci na zaklade
 * prumerne delky slova a smerodatne odchylky slova. Predpoklada normalni
 * rozdeleni delky slova. WOPT je nastaveni oken.
 */
matrix *dictionary_weight_design(dictionary *dict, detector_list_opt *opt);

/*
 * Vrati pocet vyskytu slova WORD ve slovniku DICT.
 */
int dictionary_contain_word(dictionary *dict, char *word);

/*
 * Vytvori slovnik z pole vet SENS o postu N.
 */
dictionary *dictionary_create(sentence **SENS, unsigned int n);

/*
 * Spocita Cepstral Mean Normalisation (stat_norm). Vrati matici prumeru a matici
 * smerodatnych odchylek.
 */
matrix **dictionary_stat_norm(dictionary *dict);

/*
 * Aplikuje stat_norm na slovnik pomoci prumeru AVARGE a smerodatne odchylky STDEV.
 */
void dictionary_stat_norm_aply(dictionary *dict, matrix *avarge, matrix *stdev);

/*
 * Aplikuje algoritmus SOMP na slovnik DICT. T je pocet parametru na ktery se
 * maji priznaky redukovat. Vrati matici basis (bazove funkce), At ,
 * resudial (zbytek).
 */
matrix **dictionary_somp_basis(dictionary *dict, unsigned int T);

/*
 * Promitne priznaky slovniku DICT do bazovych souradnic BASIS.
 */
void dictionary_somp_projection(dictionary *dict, matrix *basis);

/*
 * Vytiskne slova obsazena ve slovniku
 */
void dictionary_print(dictionary *dict);

/*
 * Transformuje priznaky slovniku DICT pomci neuronove site NET.
 */
void dictionary_transform_mlp (dictionary *dict, mlp *net);

/* * * * * * *
 * SENTENCE  *
 * * * * * * */

/*
 * Alokuje vetu ve ktere bude celkem N slov.
 */
sentence *sentence_alloc(unsigned int n);

/*
 * Uvolni z pameti vetu spolu s vsemi jejimi slovy.
 */
void sentence_free(sentence *sen);

/*
 * Nacte vety ze struktury ziskane z matlabu PC.
 */
sentence **sentences_create(cell *pc, unsigned int *n);

/*
 * Vypocita priznaky vety SEN pomoci transformacni funkce TRFUNC(SIGNAL, WIN, INC, FREQUENCY).
 */
void sentence_comp_features1(sentence *sen, matrix *(* trfunc)(matrix *, unsigned int, unsigned int, unsigned int));

/*
 * Vypocita priznaky vet SEN pomoci transformacni funkce TRFUNC(SIGNAL, WIN, INC, FREQUENCY).
 */
void sentence_comp_features1(sentence *sen, matrix *(* trfunc)(matrix *, unsigned int, unsigned int, unsigned int));

/*
 * Vypocita priznaky vet SENS o poctu N pomoci transformacni funkce TRFUNC(SIGNAL, WIN, INC, FREQUENCY).
 */
void sentence_comp_features2(sentence **sen, unsigned int n, matrix *(* trfunc)(matrix *, unsigned int, unsigned int, unsigned int));

/*
 * Transformuje priznaky vety SEN pomoci neuronove site NET.
 */
void sentence_mlp_transform1(sentence *sen, mlp *net);

/*
 * Transformuje priznaky vet SEN pomoci neuronove site NET.
 */
void sentence_mlp_transform2(sentence **sen, unsigned int n, mlp *net);

/*
 * Aplikuje stat_norm na vetu SEN.
 * AVARGE - matice prumeru
 * STDEV - matice smerodatnych odchylek
 */
void sentence_stat_norm_aply(sentence *sen, matrix *avarge, matrix *stdev);

/*
 * Aplikuje stat_norm na vety SENS o poctu N.
 * AVARGE - matice prumeru
 * STDEV - matice smerodatnych odchylek
 */
void sentence_stat_norm_aply2(sentence **sens, unsigned int n, matrix *avarge, matrix *stdev);

/*
 * Promitne priznaky vety SEN do bazovych souradnic BASIS.
 */
void sentence_somp_projection(sentence *sen, matrix *basis);

/*
 * Promitne priznaky vet SENS o poctu N do bazovych souradnic BASIS.
 */
void sentence_somp_projection2(sentence **sens, unsigned int n, matrix *basis);

/*
 * Zkusi ve vete SEN najit K-ty vyskyt slova WORD. Pokud ho najde tak do BEG se
 * ulozi jeho zacatek v signalu a do END se ulozi jeho konec v signále, jinak
 * se BEG a END nijak nezmeni. V pripade nalezu funkce vrati 1 jinak 0.
 */
int sentence_find_word(sentence *sen, char *word, unsigned int k, unsigned int *beg, unsigned int *end);

/*
 * Vrati 1 pokud slovo WORD lezi ve vete SEN na pozici POS v toleranci TOL.
 * Jinak vrati 0.
 */
int sentence_is_word(sentence *sen, unsigned int pos, char *word, unsigned int tol);

/*
 * Vrati pocet obsazenych slov WORD ve vete SEN.
 */
int sentence_contein_word(sentence *sen, char *word);

/*
 * Vytiskne slova ve vete, a jeji delku v [s].
 */
void sentence_print_info(sentence *sen);

/*
 * Vrati retezec, ktery reprezentuje vetu.
 */
char *sentence_save_string (sentence *sen);

/*
 * Rozparsuje retezec STRING, ktery musi byt ve formatu, ktery je ziskan funkci
 * SENTENCE_SAVE_STRING(...) a vytvori z nej vetu.
 */
sentence *sentence_parse_string (char *string);

void sentences_save (const char *filename, sentence **sens, unsigned int n);
sentence **sentences_load (const char *filename, unsigned int *n, unsigned int max);

#endif	/* DICTIONARY_H */

