📄 util.c
字号:
* 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 + -