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

📄 bitaudio.cpp

📁 2002年
💻 CPP
📖 第 1 页 / 共 2 页
字号:

bool CBitAuditory::AddPosMsg(unsigned char type, unsigned char acu, const Vector& v){
	return AddPosMsg(type,acu,v.x,v.y);
}

bool CBitAuditory::AddPosMsg(unsigned char type, unsigned char acu, float x, float y){
	CParseBit pb;
//+type
	if(type >= CAudio_extend){
		type -= CAudio_extend;
		unsigned char tmp = CAudio_extend;
		pb.Add(&tmp, CAudio_type_bits);
	}
	pb.Add(&type, CAudio_type_bits);
//+accuracy
	pb.Add(&acu, CAudio_accuracy_bits);
//+data
	AddPosMsg(pb, x, y, acu);
//try to pack all at last
	if(!msg.Add(pb.GetBufHead(), pb.GetTotalBits())){
		pack_err_type = AudioPack_Oversize;
		return false;
	}else{
		return true;
	}
}

bool CBitAuditory::AddVelMsg(unsigned char type, unsigned char time_delay, const Vector& vel){
	CParseBit pb;	
	//+type
	pb.Add(&type, CAudio_type_bits);
	//+accuracy
	pb.Add(&time_delay, CAudio_accuracy_bits);
	//+data
	AddVelMsg(pb, time_delay, vel);
	//try to pack all at last
	
	if(!msg.Add( pb.GetBufHead(), pb.GetTotalBits() )){
		pack_err_type = AudioPack_Oversize;
		return false;
	}else{
		return true;
	}
}

void CBitAuditory::InitSay(){
	msg.Clear();

#ifdef Version7_Compatible
	if(ServerParam::version < 8.0f){
		unsigned char tmp;
		tmp = 1;
		msg.Add(&tmp, 1);	//default
		tmp = situation.CurrentTime % 2;
		msg.Add(&tmp, 1);	//time
		return;
	}
#endif
}

bool CBitAuditory::SayBall(){
	CParseBit pb;
//+type
	unsigned char type = CAudio_ball;
	pb.Add(&type, CAudio_type_bits);
//+pos(accuracy+data)
	unsigned char acu;
	acu = delta_2_accuracy(ball.pos_delta);	
	pb.Add(&acu, CAudio_accuracy_bits);
	AddPosMsg(pb, ball.pos.x, ball.pos.y, acu);
//+vel(accuracy+data)
	unsigned char time_delay = (unsigned char)ball.PosDelay();// .VelDelay();// + int (ball.distance / 7);
	if(time_delay >= CAudio_max_accuracy){
		pack_err_type = AudioPack_Inaccurate;
		return false;
	}
	pb.Add(&time_delay, CAudio_accuracy_bits);
	AddVelMsg(pb, time_delay, ball.global_vel); 
//+ballcontroller	
	unsigned char no = CAudio_Invalid_Num;
	if(!situation.BallFree){
		if( 0 < situation.ballcontroller && situation.ballcontroller<= 2*SP_team_size){
			no = situation.ballcontroller;
		}
	} 
	pb.Add(&no, CAudio_Num_bits);
//try to pack all at last
	if(!msg.Add(pb.GetBufHead(), pb.GetTotalBits())){
		pack_err_type = AudioPack_Oversize;
		return false;
	}else{
		return true;
	}
}

bool CBitAuditory::SayPlayer(int num){
	if(!Player::IsUniformNo(num)){
		pack_err_type = AudioPack_InValid_Num;
		return false;
	}

	Player* p = &GetPlayer(num);
	unsigned char acu;
	acu = delta_2_accuracy(p->pos_delta);

	if(acu >= CAudio_max_accuracy){
		DoLog("fail to say %d, conf%.2f, pos(%.2f, %.2f), delta%.1f", 
			num, p->pos_conf, p->pos.x, p->pos.y, p->pos_delta);
		pack_err_type = AudioPack_Inaccurate;
		return false;
	}
	
	if(announce_side ^ Player::IsMyPlayer(num)){
		if(Player::IsMyPlayer(num)) num = num + CAudio_extend;
		else num = num - SP_team_size + CAudio_extend;
	}else{
		if(num > SP_team_size) num -= SP_team_size;
	}
	return AddPosMsg(num, acu, p->pos);
}

bool CBitAuditory::SayCtrl(){
	unsigned char type = CAudio_Ctrl;

	CParseBit pb; 

	pb.Add(&type, CAudio_type_bits);
	AddPosMsg(pb, Self.pos.x, Self.pos.y, 0);

	if(!msg.Add(pb.GetBufHead(), pb.GetTotalBits())){
		pack_err_type = AudioPack_Oversize;
		return false;
	}else{
		DoLog(LOG_HEAR, "say ctrl ballpos(%.1f,%.1f)", Self.pos.x, Self.pos.y);
		return true;
	}	
}

bool CBitAuditory::SayPass(){
	unsigned char type = CAudio_pass;

	CParseBit pb; 

	pb.Add(&type, CAudio_type_bits);

	Vector predict_vel = ball.global_vel + Skill::action.KickEffect(situation.CurrentTime);
	Vector predict_pos = ball.pos;
	AddPosMsg(pb, predict_pos.x, predict_pos.y, 0);
	AddVelMsg(pb, 0, predict_vel);

	if(!msg.Add(pb.GetBufHead(), pb.GetTotalBits())){
		pack_err_type = AudioPack_Oversize;
		return false;
	}else{
		DoLog(LOG_HEAR, "say pass ballpos(%.1f,%.1f), vel(%.1f,%.1f)", predict_pos.x, predict_pos.y,
			predict_vel.x, predict_vel.y);
		return true;
	}
}

void CBitAuditory::HearBallController(int No){
	int i;
	for(i = 1; i <= SP_team_size; i ++){
		MyPlayer(i).heard_iscontrolball.Setdata(false, parse_time);
		TheirPlayer(i).heard_iscontrolball.Setdata(false, parse_time);;
	}
	if(0<No && No <= 2*SP_team_size){
		GetPlayer(No).heard_iscontrolball.Setdata(true, parse_time);;
	}
}

//code a float-type data into unsigned char
//acu is the accuracy level of coding


//compute delta error made by quantization in coding
//acu is the accuracy level of coding
float CBitAuditory::Quantize_delta(int acu){
#ifdef _LONG_AUDIO	
	return 0.5f;
#else
	return 0.5f * (1 << acu);
#endif
}

//transfate float-type delta error into accuracy level
unsigned char AudioDatamap::delta_2_accuracy(float delta){	
	unsigned char acu = 0;
	delta = (float)round(delta);
#ifdef _LONG_AUDIO
	acu = (unsigned char) delta;
#else
	delta += 1.0f;
	while(delta > 2){
		delta /= 2;
		acu ++;
	}
#endif
	return acu; 
}

//transfate the accuracy level into a float-type delta error
float AudioDatamap::accuracy_2_delta(unsigned char acu){
#ifdef _LONG_AUDIO
	return (float)acu;
#else
	return float(1 << (acu+1)) - 1.0f;
#endif

}

//calculate the bits occupied by a data in some accuracy level.
//specifically reprensenting position information.
int AudioDatamap::bit_len(int acu, int range_exp){
#ifdef _LONG_AUDIO	
	return 8;
#else
	return range_exp - acu;
#endif	
}

//encode x,y coordinate into a character
unsigned char AudioDatamap::f2c_x(float f, int acu, int range_exp){
	unsigned char data = map(f, ServerParam::pitch_length, 127.0f);

#ifdef _LONG_AUDIO	
	return data;
#else
	//we needn't the following sentence because when the data is packed, its high bits will be cut
	data = data << (8-range_exp);
	data = data >> (8-range_exp);
	return data >> acu;
#endif
}

unsigned char AudioDatamap::f2c_y(float f, int acu, int range_exp){
	unsigned char data = map(f, ServerParam::pitch_width, 63.0f);

#ifdef _LONG_AUDIO	
	return data;
#else
	data = data << (8-range_exp);
	data = data >> (8-range_exp);
	return data >> acu;
#endif
}

//decode an unsigned char into a float
//acu is the accuracy of coding
//ref_value is a reference value
float AudioDatamap::c2f_x(unsigned char c, int acu, int range_exp, float ref_value){
#ifndef _LONG_AUDIO	
	unsigned char data = map(ref_value, ServerParam::pitch_length, 127.0f);	
	unsigned char tmp, high_bits;
	unsigned char mask = 255;

	//retrieve high bits (which is cut off when msg is generated)
	mask = mask << range_exp;
	high_bits = (data & mask) >> range_exp;

/*simulate transferd bits and compare it with received bits 
(the comparing result is used to rectify the high bits)
 if their distance > 1/2 max_distance then high bits should be rectified
*/
	tmp = data << (8-range_exp);
	tmp = tmp >> (8-range_exp);
	tmp = tmp >> acu;
	
	if(abs(tmp - c) > (1 << (bit_len(acu, range_exp)-1))){
		if(tmp > c) high_bits ++;
		else high_bits --;
	}

	data = high_bits << range_exp;	
	data = data >> acu;
	data |= c;
	data = data << acu;

	return antimap(data, ServerParam::pitch_length, 127.0f);
#else
	return antimap(c, ServerParam::pitch_length, 127.0f);
#endif
}

float AudioDatamap::c2f_y(unsigned char c, int acu, int range_exp, float ref_value){	
#ifndef _LONG_AUDIO	
	unsigned char data = map(ref_value, ServerParam::pitch_width, 63.0f);
	unsigned char tmp, high_bits;
	unsigned char mask = 255;

	//retrieve high bits (which is cut off when msg is generated)
	mask = mask << range_exp;
	high_bits = (data & mask) >> range_exp;

/*simulate transferd bits and compare it with received bits 
(the comparing result is used to rectify the high bits)
 if their distance > 1/2 max_distance then high bits should be rectified
*/
	tmp = data << (8-range_exp);
	tmp = tmp >> (8-range_exp);
	tmp = tmp >> acu;
	
	if(abs(tmp - c) >= (1 << (bit_len(acu, range_exp)-1))){
		if(tmp > c) high_bits ++;
		else high_bits --;
	}

	data = high_bits << range_exp;	
	data = data >> acu;
	data |= c;
	data = data << acu;
	return antimap(data, ServerParam::pitch_width, 63.0f);
#else
	return antimap(c, ServerParam::pitch_width, 63.0f);
#endif
}

float AudioDatamap::Max_ref_delta(int range_exp){
	if(range_exp == 5) return 15.0f;
	else if(range_exp == 6) return 31.0f;
	return (float)pow(2, range_exp-1) - 1.0f;
}

//communication strategy: 
//	odd-number player announce opp in even time, teammates in odd time. vice versa.
//return value : true-myside, false-oppside
bool AudioDatamap::SideSpeak(int NO, int time){
	return bool(((NO%2)^(time%2)) == 0);
}

char AudioDatamap::map_into_printablechar(int i){
	if (i < 10) return i + '0';
	i -= 10;
	if (i < 26) return i + 'a';
	i -= 26;
	if (i < 26) return i + 'A';
	i -= 26;
	switch(i){
	case 0: return '(';
	case 1: return ')';
	case 2: return '.';
	case 3: return '+';
	case 4: return '-';
	case 5: return '*';
	case 6: return '/';
	case 7: return '?';
	case 8: return '<';
	case 9: return '>';
	default:return '_';
	}
}

int AudioDatamap::map_from_printablechar(char m){
	if (m >= '0' && m <= '9')
		return m - '0';
	if (m >= 'a' && m <= 'z')
		return m - 'a' + 10;
	if (m >= 'A' && m <= 'Z')
		return m - 'A' + 36;
	if (m == '(')
		return 62;
	if (m == ')')
		return 63;
	if (m == '.')
		return 64;
	if (m == '+')
		return 65;
	if (m == '-')
		return 66;
	if (m == '*')
		return 67;
	if (m == '/')
		return 68;
	if (m == '?')
		return 69;
	if (m == '<')
		return 70;
	if (m == '>')
		return 71;
	return 72;
}

void AudioDatamap::DualByteMap(float x, char* s)	//range (-204.8,204.8)
{
	int ix= int(x * 10);
	ix+=2048;
	s[0] = map_into_printablechar(ix % 64);
	s[1] = map_into_printablechar(ix / 64);
}

float AudioDatamap::DualByteDemap(char* s)
{
	int ix = map_from_printablechar(s[1]) * 64 + map_from_printablechar(s[0]);
	return float(ix -2048)/10;
}

⌨️ 快捷键说明

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