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
This commit is contained in:
BotoX 2021-04-30 11:24:56 +02:00
parent c4f5affecd
commit d5d32ed86d
2 changed files with 42 additions and 1 deletions

View File

@ -312,6 +312,12 @@ const sp_nativeinfo_t MyNatives[] =
{ NULL, NULL } { NULL, NULL }
}; };
static void ListenSocketAction(void *pData)
{
CVoice *pThis = (CVoice *)pData;
pThis->ListenSocket();
}
void CVoice::SDK_OnAllLoaded() void CVoice::SDK_OnAllLoaded()
{ {
sharesys->AddNatives(myself, MyNatives); sharesys->AddNatives(myself, MyNatives);
@ -350,9 +356,19 @@ void CVoice::SDK_OnAllLoaded()
return; return;
} }
// This doesn't seem to work right away ...
engine->ServerCommand("exec sourcemod/extension.Voice.cfg\n"); engine->ServerCommand("exec sourcemod/extension.Voice.cfg\n");
engine->ServerExecute(); engine->ServerExecute();
// ... delay starting listen server to next frame
smutils->AddFrameAction(ListenSocketAction, this);
}
void CVoice::ListenSocket()
{
if(m_PollFds > 0)
return;
sockaddr_in bindAddr; sockaddr_in bindAddr;
memset(&bindAddr, 0, sizeof(bindAddr)); memset(&bindAddr, 0, sizeof(bindAddr));
bindAddr.sin_family = AF_INET; bindAddr.sin_family = AF_INET;
@ -475,6 +491,7 @@ void CVoice::HandleNetwork()
m_aClients[Client].m_LastLength = 0; m_aClients[Client].m_LastLength = 0;
m_aClients[Client].m_LastValidData = 0.0; m_aClients[Client].m_LastValidData = 0.0;
m_aClients[Client].m_New = true; m_aClients[Client].m_New = true;
m_aClients[Client].m_UnEven = false;
m_aPollFds[m_PollFds].fd = Socket; m_aPollFds[m_PollFds].fd = Socket;
m_aPollFds[m_PollFds].events = POLLIN | POLLHUP; 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)) if(min(BytesAvailable, sizeof(aBuf)) > m_Buffer.CurrentFree() * sizeof(int16_t))
continue; 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) if(Bytes <= 0)
{ {
@ -544,6 +570,17 @@ void CVoice::HandleNetwork()
continue; 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! // Got data!
OnDataReceived(pClient, (int16_t *)aBuf, Bytes / sizeof(int16_t)); OnDataReceived(pClient, (int16_t *)aBuf, Bytes / sizeof(int16_t));

View File

@ -139,6 +139,8 @@ public:
void OnGameFrame(bool simulating); void OnGameFrame(bool simulating);
bool OnBroadcastVoiceData(IClient *pClient, int nBytes, char *data); bool OnBroadcastVoiceData(IClient *pClient, int nBytes, char *data);
void ListenSocket();
private: private:
int m_ListenSocket; int m_ListenSocket;
@ -149,6 +151,8 @@ private:
size_t m_LastLength; size_t m_LastLength;
double m_LastValidData; double m_LastValidData;
bool m_New; bool m_New;
bool m_UnEven;
unsigned char m_Remainder;
} m_aClients[MAX_CLIENTS]; } m_aClients[MAX_CLIENTS];
struct pollfd m_aPollFds[1 + MAX_CLIENTS]; struct pollfd m_aPollFds[1 + MAX_CLIENTS];