/*****************************************************************************

        GRAOUMF TRACKER 2
        Author: Laurent de Soras, 1996-2016

--- Legal stuff ---

This program is free software. It comes without any warranty, to
the extent permitted by applicable law. You can redistribute it
and/or modify it under the terms of the Do What The Fuck You Want
To Public License, Version 2, as published by Sam Hocevar. See
http://sam.zoy.org/wtfpl/COPYING for more details.

*****************************************************************************/



/*

Trucs a faire quand on rajoute un effet
=======================================

FxPreset
--------

	- Creer un label FxPreset_TYPE_???
	- Creer une structure FxPreset_???
	- Inserer cette structure dans l'union FxPreset_EFFECT_CONF
	- Creer des constantes de limitation des parametres
	- Rajouter son nom dans FxPreset::effect_name_0
	- Creer des masques de bit FxPreset_AUTO_VAL_???_ si necessaire
	- Modifier les routines suivantes:
		FxPreset::validate_parameters
		FxPreset::reset_parameters
		FxPreset::copy_preset si necessaire

player
------

	- Creer une structure Player::FxInternal???
	- L'ajouter dans Player::TrackInfoFx

play_fx
-------

	- Modifier:
		Player::fx_init, variable "functions"
		Player::fx_fx_set_default_parameters
		Player::fx_fx_init
		Player::fx_fx_set_stereo
		Player::fx_fx_silence
		Player::fx_fx_update
		Player::fx_fx_restore

	- Ajouter:
		Player::fx_???_set_default_parameters
		Player::fx_???_init. Ne pas oublier d'imposer la stereo si necessaire.
		Player::fx_???_set_stereo
		Player::fx_???_silence
		Player::fx_???_update
		Player::fx_???_restore
		Player::fx_???_activate (private)
		Toutes les fonctions en debut de tick et pendant le tick

mix_fx
------

	- Modifier MIXFX_do_fx
	- Ajouter MIXFX_???. Faire avancer les phases des oscillateurs en fonction de longueur_frame / freq_ech

mod_gt2
-------

	- Creer une structure MODGT2_FX_???
	- Completer le tableau MODGT2_fx_chunk_size
	- Modifier:
		MODGT2_save_fx_preset
		MODGT2_load_fx_preset

Creer un module PatEdMenuFx???
------------------------------

PatEdMenuFx
-----------

	- Ajouter une variable membre _??? du type PatEdMenuFx???
	- Include le fichier PatEdMenuFx??? dans le .h
	- Creer une constante PatEdMenuFx_SUBMENU_???
	- Etablir un lien fils -> pere dans le constructeur
	- Modifier:
		PatEdMenuFx::refresh
		PatEdMenuFx::refresh_dynamic
		PatEdMenuFx::manage
		PatEdMenuFx::set_submenu
		PatEdMenuFx::redraw_submenu

PatEdTracks
-----------
   - Modifier TRK_select_fx_command. Ne pas oublier de modifier list [] et le
switch (group).

*/



#if defined (FxPreset_CURRENT_HEADER)
	#error Inclusion recursive du header FxPreset.
#endif
#define	FxPreset_CURRENT_HEADER

#if ! defined (FxPreset_HEADER_INCLUDED)
#define	FxPreset_HEADER_INCLUDED



/*\\\ INCLUDES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

#include	"archi.h"



/*\\\ CONSTANTES PUBLIQUES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

#define	FxPreset_NAME_LEN					32			/* Longueur du nom d'un preset d'effet */

enum
{
	FxPreset_TYPE_NONE = 0,
	FxPreset_TYPE_DELAY,
	FxPreset_TYPE_RESFILT,
	FxPreset_TYPE_DISTO,

	FxPreset_NBR_TYPES
};

/*--------------------------------------------------------------------------*/
/*      Constante de limitation des presets                                 */
/*--------------------------------------------------------------------------*/

/* Delay */
#define	FxPreset_DELAY_MAX_TIME			(4.0)		/* 4 secondes maxi pour le temps de delay */
#define	FxPreset_DELAY_MIN_TIME			(1.0e-4)	/* 0.1 milli-secondes mini pour le temps de delay */
#define	FxPreset_DELAY_MAX_FDBK			(1.0)		/* feedback max: 100 % */
#define	FxPreset_DELAY_MIN_FDBK			(0.0)		/* feedback min: 0 % */

/* Filtre resonnant */
#define	FxPreset_RESFILT_MIN_Q			0.01
#define	FxPreset_RESFILT_MAX_Q			100.0
#define	FxPreset_RESFILT_MIN_FREQ		20.0		/* Limites pour toutes les frequences. Au dela, la cellule ne rentre pas en compte dans le filtre */
#define	FxPreset_RESFILT_MAX_FREQ		20000.0
#define	FxPreset_RESFILT_MIN_CRATIO	0.0
#define	FxPreset_RESFILT_MAX_CRATIO	64.0
#define	FxPreset_RESFILT_MIN_BIQUAD	1			/* Au moins 1 biquad au total */
#define	FxPreset_RESFILT_MAX_BIQUAD	8			/* Limite le nombre total de biquad (ordre et cellules) */
#define	FxPreset_RESFILT_MIN_CELLFREQ	0.0
#define	FxPreset_RESFILT_MAX_CELLFREQ	20000.0
#define	FxPreset_RESFILT_MIN_LFOFREQ	(1.0e-3)
#define	FxPreset_RESFILT_MAX_LFOFREQ	100.0
#define	FxPreset_RESFILT_MIN_LFODEPTH	0.0
#define	FxPreset_RESFILT_MAX_LFODEPTH	48.0

/* Distorsion */
#define	FxPreset_DISTO_MIN_GAIN			0
#define	FxPreset_DISTO_MAX_GAIN			60
#define	FxPreset_DISTO_MIN_SEC_GAIN	6
#define	FxPreset_DISTO_MAX_SEC_GAIN	60
#define	FxPreset_DISTO_MIN_THRESHOLD	6			/* Doit toujours etre superieur a 20*log10(PI) */
#define	FxPreset_DISTO_MAX_THRESHOLD	60
enum															/* Types de distorsions */
{
	FxPreset_DISTO_TYPE_BOOST,							/* Log */
	FxPreset_DISTO_TYPE_PUNCH,							/* Sin */

	FxPreset_DISTO_NBR_TYPES
};

/* Delay multi-tap */
#define	FxPreset_MTDELAY_NBR_TAPS		4			/* Nombre maxi de taps pour le delay multi-tap */

/*--------------------------------------------------------------------------*/
/*      Champs de bits correspondant aux valeurs du preset qui sont         */
/*      modifiees en temps reel par l'effet. On peut ainsi choisir          */
/*      explicitement de ne pas modifier ces valeurs quand on copie un      */
/*      preset.                                                             */
/*--------------------------------------------------------------------------*/

/* Filtre resonnant */
#define	FxPreset_AUTO_VAL_RESFILT_LFO_PHASE	0x0001



/*\\\ TYPES & STRUCTURES PUBLIQUES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

/* Delay */
typedef struct
{
	double		delay;		// Temps de delay, en secondes
	double		feedback;	// Taux de regeneration, 0...1
} FxPreset_DELAY;

/* Filtre */
typedef struct
{
	double	q;					// Facteur de qualite, 0.01...0.5...100
	double	freq;				// Frequence centrale (de la premiere cellule), en Hz
	double	cell_ratio;		// Nombre de 1/2 tons separant la premiere et la deuxieme cellule
	double	lfo_freq;		// Frequence en Hz d'oscillation de la frequence centrale
	double	lfo_depth;		// Amplitude des oscillation: en demi-tons
	double	lfo_phase;		// Phase courante du LFO [0...1[
	int		lfo_waveform;	// Type de courbe de l'onde du LFO
	int		type;				// Type: Low-pass, High-pass, Band-pass, Band-reject
	int		nbr_biquads;	// Nombre de biquads par cellule 1...???
	int		nbr_cells;		// Nombre de cellules additionnelles 0...???
	bool		cell_flag;		// true: indique qu'il doit y avoir plus d'une cellule. Uniquement pour Band Pass et Notch.
	bool		lfo_flag;		// true: LFO actif.
} FxPreset_RESFILT;

/* Distorsion */
typedef struct
{
	double	gain;				// Gain (dB)
	double	threshold;		// Type 1: Niveau de tassement des ondulation (dB)
	double	sec_gain;		// Type 1: Gain secondaire (dB).
	int		type;				// Type de distorsion (0 = log, 1 = sin)
} FxPreset_DISTO;

/* Delay multitap */
typedef struct
{
	double	delay;			// Temps de delay, en s
	double	feedback;		// Taux de regeneration, 0...1
	struct
	{
		double	delay;		// Retard du tap, en s
		double	level;		// Niveau d'entree, 0...1
		UWORD		balance;		// Balance du tap 0000...8000...FFFF
	}			tap [FxPreset_MTDELAY_NBR_TAPS];	// Donnees de chaque tap
	int		nbr_taps;		// Nombre de taps, de 1 a FxPreset_MTDELAY_NBR_TAPS
} FxPreset_MTDELAY;

/* Flanger */
typedef struct
{
	double	delay;			// Temps de delay, en s
	double	feedback;		// Taux de regeneration, -1...0...1
	double	depth;			// Profondeur, en s
	double	freq;				// Frequence d'oscillation, en Hz
	double	phase;			// Phase courante de l'oscillation, 0...1
	int		waveform;		// Forme de l'onde de l'oscillateur
} FxPreset_FLANGER;



/* La totale */
typedef union
{
	FxPreset_DELAY			delay;
	FxPreset_MTDELAY		mtdelay;
	FxPreset_FLANGER		flanger;
	FxPreset_RESFILT		resfilt;
	FxPreset_DISTO			disto;
} FxPreset_EFFECT_CONF;		// Configuration de l'effet, vue par la partition



/*\\\ DEFINITION DE LA CLASSE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

class FxPreset
{



/*\\\ CONSTANTES PUBLIQUES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

public:
static const char	*const effect_name_0 [FxPreset_NBR_TYPES];



/*\\\ PROTOTYPES DES METHODES PUBLIQUES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

public:
FxPreset (int number);
~FxPreset (void);
signed int	check_ok (void) const;
void		self_display (void) const;

void		get_name (char name_0 [FxPreset_NAME_LEN+1]);
void		set_name (const char *name_0);
int		get_number (void);
void		set_number (int number);
int		get_effect_type (void);
void		set_effect_type (int type);
const FxPreset_EFFECT_CONF	&get_parameters (void);
void		set_parameters (const FxPreset_EFFECT_CONF &conf);
void		validate_parameters (void);

static void	reset_parameters (FxPreset_EFFECT_CONF &conf, int type);
static void	validate_parameters (FxPreset_EFFECT_CONF &conf, int type);
static void	copy_preset (FxPreset_EFFECT_CONF &conf, const FxPreset_EFFECT_CONF &src_conf, int type, long auto_val);



/*\\\ ATTRIBUTS PUBLIQUES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

public:



/*\\\ VARIABLES DE CLASSE PUBLIQUES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

public:



/*\\\ CONSTANTES PRIVEES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

private:



/*\\\ PROTOTYPES DES METHODES PRIVEES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

private:



/*\\\ ATTRIBUTS PRIVES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

private:
int		_number;							/* Numero du preset */
char		_name [FxPreset_NAME_LEN];	/* Nom du preset */
int		_type;							/* Type de l'effet */
FxPreset_EFFECT_CONF	_conf;			/* Configuration de l'effet */



/*\\\ VARIABLES DE CLASSE PRIVEES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

private:



/*\\\ PROTOTYPES DES METHODES INTERDITES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

private:
FxPreset (void);
FxPreset (const FxPreset &other);
void		operator = (const FxPreset &other);
int		operator == (const FxPreset &other) const;

};	// Fin de la definition de la classe



/*\\\ FIN DU FICHIER \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

#endif

#undef FxPreset_CURRENT_HEADER
