/* buffer.h definitions for administration  *
 *	of  filebuffers (always stereo)     */

#ifndef __BUFFER_H__
#define __BUFFER_H__

#include <pthread.h>
#include <stdio.h>
#include <sndfile.h>
#include "filechunk.h"
#include "speciallist.h"

/* how many frames will we read at once */
#define TBS = 32768

#define BUFFER_STATUS_NEW 	1
#define BUFFER_STATUS_TOLOAD	2
#define BUFFER_STATUS_LOADING 	3
#define BUFFER_STATUS_READY	4
#define BUFFER_STATUS_DEAD	5

#define BUFFER_ERROR_UNKNOWN	-1
#define BUFFER_ERROR_ALLOC	-2
#define BUFFER_ERROR_NOSF	-3

#define BUFFER_TYPE_MEMORY	1
#define BUFFER_TYPE_FILEBUFFER  2
#define BUFFER_TYPE_DISCSTREAM	3

typedef struct _buffer_info {
	int 		id;
	int		type;
	int		status;
	int		pending;
	int 		error;
	int		group_max;
	pthread_mutex_t buffermutex;
	char* 		filename; /* only if data comes from file */
	char*		shortname;
	double		percent_filled;
	int		normalized;
	float		volume_factor;
	long		parent_samplerate;
	long		snap_offset;
	float		samplerate_factor;
	chunk_group_t** chunk_list;
} buffer_info_t;

typedef struct _buffer_save_data{
	buffer_info_t 	*buf;
	long		start;
	long		end;
} buffer_save_data_t;

buffer_info_t* 	buffer_new(int id, long rate);
int 		buffer_get_type(buffer_info_t* buf);
void 		buffer_lock(buffer_info_t* buf);
void 		buffer_unlock(buffer_info_t* buf);
void 		buffer_open_discstream (buffer_info_t* buf, char* fname, long srate);
void	 	buffer_loadfile(buffer_info_t* buf, char* fname,long srate);
int		buffer_save (buffer_info_t* buf, char* fname, long srate, long start, long end);
void 		buffer_set_filename(buffer_info_t* buf, char* name);
void 		buffer_set_shortname(buffer_info_t* buf, char* name);
char* 		buffer_get_shortname(buffer_info_t* buf);
int		buffer_get_group(buffer_info_t* buf, int priority);
void 		buffer_delete_group(buffer_info_t* buf, int gid);
int		buffer_get_status(buffer_info_t* buf);
int 		buffer_get_channels(buffer_info_t* buf);
void 		buffer_set_channels(buffer_info_t* buf, int channels);
/*void		buffer_set_ds(buffer_info_t* buf, int is_ds);*/
void		buffer_set_area(buffer_info_t* buf, int group, long start, long end, long bandwith);
void		buffer_resize(buffer_info_t* buf, long new_size);
long		buffer_get_size(buffer_info_t* buf);
/*long 		buffer_get_corrected_size(buffer_info_t* buf, long srate);*/
int 		buffer_delete(buffer_info_t* b);
float 		buffer_analyze(buffer_info_t* buf, int group, long start, long end);
void		buffer_normalize(buffer_info_t* buf, float factor,long start, long end);
void		buffer_set_volume_factor(buffer_info_t* buf, float factor);
float           buffer_get_volume_factor(buffer_info_t* buf);
/*
void           	buffer_set_snap_offset(buffer_info_t* buf, long offset);
long           	buffer_get_snap_offset(buffer_info_t* buf);
*/
/*speciallist_t*  buffer_list_new();*/
void		buffer_discthread_launch(speciallist_t *buffer_list);
/*float		buffer_readsample(buffer_info_t* buf, int channel, long index, int group);*/
float 		buffer_readsample_interpolated(buffer_info_t* buf, int channel, double index, int group);
void		buffer_writesample(buffer_info_t* buf, int channel, long index, int group, float sample);
void 		buffer_write_sampleblock(buffer_info_t* buf, long index, long size, int group, float* Lbuf, float* Rbuf);
float 		buffer_get_sampleratefactor(buffer_info_t* buf, long srate);
#endif
