diff options
Diffstat (limited to 'src/client/cl_parse.c')
-rw-r--r-- | src/client/cl_parse.c | 105 |
1 files changed, 51 insertions, 54 deletions
diff --git a/src/client/cl_parse.c b/src/client/cl_parse.c index a8b68ca5..4230c04f 100644 --- a/src/client/cl_parse.c +++ b/src/client/cl_parse.c @@ -35,7 +35,8 @@ char *svc_strings[256] = { "svc_download", "svc_snapshot", "svc_EOF", - "svc_voip", + "svc_voipSpeex", + "svc_voipOpus", }; void SHOWNET( msg_t *msg, char *s) { @@ -354,8 +355,8 @@ void CL_SystemInfoChanged( void ) { cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) ); #ifdef USE_VOIP - s = Info_ValueForKey( systemInfo, "sv_voip" ); - clc.voipEnabled = atoi(s); + s = Info_ValueForKey( systemInfo, "sv_voipProtocol" ); + clc.voipEnabled = !Q_stricmp(s, "opus"); #endif // don't set any vars when playing a demo @@ -674,13 +675,13 @@ static void CL_PlayVoip(int sender, int samplecnt, const byte *data, int flags) { if(flags & VOIP_DIRECT) { - S_RawSamples(sender + 1, samplecnt, clc.speexSampleRate, 2, 1, + S_RawSamples(sender + 1, samplecnt, 48000, 2, 1, data, clc.voipGain[sender], -1); } if(flags & VOIP_SPATIAL) { - S_RawSamples(sender + MAX_CLIENTS + 1, samplecnt, clc.speexSampleRate, 2, 1, + S_RawSamples(sender + MAX_CLIENTS + 1, samplecnt, 48000, 2, 1, data, 1.0f, sender); } } @@ -693,8 +694,8 @@ A VoIP message has been received from the server ===================== */ static -void CL_ParseVoip ( msg_t *msg ) { - static short decoded[4096]; // !!! FIXME: don't hardcode. +void CL_ParseVoip ( msg_t *msg, qboolean ignoreData ) { + static short decoded[VOIP_MAX_PACKET_SAMPLES*4]; // !!! FIXME: don't hard code const int sender = MSG_ReadShort(msg); const int generation = MSG_ReadByte(msg); @@ -702,7 +703,8 @@ void CL_ParseVoip ( msg_t *msg ) { const int frames = MSG_ReadByte(msg); const int packetsize = MSG_ReadShort(msg); const int flags = MSG_ReadBits(msg, VOIP_FLAGCNT); - char encoded[1024]; + unsigned char encoded[4000]; + int numSamples; int seqdiff; int written = 0; int i; @@ -732,14 +734,15 @@ void CL_ParseVoip ( msg_t *msg ) { return; // overlarge packet, bail. } - if (!clc.speexInitialized) { - MSG_ReadData(msg, encoded, packetsize); // skip payload. - return; // can't handle VoIP without libspeex! + MSG_ReadData(msg, encoded, packetsize); + + if (ignoreData) { + return; // just ignore legacy speex voip data + } else if (!clc.voipCodecInitialized) { + return; // can't handle VoIP without libopus! } else if (sender >= MAX_CLIENTS) { - MSG_ReadData(msg, encoded, packetsize); // skip payload. return; // bogus sender. } else if (CL_ShouldIgnoreVoipSender(sender)) { - MSG_ReadData(msg, encoded, packetsize); // skip payload. return; // Channel is muted, bail. } @@ -752,70 +755,59 @@ void CL_ParseVoip ( msg_t *msg ) { // This is a new "generation" ... a new recording started, reset the bits. if (generation != clc.voipIncomingGeneration[sender]) { Com_DPrintf("VoIP: new generation %d!\n", generation); - speex_bits_reset(&clc.speexDecoderBits[sender]); + opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE); clc.voipIncomingGeneration[sender] = generation; seqdiff = 0; } else if (seqdiff < 0) { // we're ahead of the sequence?! // This shouldn't happen unless the packet is corrupted or something. Com_DPrintf("VoIP: misordered sequence! %d < %d!\n", sequence, clc.voipIncomingSequence[sender]); - // reset the bits just in case. - speex_bits_reset(&clc.speexDecoderBits[sender]); + // reset the decoder just in case. + opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE); seqdiff = 0; - } else if (seqdiff * clc.speexFrameSize * 2 >= sizeof (decoded)) { // dropped more than we can handle? + } else if (seqdiff * VOIP_MAX_PACKET_SAMPLES*2 >= sizeof (decoded)) { // dropped more than we can handle? // just start over. Com_DPrintf("VoIP: Dropped way too many (%d) frames from client #%d\n", seqdiff, sender); - speex_bits_reset(&clc.speexDecoderBits[sender]); + opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE); seqdiff = 0; } if (seqdiff != 0) { Com_DPrintf("VoIP: Dropped %d frames from client #%d\n", seqdiff, sender); - // tell speex that we're missing frames... + // tell opus that we're missing frames... for (i = 0; i < seqdiff; i++) { - assert((written + clc.speexFrameSize) * 2 < sizeof (decoded)); - speex_decode_int(clc.speexDecoder[sender], NULL, decoded + written); - written += clc.speexFrameSize; + assert((written + VOIP_MAX_PACKET_SAMPLES) * 2 < sizeof (decoded)); + numSamples = opus_decode(clc.opusDecoder[sender], NULL, VOIP_MAX_PACKET_SAMPLES * 2, decoded + written, sizeof (decoded) - written, 0); + if ( numSamples <= 0 ) { + Com_DPrintf("VoIP: Error decoding frame %d from client #%d\n", i, sender); + continue; + } + written += numSamples; } } - for (i = 0; i < frames; i++) { - const int len = MSG_ReadByte(msg); - if (len < 0) { - Com_DPrintf("VoIP: Short packet!\n"); - break; - } - MSG_ReadData(msg, encoded, len); + numSamples = opus_decode(clc.opusDecoder[sender], encoded, packetsize, decoded + written, sizeof (decoded) - written, 0); - // shouldn't happen, but just in case... - if ((written + clc.speexFrameSize) * 2 > sizeof (decoded)) { - Com_DPrintf("VoIP: playback %d bytes, %d samples, %d frames\n", - written * 2, written, i); - - CL_PlayVoip(sender, written, (const byte *) decoded, flags); - written = 0; - } - - speex_bits_read_from(&clc.speexDecoderBits[sender], encoded, len); - speex_decode_int(clc.speexDecoder[sender], - &clc.speexDecoderBits[sender], decoded + written); + if ( numSamples <= 0 ) { + Com_DPrintf("VoIP: Error decoding voip data from client #%d\n", sender); + numSamples = 0; + } - #if 0 - static FILE *encio = NULL; - if (encio == NULL) encio = fopen("voip-incoming-encoded.bin", "wb"); - if (encio != NULL) { fwrite(encoded, len, 1, encio); fflush(encio); } - static FILE *decio = NULL; - if (decio == NULL) decio = fopen("voip-incoming-decoded.bin", "wb"); - if (decio != NULL) { fwrite(decoded+written, clc.speexFrameSize*2, 1, decio); fflush(decio); } - #endif + #if 0 + static FILE *encio = NULL; + if (encio == NULL) encio = fopen("voip-incoming-encoded.bin", "wb"); + if (encio != NULL) { fwrite(encoded, len, 1, encio); fflush(encio); } + static FILE *decio = NULL; + if (decio == NULL) decio = fopen("voip-incoming-decoded.bin", "wb"); + if (decio != NULL) { fwrite(decoded+written, clc.speexFrameSize*2, 1, decio); fflush(decio); } + #endif - written += clc.speexFrameSize; - } + written += numSamples; Com_DPrintf("VoIP: playback %d bytes, %d samples, %d frames\n", - written * 2, written, i); + written * 2, written, frames); if(written > 0) CL_PlayVoip(sender, written, (const byte *) decoded, flags); @@ -918,9 +910,14 @@ void CL_ParseServerMessage( msg_t *msg ) { case svc_download: CL_ParseDownload( msg ); break; - case svc_voip: + case svc_voipSpeex: +#ifdef USE_VOIP + CL_ParseVoip( msg, qtrue ); +#endif + break; + case svc_voipOpus: #ifdef USE_VOIP - CL_ParseVoip( msg ); + CL_ParseVoip( msg, !clc.voipEnabled ); #endif break; } |