11#include " FRadAudioInfo.h"
2+ #include " SDK/Include/rada_decode.h"
23
34#include < random>
45
@@ -14,14 +15,19 @@ bool FRadAudioInfo::ParseHeader(const uint8_t* InSrcBufferData, uint32_t InSrcBu
1415
1516 uint8_t NumChannels = FileHeader->channels ;
1617
18+ // seek_table_entry_count is 16 bit, no overflow possible
1719 uint32_t SeekTableSize = FileHeader->seek_table_entry_count * sizeof (uint16_t );
1820 if (sizeof (RadAFileHeader) + SeekTableSize > InSrcBufferDataSize)
1921 return false ;
2022
23+ // Store the offset to where the audio data begins.
2124 auto audioDataOffset = RadAGetBytesToOpen (FileHeader);
25+
26+ // Check we have all headers and seek table data in memory.
2227 if (audioDataOffset > InSrcBufferDataSize)
2328 return false ;
2429
30+ // Write out the header info
2531 if (QualityInfo)
2632 {
2733 QualityInfo->SampleRate = RadASampleRateFromEnum (FileHeader->sample_rate );
@@ -56,6 +62,90 @@ bool FRadAudioInfo::CreateDecoder(const uint8_t* SrcBufferData, uint32_t SrcBuff
5662 }
5763
5864 uint32_t TotalMemory = DecoderMemoryNeeded + sizeof (RadAudioDecoderHeader);
65+
66+ //
67+ // Allocate and save offsets
68+ //
69+ RawMemory = (uint8_t *)malloc (TotalMemory);
70+ memset (RawMemory, 0 , TotalMemory);
71+
72+ Decoder = (RadAudioDecoderHeader*)RawMemory;
73+
74+ Container = Decoder->Container ();
75+
76+ if (RadAOpenDecoder (SrcBufferData, SrcBufferDataSize, Container, DecoderMemoryNeeded) == 0 )
77+ {
78+ printf (" Failed to open decoder, likely corrupted data." );
79+ free (RawMemory);
80+ return false ;
81+ }
82+
83+ // Set our buffer at the start of the audio data.
84+ SrcBufferOffset = RadAGetBytesToOpen (FileHeader);
85+ return true ;
86+ }
87+
88+ bool FRadAudioInfo::Decode (const uint8_t * CompressedData, const int32_t CompressedDataSize, uint8_t * OutPCMData, const int32_t OutputPCMDataSize, uint32_t NumChannels, RadAudioDecoderHeader* Decoder)
89+ {
90+ uint32_t SampleStride = NumChannels * sizeof (int16_t ); // constexpr uint32 MONO_PCM_SAMPLE_SIZE = sizeof(int16);
91+ uint32_t RemnOutputFrames = OutputPCMDataSize / SampleStride;
92+ uint32_t RemnCompressedDataSize = CompressedDataSize;
93+ const uint8_t * CompressedDataEnd = CompressedData + CompressedDataSize;
94+
95+ std::vector<float > DeinterleavedDecodeBuffer;
96+
97+ while (RemnOutputFrames)
98+ {
99+ // Drain the output reservoir before attempting a decode.
100+ if (Decoder->OutputReservoirReadFrames < Decoder->OutputReservoirValidFrames )
101+ {
102+
103+ }
104+
105+ if (RemnCompressedDataSize == 0 )
106+ return false ;
107+
108+ // This shit is bs if we pass the data from the offset it fucking fails but if we pass the fucker with pos 0 it passes but then is corrupted apparently
109+ // Either this fucker needs its pos to be increased manually or something, but I highly doubt it
110+ // But the container shit is correct, so I don't even fucking know now
111+ uint32_t CompressedBytesNeeded = 0 ;
112+ RadAExamineBlockResult BlockResult = RadAExamineBlock (Decoder->Container (), CompressedData, RemnCompressedDataSize, &CompressedBytesNeeded);
113+
114+ CompressedData += sizeof (RadAContainer*);
115+
116+ if (BlockResult != RadAExamineBlockResult::Valid)
117+ {
118+ printf (" Invalid block in FRadAudioInfo::Decode: Result = %d, RemnSize = %d \n " , BlockResult, RemnCompressedDataSize);
119+ if (RemnCompressedDataSize >= 8 )
120+ printf (" First 8 bytes of buffer: 0x%02x 0x%02x 0x%02x 0x%02x:0x%02x 0x%02x 0x%02x 0x%02x \n " , CompressedData[0 ], CompressedData[1 ], CompressedData[2 ], CompressedData[3 ], CompressedData[4 ], CompressedData[5 ], CompressedData[6 ], CompressedData[7 ]);
121+
122+ return false ;
123+ }
124+
125+ // RadAudio outputs deinterleaved 32 bit float buffers - we don't want to carry around
126+ // those buffers all the time and rad audio uses a pretty healthy amount of stack already
127+ // so we drop these in the temp buffers.
128+ if (DeinterleavedDecodeBuffer.size () == 0 )
129+ DeinterleavedDecodeBuffer = std::vector<float >(RadADecodeBlock_MaxOutputFrames * NumChannels);
130+
131+ size_t CompressedDataConsumed = 0 ;
132+ int16_t DecodeResult = RadADecodeBlock (Decoder->Container (), CompressedData, RemnCompressedDataSize, DeinterleavedDecodeBuffer.data (), RadADecodeBlock_MaxOutputFrames, &CompressedDataConsumed);
133+
134+ if (DecodeResult == RadADecodeBlock_Error)
135+ {
136+ printf (" Failed to decode block that passed validation checks, corrupted buffer?" );
137+ return false ;
138+ }
139+ else if (DecodeResult == RadADecodeBlock_Done)
140+ {
141+ return true ;
142+ }
143+
144+ CompressedData += CompressedDataConsumed;
145+ RemnCompressedDataSize -= CompressedDataConsumed;
146+ }
147+
148+ return true ;
59149}
60150
61151
0 commit comments