mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-22 20:11:44 +00:00
fix some voip stuff, opus should be properly supported now.
fix iqm+events... again. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5043 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
36c0c3302f
commit
15a2038e4e
7 changed files with 69 additions and 52 deletions
|
@ -1688,7 +1688,7 @@ qboolean CLQW_SendCmd (sizebuf_t *buf, qboolean actuallysend)
|
|||
void CL_SendCmd (double frametime, qboolean mainloop)
|
||||
{
|
||||
sizebuf_t buf;
|
||||
qbyte data[1024];
|
||||
qbyte data[MAX_DATAGRAM];
|
||||
int i, plnum;
|
||||
usercmd_t *cmd;
|
||||
float wantfps;
|
||||
|
|
|
@ -417,7 +417,7 @@ void CL_ConnectToDarkPlaces(char *challenge, netadr_t *adr)
|
|||
|
||||
connectinfo.time = realtime; // for retransmit requests
|
||||
|
||||
Q_snprintfz(data, sizeof(data), "%c%c%c%cconnect\\protocol\\darkplaces 3\\protocols\\DP7 DP6 DP5 FITZ NEHAHRABJP NEHAHRABJP2 NEHAHRABJP3 QUAKE\\challenge\\%s", 255, 255, 255, 255, challenge);
|
||||
Q_snprintfz(data, sizeof(data), "%c%c%c%cconnect\\protocol\\darkplaces 3\\protocols\\DP7 DP6 DP5 RMQ FITZ NEHAHRABJP NEHAHRABJP2 NEHAHRABJP3 QUAKE\\challenge\\%s", 255, 255, 255, 255, challenge);
|
||||
|
||||
NET_SendPacket (NS_CLIENT, strlen(data), data, adr);
|
||||
|
||||
|
|
|
@ -268,7 +268,7 @@ char *svc_nqstrings[] =
|
|||
"NEW PROTOCOL(81)", //81
|
||||
"NEW PROTOCOL(82)", //82
|
||||
"nqsvcfte_cgamepacket(83)", //83
|
||||
"NEW PROTOCOL(84)", //84
|
||||
"nqsvcfte_voicechat", //84
|
||||
"NEW PROTOCOL(85)", //85
|
||||
"nqsvcfte_updateentities", //86
|
||||
"NEW PROTOCOL(87)", //87
|
||||
|
@ -3659,6 +3659,10 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
|
|||
if (CPNQ_IS_DP) //DP's protocol requires client+server to have exactly the same data files. this is shit, but in the interests of compatibility...
|
||||
COM_Effectinfo_Enumerate(CL_Darkplaces_Particle_Precache);
|
||||
|
||||
#ifdef VOICECHAT
|
||||
S_Voip_MapChange();
|
||||
#endif
|
||||
|
||||
#ifdef PEXT_CSQC
|
||||
CSQC_Shutdown();
|
||||
CSQC_Init(cls.demoplayback, false, 0);
|
||||
|
@ -7823,6 +7827,12 @@ void CLNQ_ParseServerMessage (void)
|
|||
S_StopSound(i>>3, i&7);
|
||||
break;
|
||||
|
||||
#ifdef PEXT2_VOICECHAT
|
||||
case svcfte_voicechat:
|
||||
S_Voip_Parse();
|
||||
break;
|
||||
#endif
|
||||
|
||||
case svc_temp_entity:
|
||||
CL_ParseTEnt (true);
|
||||
break;
|
||||
|
|
|
@ -552,19 +552,23 @@ void M_Menu_Audio_f (void)
|
|||
};
|
||||
#ifdef VOICECHAT
|
||||
static const char *voipcodecoptions[] = {
|
||||
"Auto",
|
||||
"Speex (ez-compat)",
|
||||
// "Raw (11025)",
|
||||
"Opus (external)",
|
||||
// "Raw16 (11025)",
|
||||
"Opus",
|
||||
"Speex (Narrow)",
|
||||
"Speex (Wide)",
|
||||
// "Speex (UltraWide)",
|
||||
NULL
|
||||
};
|
||||
static const char *voipcodecvalue[] = {
|
||||
"",
|
||||
"0",
|
||||
// "1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
// "5",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -2684,7 +2684,7 @@ static void Sbar_Voice(int y)
|
|||
int s, i;
|
||||
float range = loudness/100.0f;
|
||||
w = 0;
|
||||
Font_BeginString(font_default, sbar_rect.x + sbar_rect.width/2, sbar_rect.y + y + sbar_rect.height-SBAR_HEIGHT, &x, &y);
|
||||
Font_BeginString(font_default, sbar_rect.x + min(320,sbar_rect.width)/2, sbar_rect.y + y + sbar_rect.height-SBAR_HEIGHT, &x, &y);
|
||||
w += Font_CharWidth(CON_WHITEMASK, 0xe080);
|
||||
w += Font_CharWidth(CON_WHITEMASK, 0xe081)*16;
|
||||
w += Font_CharWidth(CON_WHITEMASK, 0xe082);
|
||||
|
|
|
@ -150,10 +150,10 @@ cvar_t snd_voip_showmeter = CVARAFD("cl_voip_showmeter", "1", NULL, CVAR_ARCHIV
|
|||
cvar_t snd_voip_play = CVARAFDC("cl_voip_play", "1", NULL, CVAR_ARCHIVE, "Enables voip playback. Value is a volume scaler.", S_Voip_Play_Callback);
|
||||
cvar_t snd_voip_ducking = CVARAFD("cl_voip_ducking", "0.5", NULL, CVAR_ARCHIVE, "Scales game audio by this much when someone is talking to you. Does not affect your speaker volume when you speak (minimum of cl_voip_capturingvol and cl_voip_ducking is used).");
|
||||
cvar_t snd_voip_micamp = CVARAFDC("cl_voip_micamp", "2", NULL, CVAR_ARCHIVE, "Amplifies your microphone when using voip.", 0);
|
||||
cvar_t snd_voip_codec = CVARAFDC("cl_voip_codec", "0", NULL, CVAR_ARCHIVE, "0: speex(@11khz). 1: raw. 2: opus. 3: speex(@8khz). 4: speex(@16). 5:speex(@32).", 0);
|
||||
cvar_t snd_voip_codec = CVARAFDC("cl_voip_codec", "", NULL, CVAR_ARCHIVE, "0: speex(@11khz). 1: raw. 2: opus. 3: speex(@8khz). 4: speex(@16). 5:speex(@32).", 0);
|
||||
cvar_t snd_voip_noisefilter = CVARAFDC("cl_voip_noisefilter", "1", NULL, CVAR_ARCHIVE, "Enable the use of the noise cancelation filter.", 0);
|
||||
cvar_t snd_voip_autogain = CVARAFDC("cl_voip_autogain", "0", NULL, CVAR_ARCHIVE, "Attempts to normalize your voice levels to a standard level. Useful for lazy people, but interferes with voice activation levels.", 0);
|
||||
cvar_t snd_voip_bitrate = CVARAFDC("cl_voip_bitrate", "0", NULL, CVAR_ARCHIVE, "For codecs with non-specific bitrates, this specifies the target bitrate to use (in kb).", 0);
|
||||
cvar_t snd_voip_opus_bitrate = CVARAFDC("cl_voip_opus_bitrate", "3000", NULL, CVAR_ARCHIVE, "For codecs with non-specific bitrates, this specifies the target bitrate to use.", 0);
|
||||
#endif
|
||||
|
||||
extern vfsfile_t *rawwritefile;
|
||||
|
@ -248,7 +248,7 @@ void S_SoundInfo_f(void)
|
|||
enum
|
||||
{
|
||||
VOIP_SPEEX_OLD = 0, //original supported codec (with needless padding and at the wrong rate to keep quake implementations easy)
|
||||
VOIP_RAW = 1, //support is not recommended.
|
||||
VOIP_RAW16 = 1, //support is not recommended.
|
||||
VOIP_OPUS = 2, //supposed to be better than speex.
|
||||
VOIP_SPEEX_NARROW = 3, //narrowband speex. packed data.
|
||||
VOIP_SPEEX_WIDE = 4, //wideband speex. packed data.
|
||||
|
@ -256,6 +256,7 @@ enum
|
|||
|
||||
VOIP_INVALID = 16 //not currently generating audio.
|
||||
};
|
||||
#define VOIP_DEFAULT_CODEC (cls.protocol==CP_QUAKEWORLD?VOIP_SPEEX_OLD:VOIP_OPUS) //opus is preferred, but ezquake is still common and only supports my first attempt at voice compression so favour that for quakeworld.
|
||||
static struct
|
||||
{
|
||||
struct
|
||||
|
@ -301,7 +302,7 @@ static struct
|
|||
unsigned char decgen[MAX_CLIENTS]; /*last generation. if it changes, we flush speex to reset packet loss*/
|
||||
unsigned int decsamplerate[MAX_CLIENTS];
|
||||
unsigned int decframesize[MAX_CLIENTS];
|
||||
float lastspoke[MAX_CLIENTS]; /*time when they're no longer considered talking. if future, they're talking*/
|
||||
float lastspoke[MAX_CLIENTS]; /*time when they're no longer considered talking. if future, they're talking (timeout avoids flickering, and harder to troll with fake-tourettes when noone is looking)*/
|
||||
float lastspoke_any;
|
||||
|
||||
unsigned char capturebuf[32768]; /*pending data*/
|
||||
|
@ -511,8 +512,6 @@ static qboolean S_Opus_Init(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
Con_Printf("OPUS support is experimental and should not be used\n"); //need to remove the packet length prefix.
|
||||
|
||||
s_voip.opus.loaded = true;
|
||||
return s_voip.opus.loaded;
|
||||
}
|
||||
|
@ -551,7 +550,7 @@ void S_Voip_Decode(unsigned int sender, unsigned int codec, unsigned int gen, un
|
|||
case VOIP_SPEEX_ULTRAWIDE:
|
||||
qspeex_decoder_destroy(s_voip.decoder[sender]);
|
||||
break;
|
||||
case VOIP_RAW:
|
||||
case VOIP_RAW16:
|
||||
break;
|
||||
case VOIP_OPUS:
|
||||
qopus_decoder_destroy(s_voip.decoder[sender]);
|
||||
|
@ -565,7 +564,7 @@ void S_Voip_Decode(unsigned int sender, unsigned int codec, unsigned int gen, un
|
|||
{
|
||||
default: //codec not supported.
|
||||
return;
|
||||
case VOIP_RAW:
|
||||
case VOIP_RAW16:
|
||||
s_voip.decsamplerate[sender] = 11025;
|
||||
break;
|
||||
case VOIP_SPEEX_OLD:
|
||||
|
@ -634,7 +633,7 @@ void S_Voip_Decode(unsigned int sender, unsigned int codec, unsigned int gen, un
|
|||
if (!s_voip.decoder[sender])
|
||||
return;
|
||||
|
||||
s_voip.decframesize[sender] = (sizeof(decodebuf) / sizeof(decodebuf[0])) / 2; //this is the maximum size in a single frame.
|
||||
s_voip.decframesize[sender] = s_voip.decsamplerate[sender]/400; //this is the maximum size in a single frame.
|
||||
}
|
||||
else
|
||||
qopus_decoder_ctl(s_voip.decoder[sender], OPUS_RESET_STATE);
|
||||
|
@ -715,7 +714,7 @@ void S_Voip_Decode(unsigned int sender, unsigned int codec, unsigned int gen, un
|
|||
}
|
||||
}
|
||||
break;
|
||||
case VOIP_RAW:
|
||||
case VOIP_RAW16:
|
||||
len = min(bytes, sizeof(decodebuf)-(sizeof(decodebuf[0])*decodesamps));
|
||||
memcpy(decodebuf+decodesamps, start, len);
|
||||
decodesamps += len / sizeof(decodebuf[0]);
|
||||
|
@ -734,9 +733,10 @@ void S_Voip_Decode(unsigned int sender, unsigned int codec, unsigned int gen, un
|
|||
// Con_Printf("Decoded %i frames from %i bytes\n", r, len);
|
||||
if (r > 0)
|
||||
{
|
||||
int frames = r / s_voip.decframesize[sender];
|
||||
decodesamps += r;
|
||||
s_voip.decseq[sender] = (s_voip.decseq[sender] + 1) & 0xff;//r / s_voip.decframesize[sender];
|
||||
seq = (seq+1)&0xff;//r / s_voip.decframesize[sender];
|
||||
s_voip.decseq[sender] = (s_voip.decseq[sender] + frames) & 0xff;
|
||||
seq = (seq+frames)&0xff;
|
||||
}
|
||||
else if (r < 0)
|
||||
Con_Printf("Opus decoding error %i\n", r);
|
||||
|
@ -909,7 +909,7 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
|
|||
int len;
|
||||
float micamp = snd_voip_micamp.value;
|
||||
qboolean voipsendenable = true;
|
||||
int voipcodec = snd_voip_codec.ival;
|
||||
int voipcodec = *snd_voip_codec.string?snd_voip_codec.ival:VOIP_DEFAULT_CODEC;
|
||||
qboolean rtpstream = NET_RTP_Active();
|
||||
|
||||
if (buf)
|
||||
|
@ -1023,7 +1023,7 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
|
|||
qspeex_encoder_ctl(s_voip.encoder, SPEEX_SET_SAMPLING_RATE, &s_voip.encsamplerate);
|
||||
}
|
||||
break;
|
||||
case VOIP_RAW:
|
||||
case VOIP_RAW16:
|
||||
s_voip.encsamplerate = 11025;
|
||||
s_voip.encframesize = 256;
|
||||
break;
|
||||
|
@ -1037,7 +1037,6 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
|
|||
//use whatever is convienient.
|
||||
s_voip.encsamplerate = 48000;
|
||||
s_voip.encframesize = s_voip.encsamplerate / 400; //2.5ms frames, at a minimum.
|
||||
s_voip.encframesize *= 4; //go for 10ms
|
||||
s_voip.encoder = qopus_encoder_create(s_voip.encsamplerate, 1, OPUS_APPLICATION_VOIP, NULL);
|
||||
if (!s_voip.encoder)
|
||||
return;
|
||||
|
@ -1100,7 +1099,7 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
|
|||
case VOIP_SPEEX_ULTRAWIDE:
|
||||
qspeex_bits_reset(&s_voip.speex.encbits);
|
||||
break;
|
||||
case VOIP_RAW:
|
||||
case VOIP_RAW16:
|
||||
break;
|
||||
case VOIP_OPUS:
|
||||
qopus_encoder_ctl(s_voip.encoder, OPUS_RESET_STATE);
|
||||
|
@ -1196,7 +1195,7 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
|
|||
len = qspeex_bits_write(&s_voip.speex.encbits, outbuf+outpos, sizeof(outbuf) - outpos);
|
||||
outpos += len;
|
||||
break;
|
||||
case VOIP_RAW:
|
||||
case VOIP_RAW16:
|
||||
len = s_voip.capturepos-encpos; //amount of data to be eaten in this frame
|
||||
len = min(len, sizeof(outbuf)-outpos);
|
||||
len &= ~((s_voip.encframesize*2)-1);
|
||||
|
@ -1216,38 +1215,36 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
|
|||
//densely pack the frames.
|
||||
start = (short*)(s_voip.capturebuf + encpos);
|
||||
frames = (s_voip.capturepos-encpos)/2;
|
||||
frames = s_voip.encframesize;
|
||||
if (frames >= 2880)
|
||||
frames = 2880;
|
||||
else if (frames >= 1920)
|
||||
frames = 1920;
|
||||
else if (frames >= 960)
|
||||
frames = 960;
|
||||
else if (frames >= 480)
|
||||
frames = 480;
|
||||
else if (frames >= 240)
|
||||
frames = 240;
|
||||
else if (frames >= 120)
|
||||
frames = 120;
|
||||
else
|
||||
{
|
||||
Con_Printf("invalid Opus frame size\n");
|
||||
frames = 0;
|
||||
}
|
||||
|
||||
nrate = snd_voip_bitrate.value * 1000;
|
||||
nrate = snd_voip_opus_bitrate.value;
|
||||
if (nrate != s_voip.curbitrate)
|
||||
{
|
||||
s_voip.curbitrate = nrate;
|
||||
if (nrate == 0)
|
||||
nrate = -1000;
|
||||
qopus_encoder_ctl(s_voip.encoder, OPUS_SET_BITRATE_REQUEST, (int)nrate);
|
||||
nrate = 10000;
|
||||
}
|
||||
|
||||
// Con_Printf("Encoding %i frames", frames);
|
||||
if (frames >= 2880)
|
||||
frames = 2880;
|
||||
else if (frames >= 1920 && nrate > 100)
|
||||
frames = 1920;
|
||||
else if (frames >= 960 && nrate > 500)
|
||||
frames = 960;
|
||||
else if (frames >= 480 && nrate > 1000)
|
||||
frames = 480;
|
||||
else if (snd_voip_send.ival & 4)
|
||||
break; //don't send small rtp packets, its abusive.
|
||||
else if (frames >= 240 && nrate > 2000)
|
||||
frames = 240;
|
||||
else if (frames >= 120 && nrate > 4000)
|
||||
frames = 120;
|
||||
else
|
||||
break; //invalid size, wait for more.
|
||||
|
||||
level += S_Voip_Preprocess(start, frames, micamp);
|
||||
len = qopus_encode(s_voip.encoder, start, frames, outbuf+outpos, sizeof(outbuf) - outpos);
|
||||
// Con_Printf(" (%i bytes)\n", len);
|
||||
if (len >= 0)
|
||||
{
|
||||
s_voip.encsequence += frames / s_voip.encframesize;
|
||||
|
@ -1301,9 +1298,11 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
|
|||
}
|
||||
}
|
||||
|
||||
if (outpos && (!buf || buf->maxsize - buf->cursize >= outpos+4))
|
||||
if (outpos)
|
||||
{
|
||||
if (buf && (snd_voip_send.ival != 4))
|
||||
if (buf && !(snd_voip_send.ival & 4))
|
||||
{
|
||||
if (buf->maxsize - buf->cursize >= 5+outpos)
|
||||
{
|
||||
MSG_WriteByte(buf, clc);
|
||||
MSG_WriteByte(buf, (s_voip.enccodec<<4) | (s_voip.generation & 0x0f)); /*gonna leave that nibble clear here... in this version, the client will ignore packets with those bits set. can use them for codec or something*/
|
||||
|
@ -1311,6 +1310,9 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
|
|||
MSG_WriteShort(buf, outpos);
|
||||
SZ_Write(buf, outbuf, outpos);
|
||||
}
|
||||
else
|
||||
Con_Printf("Audio frame too small %i vs %i\n", outpos+4, buf->maxsize - buf->cursize);
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_ICE
|
||||
if (rtpstream)
|
||||
|
@ -1379,6 +1381,7 @@ static void QDECL S_Voip_Play_Callback(cvar_t *var, char *oldval)
|
|||
}
|
||||
void S_Voip_MapChange(void)
|
||||
{
|
||||
voipbutton = false;
|
||||
Cvar_ForceCallback(&snd_voip_play);
|
||||
}
|
||||
int S_Voip_Loudness(qboolean ignorevad)
|
||||
|
@ -1417,6 +1420,7 @@ void S_Voip_Init(void)
|
|||
Cvar_Register(&snd_voip_codec, "Voice Chat");
|
||||
Cvar_Register(&snd_voip_noisefilter, "Voice Chat");
|
||||
Cvar_Register(&snd_voip_autogain, "Voice Chat");
|
||||
Cvar_Register(&snd_voip_opus_bitrate, "Voice Chat");
|
||||
Cmd_AddCommand("+voip", S_Voip_Enable_f);
|
||||
Cmd_AddCommand("-voip", S_Voip_Disable_f);
|
||||
Cmd_AddCommand("voip", S_Voip_f);
|
||||
|
|
|
@ -7217,7 +7217,6 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, size_t fsi
|
|||
oevent->code = fteevents->evcode;
|
||||
oevent->data = ZG_Malloc(&mod->memgroup, strlen(strings+fteevents->evdata_str)+1);
|
||||
strcpy(oevent->data, strings+fteevents->evdata_str);
|
||||
oevent->timestamp /= fgroup[fteevents->anim].rate;
|
||||
link = &fgroup[fteevents->anim].events;
|
||||
while (*link && (*link)->timestamp <= oevent->timestamp)
|
||||
link = &(*link)->next;
|
||||
|
|
Loading…
Reference in a new issue