From 718284e7dde33c1f84074479e90cb9f13d95cc0a Mon Sep 17 00:00:00 2001 From: jenz Date: Tue, 2 Jun 2026 13:46:54 +0100 Subject: [PATCH] finally getting all the subframes correctly --- extension.cpp | 157 ++++++++++++++++++++------------------------------ 1 file changed, 62 insertions(+), 95 deletions(-) diff --git a/extension.cpp b/extension.cpp index 6c8b1a8..72cd36e 100644 --- a/extension.cpp +++ b/extension.cpp @@ -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); } } }