From 984f3804cf4e4b2a497ba6110294e695906ebe4c Mon Sep 17 00:00:00 2001 From: jenz Date: Wed, 1 Jul 2026 21:18:11 +0100 Subject: [PATCH] added broadcastvoice data back but only for steam clients so that they can have voice_loopback 1 and hear their voices in demo --- extension.cpp | 71 +++++++++++++++++++-------------------------------- extension.h | 2 ++ 2 files changed, 28 insertions(+), 45 deletions(-) diff --git a/extension.cpp b/extension.cpp index d2d8a03..065da06 100644 --- a/extension.cpp +++ b/extension.cpp @@ -180,6 +180,8 @@ DETOUR_DECL_MEMBER1(ProcessVoiceData, bool, void *, msg) CLC_VoiceData *voiceMsg = (CLC_VoiceData *)msg; char voiceDataBuffer[4096]; + int startBit = voiceMsg->m_DataIn.GetNumBitsRead();//check where we start + int bitsRead = voiceMsg->m_DataIn.ReadBitsClamped(voiceDataBuffer, voiceMsg->m_nLength); int nBytes = Bits2Bytes(bitsRead); @@ -224,6 +226,7 @@ DETOUR_DECL_MEMBER1(ProcessVoiceData, bool, void *, msg) if (g_bClientMuted[i + 1][clientIndex]) continue; //smutils->LogMessage(myself, "in ProcessVoiceData before SendVoiceDataMsg"); + //send celt packets to all nosteamers SendVoiceDataMsg(playerSlot, pToClient, (unsigned char *)voiceDataBuffer, nBytes, voiceMsg->m_xuid); } } @@ -231,31 +234,36 @@ DETOUR_DECL_MEMBER1(ProcessVoiceData, bool, void *, msg) { //convert steam OPUS packet to CELT for no steam clients g_Interface.PushPlayerVoiceData(playerSlot, nBytes, voiceDataBuffer); - // Send steam Opus packet to Steam clients - int maxClients = iserver->GetClientCount(); - for (int i = 0; i < maxClients; i++) - { - IClient *pToClient = iserver->GetClient(i); - if (!pToClient || !pToClient->IsConnected() || !pToClient->IsActive() || pToClient->IsFakeClient()) - continue; - bool bSelf = (i == playerSlot); - - if (bSelf) - continue; - if (g_bIsNoSteam[i + 1]) - continue; - if (g_bClientMuted[i + 1][clientIndex]) - continue; - //smutils->LogMessage(myself, "in ProcessVoiceData before SendVoiceDataMsg"); - SendVoiceDataMsg(playerSlot, pToClient, (unsigned char *)voiceDataBuffer, nBytes, voiceMsg->m_xuid); - } + voiceMsg->m_DataIn.Seek(startBit);// rewind so the real engine can read the voice data as well. + //send opus packets from steam clients to actual broadcastvoice data. makes voices in demos work and voice_loopback 1 as well. + DETOUR_MEMBER_CALL(ProcessVoiceData)(msg); } return true; } +//re-introduced for the sake of voice_loopback 1 working and demos having voice chat again but only for steam clients. DETOUR_DECL_STATIC4(SV_BroadcastVoiceData, void, IClient *, pClient, int, nBytes, char *, data, int64, xuid) { + if(g_Interface.OnBroadcastVoiceData(pClient, nBytes, data)) + { + DETOUR_STATIC_CALL(SV_BroadcastVoiceData)(pClient, nBytes, data, xuid); + } +} + +bool CVoice::OnBroadcastVoiceData(IClient *pClient, int nBytes, char *data) +{ + // Reject empty packets + if(nBytes < 1) + return false; + + int client = pClient->GetPlayerSlot() + 1; + if (g_aFrameVoiceBytes[client] > NET_MAX_VOICE_BYTES_FRAME) + { + return false; + } + + return true; } double getTime() @@ -1474,33 +1482,6 @@ void CVoice::TranscodeNoSteamToSteam(int playerSlot, int nBytes, char *data) } } - - - - - - - - - - - /* - // Resample 22050 -> 24000 and push into ring buffer - const int STEP = 24000; - const int DIV = 22050; - - for (int i = 0; i < decoded; i++) - { - m_nosteamResampleAccum[playerSlot] += STEP; - while (m_nosteamResampleAccum[playerSlot] >= DIV) - { - m_nosteamResampleAccum[playerSlot] -= DIV; - int16_t sample = pcmBuf[i]; - if (m_nosteamOpusPCMBuffer[playerSlot].CurrentFree() > 0) - m_nosteamOpusPCMBuffer[playerSlot].Push(&sample, 1); - } - } - */ } void CVoice::HandleNoSteamVoiceData() diff --git a/extension.h b/extension.h index 3ddf537..3861c86 100644 --- a/extension.h +++ b/extension.h @@ -137,6 +137,7 @@ public: // IConCommandBaseAccessor public: CVoice(); void OnGameFrame(bool simulating); + bool OnBroadcastVoiceData(IClient *pClient, int nBytes, char *data); void ListenSocket(); void PushPlayerVoiceData(int playerSlot, int nBytes, char *data); @@ -218,6 +219,7 @@ private: void OnDataReceived(CClient *pClient, int16_t *pData, size_t Samples); void HandleVoiceDataTorchlight(); void HandleNoSteamVoiceData(); + void BroadcastVoiceData(IClient *pClient, int nBytes, unsigned char *pData); }; #endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_