/* definitions for a looper */

#ifndef __LOOPERDATA_H__
#define __LOOPERDATA_H__

#include <pthread.h>
#include "buffer.h"
#include "speciallist.h"

#define GRAINPITCH_AUTO 	1
#define GRAINPITCH_RANGE    	2
#define GRAINPITCH_CHORD	3

#define THRESHOLDSTATE_LOW 	0
#define THRESHOLDSTATE_HIGH	1
#define THRESHOLDSTATE_ANY	2

enum {
        LOOP_PLAYMODE_LOOP,
	LOOP_PLAYMODE_BACKFORTH,
	LOOP_PLAYMODE_SINE,
	LOOP_PLAYMODE_CUSTOMSPEED,
	LOOP_PLAYMODE_POSITION,
	LOOP_PLAYMODE_EXTERNALPOS,
	LOOP_PLAYMODE_ONCE,
        LOOP_PLAYMODE_LAST
};

enum {
        LOOP_RECMODE_LOOP,
        LOOP_RECMODE_ONCE,
        LOOP_RECMODE_LAST
};


typedef struct _looper_data {
/*	GMutex		*looperdatamutex; */
	pthread_mutex_t looperdatamutex;
	buffer_info_t 	*buf;
	buffer_info_t	*clickmode_buf;
	int		buffer_group;
	int		id;
	int		looper_id;
	long 		samplerate;
	int		playmode;
	int 		recmode;
	double		speed;
	double		modespeed;
	float		vol;
	float		pan;
	float		panswing;
	float		panpos;
	float		pandir;
	float		Lfact;
	float		Rfact;
	float           recmix;
	float		recmixnew;
	float		recmixorig;
	float		playvuL;
	float		playvuR;
	float		recvuL;
	float		recvuR;
	float		inmaxL;
	float		inmaxR;
	float		outmaxL;
	float		outmaxR;
	double		playpos;
	double		playindex;
	long		recpos;
	float		pointer;
	long		loopstart;
	long		loopend;
	long		recstart;
	long		recend;
	int		isplaying;
	int		isrecording;
	int		linkrec2play;
	int		grainpitchmode;
	double		grainpitchbend;
	double		stereodiversity;
	int		keepabsolute;
	int		limiter;
	float		limit;
	float		limknee;
	float		limconst;
	int		cm_size;
	float		cm_min;
	float		cm_max;
	float*		customplaymode;
	int		midichannel;
	double		low_threshold;	
	double		high_threshold;
	int		thresholdstate;
	int		thresholdmode;
	float*		threshring;
	int		threshringsize;
	int		threshringptr;

	/* reverb */
	buffer_info_t   *reverb;
	long		reverblength;
	long		revpos;
	double		feedback;
	
	/* the granular player part */
	int		ngrains;
	int		graindensity;
	float		grainmixfactor;
	double		mingrainspeed;
	double		maxgrainspeed;
	long 		mingrainlength;
	long 		maxgrainlength;
	double*		grainspeeds;
	double*		grainpitchtable;
	double*		grainpitchvolumes;
	double*		grainpansL;
	double*		grainpansR;
	long*		grainoffsets;
	long*		grainsizes;
	int*		grainfadelengths;
	int*		grainsactive;		
	long*           grainindexes;

	/* list of bufferchanges */
/*	GList* 		dirtylist;*/
	speciallist_t*  dirtylist;
} looper_data_t;

looper_data_t* looperdata_new(buffer_info_t* buf, long samplerate, int id);
void looperdata_free(looper_data_t* data);

void looperdata_lock(looper_data_t* data);
void looperdata_unlock(looper_data_t* data);

void looperdata_copy_settings (looper_data_t* dst, looper_data_t* src);

void looperdata_set_clickmode_buf(looper_data_t* data, buffer_info_t* buf);
buffer_info_t* looperdata_get_clickmode_buf(looper_data_t* data);

void looperdata_write_dirtyblock(looper_data_t* data, double start, double end);
int looperdata_read_once_dirtyblock(looper_data_t* data, 
	double* start, double* end);

void looperdata_set_playing(looper_data_t* data, int isplaying);
void looperdata_set_recording(looper_data_t* data, int isrecording);
int looperdata_get_playing(looper_data_t* data);
int looperdata_get_recording(looper_data_t* data);

void looperdata_set_vol(looper_data_t* data, float vol);
float looperdata_get_vol(looper_data_t* data);
void looperdata_set_pan(looper_data_t* data, float pan);
void looperdata_set_panswing(looper_data_t* data, float pan);
void looperdata_set_recmix(looper_data_t* data, float recmix);
float looperdata_get_recmix(looper_data_t* data);

void looperdata_set_loopstart(looper_data_t* data, long start);
long looperdata_get_loopstart(looper_data_t* data);
void looperdata_set_loopend(looper_data_t* data, long end);
long looperdata_get_loopend(looper_data_t* data);
void looperdata_set_recstart(looper_data_t* data, long start);
long looperdata_get_recstart(looper_data_t* data);
void looperdata_set_recend(looper_data_t* data, long end);
long looperdata_get_recend(looper_data_t* data);

void looperdata_set_mingrainspeed(looper_data_t* data,double speed);
void looperdata_set_maxgrainspeed(looper_data_t* data,double speed);
void looperdata_set_mingrainlength(looper_data_t* data,long length);
void looperdata_set_maxgrainlength(looper_data_t* data,long length);
void looperdata_set_graindensity(looper_data_t* data,int density);
void looperdata_set_playmode(looper_data_t* data,int mode);
void looperdata_set_recmode(looper_data_t* data,int mode);
void looperdata_set_playpos(looper_data_t* data, double playpos);
void looperdata_set_recpos(looper_data_t* data, long recpos);
void looperdata_set_grainpitchmode (looper_data_t* data, int mode);
int looperdata_get_grainpitchmode (looper_data_t* data);
void looperdata_set_grainpitchtablevalue (looper_data_t* data, double value, double vol);
void looperdata_set_grainpitchbend (looper_data_t* data, double bend);
double looperdata_get_mingrainspeed(looper_data_t* data);
double looperdata_get_maxgrainspeed(looper_data_t* data);
long looperdata_get_mingrainlength(looper_data_t* data);
long looperdata_get_maxgrainlength(looper_data_t* data);
int looperdata_get_graindensity(looper_data_t* data);
void looperdata_set_stereodiversity(looper_data_t* data, double diversity);
double looperdata_get_stereodiversity(looper_data_t* data);

void looperdata_set_reverblength(looper_data_t* data, long length);
long looperdata_get_reverblength(looper_data_t* data);
void looperdata_set_feedback(looper_data_t* data, double feedback);
double looperdata_get_feedback(looper_data_t* data);

void looperdata_set_speed(looper_data_t* data, double speed);
int looperdata_get_limiter(looper_data_t* data);
void looperdata_set_limiter(looper_data_t* data, int limiter);
float looperdata_get_limknee(looper_data_t* data);
void looperdata_set_limknee(looper_data_t* data, float limknee);
float looperdata_get_limit(looper_data_t* data);
void looperdata_set_limit(looper_data_t* data, float limit);
double looperdata_get_speed(looper_data_t* data);
double looperdata_get_playpos(looper_data_t* data);
long looperdata_get_recpos(looper_data_t* data);
int looperdata_get_cm_size(looper_data_t* data);
char* looperdata_cm2str (looper_data_t* data, char* str);
void looperdata_str2cm (looper_data_t* data, char* str, int cm_size);

int    looperdata_get_thresholdmode(looper_data_t* data);
void   looperdata_set_thresholdmode(looper_data_t* data, int mode);
double looperdata_get_low_threshold(looper_data_t* data);
void   looperdata_set_low_threshold(looper_data_t* data, double low);
double looperdata_get_high_threshold(looper_data_t* data);
void   looperdata_set_high_threshold(looper_data_t* data, double high);
int    looperdata_get_thresholdbuffersize(looper_data_t* data);
void   looperdata_set_thresholdbuffersize(looper_data_t* data, int size);

void looperdata_get_playmeters(looper_data_t* data,float* L,float* R);
void looperdata_get_recmeters(looper_data_t* data,float* L,float* R);

/*void looperdata_write_sample(looper_data_t* data,float* L, float* R);*/
void looperdata_write_sampleblock(looper_data_t* data, long size, float* Lbuf, float* Rbuf);
/*void looperdata_calc_sample(looper_data_t* data,float* L, float* R);*/
void looperdata_calc_sampleblock(looper_data_t* data, long size, float* Lbuf, float* Rbuf, float* Pbuf,int do_play, int do_rec);

void looperdata_set_pointer(looper_data_t* data, float *P);
void looperdata_get_pointer(looper_data_t* data, float *P);

/* granular player functions */
int looperdata_get_ngrains (looper_data_t* data);
void looperdata_set_ngrains (looper_data_t* data, int ngrains);
void looperdata_set_grainlength (looper_data_t* data, long length);

int looperdata_get_midichannel (looper_data_t* data);
void looperdata_set_midichannel (looper_data_t* data, int channel);

#endif
