/*****************************************************************************\

  File Name: AudioStreaming.h
  
  Description: This header file contains all audio related definitions 
               including types and structures.
  
\*****************************************************************************/

#ifndef __AUDIOSTREAMING_H__
#define __AUDIOSTREAMING_H__

#include <string.h>
#include <stdio.h>
#include <services/services.h>
#include <drivers/adi_dev.h>
#include <SDK-ezkitutilities.h>
#include <adi_ssl_Init.h>

//-----------------------------------------------------------------------------
//  U S E R    C O N F I G    O P T I O N S
//-----------------------------------------------------------------------------
#define AUDIO_DEBUG //Uncomment this value to enable debugging facilities
//#define AUDIO_SUPPORT_INPUT_ONLY
//#define AUDIO_SUPPORT_OUTPUT_ONLY
#ifdef AUDIO_SUPPORT_INPUT_ONLY
#ifdef AUDIO_SUPPORT_OUTPUT_ONLY
#error Must have audio INPUT, OUTPUT or BOTH supported!
#endif
#endif

//-----------------------------------------------------------------------------
// Peripheral ID Macros
//
// This program works on the EZ-Kits.  The macros
// below are used to identify which EZ-Kit we're targeting.  Specifically, 
// the FLAG_PERIPHERAL_ID macro is set to the peripheral ID to which the 
// interrupt driven push buttons are mapped.  See the adi_int.h file
// within the system services library (blackfin/include/services) for
// more information on peripheral IDs.  
//-----------------------------------------------------------------------------
#if defined(__ADSP_EDINBURGH__)
#define FLAG_PERIPHERAL_ID	(ADI_INT_PFA)
#endif

#if defined(__ADSP_BRAEMAR__)
#define FLAG_PERIPHERAL_ID	(ADI_INT_PORTFG_A)
#endif

#if defined(__ADSP_TETON__)
#define FLAG_PERIPHERAL_ID	(ADI_INT_PF0_15_A)
#endif

//-----------------------------------------------------------------------------
//  E N U M S
//-----------------------------------------------------------------------------
typedef enum //Encoder identifier
{
  ENCDR_UNKNOWN = (u16)0,
  ENCDR_PCM,
  ENCDR_WAV,
  ENCDR_MP3,
  ENCDR_OGGVORBIS=20,
  ENCDR_OGGSPEEX
} ENCDRID, *PENCDRID;

typedef enum //Sound intyerface result codes
{
  AUD_SUCCESS=0,
  AUD_ERR_INTERNAL = -10000,  
  AUD_ERR_FILTERINIT,
  AUD_ERR_FILTEROPEN,  
  AUD_ERR_FILTERGENERAL,
  AUD_ERR_EZKITINIT,  
  AUD_ERR_DEVICEOPEN,  
  AUD_ERR_DEVICERESET,  
  AUD_ERR_DEVICENOTINIT,
  AUD_ERR_STREAMNOTINIT,
  AUD_ERR_INVALID_POINTER,
  AUD_ERR_INVALID_DATBFRS,
  AUD_ERR_UNSUPRT_NUMCHNLS,
  AUD_ERR_UNSUPRT_RATE,
  AUD_ERR_UNSUPRT_FORMAT
} AUDRETVALUE, *PAUDRETVALUE;

typedef enum //Sample sample formats
{
  AUD_SAMPLFORMAT_UNKNOWN = 0, //Unknown sample format
  AUD_SAMPLFORMAT_FIXED16 = (1 << 0), //16-bit fixed-point
  AUD_SAMPLFORMAT_FIXED20 = (1 << 1), //20-bit fixed-point
  AUD_SAMPLFORMAT_FIXED24 = (1 << 2), //24-bit fixed-point
  AUD_SAMPLFORMAT_FIXED_ALL = ( AUD_SAMPLFORMAT_FIXED16 | 
                                AUD_SAMPLFORMAT_FIXED20 | 
                                AUD_SAMPLFORMAT_FIXED24 )
} AUDSAMPLFORMAT, *PAUDSAMPLFORMAT;

//-----------------------------------------------------------------------------
//  T Y P E D E F S
//-----------------------------------------------------------------------------
typedef void VOID, *PVOID;
typedef u8   BYTE, *PBYTE;
typedef int  AUDDEVRESULTS, *PAUDDEVRESULTS;
typedef long AUDIORATE, *PAUDIORATE;

//Sample rate related type definitions
#define RATE_UNKNOWN  0
typedef u16 ARTYP_16BITS, *PARTYP_16BITS; //smallest needed for 16-bit data
typedef u32 ARTYP_20BITS, *PARTYP_20BITS; //smallest needed for 20-bit data
typedef u32 ARTYP_24BITS, *PARTYP_24BITS; //smallest needed for 24-bit data

//Callback function structure definition.  Once one such thing is properly set
//up, the audio sub-system calls it when a new block of data is available for
//processing.
typedef int AUDIOCBFUNC
(
  PVOID, //Pointer to the received data
  PVOID, //Pointer to data queued for transmission
  PVOID  //Data specific to the application
);
typedef AUDIOCBFUNC *PAUDIOCBFUNC;

//Structure used to contains various system handles
typedef struct __SYSTEMHANDLES__
{
  ADI_DEV_MANAGER_HANDLE hDevMgr;
  ADI_DMA_MANAGER_HANDLE hDMA;
  ADI_DCB_HANDLE         hDCB;
} SYSHANDLES, *PSYSHANDLES;

//This structure contains stream specific properties.  This must be initialized
//at startup of application once an audio stream/clip is to be processed.  This
//is done as specified by the clip and known/supported audio encoding filters.
//Note: Supported filters --> Ogg Vorbis, Ogg Speex
//~%GROTS%~ - GXS: This structure may not be needed after combining support for
//                 vorbis and speex into the same set of common files.
typedef struct __STREAMPROPERTIES__
{
  ADI_DEV_DIRECTION Direction; //Stream direction (In/Out/Both)
  u32            FrameCnt;  //Stream frame (including all channels) count.
  u32            InChCnt;   //Number (count) of INPUT stream channels.
  u32            OutChCnt;  //Number (count) of OUTPUT stream channels.
  AUDSAMPLFORMAT Format;    //Stream supported sample format.
  u32            DatBitSz;  //Stream data sample bit size per data sample
  u32            DatBytCnt; //Stream data sample byte count per data sample
  u32            Rate;      //Stream sampling rate.
  u32            Flags;     //Additional flag params (ie deinterleaving stereo)
  u32            Size;      //Size of allocated data buffers
  PBYTE          pCptrBfr;  //Pointer to a capture data buffer (IN from mic etc)
  PBYTE          pRndrBfr;  //Pointer to a render data buffer (OUT to spkrs etc)
  PBYTE          pUsrData;  //Ptr to where user data is passed after tansfer
  ENCDRID        EID;       //Indicates encoder identifier i.e. Vorbis
  PVOID          pEncoderInfo; //Pointer to encoder specific info i.e. Vorbis
} AUDSTREAMPROP, *PAUDSTREAMPROP;

//This structure contains codec specific properties.  This must be initialized
//at startup based on the codec being used.  This should typically be init-
//ialized from tables saved for each supported codec.
//Note: Supported codecs are --> 1836
typedef struct __AUDIODEVICEPROPERTIES__
{
#ifdef _VORBISDEMO_ //~%GROTS%~ USED WITH VORBIS DEMO
  PBYTE     pRxData;        //Capture data buffer pointer
  PBYTE     pTxData;        //Render/playback data buffer pointer
#endif //USED WITH VORBIS EXAMPLE
  u32       HWInChCnt;      //Indicates codec input channel count
  u32       HWOutChCnt;     //Indicates codec output channel count
  u32       SmplRateCnt;    //Indicates codec supported sample rate count
  const u32 *pSmplRateList; //Points to the list of codec supported sample rates
  u32       SmplFormats;    //Indicates codec supported sample fomats
} AUDDEVPROPS, *PAUDDEVPROPS;

typedef struct __audio_streaming_state__
{
  bool                   bDevInit; //Indicates device was init'd
#ifdef _VORBISDEMO_ //~%GROTS%~ USED WITH VORBIS DEMO
  bool                   bStrInit; //Indicates stream was init'd
  PSYSHANDLES            pHndl;
  PAUDSTREAMPROP         pStrProp;
#else  //_VORBISDEMO_
  ADI_DEV_MANAGER_HANDLE DeviceManagerHandle;
  ADI_DMA_MANAGER_HANDLE DMAHandle;
  ADI_DCB_HANDLE         DCBHandle;
  PBYTE                  RxBuffer;
  PBYTE                  TxBuffer;
  int                    NumInChannels;
  int                    NumOutChannels;
  AUDSAMPLFORMAT         SampleFormat;
  long                   SampleRate;
  int                    NumFrames;  
  ADI_DEV_DIRECTION      Direction;
  int                    SampleSize;
  int                    SampleHostSize;
#endif //_VORBISDEMO_
  PAUDDEVPROPS           pDevProp;  
  PAUDIOCBFUNC           pCBFunc;
} AUDIOSTATE, *PAUDIOSTATE;

//-----------------------------------------------------------------------------
//  M A C R O S
//-----------------------------------------------------------------------------
#define IS_SUCCESS(x)        (AUD_SUCCESS ==  x)
#define IS_FAILED(x)         (AUD_SUCCESS != x)
#define FLUSHPRINTF(args...) { printf(args); fflush(stdout); }
#define ERRPRINTF(args...)   { printf("?(ERROR) "); FLUSHPRINTF(args); }
#define WRNPRINTF(args...)   { printf("?(WARNING) "); FLUSHPRINTF(args); }

#define CLR_AUDIOSTATE(x) { x->bDevInit = false; \
                            x->bStrInit = false; \
                            x->pHndl    = NULL;  \
                            x->pStrProp = NULL;  \
                            x->pDevProp = NULL;  \
                            x->pCBFunc  = NULL; }

#define CLR_SYSHANLDLES(x) { x->hDevMgr=NULL; x->hDMA=NULL; x->hDCB=NULL; }

                            
#define CLR_STRMPROP(x) { x->Direction = AUD_DIRECTION_UNDEFINED;         \
                          x->FrameCnt = x->Size = 0; x->Flags = 0;        \
                          x->InChCnt = x->OutChCnt = 0;                   \
                          x->Format = AUD_SAMPLFORMAT_UNKNOWN;            \
                          x->DatBitSz = 0; x->DatBytCnt = 0;              \
                          x->Rate = RATE_UNKNOWN;                         \
                          x->EID = ENCDR_UNKNOWN; x->pEncoderInfo = NULL; \
                          x->pCptrBfr = x->pRndrBfr = x->pUsrData = NULL; }

#define CLR_DEVPROP(x) { x->pRxData = x->pTxData = NULL;              \
                         x->HWInChCnt = x->HWOutChCnt = 0;            \
                         x->SmplRateCnt = 0; x->pSmplRateList = NULL; \
                         x->SmplFormats = AUD_SAMPLFORMAT_UNKNOWN; }
                          
#endif  //__AUDIOSTREAMING_H__


