/*****************************************************************************
Copyright(c) 2007 Analog Devices, Inc.  All Rights Reserved. This software is
proprietary and confidential to Analog Devices, Inc. and its licensors.
******************************************************************************

$Revision: 1.2 $
$Date: 2008/06/06 05:58:26 $
$LastChangedBy: dwu $
	
Project:	Audio Kit
Title:		WAV decode/encode
Author(s):	ADA

Description:
			High level WAV encoding/decoding functions

References:
			None

******************************************************************************/

#include <mediaplayer.h>
#include <SDK-ezkitutilities.h>
#include <adac_buffer.h>

#if defined(__ADSP_MOAB__) | defined(__ADSP_KOOKABURRA__)
#include "mediaplayer.h"
#include "devicecontrol.h"
lcd_taginfo_t *wavtag;
#endif
//#include <codec_1980.h>
#include <codec.h>
#include <WAV_codec.h>
#include <riff_header.h>

#include <stdio.h>					// stdio header
#include <string.h>					// string header
#include <stdlib.h>
#include <math.h>
#include <cycle_count.h> 			// for basic cycle counting

//#if defined(__ADSP_MOAB__) /* BF548 EZKit */
//#include <mediaplayer.h>
//lcd_taginfo_t *wavtag;
//#endif

/*
**
** Function:            WAV_Decode
**
** Description:         Function that decodes the given WAV file
**
** Arguments:			FileName
**
** Outputs:             none
**
** Return value:        WAV decoder status
**
*/
//section("adi_code_cache")
int WAV_Decode(char *FileName)
{
    u8 printed = 0;
    u8 *pFifoBuffer;
    u32 NumChannels;
  	u32 SamplingRate=0;
  	u32 NumBytesRead=0;
    u32 Result,Sense;
	FILE *filein;
    u32 i, j;
    u32 FileSizeInBytes = 0;
    int decode_status = 0;
	riffheader_t    riffheader;
	chunkheader_t   chunkheader;
	chunkformat_t   *chunkformat;
    bool audio_enabled = 0;
#if defined(__ADSP_MOAB__) || defined(__ADSP_KOOKABURRA__) /* BF548 EZKit */
	MPPMESSAGE	MessageToApp;
	extern OS_EVENT *mgr_application_Q;
	
	MessageToApp.uMID = MSGID_LCD_TAG;
	MessageToApp.Param1 = NO_TAG_DISPLAY;
	wavtag->file_type = WAV_TYPE;

#endif
	/* Open the WAV file */
	filein = fopen(FileName,"rb");

	if (filein == NULL)
	{
		printf("\nUnable to read input file: %s\n\n",FileName);
		return CODEC_FILE_ERROR;
	}
	else
	{
	    printf("\nPlaying WAV file: %s\n\n",FileName);
	}

    fseek(filein,0,SEEK_END);
    FileSizeInBytes = (u32)ftell(filein);
    fseek(filein,0,SEEK_SET);
    
	/* clear output buffers */
	//memset((char*)AudioDecoderOutBuf, 0, (NUM_AUDIO_DAC_CHANNELS*AUDIO_MAX_OUTPUT_PCM_SAMPLES_PER_CHAN*PCM_SAMPLE_RESOLUTION_IN_BYTES));
	
	decode_status = parse_riff_header(filein, &riffheader);
	if(decode_status)
	{
		printf("\terror:  bad RIFF header\n");
		return -1;
	}

	decode_status = parse_chunk_header(filein, &chunkheader);
	if(decode_status)
	{
		printf("\tError:  bad chunk header\n");
		return -1;
	}
	chunkformat = chunkheader.chunkdata;

	if((chunkformat->bitspersample != 16) || (chunkformat->audioformat != 1))
	{
		printf("\tError:  WAVE format not supported\n");
		printf("\t\t bits per sample = %d, audio format = %d\n", chunkformat->bitspersample, chunkformat->audioformat);
		return -1;
	}		
	
	NumChannels     = (u32)chunkformat->numchannels;
	SamplingRate    = (u32)chunkformat->samplerate;

    	printf("\tSampling Frequency  = %dHz\n", SamplingRate);  	
    	printf("\tNumber of Channels  = %d\n", NumChannels);
#if defined(__ADSP_MOAB__) || defined(__ADSP_KOOKABURRA__)/* BF548 EZKit */
    /* Send Tag info to Application Manager */
    MessageToApp.Param2 = wavtag;
	OSQPost(mgr_application_Q, &MessageToApp);
#endif
	
   //PCM_Fifo.EndOfAudioFile = FALSE;
    
	while(1)
	{	    		
		/* get a free FIFO buffer */
		do
		{
            pFifoBuffer = (u8 *)usr_getpcmbuffer((AUDIO_MAX_OUTPUT_PCM_SAMPLES_PER_CHAN * NumChannels));

		} while(pFifoBuffer == NULL);
		
		
		
		adi_sem_Pend( PauseSemaphoreHandle, ADI_SEM_TIMEOUT_FOREVER );

		/* continue playing this file until the user presses Stop button or reach end of file */
        /* IF (STOP button pressed) */
        if(StopButton)
        {
        	break;
        }


        	/* read PCM audio of data from the given WAV file */
		NumBytesRead = fread((char*)pFifoBuffer, 1, (AUDIO_MAX_OUTPUT_PCM_SAMPLES_PER_CHAN*NumChannels*PCM_SAMPLE_RESOLUTION_IN_BYTES), filein);
		
		/* Check for end of file */
		if (NumBytesRead < (AUDIO_MAX_OUTPUT_PCM_SAMPLES_PER_CHAN*NumChannels))
		{
			//PCM_Fifo.EndOfAudioFile = TRUE;
			break;
		}
		
		
		// Set the number of samples written
		usr_setsamplecount(AUDIO_MAX_OUTPUT_PCM_SAMPLES_PER_CHAN * NumChannels );		

		
		/* Update File progress */
		//DisplayProgress(filein,FileSizeInBytes,0,TotalPcmSamplesRead,SamplingRate);
		
		/* Unmute the output if all the output buffers have been filled */
					// Unmute the output if all the output buffers have been filled
		if ( (!audio_enabled) && (usr_get_freebuffercount() <= 1) )
		{
			audio_enabled = true;
			usr_mute_output(false, SamplingRate );
		}

		

	}

	// inform that there's no more data to be written for output
	usr_nomore_data();	
	
	// wait until all buffer contents have been played out
	if (audio_enabled)
	{
	    usr_wait_buffers_emptied();
	}   
	
	usr_mute_output(true, SamplingRate );
	

	fclose(filein);

	printf("\n");
    return CODEC_SUCCESS;
}
