⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 ESS3890+SL原代码(1*16内存)
💻 C
📖 第 1 页 / 共 3 页
字号:
 * Inputs:
 *	level:	Spatializer level
 *
 * Return:
 *	OSD string
 */
#define assign_ptr(a, b) { a = b; }
char * SPA_set_level(level)
int level;
{
    unsigned int * filter;
    int i, offset = 0;
    char * ptr;

    assign_ptr(ptr, MSG_audfx_off);

    if (level == SPA_SURROUND) {		/* 1 */
	assign_ptr(ptr, MSG_surround_on);
    } else if (level == SPA_3D) {		/* 2 */
	assign_ptr(ptr, MSG_3d);
	offset = BP_size;
    } else if (level == SPA_HALL) {		/* 3 */
	assign_ptr(ptr, MSG_hall);
	offset = BP_size * 2;
    } else if (level == SPA_VOCAL_CUT) {	/* 4 */
	assign_ptr(ptr, MSG_voice_can);
	offset = BP_size * 3;
    }

    filter = bp_ham + offset;
    for (i = 0; i < BP_size; i++) {
	*(int *) dram(BP_start + i) = filter[i];
    }

    SPA_level = level;
    return(ptr);
}
#endif /* SPATIAL */

#ifdef ECHO
/************************************************************************
 * Following code is echo related. Since echo.c is protected, I'll	*
 * leave this code here so we can have compilation options and customers*
 * can make changes.							*
 ************************************************************************/
#ifdef DSC_SW_DETECT_CENTER
static int mic_level_ok(mic_dc_level)
int mic_dc_level;
{
    int i;
    int mic_mean = 0;
    int *ptr = (int *)dram(MIC_start + ECHO_AF); /* skip 1st 48 DWs */

    for (i = 0; i < (ECHO_AF * 2); i++) {
	int t = (int)(*ptr++);
	int t0 = t>>16;
	int t1 = (t<<16)>>16;
	mic_mean += t0 + t1;
	asm("nop");
	asm("nop");
    }
    mic_mean /= (ECHO_AF * 2 * 2);

    if ((mic_mean > mic_dc_level) || (mic_mean < -(mic_dc_level)))
	return 0;
    else
	return 1;
}
#endif /* DSC_SW_DETECT_CENTER */

/*
 * This is a new algorithm of turning on MIC. We'll not hog CPU
 * until MIC is turned on. In contrast, we'll just start taking in
 * the data then release CPU. When 3 * 48B are collected, we'll
 * stop taking in the data in the interrupt service routine. Then
 * we'll compute the average here. If the average is good, then we
 * consider the MIC is turned on successfully; otherwise, we'll
 * go the whole thing again.
 *
 * For older 3207's, since reference voltage may not be stable for
 * few seconds, we'll be conservative and wait for 8 seconds before
 * starting taking in the data.
 */
void MIC_turn_on()
{
    PRIVATE int mic_dc_level = 0x80;
    /*
     * Don't turn on Ain for 3881/3883 or when power is down.
     */
    if (IS_POWER_DOWN)
        return;

#ifndef DSC_SW_DETECT_CENTER
    /*
     * New way of turn on Ain. This applies to 3207 only. 3881 doesn't
     * even need this.
     */

#ifdef DSC
    DSC_mic_off();
    DSC_mic_on();
#endif
    MIC_init();
    MIC_is_turned_on = 1;
#else
    /*
     * This is really an obsolete way of doing things. In addition,
     * for 3881/3883, this way won't work.
     */
    /*
     * Don't do the evaluation for 8 seconds (hopefully the reference
     * voltage can be stabilized by then.
     */
    if (glbTimer < EIGHT_SECOND)
      return;

    if (MIC_got_sample == 1) {
	/*
	 * According to interrupt service routine, we got enough data
	 * (i.e. enough for evaluation.)
	 */

	/*
	 * We'll loop 256 times in small increment. After which, we'll
	 * jump geomatrically.
	 */
	if (mic_dc_level > 0x1080) {
	    goto gotit;	/* Prevent very long loop! */
	} else if (mic_dc_level == 0x880) {
	    mic_dc_level = 0x1000;
	    mic_sensitivity = 7;
	} else if (mic_dc_level == 0x480) {
	    mic_dc_level = 0x800;
	    mic_sensitivity = 6;
	} else if (mic_dc_level == 0x280) {
	    mic_dc_level = 0x400;
	    mic_sensitivity = 5;
	} else if (mic_dc_level == 0x180) {
	    mic_dc_level = 0x200;
	    mic_sensitivity = 4;
	} else if (mic_dc_level == 0x100) {
	    mic_sensitivity = 3;
	}
	if (mic_level_ok(mic_dc_level)) {
	  gotit:
	    MIC_is_turned_on = 1;
	    if (vcx_echo >= 0) {
		/*
		 * In case ECHO is already on, we need to initialize
		 * MIC stuff, then start take in.
		 */
		MIC_init();
		MIC_start_take_in();
	    } else {
		/* To be consistent with before */
		MIC_stop_take_in();
	    }
	    return;
	}
	mic_dc_level++;
    }

    if (MIC_got_sample != 2) {
	/* Not getting sample, then start collecting data. */
#ifdef DSC
	DSC_mic_off();
	DSC_mic_on();
#endif
	MIC_init();
	MIC_start_take_in();
	MIC_got_sample = 2;
    }
#endif /* else of DSC_SW_DETECT_CENTER */
}
#endif   /* ECHO */


#ifdef EXT_INPUT
void swap_values(int *vala, int *valb)
{
    *vala ^= *valb;
    *valb ^= *vala;
    *vala ^= *valb;
}
#endif

/*------------------------------------------------------------------------
  Function:

  Parameters:

  Description: This function converts numbers <= 9999 to BCD format
------------------------------------------------------------------------*/
uint UTIL_hex2bcd(int hex)
{
    int pos32=0;

    /* convert number to bcd..
     * since our hex2bcd/bcd2hex tables are limited to "99",
     * we split the number into two parts for processing.
     *
     * NOTE: hex <= 9999
     */
    while (hex >= 100) {
	pos32++;
	hex -= 100;
    }

    return ((hex2bcd[pos32] << 8) | hex2bcd[hex]);
}

/*------------------------------------------------------------------------
  Function:

  Parameters:

  Description: This function appends number <= 9999 to a string with
               null termination.
------------------------------------------------------------------------*/
uchar *hex2string(char *str, int number)
{
    int i, tmp = 0, digits=0;
    uint num_bcd;


    if (number > 9999) number = 9999; /* limit */

    num_bcd = UTIL_hex2bcd(number);

    for (i = 0; i < 3; i++) {
	tmp = (num_bcd>>12) & 0xf;
	if (tmp || digits) {
	    *str++ = tmp + '0';
	    digits++;
	}
	num_bcd <<= 4;
    };

    /* "ones" digit (digit position 0)..always display */
    tmp = (num_bcd>>12) & 0xf;
    *str++ = tmp + '0';
    *str = 0;

    return str;
}

/* append "str2" to "dest"..
 * Where str2 is zero-terminated string, and "dest" buffer
 * has enough space for characters in str2.
 * Returns end address.
 */
unsigned char *cat_str(unsigned char *dest, unsigned char *str2)
{
    unsigned char *src;

    src = str2;
    while (*src) {
	*dest++ = *src++;
    }
    *dest = 0; /* zero-termination */

    return (dest);
}

/* moved out of sched.c for saving stack if
 * protected globals are unused, i.e. LC code.
 */
void AS_set_sched_limits(SCHED_LIMITS *limits_ptr)
{
    int tmp;

    if (TDM_isCDDA) {
#ifdef ANTI_SHOCK /* ANTI_SHOCK enabled */
	/* for decoding task */
	limits_ptr->audio_task = 1;
	limits_ptr->dst_thresh = CDDA_chunk;

	/* standby..lower decoding limit when ESP on */
	limits_ptr->src_thresh = (PLAY_set_2x_speed) ?
	    ABV_write<<3/*PRL388*/ : (AS_ABV_size>>3);

	limits_ptr->go_limit = (AS_ABV_size>>1) + (AS_ABV_size>>2);
	limits_ptr->end_limit = ABV_write;

	/* for encoding task */
	limits_ptr->as_abv_fullness = limits_ptr->abv_fullness;
	AS_ABV_update_occupancy(limits_ptr->abv_fullness);

	/* NOTE: for purposes of sharing "legacy code", and streamlining
	 * code for both MP3 and CDDA tasks, abv_fullness and as_abv_fullness
	 * above are misnomers. "abv_fullness" actually indicates fullness of
	 * AS_ABV (compressed data) buffer, whereas, "as_abv_fullness"
	 * indicates fullness of ABV (raw PCM data) buffer.
	 */
#else
	/* for decoding task */
	limits_ptr->audio_task = 4;
	limits_ptr->dst_thresh = CDDA_chunk;
	limits_ptr->src_thresh = CDDA_chunk; /* standby */
	limits_ptr->go_limit = ABV_size - 2*ABV_write;
#endif
    } else {
	limits_ptr->audio_task = 1;
	limits_ptr->dst_thresh = PCM_PER_DECODE;
	limits_ptr->go_limit = ABV_size - 2*ABV_write; /* mpeg audio */

	tmp = 0;
#ifdef ANTI_SHOCK
	/* for VCD anti-shock AV_sync */
	if (ABV_size == AS_VCD_ABV_size) {
	    tmp = ABV_size>>1 + ABV_size>>2; /* ABV_size*3/4 */
	}

	limits_ptr->end_limit = ABV_write;
#endif
	limits_ptr->src_thresh = tmp + AUD_resync; /* standby */

    }
}

void AS_audio_decode_monitor(SCHED_LIMITS *limits_ptr, int go)
{
#ifdef ANTI_SHOCK
    /* All of the data for this CDDA track has been
     * read. We need to decode all of the data(compressed)
     * before setting end_of_play.
     */
    if (limits_ptr->abv_fullness < limits_ptr->end_limit) {
	XPORT_data_end = 0;
	end_of_play = 1;
	limits_ptr->audio_go = 0;
    } else {
	limits_ptr->audio_go = go;
    }
#endif
}

int AS_audio_encode_monitor(SCHED_LIMITS *limits_ptr)
{
#ifdef ANTI_SHOCK
    static int as_abv_draining;


    if(TDM_isCDDA) {
	/* CDDA encoding monitor */
	AS_ABV_update_space(limits_ptr->dst_space);
	if (as_abv_draining) {
	    /* maintain AS buffer at ~87% full (~20secs)..*/
	    if (limits_ptr->dst_space > (AS_ABV_size>>3)) {
		as_abv_draining = 0; /* start filling */
	    }
	} else {
	    if (limits_ptr->dst_space > (ABV_write<<2) /* AS buffer space */) {
		if (limits_ptr->as_abv_fullness > (ABV_size>>1) /* immediate limit */) {
		    return (1);
		} else if (!limits_ptr->audio_go) {
		    if (limits_ptr->as_abv_fullness >= (ABV_size>>3) /*standby limit*/){
			limits_ptr->audio_task = limits_ptr->audio_go = 7;
		    } else if (XPORT_data_end
#if 0 /* PVU..don't encode when scratched, to prevent repeating same ABV
       * data when XPORT has stopped!
       */
			       || (c2po_timeout > glbTimer)
#endif
			       ) {
			/* no more..finish encoding rest of data */
			limits_ptr->audio_go =
			    (limits_ptr->as_abv_fullness < limits_ptr->end_limit) ?
			    0 : 7;
			limits_ptr->audio_task = limits_ptr->audio_go;
		    }
		}
	    } else {
		as_abv_draining = 1; /* full..let it drain */
		PLAY_set_2x_speed = 0; /* back to 1X speed */
	    }
	}
    }
#endif ANTI_SHOCK

    return (0);
}

void AS_update_abv_gd2wr(SCHED_LIMITS *limits_ptr)
{
#ifdef ANTI_SHOCK
    ABV_update_gd2wr(limits_ptr->as_abv_fullness);
    if (limits_ptr->as_abv_fullness > (MP3_SECTOR_SIZE+0x100)) {
	ABV_gdptr_advance(MP3_SECTOR_SIZE);
    }
#endif
}

int AS_xport_data_end(void)
{
#ifdef ANTI_SHOCK
    return(XPORT_data_end);
#else
    return(0);
#endif
}

/* Decompression utilities */
#if defined(COMPRESS_MKTBL_DATA) || \
    defined(XSEG1_ON_FLY) || defined(XSEG2_ON_FLY) || \
    defined(XSEG3_ON_FLY) || defined(XSEG4_ON_FLY)

#ifdef XSEG1_ON_FLY
int xtra_s1_compress_data_start=0;
#endif
#ifdef XSEG2_ON_FLY
int xtra_s2_compress_data_start=0;
#endif
#ifdef XSEG3_ON_FLY
int xtra_s3_compress_data_start = 0;
#endif /* XSEG3_ON_FLY */
#ifdef XSEG4_ON_FLY
int xtra_s4_compress_data_start=0;
#endif

int tmp_reg_save=-1;
#ifdef XSEG1_ON_FLY
int xtra_s1_compress_text_start=0;
#endif
#ifdef XSEG2_ON_FLY
int xtra_s2_compress_text_start=0;
#endif
#ifdef XSEG3_ON_FLY
int xtra_s3_compress_text_start = 0;
#endif /*XSEG3_ON_FLY*/
#ifdef XSEG4_ON_FLY
int xtra_s4_compress_text_start=0;
#endif


extern unsigned char *inbuf;
extern unsigned char *gzip_window;
extern unsigned int heap_top;
extern unsigned int base_heap_top;
int decompress_stack_start;
int save_riface_irqmask;

/* For decompressing both code and data */
void Decompress(int from,int to, int xsegn)
{
    /* make sure "DATA_START" > 0x48 */
    asm("st 0x40[r0],r4");
    asm("st 0x44[r0],r5");
    asm("st 0x3c[r0],r19");
    asm("st 0x30[r0],r29");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -