//
//
// Copyright 2005 Pingtel Corp.
//
// $$
//////////////////////////////////////////////////////////////////////////////

// SYSTEM INCLUDES

// APPLICATION INCLUDES
#include <os/fstream>
#include <os/OsSysLog.h>
#include <mp/MpAudioFileOpen.h>
#include <mp/MpAudioWaveFileRead.h>
#include <mp/MpRawAudioBuffer.h>

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */

/**
 * Default constructor
 */
MpRawAudioBuffer::MpRawAudioBuffer(const char* pFilePath)
{
   MpAudioAbstract* pAudioAbstract;
   long minRate, maxRate, prefRate;
   int  minChan, maxChan, prefChan;
   int  decompressionType;

   mpAudioBuffer = NULL;
   mAudioBufferLength = 0;

   // Open an IO stream to the audio file
   ifstream sourceFile(pFilePath, ios::in | ios::binary);

   pAudioAbstract = MpOpenFormat(sourceFile);
   if (pAudioAbstract == NULL) {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpRawAudioBuffer::MpRawAudioBuffer(%s) - Failed to load file", pFilePath);
      return;
   }

   // Now validate the format. It must be a WAV file formated as
   // unsigned 16 bit mono at 8KHz
   if (pAudioAbstract->getAudioFormat() != AUDIO_FORMAT_WAV) {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpRawAudioBuffer::MpRawAudioBuffer(%s) Not in WAV format", pFilePath);
      return;
   }

   // Now validate the sampling rate, number of channels and decompression type
   pAudioAbstract->minMaxSamplingRate(&minRate, &maxRate, &prefRate);
   if (prefRate != 8000) {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpRawAudioBuffer::MpRawAudioBuffer(%s) Invalid sampling rate: %d",
                    pFilePath, prefRate);
      return;
   }

   pAudioAbstract->minMaxChannels(&minChan, &maxChan, &prefChan);
   if (prefChan != 1) {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpRawAudioBuffer::MpRawAudioBuffer(%s) Invalid number of channels: %d",
                    pFilePath, prefChan);
      return;
   }

   decompressionType = pAudioAbstract->getDecompressionType();
   if (decompressionType != MpAudioWaveFileRead:: DePcm16LsbSigned) {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpRawAudioBuffer::MpRawAudioBuffer(%s) Data not PCM 16bit Signed", pFilePath);
      return;
   }

   // Determine the audio data size and allocate storage for it
   mAudioBufferLength = pAudioAbstract->getBytesSize();
   mpAudioBuffer = new char[mAudioBufferLength];
   if (mpAudioBuffer == NULL) {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpRawAudioBuffer::MpRawAudioBuffer(%s) - Failed to allocate storage: new char[%d]",
                    pFilePath, mAudioBufferLength);
      mAudioBufferLength = 0;
      return;
   }

   // Finally read in the data
   unsigned long readLen = pAudioAbstract->readBytes(reinterpret_cast<AudioByte*>(mpAudioBuffer), mAudioBufferLength);
   if (readLen != mAudioBufferLength) {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpRawAudioBuffer::MpRawAudioBuffer(%s) Failed to read audio data", pFilePath);
      mAudioBufferLength = 0;
      delete[] mpAudioBuffer;
   }
}

/**
 * Destructor
 */
MpRawAudioBuffer::~MpRawAudioBuffer()
{
   mAudioBufferLength = 0;

   if (mpAudioBuffer)
      delete[] mpAudioBuffer;
}

/* ============================ MANIPULATORS ============================== */

/* ============================ ACCESSORS ================================= */
char* MpRawAudioBuffer::getAudio(char*& prAudio, unsigned long& rLength)
{
   prAudio  = mpAudioBuffer;
   rLength = mAudioBufferLength;

   return mpAudioBuffer;
}

/* ============================ INQUIRY =================================== */

/* //////////////////////////// PROTECTED ///////////////////////////////// */

/* //////////////////////////// PRIVATE /////////////////////////////////// */

/* ============================ FUNCTIONS ================================= */
