usbdev_dec.c 5.78 KB
#include "os_config.h"

#include "c_def.h"
#include "debug.h"
#include "oem.h"

#include "regmap.h"

#include "hw_dma.h"
#include "hw_da_pp.h"
#include "hw_timer.h"


#include "mem_reloc.h"

#include "message.h"

#include "interrupt.h"
#include "fifo.h"
#include "audio_com.h"
#include "app_dac.h"
#include "codec.h"
#include "audio_dec.h"

#include "app_sdram.h"
#include "app_cmd.h"
#include "app_main.h"

#include "usbdev.h"
#include "hw_pll.h"
#include "optek_link.h"

#if 1//def USB_DEV_ENABLE

#ifdef USB_SPEAKER


#define EX_AUDIO_DEC_SAMPLES    dec_frame_size

#define EX_AUDIO_STREAM_THRESHOLD_FOR_USB_DEV      (EX_AUDIO_DEC_SAMPLES+192*2)

void audiodata_down_sample_24bit_by_2(U8 *pBuf, U16 len)
{
	U8 *pBufD;
	U16 i;
	pBufD = pBuf;

	for (i=0; i<(len); i++)
	{
		*pBufD++ = *pBuf++;
		*pBufD++ = *pBuf++;
		*pBufD++ = *pBuf++;	//L channel

		*pBufD++ = *pBuf++;
		*pBufD++ = *pBuf++;
		*pBufD++ = *pBuf++;	//R channel

		pBuf += 6;
		i += 6;
	}
}

U8 *usbSpeaker_dec_buffer;
static U32 sync_cnt;
void usbSpeaker_dec_init( void )
{
	DBG_Printf ("%s\n\r", __func__);

	app_main_data.audio_src_bit = AUDIO_SRC_16BIT;

	app_main_data.playing_stream_chans = 2;
	app_main_data.playing_stream_sample_bits = 16;
	app_main_data.playing_stream_sample_rate = SAMPLE_RATE_48K;
	app_main_data.playing_stream_bitrate = app_main_data.playing_stream_sample_rate*app_main_data.playing_stream_chans*app_main_data.playing_stream_sample_bits;

	app_audio_clock_freq_setting(app_main_data.playing_stream_sample_rate);

	//init codec mem alloc
	codec_malloc_init ();

	usbSpeaker_dec_buffer = codec_malloc(EX_AUDIO_DEC_SAMPLES+10);

	daudio_SetFBSamplerateCorrection(0);
	clock_sync_init();

	sync_cnt = 10000/5;
}

void usbSpeaker_dec_fini(int reason)
{
	DBG_Printf ("%s\n\r", __func__);
	optek_link_set_master_tx_dynamic_sync(0,0xffff,0,OPTEK_LINK_H1);
}

#if 0
short usbspout[EX_AUDIO_DEC_SAMPLES+10];
#endif

extern U8 USBAUDIO_BITs; //AUDIO_BIT_RESOLUTION
void clock_sync_init(void);
int usbdev_clk_adaption_process(void);
//int usbSpeaker_dec_decode(U8 **pout,U16 *plen) __INTERNAL_RAM_TEXT;
int usbSpeaker_dec_decode(U8 **pout, U16 *plen)
{
	//STREAM_ID s;
	I32 rlen;
	U32 size;

	U8 *buffer;

	U32 eventMask;
	U32 *pADCDest;
	U32 wlen,dlen;
	U32 free_space;
	I32 diff;
	

	wlen = AUDIO_FIFO_STREAM_FIFO_WLEN();
	dlen = AUDIO_FIFO_STREAM_DATA_LEN();
	if (wlen < 0x5000)
	{
		if (dlen > EX_AUDIO_STREAM_THRESHOLD_FOR_USB_DEV - EX_AUDIO_DEC_SAMPLES)
		{
			AUDIO_FIFO_STREAM_DISCARD_DATA(dlen - (EX_AUDIO_STREAM_THRESHOLD_FOR_USB_DEV - EX_AUDIO_DEC_SAMPLES));
		}
		memset(usbSpeaker_dec_buffer, 0, EX_AUDIO_DEC_SAMPLES);
		*pout = usbSpeaker_dec_buffer;
		*plen = EX_AUDIO_DEC_SAMPLES;

		return DECODE_SUCCESS;
	}

/*
	diff = (I32)(EX_AUDIO_STREAM_THRESHOLD_FOR_USB_DEV - dlen)/(I32)192;
	
	daudio_SetFBSamplerateCorrection(diff);

	static u32 dlen_cnt;
	if(dlen_cnt++ > 1000)
	{
		DBG_Printf("G len:%d,diff:%d\n", dlen, diff);
		dlen_cnt = 0;
	}
*/

	/******************sync(clk adj)*********************/

	if (sync_cnt)
	{
		--sync_cnt;
		if (sync_cnt < (50000/5))
		{
			if (sync_cnt % (2500/5) == 0)
			{
				ukMsgSend(usbdev_clk_adaption_process);
				ukMsgSend(clock_sync_init);	
				if (sync_cnt == 0)
				{
					sync_cnt = (50000/5)+(50000/5);
				}
			}
		}
		else if(sync_cnt == (50000/5))
		{
			sync_cnt = (50000/5)+(50000/5);
			ukMsgSend(usbdev_clk_adaption_process);
			ukMsgSend(clock_sync_init);	
		}					
	}
	
	/****************sync end******************/

	if (dlen >= EX_AUDIO_DEC_SAMPLES)
	{
		AUDIO_FIFO_STREAM_GET_DATA(usbSpeaker_dec_buffer, EX_AUDIO_DEC_SAMPLES);
	}
	else
	{

		//clock_sync_init();
		//app_main_data.audio_out_24bit = FALSE;
		memset(usbSpeaker_dec_buffer, 0, EX_AUDIO_DEC_SAMPLES);
#if 1
		//clock_sync_init();
		//daudio_SetFBSamplerateCorrection(0);
#else		
		//DBG_Printf("G uf!%d\n", dlen);
		*pout = usbSpeaker_dec_buffer;
		*plen = EX_AUDIO_DEC_SAMPLES;

		clock_sync_init();

		app_main_data.playing_stream_status = STREAM_WAITING_DATA;


		daudio_SetFBSamplerateCorrection(0);

		AUDIO_FIFO_STREAM_FLUSH();

		AUDIO_FIFO_STREAM_OPEN(USB_SPEAKER_STREAM_START, USB_SPEAKER_STREAM_END - USB_SPEAKER_STREAM_START);

		AUDIO_FIFO_STREAM_CREATE(0, STREAM_LENTH_UNKNOWN, 0, 0);


		return DECODE_END;
#endif
	}

	*pout = usbSpeaker_dec_buffer;
	*plen = EX_AUDIO_DEC_SAMPLES;

    return DECODE_SUCCESS;	
}

//static const DECODE_DEVICE usbspeaker_decode = 
const DECODE_DEVICE usbspeaker_decode = 
{
	"usbspeaker decode",	
	usbSpeaker_dec_init,
	usbSpeaker_dec_fini,
	usbSpeaker_dec_decode
};

int usbdev_clk_adaption_process(void)
{
	U32 hclk,dclk;
	i32 diff;
	double drift;

	U32 dlen;

	dlen = AUDIO_FIFO_STREAM_DATA_LEN();

	if (host_dev_clock_get(&hclk,&dclk))
	{			
		DBG_Printf("G len:%d\n", dlen);

		if (sync_cnt < (50000/5))
		{
			if (dlen < EX_AUDIO_STREAM_THRESHOLD_FOR_USB_DEV)
			{
				dclk += 10*(SYS_CLK_FREQ_DEFAULT/1000000);
			}
			else if (dlen > EX_AUDIO_STREAM_THRESHOLD_FOR_USB_DEV)
			{
				dclk -= 10*(SYS_CLK_FREQ_DEFAULT/1000000);
			}
		}

		diff = dclk - hclk;

		drift = (double)diff/(double)dclk;

		if (drift > 0.000050 || drift < -0.000050)
		{
			return;
		}

		hw_audio_pll_clk_adj_by_drift(drift);


		if (diff > 0)
		{
			drift = (dclk/diff)*(0.5/5000.0);
			optek_link_set_master_tx_dynamic_sync(1,(U16)drift,(drift - (U32)drift)*0x100000000L,OPTEK_LINK_H1);
		}
		else if (diff < 0)
		{
			diff = -diff;
			drift = (dclk/diff)*(0.5/5000.0);
			optek_link_set_master_tx_dynamic_sync(-1,(U16)drift,(drift - (U32)drift)*0x100000000L,OPTEK_LINK_H1);
		}
		else
		{
			optek_link_set_master_tx_dynamic_sync(0,0xffff,0,OPTEK_LINK_H1);
		}			
	}
}

//jj+
int ex_audioZeroCheck( U32 *data, int size ) __INTERNAL_RAM_TEXT;
int ex_audioZeroCheck( U32 *data, int size )
{
	U32 tmp;
	U32 i;

	tmp = 1;
	for( i = 0; i < size; i ++ )
	{
		if( data[i] != 0 )
		{
			tmp = 0;
			break;
		}
	}

	return tmp;
}


#endif //USB_SPEAKER

#endif //USB_DEV_ENABLE