finally getting all the subframes correctly

This commit is contained in:
jenz 2026-06-02 13:46:54 +01:00
parent 009962f120
commit 718284e7dd

View File

@ -1236,8 +1236,8 @@ void CVoice::PushPlayerVoiceData(int playerSlot, int nBytes, char *data)
const unsigned char *p = (const unsigned char *)data;
/*
int dumpLen = nBytes < 24 ? nBytes : 24;
char hexBuf[24 * 3 + 1];
int dumpLen = nBytes;
char hexBuf[dumpLen * 3 + 1];
int pos = 0;
for (int i = 0; i < dumpLen; i++)
{
@ -1247,7 +1247,7 @@ void CVoice::PushPlayerVoiceData(int playerSlot, int nBytes, char *data)
hexBuf[pos++] = ' ';
}
hexBuf[pos] = '\0';
smutils->LogMessage(myself, "[INBOUND STEAM] nBytes=%d, First bytes: %s", nBytes, hexBuf);
smutils->LogMessage(myself, "[INBOUND STEAM] nBytes=%d, hexBuf: %s", nBytes, hexBuf);
*/
uint16_t totalDataLength;
@ -1262,107 +1262,74 @@ void CVoice::PushPlayerVoiceData(int playerSlot, int nBytes, char *data)
int offset = 14;
int end = 14 + (int)totalDataLength;
/*
subframe header layout
0: payload_size EXCLUDING this 4-byte header
1: 0x00
2: sequence_number
3: 0x00
4: 0x68 (TOC)
*/
//frame 1 always starts at offset 18.
int MaxFrames = 16;
int16_t pcmFrameBuffer[480 * MaxFrames];
int totalDecodedSamples = 0;
if (offset + 4 <= end)
while (offset + 4 <= end)
{
uint16_t trueAudioPayloadLen;
memcpy(&trueAudioPayloadLen, p + 12, sizeof(uint16_t));
// Frame 1 always starts exactly at offset 18
int frame1Start = 18;
if (frame1Start >= end) return;
const unsigned char *frame1Ptr = p + frame1Start;
// Find the start of Frame 2 by scanning for the next 0x68 TOC marker
int frame2Start = -1;
// A standard 24kHz Opus frame will practically never be shorter than 30 bytes
for (int i = frame1Start + 30; i < end - 4; i++)
{
if (p[i] == 0x68) //TOC -> 0x68
{
// Verify if this is the start of Frame 2
frame2Start = i;
break;
}
}
int16_t pcmFrameBuffer[960];
int totalDecodedSamples = 0;
// Calculate explicit size for Frame 1
int frame1Size = (frame2Start != -1) ? (frame2Start - frame1Start) : (end - frame1Start);
if (frame1Size > 0)
{
//smutils->LogMessage(myself, "[VOICE-FIX] Frame 1 Determined Size: %d bytes. TOC: 0x%02X", frame1Size, frame1Ptr[0]);
int FrameOffset = offset + 4; //we are now standing on TOC
int FrameSize = p[offset]; //payload size
int samples1 = opus_decode(m_PlayerOpusDecoder[playerSlot],
frame1Ptr, frame1Size,
&pcmFrameBuffer[0], 480, 0);
if (samples1 > 0) totalDecodedSamples += samples1;
}
// Process Frame 2 if a second TOC marker was identified
if (frame2Start != -1)
int samples = opus_decode(m_PlayerOpusDecoder[playerSlot],
&p[FrameOffset], FrameSize,
&pcmFrameBuffer[totalDecodedSamples], 480, 0);
if (samples > 0)
{
const unsigned char *frame2Ptr = p + frame2Start;
int frame2Size = end - frame2Start; // Frame 2 spans to the end of the payload buffer
totalDecodedSamples += samples;
}
//moving to next subframe
offset = FrameOffset + FrameSize;
}
if (frame2Size > 0)
int16_t resampledFrameBuffer[480 * MaxFrames];
int totalResampledSamples = 0;
//obviously the resampling here is AI code. i dont actually know how to resample
if (totalDecodedSamples > 0)
{
// The exact conversion ratio factor is 147 / 160
// 480 samples at 24kHz converts precisely into 441 samples at 22.05kHz
// 960 samples (2 frames) converts precisely into 882 samples
totalResampledSamples = (totalDecodedSamples * 147) / 160;
for (int i = 0; i < totalResampledSamples; i++)
{
// Determine where this output sample lands on the input timeline
double srcPosition = (double)i * 160.0 / 147.0;
int srcIndex = (int)srcPosition;
double fraction = srcPosition - (double)srcIndex;
if (srcIndex + 1 < totalDecodedSamples)
{
//smutils->LogMessage(myself, "[VOICE-FIX] Frame 2 Determined Size: %d bytes. TOC: 0x%02X", frame2Size, frame2Ptr[0]);
int samples2 = opus_decode(m_PlayerOpusDecoder[playerSlot],
frame2Ptr, frame2Size,
&pcmFrameBuffer[totalDecodedSamples], 480, 0);
if (samples2 > 0) totalDecodedSamples += samples2;
// Linear interpolate between the two closest matching input samples
int16_t sampleA = pcmFrameBuffer[srcIndex];
int16_t sampleB = pcmFrameBuffer[srcIndex + 1];
resampledFrameBuffer[i] = (int16_t)(sampleA + fraction * (sampleB - sampleA));
}
else
{
// Handle boundary edge case for the final trailing sample
resampledFrameBuffer[i] = pcmFrameBuffer[srcIndex];
}
}
int16_t resampledFrameBuffer[960];
int totalResampledSamples = 0;
if (totalDecodedSamples > 0)
}
if (totalResampledSamples > 0)
{
size_t freeSpace = m_playerVoiceBuffer[playerSlot].CurrentFree();
if ((size_t)totalResampledSamples <= freeSpace)
{
// The exact conversion ratio factor is 147 / 160
// 480 samples at 24kHz converts precisely into 441 samples at 22.05kHz
// 960 samples (2 frames) converts precisely into 882 samples
totalResampledSamples = (totalDecodedSamples * 147) / 160;
for (int i = 0; i < totalResampledSamples; i++)
{
// Determine where this output sample lands on the input timeline
double srcPosition = (double)i * 160.0 / 147.0;
int srcIndex = (int)srcPosition;
double fraction = srcPosition - (double)srcIndex;
if (srcIndex + 1 < totalDecodedSamples)
{
// Linear interpolate between the two closest matching input samples
int16_t sampleA = pcmFrameBuffer[srcIndex];
int16_t sampleB = pcmFrameBuffer[srcIndex + 1];
resampledFrameBuffer[i] = (int16_t)(sampleA + fraction * (sampleB - sampleA));
}
else
{
// Handle boundary edge case for the final trailing sample
resampledFrameBuffer[i] = pcmFrameBuffer[srcIndex];
}
}
}
// --- PUSH SOUND TIMELINES SEQUENTIALLY ---
if (totalResampledSamples > 0)
{
size_t freeSpace = m_playerVoiceBuffer[playerSlot].CurrentFree();
if ((size_t)totalResampledSamples <= freeSpace)
{
// Push the perfectly timed 22050Hz stream to the CELT ring buffer
m_playerVoiceBuffer[playerSlot].Push(resampledFrameBuffer, totalResampledSamples);
}
// Push the timed 22050Hz stream to the CELT ring buffer
m_playerVoiceBuffer[playerSlot].Push(resampledFrameBuffer, totalResampledSamples);
}
}
}