Skip to content

Commit 63b91ff

Browse files
committed
Improve internal buffer management for voice packets
1 parent bd7f4c3 commit 63b91ff

File tree

8 files changed

+58
-130
lines changed

8 files changed

+58
-130
lines changed

Client/mods/deathmatch/CVoiceRecorder.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ void CVoiceRecorder::Init(bool bEnabled, unsigned int uiServerSampleRate, unsign
101101
if (iBitRate)
102102
speex_encoder_ctl(m_pSpeexEncoderState, SPEEX_SET_BITRATE, &iBitRate);
103103

104-
m_pOutgoingBuffer = (char*)malloc(m_uiBufferSizeBytes * FRAME_OUTGOING_BUFFER_COUNT);
104+
m_pOutgoingBuffer = (unsigned char*)malloc(m_uiBufferSizeBytes * FRAME_OUTGOING_BUFFER_COUNT);
105105
m_uiOutgoingReadIndex = 0;
106106
m_uiOutgoingWriteIndex = 0;
107107

@@ -247,9 +247,9 @@ void CVoiceRecorder::DoPulse()
247247
{
248248
std::lock_guard<std::mutex> lock(m_Mutex);
249249

250-
char* pInputBuffer;
251-
char bufTempOutput[2048];
252-
unsigned int uiTotalBufferSize = m_uiBufferSizeBytes * FRAME_OUTGOING_BUFFER_COUNT;
250+
unsigned char* pInputBuffer;
251+
unsigned char audioBuffer[2048]{};
252+
unsigned int uiTotalBufferSize = m_uiBufferSizeBytes * FRAME_OUTGOING_BUFFER_COUNT;
253253

254254
// Only send every 100 ms
255255
if (CClientTime::GetTime() - m_ulTimeOfLastSend > 100 && m_VoiceState != VOICESTATE_AWAITING_INPUT)
@@ -280,8 +280,8 @@ void CVoiceRecorder::DoPulse()
280280
{
281281
unsigned t;
282282
for (t = 0; t < uiSpeexBlockSize; t++)
283-
bufTempOutput[t] = m_pOutgoingBuffer[t % uiTotalBufferSize];
284-
pInputBuffer = bufTempOutput;
283+
audioBuffer[t] = m_pOutgoingBuffer[t % uiTotalBufferSize];
284+
pInputBuffer = audioBuffer;
285285
}
286286
else
287287
pInputBuffer = m_pOutgoingBuffer + m_uiOutgoingReadIndex;
@@ -296,9 +296,9 @@ void CVoiceRecorder::DoPulse()
296296

297297
m_bIsSendingVoiceData = true;
298298

299-
unsigned int uiBytesWritten = speex_bits_write(&speexBits, bufTempOutput, 2048);
299+
unsigned int audioBufferLength = speex_bits_write(&speexBits, reinterpret_cast<char*>(audioBuffer), 2048);
300300

301-
g_pClientGame->GetLocalPlayer()->GetVoice()->DecodeAndBuffer(bufTempOutput, uiBytesWritten);
301+
g_pClientGame->GetLocalPlayer()->GetVoice()->DecodeAndBuffer(audioBuffer, audioBufferLength);
302302

303303
NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream();
304304
if (pBitStream)
@@ -307,8 +307,8 @@ void CVoiceRecorder::DoPulse()
307307

308308
if (pLocalPlayer)
309309
{
310-
pBitStream->Write((unsigned short)uiBytesWritten); // size of buffer / voice data
311-
pBitStream->Write((char*)bufTempOutput, uiBytesWritten); // voice data
310+
pBitStream->Write((unsigned short)audioBufferLength);
311+
pBitStream->Write(reinterpret_cast<char*>(audioBuffer), audioBufferLength);
312312

313313
g_pNet->SendPacket(PACKET_ID_VOICE_DATA, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_UNRELIABLE_SEQUENCED,
314314
PACKET_ORDERING_VOICE);

Client/mods/deathmatch/CVoiceRecorder.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,11 @@ class CVoiceRecorder
7979
void* m_pSpeexEncoderState;
8080
SpeexPreprocessState* m_pSpeexPreprocState;
8181

82-
char* m_pOutgoingBuffer;
83-
int m_iSpeexOutgoingFrameSampleCount;
84-
unsigned int m_uiOutgoingReadIndex;
85-
unsigned int m_uiOutgoingWriteIndex;
86-
bool m_bIsSendingVoiceData;
82+
unsigned char* m_pOutgoingBuffer;
83+
int m_iSpeexOutgoingFrameSampleCount;
84+
unsigned int m_uiOutgoingReadIndex;
85+
unsigned int m_uiOutgoingWriteIndex;
86+
bool m_bIsSendingVoiceData;
8787

8888
unsigned long m_ulTimeOfLastSend;
8989

Client/mods/deathmatch/logic/CClientPlayerVoice.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,11 @@ void CClientPlayerVoice::DoPulse()
118118
}
119119
}
120120

121-
void CClientPlayerVoice::DecodeAndBuffer(char* pBuffer, unsigned int bytesWritten)
121+
void CClientPlayerVoice::DecodeAndBuffer(const unsigned char* voiceBuffer, unsigned int voiceBufferLength)
122122
{
123+
if (!voiceBuffer || !voiceBufferLength || voiceBufferLength > 2048)
124+
return;
125+
123126
m_Mutex.lock();
124127

125128
if (!m_bVoiceActive)
@@ -143,7 +146,7 @@ void CClientPlayerVoice::DecodeAndBuffer(char* pBuffer, unsigned int bytesWritte
143146
SpeexBits speexBits;
144147
speex_bits_init(&speexBits);
145148

146-
speex_bits_read_from(&speexBits, (char*)(pBuffer), bytesWritten);
149+
speex_bits_read_from(&speexBits, reinterpret_cast<const char*>(voiceBuffer), voiceBufferLength);
147150
speex_decode_int(m_pSpeexDecoderState, &speexBits, (spx_int16_t*)pTempBuffer);
148151

149152
speex_bits_destroy(&speexBits);

Client/mods/deathmatch/logic/CClientPlayerVoice.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class CClientPlayerVoice
2828
ZERO_ON_NEW
2929
CClientPlayerVoice(CClientPlayer* pPlayer, CVoiceRecorder* pVoiceRecorder);
3030
~CClientPlayerVoice();
31-
void DecodeAndBuffer(char* pBuffer, unsigned int bytesWritten);
31+
void DecodeAndBuffer(const unsigned char* voiceBuffer, unsigned int voiceBufferLength);
3232
void DoPulse();
3333

3434
bool m_bVoiceActive;

Client/mods/deathmatch/logic/CPacketHandler.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5403,24 +5403,26 @@ void CPacketHandler::Packet_DestroySatchels(NetBitStreamInterface& bitStream)
54035403

54045404
void CPacketHandler::Packet_VoiceData(NetBitStreamInterface& bitStream)
54055405
{
5406-
unsigned short usPacketSize;
5406+
unsigned short voiceBufferLength;
54075407
ElementID PlayerID;
5408+
54085409
if (bitStream.Read(PlayerID))
54095410
{
54105411
CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->Get(PlayerID);
5411-
if (pPlayer && bitStream.Read(usPacketSize))
5412+
5413+
if (pPlayer && bitStream.Read(voiceBufferLength) && voiceBufferLength <= 2048)
54125414
{
5413-
char* pBuf = new char[usPacketSize];
5415+
const auto voiceBuffer = new unsigned char[voiceBufferLength];
54145416

5415-
if (bitStream.Read(pBuf, usPacketSize))
5417+
if (bitStream.Read(reinterpret_cast<char*>(voiceBuffer), voiceBufferLength))
54165418
{
54175419
if (pPlayer->GetVoice())
54185420
{
5419-
pPlayer->GetVoice()->DecodeAndBuffer(pBuf, usPacketSize);
5421+
pPlayer->GetVoice()->DecodeAndBuffer(voiceBuffer, voiceBufferLength);
54205422
}
54215423
}
54225424

5423-
delete[] pBuf;
5425+
delete[] voiceBuffer;
54245426
}
54255427
}
54265428
}

Server/mods/deathmatch/logic/CGame.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3859,9 +3859,7 @@ void CGame::Packet_Voice_Data(CVoiceDataPacket& Packet)
38593859

38603860
if (m_pMainConfig->IsVoiceEnabled()) // Shouldn't really be receiving voice packets at all if voice is disabled
38613861
{
3862-
usDataLength = Packet.GetDataLength();
3863-
3864-
if (usDataLength > 0)
3862+
if (!Packet.IsEmpty())
38653863
{
38663864
CPlayer* pPlayer = Packet.GetSourcePlayer();
38673865

@@ -3890,9 +3888,6 @@ void CGame::Packet_Voice_Data(CVoiceDataPacket& Packet)
38903888
if (pPlayer->GetVoiceState() ==
38913889
VOICESTATE_TRANSMITTING) // If we reach here, and we're still in idle state, then the event was cancelled
38923890
{
3893-
const unsigned char* pBuffer = Packet.GetData();
3894-
CVoiceDataPacket VoicePacket(pPlayer, pBuffer, usDataLength);
3895-
38963891
// Make list of players to send the voice packet to
38973892
std::set<CPlayer*> playerSendMap;
38983893

@@ -3935,7 +3930,7 @@ void CGame::Packet_Voice_Data(CVoiceDataPacket& Packet)
39353930
}
39363931

39373932
// Send to all players in the send list
3938-
CPlayerManager::Broadcast(VoicePacket, playerSendMap);
3933+
CPlayerManager::Broadcast(Packet, playerSendMap);
39393934
}
39403935
}
39413936
}
Lines changed: 21 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*****************************************************************************
22
*
3-
* PROJECT: Multi Theft Auto v1.0
3+
* PROJECT: Multi Theft Auto
44
* LICENSE: See LICENSE in the top level directory
55
* FILE: mods/deathmatch/logic/packets/CVoiceDataPacket.cpp
66
* PURPOSE: Voice data packet class
77
*
8-
* Multi Theft Auto is available from https://www.multitheftauto.com/
8+
* Multi Theft Auto is available from https://multitheftauto.com/
99
*
1010
*****************************************************************************/
1111

@@ -15,112 +15,47 @@
1515

1616
CVoiceDataPacket::CVoiceDataPacket()
1717
{
18-
m_pBuffer = NULL;
19-
m_usDataBufferSize = 0;
20-
m_usActualDataLength = 0;
21-
22-
AllocateBuffer(1024);
23-
}
24-
25-
CVoiceDataPacket::CVoiceDataPacket(CPlayer* pPlayer, const unsigned char* pbSrcBuffer, unsigned short usLength)
26-
{
27-
m_pBuffer = NULL;
28-
m_usDataBufferSize = 0;
29-
m_usActualDataLength = 0;
30-
31-
SetSourceElement(pPlayer);
32-
SetData(pbSrcBuffer, usLength);
33-
}
34-
CVoiceDataPacket::~CVoiceDataPacket()
35-
{
36-
DeallocateBuffer();
18+
m_voiceBuffer.reserve(2048);
3719
}
3820

3921
bool CVoiceDataPacket::Read(NetBitStreamInterface& BitStream)
4022
{
41-
if (m_pBuffer)
23+
unsigned short voiceBufferLength{};
24+
25+
if (BitStream.Read(voiceBufferLength) && voiceBufferLength <= m_voiceBuffer.capacity())
4226
{
43-
BitStream.Read(m_usActualDataLength);
44-
if (m_usActualDataLength)
45-
{
46-
BitStream.Read(reinterpret_cast<char*>(m_pBuffer), m_usActualDataLength <= m_usDataBufferSize ? m_usActualDataLength : m_usDataBufferSize);
47-
}
48-
return true;
27+
m_voiceBuffer.resize(voiceBufferLength);
28+
return BitStream.Read(reinterpret_cast<char*>(m_voiceBuffer.data()), m_voiceBuffer.size());
4929
}
5030

5131
return false;
5232
}
5333

5434
bool CVoiceDataPacket::Write(NetBitStreamInterface& BitStream) const
5535
{
56-
if (m_usActualDataLength)
36+
if (!m_voiceBuffer.empty())
5737
{
38+
const auto voiceBuffer = reinterpret_cast<const char*>(m_voiceBuffer.data());
39+
const auto voiceBufferLength = static_cast<uint16_t>(m_voiceBuffer.size());
40+
5841
// Write the source player
59-
ElementID ID = m_pSourceElement->GetID();
60-
BitStream.Write(ID);
42+
BitStream.Write(m_pSourceElement->GetID());
6143
// Write the length as an unsigned short and then write the string
62-
BitStream.Write(m_usActualDataLength);
63-
BitStream.Write(reinterpret_cast<const char*>(m_pBuffer), m_usActualDataLength);
44+
BitStream.Write(voiceBufferLength);
45+
BitStream.Write(voiceBuffer, voiceBufferLength);
6446
return true;
6547
}
6648

6749
return false;
6850
}
6951

70-
void CVoiceDataPacket::AllocateBuffer(unsigned short usBufferSize)
71-
{
72-
// Test to see if we already have an allocated buffer
73-
// that will hold the requested size.
74-
if (m_usDataBufferSize < usBufferSize)
75-
{
76-
// It's not... resize the buffer.
77-
if (m_pBuffer)
78-
{
79-
// Free the current buffer.
80-
delete[] m_pBuffer;
81-
}
82-
83-
// Allocate new buffer.
84-
m_pBuffer = new unsigned char[usBufferSize];
85-
86-
// Clear buffer.
87-
memset(m_pBuffer, 0, usBufferSize);
88-
89-
// Save the new size.
90-
m_usDataBufferSize = usBufferSize;
91-
}
92-
}
93-
94-
void CVoiceDataPacket::DeallocateBuffer()
52+
void CVoiceDataPacket::SetVoiceData(const unsigned char* voiceBuffer, unsigned short voiceBufferLength)
9553
{
96-
if (m_pBuffer)
97-
{
98-
delete[] m_pBuffer;
99-
m_pBuffer = NULL;
100-
m_usDataBufferSize = 0;
101-
m_usActualDataLength = 0;
102-
}
103-
}
54+
m_voiceBuffer.clear();
10455

105-
void CVoiceDataPacket::SetData(const unsigned char* pbSrcBuffer, unsigned short usLength)
106-
{
107-
// Allocate new buffer.
108-
AllocateBuffer(usLength);
56+
if (!voiceBuffer || !voiceBufferLength || voiceBufferLength > m_voiceBuffer.capacity())
57+
return;
10958

110-
// Copy in the data.
111-
if (m_pBuffer)
112-
{
113-
memcpy(m_pBuffer, pbSrcBuffer, usLength);
114-
m_usActualDataLength = usLength;
115-
}
116-
}
117-
118-
const unsigned char* CVoiceDataPacket::GetData() const
119-
{
120-
return m_pBuffer;
121-
}
122-
123-
unsigned short CVoiceDataPacket::GetDataLength() const
124-
{
125-
return m_usActualDataLength;
59+
m_voiceBuffer.resize(voiceBufferLength);
60+
std::copy_n(voiceBuffer, voiceBufferLength, m_voiceBuffer.data());
12661
}
Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
/*****************************************************************************
22
*
3-
* PROJECT: Multi Theft Auto v1.0
3+
* PROJECT: Multi Theft Auto
44
* LICENSE: See LICENSE in the top level directory
55
* FILE: mods/deathmatch/logic/packets/CVoiceDataPacket.h
66
* PURPOSE: Voice data packet class
77
*
8-
* Multi Theft Auto is available from https://www.multitheftauto.com/
8+
* Multi Theft Auto is available from https://multitheftauto.com/
99
*
1010
*****************************************************************************/
1111

1212
#pragma once
1313

1414
#include "CPacket.h"
15+
#include <vector>
1516

1617
class CVoiceDataPacket final : public CPacket
1718
{
1819
public:
19-
CVoiceDataPacket(CPlayer* pPlayer, const unsigned char* pbSrcBuffer, unsigned short usLength);
2020
CVoiceDataPacket();
21-
~CVoiceDataPacket();
2221

2322
ePacketID GetPacketID() const { return PACKET_ID_VOICE_DATA; }
2423
unsigned long GetFlags() const { return PACKET_LOW_PRIORITY | PACKET_SEQUENCED; };
@@ -27,16 +26,10 @@ class CVoiceDataPacket final : public CPacket
2726
bool Read(NetBitStreamInterface& BitStream);
2827
bool Write(NetBitStreamInterface& BitStream) const;
2928

30-
void SetData(const unsigned char* pbSrcBuffer, unsigned short usLength);
29+
void SetVoiceData(const unsigned char* voiceBuffer, unsigned short voiceBufferLength);
3130

32-
unsigned short GetDataLength() const;
33-
const unsigned char* GetData() const;
31+
bool IsEmpty() const noexcept { return m_voiceBuffer.empty(); }
3432

3533
private:
36-
void AllocateBuffer(unsigned short usBufferSize);
37-
void DeallocateBuffer();
38-
39-
unsigned char* m_pBuffer;
40-
unsigned short m_usDataBufferSize;
41-
unsigned short m_usActualDataLength;
34+
std::vector<unsigned char> m_voiceBuffer;
4235
};

0 commit comments

Comments
 (0)