#include <GroupsockHelper.hh>
#include <FramedSource.hh>
#include <iostream>
#include "WAVSource.hh"

// Audio device setting hardcoded for testing
 unsigned char WAVSource::audioformat=0x01;
unsigned int WAVSource::frequency=44100;
unsigned int WAVSource::channels=2;
 unsigned int WAVSource::bitspersample=16;
unsigned WAVSource::fPreferredFrameSize;
using namespace std;

EventTriggerId WAVSource::s_frameReceivedTrigger = 0;
char* WAVSource::s_pu8RawFrameBuff = NULL;


 unsigned char WAVSource::getAudioFormat() {
  return audioformat;
}

 unsigned int WAVSource::bitsPerSample() {
return bitspersample;
}

 unsigned int WAVSource::samplingFrequency() {
return frequency;
}
 unsigned int WAVSource::numChannels() {
return channels;
}


unsigned int WAVSource::s_readError = 0;
/**
 * \brief createNew: call constructor - To get code in sync with Live555 methods

 * \param[in]: None

 * \return None
      <Additional Description>

 * \details

 **/
WAVSource* WAVSource::createNew(UsageEnvironment& env) {
	return new WAVSource(env);
}
/**
 * \brief Constructor: Initializes member attributes and opens the encoder source for receiving the frames

 * \param[in]: None

 * \return None
      <Additional Description>

 * \details

 **/
WAVSource::WAVSource(UsageEnvironment& env) : AudioInputDevice(env, 0, 0, 0, 0) {
        
        


printf("audioformat:%d,channels:%d,bitspersample:%d,frequency:%d\n",audioformat,channels,bitspersample,frequency);
        
       fSamplingFrequency=frequency;
       fBitsPerSample=bitspersample;
       fNumChannels=channels;
	if (0 == s_frameReceivedTrigger) {
		s_frameReceivedTrigger = envir().taskScheduler().createEventTrigger(deliverFrame0);
	}
	s_pu8RawFrameBuff = NULL;
   fPlayTimePerSample = 1e6/(double)frequency;
         unsigned maxSamplesPerFrame = (1400*8)/(channels*bitspersample);
         unsigned desiredSamplesPerFrame = (unsigned)(0.02*frequency);
        unsigned samplesPerFrame = desiredSamplesPerFrame < maxSamplesPerFrame ? desiredSamplesPerFrame : maxSamplesPerFrame;
        fPreferredFrameSize = (samplesPerFrame*channels*bitspersample)/8;
        printf("fPreferredFrameSize:%d\n",fPreferredFrameSize);


	s_pu8RawFrameBuff = new char[16];//check

	if(NULL == s_pu8RawFrameBuff)
	{
		printf("s_pu8RawFrameBuff allocation failed\r\n");
	}

	if(true == OpenSource())
	{
		printf("Source Open Success\r\n");
	}
	else
	{
		printf("Source Open Failed\r\n");
	}
}
/**
 * \brief Destructor  - Deletes the array allocated for raw and encoded frames in constructor

 * \param[in]: None

 * \return None
      <Additional Description>

 * \details

 **/
WAVSource::~WAVSource() {
	delete []s_pu8RawFrameBuff;

}
/**
 * \brief doGetNextFrame

 * \param[in]: None

 * \return None
      <Additional Description>

 * \details

 **/
void WAVSource::doGetNextFrame () {
 printf("WAVSource::doGetNextFrame called\n");
	if (s_readError != 0) {
printf("INside and returning do get next frame\n");
		handleClosure(this);
		return;

	}
//doReadFromDriver();
//deliverFrame();
}
/**
 * \brief deliverFrame0

 * \param[in]: None

 * \return None
      <Additional Description>

 * \details

 **/
void WAVSource::deliverFrame0(void* clientData) {
	((WAVSource*)clientData)->deliverFrame();
}


s
/**
 * \brief CaptureFrame:Captures the encoded frames from the camera device

 * \param[in]: None

 * \return bool - True - If CaptureFrame is successfull
 * 				- False - If CaptureFrame Fails
      <Additional Description>

 * \details

 **/
bool WAVSource::doReadFromDriver()
{
  // Read from audio device 
   AlsaDevice::getInstance()->Readbuf(s_pu8RawFrameBuff)
}
/**
 * \brief OpenSource - Opens the Audio device on Session Initialization/Re-Initialization

 * \param[in]: None

 * \return bool - True if Open Source is Successfull
 * 				- False - If Codec device open fails
      <Additional Description>

 * \details
 * Initializes source  member variables used for connection status and streaming <br>

 **/
bool WAVSource::OpenSource()
{
AlsaDevice::getInstance()->openDevice();
return true;
	/* Open the Audio device */	
}
/**
 * \brief CloseSource: Close the Audio device

 * \param[in]: None

 * \return None
      <Additional Description>

 * \details

 **/
void WAVSource::CloseSource()
{
AlsaDevice::getInstance()->closeDevice();
	/* Close the Audio device */
	
}
/**
 * \brief deliverFrame - Live555 subclass method, receives the encoded frame and send it to lower FramedSource method for streaming

 * \param[in]: None

 * \return None
      <Additional Description>

 * \details

 **/
void WAVSource::deliverFrame() {

	static unsigned int count = 0;
	count++;
	//printf("fDurationInMicroseconds %d\r\n", fDurationInMicroseconds);
	if (!isCurrentlyAwaitingData()) return;

	/* Check the encoded frame size, it truncates the bytes if encoded frame size is greater that max send frame size */
	
	fFrameSize = fPreferredFrameSize;
    printf("fPreferredFrameSize1:%d",fPreferredFrameSize);
    printf("fFrameSize0123:%d",fFrameSize);
	

    //printf("fFrameSize %d, SOI %x, %x, EOI %x, %x \r\n", fFrameSize, m_pu8EncFrameBuff[0], m_pu8EncFrameBuff[1], m_pu8EncFrameBuff[fFrameSize - 2], m_pu8EncFrameBuff[fFrameSize - 1]);

	printf("deliverFrame\r\n");
	gettimeofday(&fPresentationTime, NULL);
        unsigned bytesPerSample = (fNumChannels*fBitsPerSample)/8;
        if (bytesPerSample == 0) bytesPerSample = 1;
         fDurationInMicroseconds = (unsigned)((fPlayTimePerSample*fFrameSize)/bytesPerSample);


#ifdef PRESENTIME
	char uSecsStr[6+1]; // used to output the 'microseconds' part of the presentation time
	sprintf(uSecsStr, "%06u", (unsigned)fPresentationTime.tv_usec);
	//envir() << "count "<<s_count<<"\t"<<" sec" << (unsigned)fPresentationTime.tv_sec <<"\t" <<"usec " << uSecsStr<<"\n";

	 static unsigned long currTime;
	 currTime = fPresentationTime.tv_sec * 1000 + fPresentationTime.tv_usec / 1000;
	 static unsigned long PrevTime = 0;
	 //printf("Time diff:%ld\r\n",currTime - PrevTime);
	 PrevTime = currTime;
	// printf("\tCount\t %d \t Pres Time\t%ld\t%d\r\n",count,(unsigned)fPresentationTime.tv_sec, uSecsStr);
#endif

	/* Copy the encoded frames to internal send buffer */
	memmove(fTo, s_pu8RawFrameBuff, fFrameSize);
    printf("fFrameSize:%d\n",fFrameSize);
	

	FramedSource::afterGetting(this);
        printf("AFTER FRAME SENDING\n");

#ifdef DEBUG_TIMEDIFF_DF
	val = stop_and_get_timer_val();
	printf ("deliver frame %d ms\r\n",val);
#endif

}
Boolean WAVSource::setInputPort(int /*portIndex*/) {
  return True;
}

double WAVSource::getAverageLevel() const {
  return 0.0;
}
















