@@ -14,14 +14,19 @@ bool FRadAudioInfo::ParseHeader(const uint8_t* InSrcBufferData, uint32_t InSrcBu
1414
1515 uint8_t NumChannels = FileHeader->channels ;
1616
17+ // seek_table_entry_count is 16 bit, no overflow possible
1718 uint32_t SeekTableSize = FileHeader->seek_table_entry_count * sizeof (uint16_t );
1819 if (sizeof (RadAFileHeader) + SeekTableSize > InSrcBufferDataSize)
1920 return false ;
2021
22+ // Store the offset to where the audio data begins.
2123 auto audioDataOffset = RadAGetBytesToOpen (FileHeader);
24+
25+ // Check we have all headers and seek table data in memory.
2226 if (audioDataOffset > InSrcBufferDataSize)
2327 return false ;
2428
29+ // Write out the header info
2530 if (QualityInfo)
2631 {
2732 QualityInfo->SampleRate = RadASampleRateFromEnum (FileHeader->sample_rate );
@@ -36,7 +41,7 @@ bool FRadAudioInfo::ParseHeader(const uint8_t* InSrcBufferData, uint32_t InSrcBu
3641 return true ;
3742}
3843
39- bool FRadAudioInfo::CreateDecoder (const uint8_t * SrcBufferData, uint32_t SrcBufferDataSize, RadAudioDecoderHeader*& Decoder, uint8_t *& RawMemory, uint32_t & SrcBufferOffset, RadAContainer*& Container )
44+ bool FRadAudioInfo::CreateDecoder (const uint8_t * SrcBufferData, uint32_t SrcBufferDataSize, RadAudioDecoderHeader*& Decoder, uint8_t *& RawMemory, uint32_t & SrcBufferOffset)
4045{
4146 if (SrcBufferOffset != 0 )
4247 return false ;
@@ -56,8 +61,73 @@ bool FRadAudioInfo::CreateDecoder(const uint8_t* SrcBufferData, uint32_t SrcBuff
5661 }
5762
5863 uint32_t TotalMemory = DecoderMemoryNeeded + sizeof (RadAudioDecoderHeader);
64+
65+ //
66+ // Allocate and save offsets
67+ //
68+ RawMemory = (uint8_t *)malloc (TotalMemory);
69+ memset (RawMemory, 0 , TotalMemory);
70+
71+ Decoder = (RadAudioDecoderHeader*)RawMemory;
72+
73+ RadAContainer* Container = Decoder->Container ();
74+
75+ if (RadAOpenDecoder (SrcBufferData, SrcBufferDataSize, Container, DecoderMemoryNeeded) == 0 )
76+ {
77+ printf (" Failed to open decoder, likely corrupted data." );
78+ free (RawMemory);
79+ return false ;
80+ }
81+
82+ // Set our buffer at the start of the audio data.
83+ SrcBufferOffset = RadAGetBytesToOpen (FileHeader);
84+ return true ;
5985}
6086
87+ bool FRadAudioInfo::Decode (const uint8_t * CompressedData, const int32_t CompressedDataSize, uint8_t * OutPCMData, const int32_t OutputPCMDataSize, uint32_t NumChannels, RadAudioDecoderHeader* Decoder)
88+ {
89+ uint32_t SampleStride = NumChannels * sizeof (int16_t ); // constexpr uint32 MONO_PCM_SAMPLE_SIZE = sizeof(int16);
90+ uint32_t RemnOutputFrames = OutputPCMDataSize / SampleStride;
91+ uint32_t RemnCompressedDataSize = CompressedDataSize;
92+ const uint8_t * CompressedDataEnd = CompressedData + CompressedDataSize;
93+
94+ float * DeinterleavedDecodeBuffer = nullptr ;
95+
96+ while (RemnOutputFrames)
97+ {
98+ // Drain the output reservoir before attempting a decode.
99+ if (Decoder->OutputReservoirReadFrames < Decoder->OutputReservoirValidFrames )
100+ {
101+
102+ }
103+
104+ if (RemnCompressedDataSize == 0 )
105+ return false ;
106+
107+ uint32_t CompressedBytesNeeded = 0 ;
108+ RadAExamineBlockResult BlockResult = MIRARadAExamineBlock_1 (Decoder->Container (), CompressedData, RemnCompressedDataSize, &CompressedBytesNeeded);
109+
110+ if (BlockResult != RadAExamineBlockResult::Valid)
111+ {
112+ printf (" Invalid block in FRadAudioInfo::Decode: Result = %d, RemnSize = %d \n " , BlockResult, RemnCompressedDataSize);
113+ if (RemnCompressedDataSize >= 8 )
114+ 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 ]);
115+
116+ return false ;
117+ }
118+
119+ // RadAudio outputs deinterleaved 32 bit float buffers - we don't want to carry around
120+ // those buffers all the time and rad audio uses a pretty healthy amount of stack already
121+ // so we drop these in the temp buffers.
122+ if (DeinterleavedDecodeBuffer == nullptr )
123+ DeinterleavedDecodeBuffer = (float *)malloc (CompressedBytesNeeded);
124+
125+ size_t CompressedDataConsumed = 0 ;
126+ int16_t DecodeResult = RadADecodeBlock (Decoder->Container (), CompressedData, RemnCompressedDataSize, DeinterleavedDecodeBuffer, RadADecodeBlock_MaxOutputFrames, &CompressedDataConsumed);
127+ }
128+
129+ return true ;
130+ }
61131
62132template <typename T>
63133bool FRadAudioInfo::MultiplyAndCheckForOverflow (T A, T B, T& OutResult)
0 commit comments