/* praat_LPC_init.c
 *
 * Copyright (C) 1994-2003 David Weenink
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 djmw 20030613 Latest modification
*/

#include <math.h>
#include "praat.h"
#include "Cepstrumc.h"
#include "DTW.h"
#include "LPC.h"
#include "MFCC.h"
#include "LFCC.h"
#include "LPC_and_Cepstrumc.h"
#include "LPC_and_Formant.h"
#include "LPC_and_LFCC.h"
#include "LPC_and_Polynomial.h"
#include "LPC_and_Tube.h"
#include "LPC_to_Spectrogram.h"
#include "LPC_to_Spectrum.h"
#include "MelFilter_and_MFCC.h"
#include "Sound_and_LPC.h"
#include "Sound_and_Cepstrum.h"
#include "Sound_to_MFCC.h"
#include "Cepstrum_and_Spectrum.h"

extern void praat_CC_init (void *klas);

/********************** Cepstrum  ****************************************/


DIRECT (Cepstrum_help)
	Melder_help ("Cepstrum");
END

FORM (Cepstrum_draw, "Draw the Cepstrum", "Cepstrum: Draw...")
	REAL ("Minimum quefrency", "0.0")
	REAL ("Maximum quefrency", "0.0")
	REAL ("Minimum", "0.0")
	REAL ("Maximum", "0.0")
    BOOLEAN ("Garnish", 0);
	OK
DO
	EVERY_DRAW (Cepstrum_draw (OBJECT, GRAPHICS,
		GET_REAL ("Minimum quefrency"), GET_REAL ("Maximum quefrency"),
		GET_REAL ("Minimum"), GET_REAL ("Maximum"),
		GET_INTEGER ("Garnish")))
END

DIRECT (Cepstrum_to_Spectrum)
	EVERY_TO (Cepstrum_to_Spectrum (OBJECT))
END

DIRECT (Cepstrum_to_Matrix)
	EVERY_TO (Cepstrum_to_Matrix (OBJECT))
END

/********************** Cepstrumc  ****************************************/

DIRECT (Cepstrumc_to_LPC)
	EVERY_TO (Cepstrumc_to_LPC (OBJECT))
END

FORM (Cepstrumc_to_DTW, "Dynamic time warping between Cepstrumcs", "Cepstrumc: To DTW...")
	LABEL ("", "Distance calculation between Cepstra")
	REAL ("Cepstral weight", "1.0")
	REAL ("Log energy weight", "0.0")
	REAL ("Regression weight", "0.0")
	REAL ("Regression weight log energy", "0.0")
	REAL ("Window for regression coefficients (seconds)", "0.056")
	LABEL("", "Boundary conditions for time warp")
	BOOLEAN ("Match begin positions", 0)
	BOOLEAN ("Match end positions", 0)
	RADIO ("Slope constraints", 1)
	RADIOBUTTON ("no restriction")
	RADIOBUTTON ("1/3 < slope < 3")
	RADIOBUTTON ("1/2 < slope < 2")
	RADIOBUTTON ("2/3 < slope < 3/2")
	OK
DO
	Cepstrumc c1 = NULL, c2 = NULL;
	WHERE (SELECTED && CLASS == classCepstrumc) if (c1) c2 = OBJECT; else c1 = OBJECT;
	NEW (Cepstrumc_to_DTW (c1, c2, GET_REAL ("Cepstral weight"),
		GET_REAL ("Log energy weight"), GET_REAL ("Regression weight"),
		GET_REAL ("Regression weight log energy"),
		GET_REAL ("Window for regression coefficients"), 
		GET_INTEGER("Match begin positions"), GET_INTEGER("Match end positions"),
		GET_INTEGER("Slope constraints")))
END

DIRECT (Cepstrumc_to_Matrix)
	EVERY_TO (Cepstrumc_to_Matrix (OBJECT))
END

/******************** Formant ********************************************/

FORM (Formant_to_LPC, "From Formant to LPC", 0)
	POSITIVE("Sampling frequency (Hz)", "16000")
	OK
DO
	EVERY_TO (Formant_to_LPC (OBJECT, 1.0/GET_REAL("Sampling frequency")))
END

/********************LFCC ********************************************/

DIRECT (LFCC_help)
	Melder_help ("LFCC");
END

FORM (LFCC_to_LPC, "LFCC to LPC", "LFCC: To LPC...")
	INTEGER ("Number of coefficients", "0")
	OK
DO
	long ncof = GET_INTEGER ("Number of coefficients");
	REQUIRE (ncof >= 0, "Number of coefficients must be greater or equal zero.")
	EVERY_TO (LFCC_to_LPC (OBJECT, ncof))
END

/********************LPC ********************************************/

DIRECT (LPC_help) Melder_help ("LPC"); END

FORM (LPC_drawGain, "Draw gain of LPC", "LPC: Draw gain...")
    REAL ("From time (seconds)", "0.0")
    REAL ("To time (seconds)", "0.0 (=all)")
    REAL ("Minimum gain", "0.0")
    REAL ("Maximum gain", "0.0")
    BOOLEAN ("Garnish", 1)
	OK
DO
    EVERY_DRAW (LPC_drawGain (OBJECT, GRAPHICS, 
    	GET_REAL ("From time"), GET_REAL ("To time"),
    	GET_REAL ("Minimum gain"), GET_REAL ("Maximum gain"),
		GET_INTEGER("Garnish")))
END

FORM (LPC_drawPoles, "Draw poles of a frame", "LPC: Draw poles...")
    REAL ("Time (seconds)", "0.0")
    BOOLEAN ("Garnish", 1)
    OK
DO
	EVERY_DRAW (LPC_drawPoles (OBJECT, GRAPHICS, GET_REAL ("Time"),
		GET_INTEGER ("Garnish")))
END

DIRECT (LPC_to_Formant)
	EVERY_TO (LPC_to_Formant (OBJECT, 50))
END

DIRECT (LPC_to_Formant_keep_all)
	EVERY_TO (LPC_to_Formant (OBJECT, 0))
END

DIRECT (LPC_to_Cepstrumc)
	EVERY_TO (LPC_to_Cepstrumc (OBJECT))
END

FORM (LPC_to_LFCC, "LPC to LFCC", "LPC: To LFCC...")
	INTEGER ("Number of coefficients", "0")
	OK
DO
	long ncof = GET_INTEGER ("Number of coefficients");
	REQUIRE (ncof >= 0, "Number of coefficients must be greater or equal zero.")
	EVERY_TO (LPC_to_LFCC (OBJECT, ncof))
END

FORM (LPC_to_Polynomial, "LPC frame to Polynomial", "LPC: To Polynomial (slice)...")
	REAL ("Time (seconds)", "0.0")
	OK
DO
	EVERY_TO (LPC_to_Polynomial (OBJECT, GET_REAL("Time")))
END

FORM (LPC_to_Spectrum, "Spectrum from LPC frame", "LPC: To Spectrum (slice)...")
	REAL ("Time (seconds)", "0.0")
	REAL ("Minimum frequency resolution (Hz)", "20.0")
	REAL ("Bandwidth reduction (Hz)", "0.0")
	REAL ("De-emphasis frequency (Hz)", "50.0")
	OK
DO
	EVERY_TO (LPC_to_Spectrum (OBJECT, GET_REAL("Time"),
		GET_REAL("Minimum frequency resolution"),
		GET_REAL("Bandwidth reduction"), GET_REAL("De-emphasis frequency")))
END

FORM (LPC_to_Spectrogram, "Spectrogram from LPC", "LPC: To Spectrogram...")
	REAL ("Minimum frequency resolution (Hz)", "20.0")
	REAL ("Bandwidth reduction (Hz)", "0.0")
	REAL ("De-emphasis frequency (Hz)", "50.0")
	OK
DO
	EVERY_TO (LPC_to_Spectrogram (OBJECT, GET_REAL("Minimum frequency resolution"),
		GET_REAL("Bandwidth reduction"), GET_REAL("De-emphasis frequency")))
END

FORM (LPC_to_VocalTract, "VocalTract from LPC", "LPC: To VocalTract (slice)...")
	REAL ("Time (seconds)", "0.0")
	POSITIVE ("Length (m)", "0.17")
	BOOLEAN("Length according to Wakita", 0)
	OK
DO
	EVERY_TO (LPC_to_VocalTract (OBJECT, GET_REAL("Time"), GET_REAL("Length"),
		GET_INTEGER("Length according to Wakita")))
END

DIRECT (LPC_to_Matrix)
	EVERY_TO (LPC_to_Matrix (OBJECT))
END

/********************** Sound *******************************************/

FORM (Sound_to_LPC_auto, "From Sound to LPC (autocorrelation method)", "Sound: To LPC (autocorrelation)...")
	NATURAL ("Prediction order", "16")
	POSITIVE ("Analysis width (seconds)", "0.025")
	POSITIVE ("Time step (seconds)", "0.005")
	REAL("Pre-emphasis from (Hz)", "50.0")
	OK
DO
	long p = GET_INTEGER ("Prediction order");
	double preEmphasisFrequency = GET_REAL("Pre-emphasis from");
	REQUIRE (p < 500, "Prediction order must be < 500.")
	REQUIRE (preEmphasisFrequency >= 0, "Pre-emphasis frequency must be >= 0")
	EVERY_TO (Sound_to_LPC_auto (OBJECT, p, GET_REAL("Analysis width"),
		GET_REAL("Time step"), preEmphasisFrequency))
END

FORM (Sound_to_LPC_covar, "From Sound to LPC (covariance method)", "Sound: To LPC (covariance)...")
	NATURAL ("Prediction order", "16")
	POSITIVE ("Analysis width (seconds)", "0.025")
	POSITIVE ("Time step (seconds)", "0.005")
	REAL("Pre-emphasis from (Hz)", "50.0")
	OK
DO
	long p = GET_INTEGER ("Prediction order");
	double preEmphasisFrequency = GET_REAL("Pre-emphasis from");
	REQUIRE (p < 500, "Prediction order must be < 500.")
	REQUIRE (preEmphasisFrequency >= 0, "Pre-emphasis frequency must be >= 0")
	EVERY_TO (Sound_to_LPC_covar (OBJECT, p, GET_REAL("Analysis width"),
		GET_REAL("Time step"), preEmphasisFrequency))
END

FORM (Sound_to_LPC_burg, "From Sound to LPC (burg method)", "Sound: To LPC (burg)...")
	NATURAL ("Prediction order", "16")
	POSITIVE ("Analysis width (seconds)", "0.025")
	POSITIVE ("Time step (seconds)", "0.005")
	REAL("Pre-emphasis from (Hz)", "50.0")
	OK
DO
	long p = GET_INTEGER ("Prediction order");
	double preEmphasisFrequency = GET_REAL("Pre-emphasis from");
	REQUIRE (p < 500, "Prediction order must be < 500.")
	REQUIRE (preEmphasisFrequency >= 0, "Pre-emphasis frequency must be >= 0")
	EVERY_TO (Sound_to_LPC_burg (OBJECT, p, GET_REAL("Analysis width"),
		GET_REAL("Time step"), preEmphasisFrequency))
END

FORM (Sound_to_LPC_marple, "From Sound to LPC (marple method)", "Sound: To LPC (marple)...")
	NATURAL ("Prediction order", "16")
	POSITIVE ("Analysis width (seconds)", "0.025")
	POSITIVE ("Time step (seconds)", "0.005")
	REAL("Pre-emphasis from (Hz)", "50.0")
	POSITIVE("Tolerance 1", "1e-6")
	POSITIVE("Tolerance 2", "1e-6")
	OK
DO
	long p = GET_INTEGER ("Prediction order");
	double preEmphasisFrequency = GET_REAL("Pre-emphasis from");
	REQUIRE (p < 500, "Prediction order must be < 500.")
	REQUIRE (preEmphasisFrequency >= 0, "Pre-emphasis frequency must be >= 0")
	EVERY_TO (Sound_to_LPC_marple (OBJECT, p, GET_REAL("Analysis width"),
		GET_REAL("Time step"), preEmphasisFrequency,
		GET_REAL("Tolerance 1"), GET_REAL("Tolerance 2")))
END

DIRECT (Sound_to_Cepstrum)
	EVERY_TO (Sound_to_Cepstrum (OBJECT))
END

FORM (Sound_to_MFCC, "From Sound to Mel Frequency Cepstral Coefficients",
	"Sound: To MFCC...")
	NATURAL ("Number of coefficients", "12")
	POSITIVE ("Analysis width (seconds)", "0.015")
	POSITIVE ("Time step (seconds)", "0.005")
	LABEL("","Filter bank parameters")
	POSITIVE ("Position of first filter (mels)", "100.0")
	POSITIVE ("Distance between filters (mels)", "100.0")
	REAL ("Maximum frequency (mels)", "0.0");
	OK
DO
	long p = GET_INTEGER ("Number of coefficients");
	REQUIRE (p < 25, "Number of coefficients must be < 25.")
	EVERY_TO (Sound_to_MFCC (OBJECT, p, GET_REAL ("Analysis width"),
		GET_REAL ("Time step"), GET_REAL ("Position of first filter"), 
		GET_REAL ("Maximum frequency"), GET_REAL ("Distance between filters")))
END


/******************* LPC & Sound *************************************/

FORM (LPC_and_Sound_filter, "Filter Sound by LPC", "LPC & Sound: Filter...")
	BOOLEAN ("Use LPC gain", 0)
	OK
DO
	NEW (LPC_and_Sound_filter (ONLY(classLPC) , ONLY(classSound),
		GET_INTEGER ("Use LPC gain")))
END

DIRECT (LPC_and_Sound_filterInverse)
	NEW (LPC_and_Sound_filterInverse (ONLY(classLPC) , ONLY(classSound)))
END

void praat_uvafon_LPC_init (void);
void praat_uvafon_LPC_init (void)
{
	Thing_recognizeClassesByName (classCepstrumc, classLPC, classLFCC,
		classMFCC, NULL);

	praat_addAction1 (classCepstrum, 0, "Cepstrum help", 0, 0,
		DO_Cepstrum_help);
	praat_addAction1 (classCepstrum, 0, "Draw...", 0, 0, DO_Cepstrum_draw);
	praat_addAction1 (classCepstrum, 0, "To Spectrum", 0, 0, 
		DO_Cepstrum_to_Spectrum);
	praat_addAction1 (classCepstrum, 0, "To Matrix", 0, 0, 
		DO_Cepstrum_to_Matrix);


	praat_addAction1 (classCepstrumc, 0, "Analyse", 0, 0, 0);
	praat_addAction1 (classCepstrumc, 0, "To LPC", 0, 0, DO_Cepstrumc_to_LPC);
	praat_addAction1 (classCepstrumc, 2, "To DTW...", 0, 0, DO_Cepstrumc_to_DTW);
	praat_addAction1 (classCepstrumc, 0, "Hack", 0, 0, 0);
	praat_addAction1 (classCepstrumc, 0, "To Matrix", 0, 0, DO_Cepstrumc_to_Matrix);
	
	praat_addAction1 (classFormant, 0, "Analyse", 0, 0, 0);
	praat_addAction1 (classFormant, 0, "To LPC...", 0, 0, DO_Formant_to_LPC);
	
	praat_addAction1 (classLFCC, 0, "LFCC help", 0, 0, DO_LFCC_help);
	praat_CC_init (classLFCC);
	praat_addAction1 (classLFCC, 0, "To LPC...", 0, 0, DO_LFCC_to_LPC);
	
	praat_addAction1 (classLPC, 0, "LPC help", 0, 0, DO_LPC_help);
	praat_addAction1 (classLPC, 0, "Draw", 0, 0, 0);
	praat_addAction1 (classLPC, 0, "Draw gain...", 0, 0, DO_LPC_drawGain);
	praat_addAction1 (classLPC, 0, "Draw poles...", 0, 0, DO_LPC_drawPoles);
	praat_addAction1 (classLPC, 0, "Extract", 0, 0, 0);
	praat_addAction1 (classLPC, 0, "To Spectrum (slice)...", 0, 0,
		DO_LPC_to_Spectrum);
	praat_addAction1 (classLPC, 0, "To VocalTract (slice)...", 0, 0,
		DO_LPC_to_VocalTract);
	praat_addAction1 (classLPC, 0, "To Polynomial (slice)...", 0, 0,
		DO_LPC_to_Polynomial);
	praat_addAction1 (classLPC, 0, "To Matrix", 0, 0,
		DO_LPC_to_Matrix);
	praat_addAction1 (classLPC, 0, "Analyse", 0, 0, 0);
	praat_addAction1 (classLPC, 0, "To Formant", 0, 0, DO_LPC_to_Formant);
	praat_addAction1 (classLPC, 0, "To Formant (keep all)", 0, 0, 
		DO_LPC_to_Formant_keep_all);
/*	praat_addAction1 (classLPC, 0, "To Cepstrumc", 0, 0, DO_LPC_to_Cepstrumc);*/
	praat_addAction1 (classLPC, 0, "To LFCC...", 0, 0, DO_LPC_to_LFCC);
	praat_addAction1 (classLPC, 0, "To Spectrogram...", 0, 0,
		DO_LPC_to_Spectrogram);
	
	praat_addAction2 (classLPC, 1, classSound, 1, "Analyse", 0, 0, 0);
	praat_addAction2 (classLPC, 1, classSound, 1, "Filter...", 0, 0,
		DO_LPC_and_Sound_filter);
	praat_addAction2 (classLPC, 1, classSound, 1, "Filter (inverse)", 0, 0,
		DO_LPC_and_Sound_filterInverse);

	praat_addAction1 (classSound, 0, "To LPC (autocorrelation)...",
		"To Formant (sl)...", 1, DO_Sound_to_LPC_auto);
	praat_addAction1 (classSound, 0, "To LPC (covariance)...",
		"To LPC (autocorrelation)...", 1, DO_Sound_to_LPC_covar);
	praat_addAction1 (classSound, 0, "To LPC (burg)...",
		"To LPC (covariance)...", 1, DO_Sound_to_LPC_burg);
	praat_addAction1 (classSound, 0, "To LPC (marple)...",
		"To LPC (burg)...", 1, DO_Sound_to_LPC_marple);
/*	praat_addAction1 (classSound, 0, "To Cepstrum",
		"To Spectrum", 1, DO_Sound_to_Cepstrum);*/
	praat_addAction1 (classSound, 0, "To MFCC...","To LPC (marple)...", 1,
		DO_Sound_to_MFCC);


	INCLUDE_MANPAGES (manual_LPC_init)
	
}

/* End of file praat_LPC_init.c */
