summaryrefslogtreecommitdiff
path: root/src/client/cl_parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/cl_parse.c')
-rw-r--r--src/client/cl_parse.c105
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;
}