Skip to content

Commit c5969a6

Browse files
committed
I don't even know
1 parent 440210e commit c5969a6

File tree

5 files changed

+109
-14
lines changed

5 files changed

+109
-14
lines changed

RADADecoder/FRadAudioInfo.cpp

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

62132
template <typename T>
63133
bool FRadAudioInfo::MultiplyAndCheckForOverflow(T A, T B, T& OutResult)

RADADecoder/FRadAudioInfo.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@ class FRadAudioInfo
88
{
99
public:
1010
static bool ParseHeader(const uint8_t* InSrcBufferData, uint32_t InSrcBufferDataSize, const FSoundQualityInfo* QualityInfo);
11-
static bool CreateDecoder(const uint8_t* SrcBufferData, uint32_t SrcBufferDataSize, RadAudioDecoderHeader*& Decoder, uint8_t*& RawMemory, uint32_t&
12-
SrcBufferOffset, RadAContainer*& Container);
13-
static void Decode(const uint8_t* compressedData, int32_t compressedDataSize, uint8_t* outPCMData, int32_t
14-
outputPCMDataSize, RadAudioDecoderHeader
15-
* decoder, int32_t numChannels);
11+
static bool CreateDecoder(const uint8_t* SrcBufferData, uint32_t SrcBufferDataSize, RadAudioDecoderHeader*& Decoder, uint8_t*& RawMemory, uint32_t& SrcBufferOffset);
12+
13+
static bool Decode(const uint8_t* CompressedData, int32_t CompressedDataSize, uint8_t* OutPCMData, int32_t OutputPCMDataSize, uint32_t
14+
NumChannels, RadAudioDecoderHeader* Decoder);
1615

1716
private:
1817
template <typename T>

RADADecoder/RADADecoder.cpp

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,42 @@ int main()
3636
uint8_t* rawMemory = nullptr;
3737
RadAudioDecoderHeader* decoder = nullptr;
3838
uint32_t srcBufferOffset = 0;
39-
RadAContainer* container = nullptr;
4039

41-
if (!FRadAudioInfo::CreateDecoder(inputData.get(), inputDataSize, decoder, rawMemory, srcBufferOffset, container))
40+
if (!FRadAudioInfo::CreateDecoder(inputData.get(), inputDataSize, decoder, rawMemory, srcBufferOffset))
4241
{
4342
std::cerr << "Failed to create decoder." << '\n';
4443
return 0;
4544
}
45+
46+
std::unique_ptr<uint8_t> compressedData = std::unique_ptr<uint8_t>(new uint8_t[inputDataSize - srcBufferOffset]);
47+
48+
bool inSkip = false;
49+
size_t dstOffset = 0;
50+
51+
for (size_t i = srcBufferOffset; i < inputDataSize; i++)
52+
{
53+
if (!inSkip && i + 4 < inputDataSize && std::memcmp(&inputData.get()[i], "SEEK", 4) == 0)
54+
{
55+
inSkip = true;
56+
i += 3;
57+
}
58+
else if (inSkip && i + 2 < inputDataSize && inputData.get()[i] == 0x99 && inputData.get()[i + 1] == 0x99)
59+
{
60+
inSkip = false;
61+
i += 1; // Skip 0x9999
62+
}
63+
else if (!inSkip)
64+
{
65+
compressedData.get()[dstOffset++] = inputData.get()[i];
66+
}
67+
}
68+
69+
uint8_t* OutPCMData = (uint8_t*)malloc(audioInfo.SampleDataSize);
70+
if (!FRadAudioInfo::Decode(compressedData.get(), dstOffset, OutPCMData, audioInfo.SampleDataSize, audioInfo.NumChannels, decoder))
71+
{
72+
std::cerr << "Failed to decode RADA file" << '\n';
73+
return 0;
74+
}
4675

47-
uint8_t* compressedData = inputData.get() + srcBufferOffset;
48-
49-
uint8_t* data = nullptr;
5076
std::cout << "Shit worked" << '\n';
5177
}

RADADecoder/RadAudioDecoderHeader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ struct RadAudioDecoderHeader
1717

1818
RadAContainer* Container()
1919
{
20-
return reinterpret_cast<RadAContainer*>(this + 1);
20+
return (RadAContainer*)(this + 1);
2121
}
2222
};

RADADecoder/SDK/Src/RadA/rada_decode.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright Epic Games Tools, LLC. All Rights Reserved.
2-
#include "rada_decode.h"
3-
#include "radaudio_decoder.h"
2+
#include "../../Include/rada_decode.h"
3+
#include "../RadAudio/radaudio_decoder.h"
44

55
#include <string.h>
66

0 commit comments

Comments
 (0)