Use Opus for VoIP

Server/client VoIP protocol is handled by adding new cvars
cl_voipProtocol and sv_voipProtocol, sv_voip and cl_voip
are used to auto set/clear them. All users need to touch
are cl/sv_voip as 0 or 1 just like before.

Old Speex VoIP packets in demos are skipped.
New VoIP packets are skipped in demos if sv_voipProtocol
doesn't match cl_voipProtocol.

Notable difference between usage of speex and opus codecs,
when using Speex client would be sent 80ms at a time.
Using Opus, 60ms is sent at a time. This was changed because
the Opus codec supports encoding up to 60ms at a time.
(Simpler to send only one codec frame in a packet.)
This commit is contained in:
Zack Middleton 2013-12-10 21:14:13 -06:00
parent fe619680f8
commit 615b73288f
13 changed files with 167 additions and 240 deletions

View file

@ -905,37 +905,27 @@ void CL_FirstSnapshot( void ) {
#endif
#ifdef USE_VOIP
if (!clc.speexInitialized) {
if (!clc.voipCodecInitialized) {
int i;
speex_bits_init(&clc.speexEncoderBits);
speex_bits_reset(&clc.speexEncoderBits);
int error;
clc.speexEncoder = speex_encoder_init(&speex_nb_mode);
clc.opusEncoder = opus_encoder_create(48000, 1, OPUS_APPLICATION_VOIP, &error);
speex_encoder_ctl(clc.speexEncoder, SPEEX_GET_FRAME_SIZE,
&clc.speexFrameSize);
speex_encoder_ctl(clc.speexEncoder, SPEEX_GET_SAMPLING_RATE,
&clc.speexSampleRate);
clc.speexPreprocessor = speex_preprocess_state_init(clc.speexFrameSize,
clc.speexSampleRate);
i = 1;
speex_preprocess_ctl(clc.speexPreprocessor,
SPEEX_PREPROCESS_SET_DENOISE, &i);
i = 1;
speex_preprocess_ctl(clc.speexPreprocessor,
SPEEX_PREPROCESS_SET_AGC, &i);
if ( error ) {
Com_DPrintf("VoIP: Error opus_encoder_create %d\n", error);
return;
}
for (i = 0; i < MAX_CLIENTS; i++) {
speex_bits_init(&clc.speexDecoderBits[i]);
speex_bits_reset(&clc.speexDecoderBits[i]);
clc.speexDecoder[i] = speex_decoder_init(&speex_nb_mode);
clc.opusDecoder[i] = opus_decoder_create(48000, 1, &error);
if ( error ) {
Com_DPrintf("VoIP: Error opus_decoder_create(%d) %d\n", i, error);
return;
}
clc.voipIgnore[i] = qfalse;
clc.voipGain[i] = 1.0f;
}
clc.speexInitialized = qtrue;
clc.voipCodecInitialized = qtrue;
clc.voipMuteAll = qfalse;
Cmd_AddCommand ("voip", CL_Voip_f);
Cvar_Set("cl_voipSendTarget", "spatial");