/*
 * FILE:    bat.h
 * PROGRAM: RAT
 * AUTHORS: Vicky Hardman + Isidor Kouvelas + Colin Perkins + Orion Hodson
 * 
 * $Revision: 1.1.1.1 $
 * $Date: 1998/08/15 19:16:45 $
 * 
 * Copyright (c) 1995,1996 University College London
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, is permitted, for non-commercial use only, provided
 * that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the Computer Science
 *      Department at University College London
 * 4. Neither the name of the University nor of the Department may be used
 *    to endorse or promote products derived from this software without
 *    specific prior written permission.
 * Use of this software for commercial purposes is explicitly forbidden
 * unless prior written permission is obtained from the authors.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _RAT_H_
#define _RAT_H_

#define MAX_ENCODINGS	7

#define FULL_DUPLEX 	0
#define NET_MUTES_MIKE 	1
#define MIKE_MUTES_NET 	2

/* Will probably move these defs if I can */
#define MAX_PACKET_SAMPLES	1280
#define SAMPLES_PER_UNIT        160
#define FRAMESIZE		SAMPLES_PER_UNIT
#define PACKET_LENGTH		sizeof(rtp_hdr_t) + MAX_PACKET_SAMPLES + 100

/* Rat mode def's */
#define AUDIO_TOOL              1
#define TRANSCODER              2
#define FLAKEAWAY               4

typedef short  sample;

extern int thread_pri;

typedef struct s_bias_ctl {
        int   active;
        int   bias;
        int   ccnt;
} bias_ctl;

typedef struct {
	int     	buf_len;        /* Length of circular buffer              */
	int     	head, tail;     /* Index to head and tail of buffer       */
	u_int32 	head_time;      /* Time of latest sample in buffer.       */
					/* In fact pad_time has to be taken into  */
					/* account to get the actual value.       */
	u_int32		tail_time;	/* Current time                           */
	int		dist;		/* Distance between head and tail.        */
					/* We must make sure that this is kept    */
					/* equal to value of the device cushion   */
					/* unless there is no audio to mix.       */
	sample		*mix_buffer;	/* The buffer containing mixed audio data */
} mix_struct;

#define MAX_CUSHION	4000
#define MIN_CUSHION	320

typedef struct s_cushion_struct {
	int             cushion_estimate;
	int             cushion_size;
	int             cushion_step;
	sample          audio_zero_buf[MAX_CUSHION];
	int		*read_history;	/* Circular buffer of read lengths */
	int		hi;		/* History index */
	int		*histogram;	/* Histogram of read lengths */
} cushion_struct;

typedef struct s_coded_unit {
	int	coding_type;
	char	*state;
	int	state_len;
	char	*data;
	int	data_len;
} coded_unit;

typedef struct s_tx_unit {
	struct s_tx_unit	*next;
	struct s_tx_unit	*prev;
	sample			*data;			/* pointer to raw data in read_buf */
	int			energy;
	coded_unit		coded[MAX_ENCODINGS];
	int			silence;		/* First pass */
	int			send;			/* Silence second pass */
	int			talkspurt_start;
	u_int32			time;
	int			dbe_source_count;	/* Num elements of the following array that are used. Will be >= 1 */
	rtcp_dbentry   		*dbe_source[16];	/* Sender info, dbe_source[0] is the SSRC of the sender.           */
} tx_unit;

typedef struct s_read_buffer {
	sample	*read_buf;	/* The read_buffer */
	int	read_buf_len;	/* The read_buffer length */
	int	read_buf_head;	/* Where we have read up to */
	int	read_buf_tail;	/* Where unit conversion is */
	int	read_buf_dist;	/* Distance between head and tail */
	int	unit_buf_size;	
	tx_unit	*unit_buf;
	tx_unit	*silence_ptr;	/* Where rules based silence is */
	int	talkspurt;	/* Whether we are in a talkspurt */
	int	posthang;	/* Posthang packet counter */
	tx_unit	*tx_ptr;	/* Where transmission is */
} read_buffer;

/*************** Receive queues */

typedef struct samples_type_tag {
	int             scheme;			/* PCM or ADPCM etc. */
	int		sampling_rate;
	int		bits_per_sample;
} samples_type;

/* Unit throughout receiver */
typedef struct rx_element_tag {
	struct rx_element_tag  *next_ptr;
	struct rx_element_tag  *prev_ptr;
        struct rx_interval_tag *interval;            /* so that interval can be extracted if necessary (i.e. lpc decoding) */
	u_int32        	playoutpt;		     /* target play out point */
	int		dbe_source_count;	     /* Num elements of the following array that are used. Will be >= 1 */
	rtcp_dbentry   *dbe_source[16];		     /* originator info */
	int             unit_size;		     /* unit size = no of equiv PCM samples */
        int             comp_count;                  /* Number of different coded data schemes for data */
	samples_type    comp_format[MAX_ENCODINGS];  /* Current state of samples */
	sample         *comp_data[MAX_ENCODINGS];     /* Pointer to compressed samples - it can be any length long */
        samples_type    decomp_format;		     /* Current state of samples */
	sample         *decomp_data;		     /* Pointer to decompressed samples - it can be any length long */
	int		mixed;
	u_int16         sequence_no;		     /* Irrelevant sequence number */
	u_int32         time_stamp;		     /* Irrelevant time stamp on packet */
	int             units_per_pckt;
	int             unit_position;		     /* unit position in packet */
	int             talk_spurt_start;	     /* talk spurt start marker */
	int             talk_spurt_end;		     /* talk spurt end pointer */
} rx_queue_element_struct;

typedef struct rx_queue_tag {
	int                      queue_empty_flag;
	rx_queue_element_struct *head_ptr;
	rx_queue_element_struct *tail_ptr;
} rx_queue_struct;

/* Playout buffer */
typedef struct rx_interval_tag {
	struct rx_interval_tag  *next_ptr;
	struct rx_interval_tag  *prev_ptr;
	u_int32                  interval_start;
	int                      no_units_in_chain;
	rx_queue_element_struct *chain_ptr;
} rx_interval_struct;

typedef struct rx_buffer_tag {
	int                 queue_empty_flag;
	int32               len; /* number of intervals in rx_buffer */
	rx_interval_struct *head_ptr;
	rx_interval_struct *tail_ptr;

	rx_interval_struct *last_to_get;
} rx_buffer_struct;

/* Packets off the net */
typedef struct pckt_queue_element_tag {
	struct pckt_queue_element_tag *next_pckt_ptr;
	struct pckt_queue_element_tag *prev_pckt_ptr;
	u_int32                        addr;
	int                            len;
	u_int32                        arrival_timestamp;
	char                          *pckt_ptr;
} pckt_queue_element_struct;

typedef struct pckt_queue_tag {
	int                        queue_empty_flag;
	pckt_queue_element_struct *head_ptr;
	pckt_queue_element_struct *tail_ptr;
} pckt_queue_struct;

typedef struct speaker_table_ {
	struct speaker_table_ 	*next;
	rtcp_dbentry		*dbe;
	int			state;
} speaker_table;

typedef struct session_tag {
	int		mode;                           /* audio tool, transcoder, flakeaway */
	char            asc_address[MAXHOSTNAMELEN+1];  /* their ascii name if unicast */
	char            maddress[16];
	u_long          net_maddress;			/* Same as above, can be used in a sendto */
	u_long          our_address;			/* our unicast address */
	int             rtp_port;
	int             rtcp_port;
	int             ttl;
	int				ui;
	int             rtp_fd;
	int             rtcp_fd;
        u_long          ipaddr;
	u_int32		cur_time;			/* The current time */
	int		rtp_seq;
	int		encodings[MAX_ENCODINGS];
	int		num_encodings;			/* 1 - MAX_ENC */
	int             sending_audio;
	int             playing_audio;
	int             units_per_pckt;
	int		repair;				/* Packet repair */
	int		lecture;			/* Lecture mode */
	int             transmit_audit_required;
	int             receive_audit_required;
	int             voice_switching;		/* NETMUTESMIKE etc. */
	int		redundancy_pt;
	int		l16_pt;
	int		detect_silence;
        int             meter;                      /* if powermeters are on */
        bias_ctl        bc;
        int             ui_on;
        int		ui_response;
        float           drop;                       /* Flakeaway drop percentage [0,1] */
	FILE		*in_file;
	FILE		*out_file;
	int		have_device;
	int		keep_device;
	struct timeval	device_time;
	int		audio_fd;
	int		double_speed;
	read_buffer	rb;
	sd_t           *sd_info;
	int		mix_count;
	rtp_db          db;
	struct adpcm_state	 adpcm_state;
	speaker_table	*speakers_active;
	int		last_zero;			/* audio.c */
	long		loop_delay;
	long		loop_estimate;
	int 		lbl_cb_base_socket;
	int 		lbl_cb_channel_socket;
	int 		lbl_cb_channel;
	int		lbl_cb_priority;
        int             filter_loopback;
        int             flake_go;                   /* counter used to avoid dropping at start */
        int             flake_os;                   /* number outstanding */
	int             trim_hold;
} session_struct;


#endif /* _RAT_H_ */

