further changes should probably be considered safed by now, switched to 2 channels, added reset state and lowered framepackets from 5 to 2
This commit is contained in:
parent
fa34037aa4
commit
b987a8207d
@ -300,20 +300,20 @@ bool CVoice::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
|||||||
|
|
||||||
//opus edit
|
//opus edit
|
||||||
int err;
|
int err;
|
||||||
m_OpusEncoder = opus_encoder_create(48000, 1, OPUS_APPLICATION_AUDIO, &err);
|
//m_OpusEncoder = opus_encoder_create(24000, 2, OPUS_APPLICATION_AUDIO, &err);
|
||||||
|
m_OpusEncoder = opus_encoder_create(48000, 2, OPUS_APPLICATION_AUDIO, &err);
|
||||||
if (err<0)
|
if (err<0)
|
||||||
{
|
{
|
||||||
smutils->LogError(myself, "failed to create encode: %s", opus_strerror(err));
|
smutils->LogError(myself, "failed to create encode: %s", opus_strerror(err));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
opus_encoder_ctl(m_OpusEncoder, OPUS_SET_BITRATE(512000));
|
opus_encoder_ctl(m_OpusEncoder, OPUS_SET_BITRATE(510000));
|
||||||
opus_encoder_ctl(m_OpusEncoder, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
|
opus_encoder_ctl(m_OpusEncoder, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
|
||||||
opus_encoder_ctl(m_OpusEncoder, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
|
opus_encoder_ctl(m_OpusEncoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); //MDCT mode
|
||||||
opus_encoder_ctl(m_OpusEncoder, OPUS_SET_COMPLEXITY(10));
|
|
||||||
|
|
||||||
opus_encoder_ctl(m_OpusEncoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
|
|
||||||
opus_encoder_ctl(m_OpusEncoder, OPUS_SET_LSB_DEPTH(16));
|
opus_encoder_ctl(m_OpusEncoder, OPUS_SET_LSB_DEPTH(16));
|
||||||
|
opus_encoder_ctl(m_OpusEncoder, OPUS_SET_PACKET_LOSS_PERC(0));
|
||||||
|
opus_encoder_ctl(m_OpusEncoder, OPUS_SET_FORCE_CHANNELS(2));
|
||||||
|
|
||||||
if (err<0)
|
if (err<0)
|
||||||
{
|
{
|
||||||
@ -501,7 +501,9 @@ bool CVoice::OnBroadcastVoiceData(IClient *pClient, int nBytes, char *data)
|
|||||||
g_aFrameVoiceBytes[client] += 5 + nBytes;
|
g_aFrameVoiceBytes[client] += 5 + nBytes;
|
||||||
|
|
||||||
if(g_aFrameVoiceBytes[client] > NET_MAX_VOICE_BYTES_FRAME)
|
if(g_aFrameVoiceBytes[client] > NET_MAX_VOICE_BYTES_FRAME)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
g_fLastVoiceData[client] = gpGlobals->curtime;
|
g_fLastVoiceData[client] = gpGlobals->curtime;
|
||||||
|
|
||||||
@ -687,36 +689,40 @@ void CVoice::OnDataReceived(CClient *pClient, int16_t *pData, size_t Samples)
|
|||||||
pClient->m_LastValidData = getTime();
|
pClient->m_LastValidData = getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SteamVoiceHeader
|
|
||||||
{
|
|
||||||
uint32_t iSteamAccountID : 32;
|
|
||||||
uint32_t iSteamCommunity : 32;
|
|
||||||
uint32_t nPayload1 : 8;
|
|
||||||
uint32_t iSampleRate : 16;
|
|
||||||
uint32_t nPayload2 : 8;
|
|
||||||
uint32_t iDataLength : 16;
|
|
||||||
};
|
|
||||||
|
|
||||||
void CVoice::HandleVoiceData()
|
void CVoice::HandleVoiceData()
|
||||||
{
|
{
|
||||||
const int SampleRate = 48000;
|
//uint32_t sampleRate = 24000;
|
||||||
|
uint32_t sampleRate = 48000;
|
||||||
const int SamplesPerChannel = 480;
|
const int SamplesPerChannel = 480;
|
||||||
const int Channels = 1;
|
const int Channels = 2;
|
||||||
int TotalSamplesPerFrame = SamplesPerChannel * Channels;
|
int TotalSamplesPerFrame = SamplesPerChannel * Channels;
|
||||||
|
|
||||||
int FramesAvailable = m_Buffer.TotalLength() / TotalSamplesPerFrame;
|
int FramesAvailable = m_Buffer.TotalLength() / TotalSamplesPerFrame;
|
||||||
float TimeAvailable = (float)m_Buffer.TotalLength() / SampleRate;
|
|
||||||
|
|
||||||
if(!FramesAvailable)
|
if(!FramesAvailable)
|
||||||
return;
|
return;
|
||||||
if(m_AvailableTime < getTime() && TimeAvailable < 0.05)
|
|
||||||
return;
|
int FramesMax = 2; //used to be 5
|
||||||
if(m_AvailableTime > getTime() + 0.02)
|
bool reset_state = false;
|
||||||
return;
|
if (FramesAvailable <= FramesMax)
|
||||||
|
{
|
||||||
|
reset_state = true;
|
||||||
|
}
|
||||||
|
FramesAvailable = min_ext(FramesAvailable, FramesMax);
|
||||||
|
|
||||||
|
// Allow less buffering after audio has started playing
|
||||||
if (m_Buffer.TotalLength() < TotalSamplesPerFrame)
|
if (m_Buffer.TotalLength() < TotalSamplesPerFrame)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FramesAvailable = min_ext(FramesAvailable, 5);
|
float TimeAvailable = (float)m_Buffer.TotalLength() / sampleRate;
|
||||||
|
if(m_AvailableTime < getTime() && TimeAvailable < 0.2)
|
||||||
|
//if(m_AvailableTime < getTime() && TimeAvailable < 0.1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
double maxBuffer = (m_AvailableTime < getTime()) ? 0.2 : 0.04;
|
||||||
|
//double maxBuffer = (m_AvailableTime < getTime()) ? 0.1 : 0.02;
|
||||||
|
if(m_AvailableTime > getTime() + maxBuffer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
IClient *pClient = iserver->GetClient(0);
|
IClient *pClient = iserver->GetClient(0);
|
||||||
if(!pClient)
|
if(!pClient)
|
||||||
@ -738,8 +744,8 @@ void CVoice::HandleVoiceData()
|
|||||||
// 3. Payload Type 11 (1 byte)
|
// 3. Payload Type 11 (1 byte)
|
||||||
aFinal[FinalSize++] = 0x0B;
|
aFinal[FinalSize++] = 0x0B;
|
||||||
|
|
||||||
|
|
||||||
// 4. Sample Rate (2 bytes little-endian)
|
// 4. Sample Rate (2 bytes little-endian)
|
||||||
uint16_t sampleRate = 48000;
|
|
||||||
memcpy(&aFinal[FinalSize], &sampleRate, sizeof(uint16_t));
|
memcpy(&aFinal[FinalSize], &sampleRate, sizeof(uint16_t));
|
||||||
FinalSize += sizeof(uint16_t);
|
FinalSize += sizeof(uint16_t);
|
||||||
|
|
||||||
@ -756,6 +762,10 @@ void CVoice::HandleVoiceData()
|
|||||||
{
|
{
|
||||||
int16_t aBuffer[TotalSamplesPerFrame];
|
int16_t aBuffer[TotalSamplesPerFrame];
|
||||||
|
|
||||||
|
size_t OldReadIdx = m_Buffer.m_ReadIndex;
|
||||||
|
size_t OldCurLength = m_Buffer.CurrentLength();
|
||||||
|
size_t OldTotalLength = m_Buffer.TotalLength();
|
||||||
|
|
||||||
if(!m_Buffer.Pop(aBuffer, TotalSamplesPerFrame))
|
if(!m_Buffer.Pop(aBuffer, TotalSamplesPerFrame))
|
||||||
{
|
{
|
||||||
smutils->LogError(myself, "Buffer pop failed!");
|
smutils->LogError(myself, "Buffer pop failed!");
|
||||||
@ -769,7 +779,6 @@ void CVoice::HandleVoiceData()
|
|||||||
// Encode with Opus
|
// Encode with Opus
|
||||||
int nbBytes = opus_encode(m_OpusEncoder, (const opus_int16*)aBuffer, SamplesPerChannel,
|
int nbBytes = opus_encode(m_OpusEncoder, (const opus_int16*)aBuffer, SamplesPerChannel,
|
||||||
&aFinal[FinalSize], *pFrameSize);
|
&aFinal[FinalSize], *pFrameSize);
|
||||||
|
|
||||||
if (nbBytes <= 1)
|
if (nbBytes <= 1)
|
||||||
{
|
{
|
||||||
smutils->LogError(myself, "Opus encode failed: %s", opus_strerror(nbBytes));
|
smutils->LogError(myself, "Opus encode failed: %s", opus_strerror(nbBytes));
|
||||||
@ -780,6 +789,23 @@ void CVoice::HandleVoiceData()
|
|||||||
*pFrameSize = (uint16_t)nbBytes;
|
*pFrameSize = (uint16_t)nbBytes;
|
||||||
*pTotalDataLength += sizeof(uint16_t) + nbBytes;
|
*pTotalDataLength += sizeof(uint16_t) + nbBytes;
|
||||||
FinalSize += nbBytes;
|
FinalSize += nbBytes;
|
||||||
|
|
||||||
|
// Check for buffer underruns
|
||||||
|
for(int Client = 0; Client < MAX_CLIENTS; Client++)
|
||||||
|
{
|
||||||
|
CClient *pClient = &m_aClients[Client];
|
||||||
|
if(pClient->m_Socket == -1 || pClient->m_New == true)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m_Buffer.SetWriteIndex(pClient->m_BufferWriteIndex);
|
||||||
|
|
||||||
|
if(m_Buffer.CurrentLength() > pClient->m_LastLength)
|
||||||
|
{
|
||||||
|
pClient->m_BufferWriteIndex = m_Buffer.GetReadIndex();
|
||||||
|
m_Buffer.SetWriteIndex(pClient->m_BufferWriteIndex);
|
||||||
|
pClient->m_LastLength = m_Buffer.CurrentLength();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8. Add CRC32
|
// 8. Add CRC32
|
||||||
@ -788,10 +814,16 @@ void CVoice::HandleVoiceData()
|
|||||||
FinalSize += sizeof(uint32_t);
|
FinalSize += sizeof(uint32_t);
|
||||||
|
|
||||||
BroadcastVoiceData(pClient, FinalSize, aFinal);
|
BroadcastVoiceData(pClient, FinalSize, aFinal);
|
||||||
|
//smutils->LogMessage(myself, "FinalSize: %d", FinalSize);
|
||||||
|
|
||||||
if (m_AvailableTime < getTime())
|
if (m_AvailableTime < getTime())
|
||||||
m_AvailableTime = getTime();
|
m_AvailableTime = getTime();
|
||||||
m_AvailableTime += (double)FramesAvailable * 0.01;
|
m_AvailableTime += (double)FramesAvailable * 0.01;
|
||||||
|
|
||||||
|
if (reset_state)
|
||||||
|
{
|
||||||
|
opus_encoder_ctl(m_OpusEncoder, OPUS_RESET_STATE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVoice::BroadcastVoiceData(IClient *pClient, int nBytes, unsigned char *pData)
|
void CVoice::BroadcastVoiceData(IClient *pClient, int nBytes, unsigned char *pData)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user