/*****************************************************************************
Copyright(c) 2005 Analog Devices, Inc.  All Rights Reserved. This software is 
proprietary and confidential to Analog Devices, Inc. and its licensors.
******************************************************************************

$RCSfile: adac_buffer.c,v $
$Revision: 1.3 $
$Date: 2008/06/10 00:19:23 $

Project:	Audio Kit
Title:		User defined routines to be called by service/utility modules
Author(s):	dwu
Revised by:

Description:
			User defined ISRs for the audio interrupts.

References:
			None

******************************************************************************
Tab Setting:			4

Target Processor:		ADSP-BF5xx
Target Tools Revision:	ADSP VisualDSP++ v4.0
******************************************************************************

Modification History:
====================
$Log: adac_buffer.c,v $
Revision 1.3  2008/06/10 00:19:23  randreol
Changes to allow for Kookaburra port

Revision 1.2  2008/03/27 02:46:09  randreol
Fixed MP3 stutter sound

Revision 1.1  2008/03/17 14:14:32  gstephan
Updates for SDK 3.00

Revision 1.2  2007/05/23 02:20:29  randreol
Modified for new combined audio application

Revision 1.3  2006/11/30 05:57:08  randreol
 Modified to support multiple codecs

Revision 1.1  2006/11/10 04:55:26  randreol
Initial rev

Revision 1.2  2006/05/10 05:03:26  dwu
Added extra function to wait for the buffers to empty

Revision 1.1.1.1  2006/05/09 04:01:29  dwu
USB based audio demonstration



*****************************************************************************/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <adac_buffer.h>
#include <system.h>
#include <codec.h>
#include <usb_services.h>
#include <fifo.h>

#if defined(__ADSP_MOAB__) /* BF548 EZKit */
#include <codec_1980.h>
#include <mediaplayer.h>
#endif

#if defined(__ADSP_KOOKABURRA__)  
#include <codec_52xc1.h>
#include <mediaplayer.h>
#endif
/*********************************************************************
	#defines
 *********************************************************************/

 
/*********************************************************************
	User defined variables
 *********************************************************************/
// FIFO object
FIFO_STRUCT pcm_fifo;

// variable to control output muting
static volatile bool mute = TRUE; // default muted

static	u32 Counter = 0;


/*****************************************************************************
 *			Macros															 *
 *****************************************************************************/

/*****************************************************************************
 *			LOCAL FUNCTION DECLARATION										 *
 *****************************************************************************/


/*****************************************************************************
 * 		    FUNCTION DEFINITIONS											 *
 *****************************************************************************/
/*****************************************************************************
 	Initialization function
 *****************************************************************************/
void usr_init(short *fifo_buffer, int fifo_buffer_size, int fifo_count)
{
	int i;

	// initialize the fifo	
	FIFO_Reset(&pcm_fifo);
	
	// set up the fifo buffers
	for(i=0;i<fifo_count;i++)
		FIFO_Configure(&pcm_fifo,FIFO_CONFIG_SETBUFFER,(int)(&(fifo_buffer[i*fifo_buffer_size])),(int)fifo_buffer_size*2);
}


/*****************************************************************************
 	Function to return a contiguous block of buffer space for writing
 	The argument buffer_size is in number of 16-bit words. Returns NULL
 	if no memory blocks are available.
 *****************************************************************************/
char *usr_getpcmbuffer(unsigned int buffer_size)
{
		char *pbuf = NULL;
	pbuf = FIFO_GetFreeWriteBlock(&pcm_fifo,buffer_size<<1);

#if defined ADI_SSL_UCOS		
	if((pbuf != NULL) && (PauseButton == FALSE))
	{
		adi_sem_Post(PauseSemaphoreHandle);
	}
#endif
	
	return(pbuf);
	
	//return (FIFO_GetFreeWriteBlock(&pcm_fifo,buffer_size<<1));

}
	

/*****************************************************************************
 	Function to set the number of bytes written into the buffer that was
 	retrived by calling usr_getpcmbuffer().
 	The argument sample_count is in number of 16-bit words.
 *****************************************************************************/
void usr_setsamplecount(unsigned int sample_count)
{
	FIFO_SetDataCount(&pcm_fifo,sample_count<<1);
}


/*****************************************************************************
 	Function to inform the module that there'll be no more data to be written
 	into the fifo.
 *****************************************************************************/
void usr_nomore_data()
{
	FIFO_SetRDFlag(&pcm_fifo);
}


/*****************************************************************************
	Function to enable/disable audio muting. Set argument to 1 for enable
	muting, 0 to disable
 *****************************************************************************/
void usr_mute_output(bool mute_enable, u32 SampleRate)
{
	mute = mute_enable;
	
#if defined(__ADSP_MOAB__) || defined (__ADSP_KOOKABURRA__)
	
	if( mute_enable )
	{
	  /* Disable ADI1980 codec dataflow */
		DisableCodecDataflow();
	}
	else
	{
		EnableCodecDataflow(SampleRate);
	}
#endif
}


/*****************************************************************************
	Function to return number of free buffers for writing
 *****************************************************************************/
int usr_get_freebuffercount()
{
	return (int)(pcm_fifo.free_buffers);
}


/*****************************************************************************
	Function to wait for all the buffers to be emptied
 *****************************************************************************/
void usr_wait_buffers_emptied()
{
	while (usr_get_freebuffercount() < pcm_fifo.buffer_count);
}
 
/*****************************************************************************
 	User ISRs
 *****************************************************************************/
/*****************************************************************************
	User ISR for DAC
 *****************************************************************************/
int DACUserISR(ADI_DEV_1D_BUFFER *pArg,unsigned int num_samples)
{
	unsigned int bytes;
	int i;
	
	if (!mute)
	{
		// Get the PCM samples	
		// single stereo channel	
		// update the buffer with new data
		bytes = FIFO_ReadDataBlock(&pcm_fifo,num_samples*2,(char*)(pArg->Data));

	}
	else
	{
#if defined (CODEC_AD1938)
		memset((char*)(pArg->Data),0,num_samples*2*8);// multichannel
#else
		memset((char*)(pArg->Data),0,num_samples*2);
#endif
		
	}	
	
	return 0;
}





