/*****************************************************************************\

  File Name: AudioDeviceIF.c

  Description: This is the source file for the functions that interface to 
               audio/sound devices.  These functions are wrappers around the
               audio codec driver.
               
\*****************************************************************************/

//-----------------------------------------------------------------------------
//  I N C L U D E S
//-----------------------------------------------------------------------------
#include "AudDriverFuncs.h"

//-----------------------------------------------------------------------------
//  G L O B A L S
//-----------------------------------------------------------------------------
PAUDIOSTATE g_pAS=NULL;

//-----------------------------------------------------------------------------
//  F U N C T I O N    P R O T O T Y P E S
//-----------------------------------------------------------------------------
AUDRETVALUE AudDev_Init(PAUDIOSTATE,  //Pointer to the Audio State structure 
                        PBYTE, PBYTE, //Pointers to In/Output data buffers
                        ADI_DEV_MANAGER_HANDLE, //Handle of the device manager
                        ADI_DMA_MANAGER_HANDLE, //Handle of the DMA manager
                        ADI_DCB_HANDLE); //Handle of the deferred callback mngr
AUDRETVALUE AudDev_Open(void);  //Open audio stream
AUDRETVALUE AudDev_Start(void); //Start the audio stream
AUDRETVALUE AudDev_Stop(void);  //Stop the audio stream
AUDRETVALUE AudDev_Close(void); //Close the audio stream
bool        AudDev_IsSampleRateSupported(AUDIORATE);
bool        AudDev_IsSampleFormatSupported(AUDSAMPLFORMAT);
bool        AudDev_IsNumInChannelsSupported(int);
bool        AudDev_IsNumOutChannelsSupported(int);
int         AudDev_GetSampleSize(AUDSAMPLFORMAT);
int         AudDev_GetSampleHostSize(AUDSAMPLFORMAT);

//-----------------------------------------------------------------------------
// AudDev_Init() - Initializes the sound driver with some Sytem Services
//                 managers and resets the ADC/DAC.
//-----------------------------------------------------------------------------
AUDRETVALUE AudDev_Init(PAUDIOSTATE pAS, PBYTE rxBuffer, PBYTE txBuffer, 
                        ADI_DEV_MANAGER_HANDLE DeviceManagerHandle,
                        ADI_DMA_MANAGER_HANDLE DMAHandle,
                        ADI_DCB_HANDLE         DCBHandle) 
{
  //Check and make sure that the state structure pointer is a valid one as in
  //a non-NULL pointer.
  if (NULL == pAS) { return AUD_ERR_INVALID_POINTER; }
  g_pAS = pAS; //Initialize global var for use by HW driver
  
  //Set up the various handles into the structure...
  g_pAS->pHndl->hDevMgr = DeviceManagerHandle;
  g_pAS->pHndl->hDMA    = DMAHandle;
  g_pAS->pHndl->hDCB    = DCBHandle;
  AudioDriver_Query(&g_pAS->pDevProp);

  g_pAS->pDevProp->pRxData = rxBuffer;
  g_pAS->pDevProp->pTxData = txBuffer;  
  
  //Check that our device supports the stream format, rate and other properties
  // as specified by the stream properties...
  if (false == AudDev_IsSampleFormatSupported(g_pAS->pStrProp->Format))
    { return AUD_ERR_UNSUPRT_FORMAT; }
  if (false == AudDev_IsSampleRateSupported(g_pAS->pStrProp->Rate))
    { return AUD_ERR_UNSUPRT_RATE; }
    
  //Make sure we support audio streaming channel counts and direction?
  if ((g_pAS->pStrProp->InChCnt > 0) && 
      (false == AudDev_IsNumInChannelsSupported(g_pAS->pStrProp->InChCnt)))
  { 
    g_pAS->pStrProp->Direction &= ~AUD_DIRECTION_INBOUND;
    return AUD_ERR_UNSUPRT_NUMCHNLS; 
  }
  if ((g_pAS->pStrProp->OutChCnt > 0) &&
      (false == AudDev_IsNumOutChannelsSupported(g_pAS->pStrProp->OutChCnt)))
  { 
    g_pAS->pStrProp->Direction &= ~AUD_DIRECTION_OUTBOUND;
    return AUD_ERR_UNSUPRT_NUMCHNLS; 
  }
  return AUD_SUCCESS;
}

//-----------------------------------------------------------------------------
// AudDev_Open() - Opens an audio stream
//-----------------------------------------------------------------------------
AUDRETVALUE AudDev_Open(void)
{ 
  if (false == g_pAS->bDevInit) { return AUD_ERR_DEVICENOTINIT; }
  AudioDriver_Open(g_pAS);
  return AUD_SUCCESS;
}

//-----------------------------------------------------------------------------
// AudDev_Start() - Starts an audio stream
//-----------------------------------------------------------------------------
AUDRETVALUE AudDev_Start(void) 
{
  int Result;

  Result = AudioDriver_Start();
  ezErrorCheck(Result);
  return AUD_SUCCESS;
}

//-----------------------------------------------------------------------------
// AudDev_Stop() - Stops an audio stream
//-----------------------------------------------------------------------------
AUDRETVALUE AudDev_Stop(void) 
{
  int Result;
 
  Result = AudioDriver_Stop();
  ezErrorCheck(Result);
  return AUD_SUCCESS;
}

//-----------------------------------------------------------------------------
// AudDev_Close() - Closes the sound driver
//-----------------------------------------------------------------------------
AUDRETVALUE AudDev_Close(void) 
{
  int Result;

  Result = AudioDriver_Close();
  ezErrorCheck(Result);        
  return AUD_SUCCESS;
}

/*****************************************************************************\
                      C O M M O N    &    F U N C T I O N S
\*****************************************************************************/
//-----------------------------------------------------------------------------
// AudDev_IsSampleRateSupported() - 
//-----------------------------------------------------------------------------
bool AudDev_IsSampleRateSupported(AUDIORATE rate) 
{
  int i;
  
  for (i=0; i<g_pAS->pDevProp->SmplRateCnt; i++) 
    { if (g_pAS->pDevProp->pSmplRateList[i] == rate) { return true; } }
  return false;
}

//-----------------------------------------------------------------------------
// AudDev_IsSampleFormatSupported() - 
//-----------------------------------------------------------------------------
bool AudDev_IsSampleFormatSupported(AUDSAMPLFORMAT format) 
{
  if ((g_pAS->pDevProp->SmplFormats & format)) { return true; }
  return false;
}

//-----------------------------------------------------------------------------
// AudDev_IsNumInChannelsSupported() - 
//-----------------------------------------------------------------------------
bool AudDev_IsNumInChannelsSupported(int iChCnt) 
{
  if ((g_pAS->pDevProp->HWInChCnt & (1 << iChCnt))) 
    { return true; }
  return false;
}

//-----------------------------------------------------------------------------
// AudDev_IsNumOutChannelsSupported() - 
//-----------------------------------------------------------------------------
bool AudDev_IsNumOutChannelsSupported(int iChCnt) 
{
  if ((g_pAS->pDevProp->HWOutChCnt & (1 << iChCnt)))
    { return true; }
  return false;
}

//-----------------------------------------------------------------------------
// AudDev_GetSampleHostSize() -
//-----------------------------------------------------------------------------
int AudDev_GetSampleHostSize(AUDSAMPLFORMAT format) 
{
  switch(format) 
  {
    case AUD_SAMPLFORMAT_FIXED16: return sizeof(ARTYP_16BITS);
    case AUD_SAMPLFORMAT_FIXED20: return sizeof(ARTYP_20BITS);
    case AUD_SAMPLFORMAT_FIXED24: return sizeof(ARTYP_24BITS);
    default: return 0;
  }  
}

//-----------------------------------------------------------------------------
// AudDev_GetSampleSize() -
//-----------------------------------------------------------------------------
int AudDev_GetSampleSize(AUDSAMPLFORMAT format) 
{
  switch(format) 
  {
    case AUD_SAMPLFORMAT_FIXED16: return 16;  
    case AUD_SAMPLFORMAT_FIXED20: return 20;
    case AUD_SAMPLFORMAT_FIXED24: return 24;
    default: return 0;
  }  
}

