From d5d32ed86da38ed6716e45816b79e4bbea88b3db Mon Sep 17 00:00:00 2001 From: BotoX Date: Fri, 30 Apr 2021 11:24:56 +0200 Subject: [PATCH] Fix sound corruption issue (random static noise caused by uneven bytes recv'd - how did this only become an issue after 4 years?) Fix loading sm_voice_* cvar from config --- extension.cpp | 39 ++++++++++++++++++++++++++++++++++++++- extension.h | 4 ++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/extension.cpp b/extension.cpp index 766517b..e6f5fad 100644 --- a/extension.cpp +++ b/extension.cpp @@ -312,6 +312,12 @@ const sp_nativeinfo_t MyNatives[] = { NULL, NULL } }; +static void ListenSocketAction(void *pData) +{ + CVoice *pThis = (CVoice *)pData; + pThis->ListenSocket(); +} + void CVoice::SDK_OnAllLoaded() { sharesys->AddNatives(myself, MyNatives); @@ -350,9 +356,19 @@ void CVoice::SDK_OnAllLoaded() return; } + // This doesn't seem to work right away ... engine->ServerCommand("exec sourcemod/extension.Voice.cfg\n"); engine->ServerExecute(); + // ... delay starting listen server to next frame + smutils->AddFrameAction(ListenSocketAction, this); +} + +void CVoice::ListenSocket() +{ + if(m_PollFds > 0) + return; + sockaddr_in bindAddr; memset(&bindAddr, 0, sizeof(bindAddr)); bindAddr.sin_family = AF_INET; @@ -475,6 +491,7 @@ void CVoice::HandleNetwork() m_aClients[Client].m_LastLength = 0; m_aClients[Client].m_LastValidData = 0.0; m_aClients[Client].m_New = true; + m_aClients[Client].m_UnEven = false; m_aPollFds[m_PollFds].fd = Socket; m_aPollFds[m_PollFds].events = POLLIN | POLLHUP; @@ -532,7 +549,16 @@ void CVoice::HandleNetwork() if(min(BytesAvailable, sizeof(aBuf)) > m_Buffer.CurrentFree() * sizeof(int16_t)) continue; - ssize_t Bytes = recv(pClient->m_Socket, aBuf, sizeof(aBuf), 0); + // Edge case: previously received data is uneven and last recv'd byte has to be prepended + int Shift = 0; + if(pClient->m_UnEven) + { + Shift = 1; + aBuf[0] = pClient->m_Remainder; + pClient->m_UnEven = false; + } + + ssize_t Bytes = recv(pClient->m_Socket, &aBuf[Shift], sizeof(aBuf) - Shift, 0); if(Bytes <= 0) { @@ -544,6 +570,17 @@ void CVoice::HandleNetwork() continue; } + Bytes += Shift; + + // Edge case: data received is uneven (can't be divided by two) + // store last byte, drop it here and prepend it right before the next recv + if(Bytes & 1) + { + pClient->m_UnEven = true; + pClient->m_Remainder = aBuf[Bytes - 1]; + Bytes -= 1; + } + // Got data! OnDataReceived(pClient, (int16_t *)aBuf, Bytes / sizeof(int16_t)); diff --git a/extension.h b/extension.h index 1c63fb2..492bc23 100644 --- a/extension.h +++ b/extension.h @@ -139,6 +139,8 @@ public: void OnGameFrame(bool simulating); bool OnBroadcastVoiceData(IClient *pClient, int nBytes, char *data); + void ListenSocket(); + private: int m_ListenSocket; @@ -149,6 +151,8 @@ private: size_t m_LastLength; double m_LastValidData; bool m_New; + bool m_UnEven; + unsigned char m_Remainder; } m_aClients[MAX_CLIENTS]; struct pollfd m_aPollFds[1 + MAX_CLIENTS];