From 5106ebae58685f4b1e4e64e4f3778177135d4b6b Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Wed, 3 Sep 2025 03:40:15 +0500 Subject: [PATCH] engine: voice: fix local player server ack'ed message --- engine/client/cl_parse.c | 8 ++++++-- engine/client/voice.c | 20 ++++++++++++++++---- engine/client/voice.h | 1 + 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index ac31fb2f..54a69a81 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -2018,10 +2018,14 @@ void CL_ParseVoiceData( sizebuf_t *msg, connprotocol_t proto ) if ( idx <= 0 || idx > cl.maxclients ) return; + // must notify client.dll about server ack'ing our local client voice data + if( idx == cl.playernum + 1 ) + Voice_LoopbackAck(); + if( proto == PROTO_GOLDSRC ) { size = MSG_ReadShort( msg ); - if ( size > VOICE_MAX_GS_DATA_SIZE ) + if( size > VOICE_MAX_GS_DATA_SIZE ) { Con_Printf( S_ERROR "Voice data size is too large: %d bytes (max: %d)\n", size, VOICE_MAX_GS_DATA_SIZE ); return; @@ -2031,7 +2035,7 @@ void CL_ParseVoiceData( sizebuf_t *msg, connprotocol_t proto ) { frames = MSG_ReadByte( msg ); size = MSG_ReadShort( msg ); - if (size > VOICE_MAX_DATA_SIZE ) + if( size > VOICE_MAX_DATA_SIZE ) { Con_Printf( S_ERROR "Voice data size is too large: %d bytes (max: %d)\n", size, VOICE_MAX_DATA_SIZE ); return; diff --git a/engine/client/voice.c b/engine/client/voice.c index 6ea7c015..72dda998 100644 --- a/engine/client/voice.c +++ b/engine/client/voice.c @@ -971,6 +971,18 @@ void Voice_StartChannel( uint samples, byte *data, int entnum ) ========================= Voice_AddIncomingData +Received encoded voice data, decode it +========================= +*/ +void Voice_LoopbackAck( void ) +{ + Voice_StatusAck( &voice.local, VOICE_LOOPBACK_INDEX ); +} + +/* +========================= +Voice_AddIncomingData + Received encoded voice data, decode it ========================= */ @@ -984,10 +996,6 @@ void Voice_AddIncomingData( int ent, const byte *data, uint size, uint frames ) if( !voice.initialized || !voice_enable.value ) return; - // must notify through as both local player and normal client - if( playernum == cl.playernum ) - Voice_StatusAck( &voice.local, VOICE_LOOPBACK_INDEX ); - status = Voice_GetPlayerStatus( ent ); Voice_StatusAck( status, ent ); @@ -1173,6 +1181,10 @@ void Voice_Idle( double frametime ) for( i = 1; i <= MAX_CLIENTS; i++ ) { voice_status_t *status = Voice_GetPlayerStatus( i ); + + // TODO: replace timeout logic with mixer channels. If mixer started playing back this player's + // voice channel, we must call VoiceStatus( true ) here and when it's done playing back, call VoiceStatus( false ) + // Also, when it's done remove StatusAck from Voice_AddIncomingData! Voice_StatusTimeout( status, i, frametime ); } } diff --git a/engine/client/voice.h b/engine/client/voice.h index 5668009b..1725d7c0 100644 --- a/engine/client/voice.h +++ b/engine/client/voice.h @@ -132,5 +132,6 @@ void Voice_Disconnect( void ); void Voice_AddIncomingData( int ent, const byte *data, uint size, uint frames ); void Voice_StatusAck( voice_status_t *status, int playerIndex ); void Voice_StartChannel( uint samples, byte *data, int entnum ); +void Voice_LoopbackAck( void ); // sends -2 to client, gets disabled on timeout #endif // VOICE_H