Skip to content

Commit 46bca7f

Browse files
committed
why did this shit not get pushed
1 parent 440210e commit 46bca7f

File tree

4 files changed

+127
-7
lines changed

4 files changed

+127
-7
lines changed

RADADecoder/FRadAudioInfo.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
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

RADADecoder/FRadAudioInfo.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ class FRadAudioInfo
1010
static bool ParseHeader(const uint8_t* InSrcBufferData, uint32_t InSrcBufferDataSize, const FSoundQualityInfo* QualityInfo);
1111
static bool CreateDecoder(const uint8_t* SrcBufferData, uint32_t SrcBufferDataSize, RadAudioDecoderHeader*& Decoder, uint8_t*& RawMemory, uint32_t&
1212
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);
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 & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,37 @@ int main()
4444
return 0;
4545
}
4646

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

49-
uint8_t* data = nullptr;
5079
std::cout << "Shit worked" << '\n';
5180
}

RADADecoder/SDK/Src/RadA/rada_decode.cpp

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

57
#include <string.h>
68

0 commit comments

Comments
 (0)