/*
 * Gnophone: A client for the Asterisk PBX
 *
 * Copyright (C) 2000, Linux Support Services, Inc.
 *
 * Written by Mark Spencer
 *
 * Linux/UNIX version distributed under the terms of
 * the GNU General Public License
 *
 * gaudio.h: Shared definitions and callback functions for gnophone audio
 *
 */


#ifndef _GNOPHONE_AUDIO_H
#define _GNOPHONE_AUDIO_H

#include <sys/time.h>

extern int phonecore_fullmulaw[];

struct audio_channel {
	char name[80];
	int  priority;			/* Higher priority == I'm a better interface */
	char *driver;
	int (*open)(struct audio_channel *c);
	int (*close)(struct audio_channel *c);
	int (*play_digit)(struct audio_channel *c, char digit);
	int (*activate)(struct audio_channel *c);
	int (*ring)(struct audio_channel *c);
	int (*dialtone)(struct audio_channel *c);
	int (*busy)(struct audio_channel *c);
	int (*fastbusy)(struct audio_channel *c);
	int (*ringing)(struct audio_channel *c);
	int (*deactivate)(struct audio_channel *c);
	int (*configure)(struct audio_channel *c);
	int (*flush)(struct audio_channel *c);	/* Flush channel if no more data coming */
	int (*sendaudio)(struct audio_channel *c, int format, void *data, int len);
	int (*readaudio)(struct audio_channel *c, int format, void *data, int *len);
	int (*exception)(struct audio_channel *c);
	int (*setspeed)(struct audio_channel *c, int speed);
	/* Simulated full duplex - this routine should switch between read
	   and write mode on non-duplex channels */
	int (*simduplex)(struct audio_channel *c, int write);
	int sformats;		/* Supported formats */
	int cananswer;		/* 0 if channel cannot indicate someone answering
						   1 if the channel can indicate it */
	int duplex;			/* True if the device is a full duplex device */					   
	int echocancelled;	/* True if the device has built in echo cancellation */
	int fd;				/* File descriptor for selecting() on */
	int hz;				/* Hz we're running at */
	/* Some convenience fields for the driver */
	void *pvt;			/* Private stuff by channel driver for everything else */

	/* Standard playback stuff */
	struct timeval 	st;	/* When we last were here */
	int pos;
	int id;				/* Sched ID */
	int repeat;			/* Repeat */
	int totallen;		/* Total length of sample (in samples) */
	int lensofar;		/* How much has been played so far (in samples) */
	short *sound;		/* The sound data itself */
	
	/* Simulated full duplex */
	int writemode;
	/* Duplex mode auto-switch ID */
	int dpid;
	int ringtone;
};

extern struct audio_channel *audio_new(void);
extern int audio_send(int format, void *data, int datalen, int loud, int stop);

#define AUDIO_DEFAULT_SPEED 8000

/* Default level of sound to consider "silence" for silence
   suppression and simulated full duplex */

#define DEFAULT_SUPPRESSION 5

#define DEFAULT_SWITCHTIME 800

/* Some standard functions for non-telephony devices */
extern int std_play_digit(struct audio_channel *c, char digit);
extern int std_ring(struct audio_channel *c);
extern int std_dialtone(struct audio_channel *c);
extern int std_ringing(struct audio_channel *c);
extern int std_busy(struct audio_channel *c);
extern int std_fastbusy(struct audio_channel *c);

extern int audio_register_channel(struct audio_channel *c);
extern int audio_ring(void);
extern int audio_busy(void);
extern int audio_ringing(void);
extern int audio_dialtone(void);
extern int audio_shutup(void);
extern int audio_deactivate(void);
extern int audio_get_fd(void);
extern int audio_get_exception(void);
extern int audio_load_modules(char *drivers);

/* Audio stuff */
extern int oss_audio_init(void);
extern int esd_audio_init(void);
extern int alsa_audio_init(void);
extern int send_digit(char digit);
extern int set_rec_source(void);
extern int audio_check_exception(void);
extern int audio_read(int format, char *buffer, int *len);
extern int audio_select(int chan);
extern void audio_digit_ready(int digit);
extern int audio_current(void);
extern int audio_findbest(void);
extern char *audio_getname(int chan);
extern void phonecore_init_tables(void);

#endif
