/*
 * ad.h -- generic live audio interface for recording and playback
 * 
 * **********************************************
 * CMU ARPA Speech Project
 *
 * Copyright (c) 1996 Carnegie Mellon University.
 * ALL RIGHTS RESERVED.
 * **********************************************
 * 
 * HISTORY
 * 
 * $Log: ad.h.in,v $
 * Revision 1.1  2000/12/12 23:01:41  lenzo
 * Rationalizing libs and names some more.  Split a/d and fe libs out.
 *
 * Revision 1.5  2000/12/05 01:45:11  lenzo
 * Restructuring, hear rationalization, warning removal, ANSIfy
 *
 * Revision 1.4  2000/06/29 14:15:01  lenzo
 * *** empty log message ***
 *
 * 
 * 19-Jan-1999	M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
 * 		Added AD_ return codes.  Added ad_open_sps_bufsize(), and
 * 		ad_rec_t.n_buf.
 * 
 * 17-Apr-98	M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
 * 		Added ad_open_play_sps().
 * 
 * 07-Mar-98	M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
 * 		Added ad_open_sps().
 * 
 * 10-Jun-96	M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
 * 		Added ad_wbuf_t, ad_rec_t, and ad_play_t types, and augmented all
 * 		recording functions with ad_rec_t, and playback functions with
 * 		ad_play_t.
 * 
 * 06-Jun-96	M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
 *		Created.
 */


#ifndef _AD_H_
#define _AD_H_

#define AD_BACKEND_OSS_BSD

#ifdef AD_BACKEND_WIN32

#include <windows.h>
#include <mmsystem.h>

#elif defined(AD_BACKEND_OSF) /* Not implemented, it seems */

#include <AF/AFlib.h>

#elif defined(AD_BACKEND_HPUX) /* Not implemented, it seems */

#include <audio/Alib.h>

#elif defined(AD_BACKEND_ALSA)

#include <sys/asoundlib.h>

#elif defined(AD_BACKEND_IRIX)

#include <dmedia/audio.h>

#endif


#define AD_SAMPLE_SIZE		(sizeof(int16))
#define DEFAULT_SAMPLES_PER_SEC	16000

/* Return codes */
#define AD_OK		0
#define AD_EOF		-1
#define AD_ERR_GEN	-1
#define AD_ERR_NOT_OPEN	-2
#define AD_ERR_WAVE	-3


#ifdef AD_BACKEND_WIN32
typedef struct {
    HGLOBAL h_whdr;
    LPWAVEHDR p_whdr;
    HGLOBAL h_buf;
    LPSTR p_buf;
} ad_wbuf_t;
#endif


/* ------------ RECORDING -------------- */

/*
 * NOTE: ad_rec_t and ad_play_t are READ-ONLY structures for the user.
 */

#ifdef AD_BACKEND_WIN32

typedef struct {
    HWAVEIN h_wavein;	/* "HANDLE" to the audio input device */
    ad_wbuf_t *wi_buf;	/* Recording buffers provided to system */
    int32 n_buf;	/* #Recording buffers provided to system */
    int32 opened;	/* Flag; A/D opened for recording */
    int32 recording;
    int32 curbuf;	/* Current buffer with data for application */
    int32 curoff;	/* Start of data for application in curbuf */
    int32 curlen;	/* #samples of data from curoff in curbuf */
    int32 lastbuf;	/* Last buffer containing data after recording stopped */
    int32 sps;		/* Samples/sec */
    int32 bps;		/* Bytes/sample */
} ad_rec_t;

#elif defined(AD_BACKEND_OSF)

typedef struct {
    AFAudioConn *aud;
    AC ac;
    int32 recording;		/* flag; TRUE iff currently recording */
    ATime last_rec_time;	/* timestamp of last sample recorded in buffer */
    ATime end_rec_time;		/* time at which recording stopped */
    int32 sps;		/* Samples/sec */
    int32 bps;		/* Bytes/sample */
} ad_rec_t;

#elif defined(AD_BACKEND_SUNOS)

typedef struct {
    int32 audio_fd;
    int32 recording;
    int32 sps;		/* Samples/sec */
    int32 bps;		/* Bytes/sample */
} ad_rec_t;

#elif defined(AD_BACKEND_OSS) || defined(AD_BACKEND_OSS_BSD)

/* Added by jd5q+@andrew.cmu.edu, 10/3/1997: */
typedef struct {
    int32 dspFD;	/* Audio device descriptor */
    int32 recording;
    int32 sps;		/* Samples/sec */
    int32 bps;		/* Bytes/sample */
} ad_rec_t;

#elif defined(AD_BACKEND_ALSA)

typedef struct {
    snd_pcm_t *dspH;
    int32 recording;
    int32 sps;
    int32 bps;
} ad_rec_t;

#elif defined(AD_BACKEND_HPUX)

typedef struct {
    Audio *audio;	/* The main audio handle */
    ATransID xid;	/* The current transaction ID */
    int32 streamSocket;	/* Connection socket */
    int32 recording;	/* TRUE iff currently recording */
    int32 sps;		/* Samples/sec */
    int32 bps;		/* Bytes/sample */
} ad_rec_t;

#elif defined(AD_BACKEND_IRIX)
typedef struct {
    ALport audio;	/* The main audio handle */
    int32 recording;	/* TRUE iff currently recording */
    int32 sps;		/* Samples/sec */
    int32 bps;		/* Bytes/sample */
} ad_rec_t;

#else

typedef struct {
    int32 sps;		/* Samples/sec */
    int32 bps;		/* Bytes/sample */
} ad_rec_t;	/* Dummy definition for systems without A/D stuff */


#endif


/*
 * Open audio device for recording.  Opened in non-blocking mode and placed in idle
 * state.  Return value: pointer to read-only ad_rec_t structure if successful, NULL
 * otherwise.  The return value to be used as the first argument to other recording
 * functions.
 */
ad_rec_t *ad_open_sps (int32 samples_per_sec);


/* Like ad_open_sps but with default samples/sec and bufsize */
ad_rec_t *ad_open ( void );


#ifdef WIN32
/*
 * Like ad_open_sps but specifies buffering required within driver.  This function is
 * useful if the default (5000 msec worth) is too small and results in loss of data.
 */
ad_rec_t *ad_open_sps_bufsize (int32 samples_per_sec, int32 bufsize_msec);
#endif


/* Start audio recording.  Return value: 0 if successful, <0 otherwise */
int32 ad_start_rec (ad_rec_t *);


/* Stop audio recording.  Return value: 0 if successful, <0 otherwise */
int32 ad_stop_rec (ad_rec_t *);


/* Close the recording device.  Return value: 0 if successful, <0 otherwise */
int32 ad_close (ad_rec_t *);


/*
 * Read next block of audio samples while recording; read upto max samples into buf.
 * Return value: # samples actually read (could be 0 since non-blocking); -1 if not
 * recording and no more samples remaining to be read from most recent recording.
 */
int32 ad_read (ad_rec_t *, int16 *buf, int32 max);


/* ------ PLAYBACK; SIMILAR TO RECORDING ------- */

#ifdef WIN32

typedef struct {
    HWAVEOUT h_waveout;	/* "HANDLE" to the audio output device */
    ad_wbuf_t *wo_buf;	/* Playback buffers given to the system */
    int32 opened;	/* Flag; A/D opened for playback */
    int32 playing;
    char *busy;		/* flags [N_WO_BUF] indicating whether given to system */
    int32 nxtbuf;	/* Next buffer [0..N_WO_BUF-1] to be used for playback data */
    int32 sps;		/* Samples/sec */
    int32 bps;		/* Bytes/sample */
} ad_play_t;

#else

typedef struct {
    int32 sps;		/* Samples/sec */
    int32 bps;		/* Bytes/sample */
} ad_play_t;	/* Dummy definition for systems without A/D stuff */

#endif


ad_play_t *ad_open_play_sps (int32 samples_per_sec);

ad_play_t *ad_open_play ( void );

int32 ad_start_play (ad_play_t *);

int32 ad_stop_play (ad_play_t *);

int32 ad_close_play (ad_play_t *);


/*
 * Write the next block of [len] samples from rawbuf to the A/D device for playback.
 * The device may queue less than len samples, possibly 0, since it is non-blocking.
 * The application should resubmit the remaining data to be played.
 * Return value: # samples accepted for playback; -1 if error.
 */
int32 ad_write (ad_play_t *, int16 *buf, int32 len);


/* ------ MISCELLANEOUS ------- */

/*
 * Convert mu-law data to int16 linear PCM format.
 */
void ad_mu2li (int16 *outbuf,		/* Out: PCM data placed here (allocated by user) */
	       unsigned char *inbuf,	/* In: Input buffer with mulaw data */
	       int32 n_samp);		/* In: #Samples in inbuf */

#endif
