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

        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.

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



#if defined (Sample_CURRENT_HEADER)
	#error Inclusion recursive du header Sample.
#endif
#define	Sample_CURRENT_HEADER

#if ! defined (Sample_HEADER_INCLUDED)
#define	Sample_HEADER_INCLUDED



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

#include	"archi.h"
#include	"base_ct.h"

#include	<cstdio>



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

#define	Sample_NAME_LEN					28			/* Longueur du nom d'un sample */

#define	Sample_MIN_FREQ					2000		/* Frequence min de replay d'un sample, en Hz */
#define	Sample_MAX_FREQ					240000	/* Frequence max de replay d'un sample, en Hz (tient dans 18 bits) */

#define	Sample_INIT_LOOPBUF_LEN			512		/* Taille des buffers de bouclage initiaux en samples */
#define	Sample_INIT_INIT_NBR_TRACKS	1			/* Samples Mono par defaut */
#define	Sample_INIT_INIT_NBR_BYTES		1			/* Samples 8 bits par defaut */

#define	Sample_REF_A440					69
#define	Sample_REF_C2						(Sample_REF_A440 - 21)

#define	Sample_H_ZOOM_MIN					(-4)
#define	Sample_H_ZOOM_MAX					16
#define	Sample_H_ZOOM_TO_INIT			999		/* Signifie que l'editeur doit initialiser le zoom tel que la vue soit la plus globle possible. */

#define	Sample_V_ZOOM_MIN					1.0f
#define	Sample_V_ZOOM_MAX					256.0f




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

/* Selection dans l'editeur de samples */
typedef struct
{
	bool		flag;				// true: la selection est active
	long		start;			// En samples
	long		length;			// En samples
	int		start_channel;	// Toujours 0 pour les mono
	int		nbr_channel;	// Toujours 1 pour les mono
} Sample_SELECTION;

/* Vue dans l'editeur de samples */
typedef struct
{
	long		h_pos;			// En samples. 0 a length - 1
	signed int	h_zoom;		// < 0: grossissement, > 0: zoom out. Sample_H_ZOOM_TO_INIT: zoom a definir.
	float		v_pos;			// entre -1 et 1
	float		v_zoom;			// toujours >= 1 (grossissement)
} Sample_VIEW;



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

class Sample
{



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

public:



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

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

/*--------------------------------------------------------------------------*/
/*      Routines de base                                                    */
/*--------------------------------------------------------------------------*/

void		get_sample_name (char *name_0);
void		set_sample_name (const char *name_0);
int		get_sample_resolution (void);
signed int	set_sample_resolution (int nbits);
int		get_sample_stereo (void);
signed int	set_sample_stereo (int tracks);
int		get_sample_bytes_per_sample (void);
signed int	get_sample_balance (void);
void		set_sample_balance (signed int balance);
int		get_sample_midi_note (void);
void		set_sample_midi_note (int note);
int		get_sample_volume (void);
void		set_sample_volume (int volume);
signed int	get_sample_finetune (void);
void		set_sample_finetune (signed int finetune);
long		get_sample_freq (void);
void		set_sample_freq (long freq);
long		get_sample_length (void);
signed int	set_sample_length (long length);
long		get_sample_repeat (void);
long		get_sample_replen (void);
long		get_sample_loop (void);
void		set_sample_loop (int loop_type, long reppos, long replen);
long		get_sample_loopbuf (void);
signed int	set_sample_loopbuf (long loopbuf);
void		*get_sample_loopbuf_adr (void);
void		*get_sample_data_adr (void);
void		set_sample_group (int group);
int		get_sample_group () const;
int		get_sample_type (void);

FILE		*get_sample_file_ptr (void);
void		set_sample_file_ptr (FILE *file_ptr);
long		get_sample_buffer_len (int buffer);
signed int	set_sample_d2d_buffers (long sbuffer_len, long buffer1_len, long buffer2_len);
void		*get_sample_startbuf_ptr (void);
int64_t	get_sample_file_data_offset (void);
void		set_sample_file_data_offset (int64_t pos);
bool		get_read_d2d_header_flag (void);
void		set_read_d2d_header_flag (bool flag);
const char	*get_sample_d2d_filename (void);
signed int	set_sample_d2d_filename (const char *filename_0);
signed int	use_file_for_d2d (const char *filename_0);
signed int	read_d2d_header (void);
signed int	update_d2d_header (void);

signed int	make_buffers (void);

signed int	kill_sample (void);
long		estimate_memory_usage () const;

BYTE	*get_access_buffer_ptr (long position, long length, int buffer_id, bool write_flag, bool peak_file_flag = false);

void	get_sample_view (Sample_VIEW &view);
void	set_sample_view (const Sample_VIEW &view);
void	get_sample_selection (Sample_SELECTION &selection);
void	set_sample_selection (const Sample_SELECTION &selection);

/*--------------------------------------------------------------------------*/
/*      Conversions                                                         */
/*--------------------------------------------------------------------------*/

signed int	convert_sample_8_2_16 (void);
signed int	convert_sample_16_2_8 (void);
signed int	convert_sample_mono_2_stereo (void);
signed int	convert_sample_stereo_2_mono (void);

static signed int	release_access_buffer (int buffer_id);



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

public:



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

public:



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

private:



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

private:
signed int	init (void);
void		restore (void);

signed int	correct_buffer_len (void);
void		check_se_view (void);



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

private:
int		_number;
char		_name [Sample_NAME_LEN];
int		_type;			// Position du sample: 0 = memoire, 1 = D2D
int		_nbits;			// Nombre de bits: 8 ou 16
int		_tracks;			// Nombre de voies: 1 = mono, 2 = stereo, >2 = multi-piste
signed int	_autobal;	// Balance automatique: 0..800..FFF, -1 = pas de balance
int		_volume;			// 0..100..FFF
signed int	_finetune;	// -8 = -1/2 ton, a +7 = +7/16 ton
int		_loop;			// Bits 0-1: 00 = pas de boucle, 01 = boucle normale, 11 = ping-pong
int		_midi_note;		// Reference: 48 = C2. ?? Ne pas tenir compte de ce parametre ?
long		_freq;			// Frequence pour le C2: 2000 a 240000 Hz
long		_length;			// Longueur, en samples
long		_repeat;			// Point de bouclage, en samples
long		_replen;			// Longueur de la boucle, en samples
long		_loopbuf;		// Longueur du buffer de bouclage, en samples
char		*_filename_0;	// Nom du fichier
void		*_data_ptr;		// Donnees du sample
void		*_loopbuf_ptr;	// Buffer de repetition

int		_group;			// Index du groupe de sample. 0 = pas de groupe specifique.

/* Pour le D2D */
long		_buffer_len [3];		// Longueur des buffers en samples: 0 = debut, 1,2 = normal */
bool		_header_flag;			// 0 = ne pas lire de header, 1 = lire le header du fichier a l'initialisation */
int64_t	_file_data_offset;	// Offset des donnees dans le fichier */
void		*_start_buf_ptr;		// Buffer de debut du sample */
FILE		*_file_ptr;				// Pointeur sur le fichier du sample */

/* Pour l'editeur de samples */
Sample_VIEW			_view;
Sample_SELECTION	_sel;



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

private:



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

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

};	// Fin de la definition de la classe



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

#endif

#undef Sample_CURRENT_HEADER
