📄 bitaudio.cpp
字号:
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 + -