Skip to content

Commit c3454cf

Browse files
committed
ouin ouin ouin
1 parent 3fa2bf3 commit c3454cf

File tree

8 files changed

+201
-41
lines changed

8 files changed

+201
-41
lines changed
141 KB
Binary file not shown.

RADADecoder/FDecodeResult.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#pragma once
2+
#include <cstdint>
3+
4+
struct FDecodeResult
5+
{
6+
int32_t shii;
7+
8+
// Number of bytes of compressed data consumed
9+
int32_t NumCompressedBytesConsumed;
10+
// Number of bytes produced
11+
int32_t NumPcmBytesProduced;
12+
// Number of frames produced.
13+
int32_t NumAudioFramesProduced;
14+
};

RADADecoder/FRadAudioInfo.cpp

Lines changed: 107 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
#include "FRadAudioInfo.h"
2+
3+
#include <fstream>
4+
#include <iostream>
5+
26
#include "SDK/Include/rada_decode.h"
37

48
#include <random>
59

10+
#include "FDecodeResult.h"
11+
612
bool FRadAudioInfo::ParseHeader(const uint8_t* InSrcBufferData, uint32_t InSrcBufferDataSize, const FSoundQualityInfo* QualityInfo)
713
{
814
const RadAFileHeader* FileHeader = RadAGetFileHeader(InSrcBufferData, InSrcBufferDataSize);
@@ -46,13 +52,13 @@ bool FRadAudioInfo::CreateDecoder(const uint8_t* SrcBufferData, uint32_t SrcBuff
4652
{
4753
if (SrcBufferOffset != 0)
4854
return false;
49-
50-
const RadAFileHeader* FileHeader = RadAGetFileHeader(SrcBufferData, SrcBufferDataSize);
55+
56+
const RadAFileHeader* FileHeader = MIRARadAGetFileHeader_1(SrcBufferData, SrcBufferDataSize);
5157
if (FileHeader == nullptr)
5258
return false;
53-
59+
5460
uint32_t DecoderMemoryNeeded = 0;
55-
if (RadAGetMemoryNeededToOpen(SrcBufferData, SrcBufferDataSize, &DecoderMemoryNeeded) != 0)
61+
if (MIRARadAGetMemoryNeededToOpen_1(SrcBufferData, SrcBufferDataSize, &DecoderMemoryNeeded) != 0)
5662
{
5763
printf("Invalid/insufficient data in FRadAudioInfo::CreateDecoder - bad buffer passed / bad cook? Size = %d", SrcBufferDataSize);
5864
if (SrcBufferDataSize > 8)
@@ -73,7 +79,7 @@ bool FRadAudioInfo::CreateDecoder(const uint8_t* SrcBufferData, uint32_t SrcBuff
7379

7480
Container = Decoder->Container();
7581

76-
if (RadAOpenDecoder(SrcBufferData, SrcBufferDataSize, Container, DecoderMemoryNeeded) == 0)
82+
if (MIRARadAOpenDecoder_1(SrcBufferData, SrcBufferDataSize, Container, DecoderMemoryNeeded) == 0)
7783
{
7884
printf("Failed to open decoder, likely corrupted data.");
7985
free(RawMemory);
@@ -85,67 +91,143 @@ bool FRadAudioInfo::CreateDecoder(const uint8_t* SrcBufferData, uint32_t SrcBuff
8591
return true;
8692
}
8793

88-
bool FRadAudioInfo::Decode(const uint8_t* CompressedData, const int32_t CompressedDataSize, uint8_t* OutPCMData, const int32_t OutputPCMDataSize, uint32_t NumChannels, RadAudioDecoderHeader* Decoder)
94+
FDecodeResult FRadAudioInfo::Decode(uint8_t* CompressedData, const int32_t CompressedDataSize, uint8_t* OutPCMData, const int32_t OutputPCMDataSize, uint32_t NumChannels, RadAudioDecoderHeader* Decoder)
8995
{
9096
uint32_t SampleStride = NumChannels * sizeof(int16_t); // constexpr uint32 MONO_PCM_SAMPLE_SIZE = sizeof(int16);
9197
uint32_t RemnOutputFrames = OutputPCMDataSize / SampleStride;
9298
uint32_t RemnCompressedDataSize = CompressedDataSize;
9399
const uint8_t* CompressedDataEnd = CompressedData + CompressedDataSize;
94100

95101
std::vector<float> DeinterleavedDecodeBuffer;
102+
std::vector<uint8_t> OutputReservoir;
96103

97104
while (RemnOutputFrames)
98105
{
99106
// Drain the output reservoir before attempting a decode.
100107
if (Decoder->OutputReservoirReadFrames < Decoder->OutputReservoirValidFrames)
101108
{
102-
109+
uint32_t AvailableFrames = Decoder->OutputReservoirReadFrames - Decoder->OutputReservoirValidFrames;
110+
uint32_t CopyFrames = std::min(AvailableFrames, RemnOutputFrames);
111+
112+
uint32_t CopyByteCount = SampleStride * CopyFrames;
113+
uint32_t CopyOffset = SampleStride * Decoder->OutputReservoirReadFrames;
114+
memcpy(OutPCMData, OutputReservoir.data() + CopyOffset, CopyByteCount);
115+
116+
Decoder->OutputReservoirReadFrames += CopyFrames;
117+
RemnOutputFrames -= CopyFrames;
118+
OutPCMData += CopyByteCount;
119+
120+
if (RemnOutputFrames == 0)
121+
break;
103122
}
104123

105124
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
125+
break;
126+
111127
uint32_t CompressedBytesNeeded = 0;
112128
RadAExamineBlockResult BlockResult = RadAExamineBlock(Decoder->Container(), CompressedData, RemnCompressedDataSize, &CompressedBytesNeeded);
113-
114-
CompressedData += sizeof(RadAContainer*);
115-
129+
116130
if (BlockResult != RadAExamineBlockResult::Valid)
117131
{
118132
printf("Invalid block in FRadAudioInfo::Decode: Result = %d, RemnSize = %d \n", BlockResult, RemnCompressedDataSize);
119133
if (RemnCompressedDataSize >= 8)
120134
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]);
121135

122-
return false;
136+
break;
123137
}
124138

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
139+
// RadAudio outputs deinterleaved 32-bit float buffers - we don't want to carry around
140+
// those buffers all the time and rad audio uses a pretty healthy amount of stack already,
127141
// so we drop these in the temp buffers.
128-
if (DeinterleavedDecodeBuffer.size() == 0)
142+
if (DeinterleavedDecodeBuffer.empty())
129143
DeinterleavedDecodeBuffer = std::vector<float>(RadADecodeBlock_MaxOutputFrames * NumChannels);
130-
144+
131145
size_t CompressedDataConsumed = 0;
132146
int16_t DecodeResult = RadADecodeBlock(Decoder->Container(), CompressedData, RemnCompressedDataSize, DeinterleavedDecodeBuffer.data(), RadADecodeBlock_MaxOutputFrames, &CompressedDataConsumed);
133147

134148
if (DecodeResult == RadADecodeBlock_Error)
135149
{
136-
printf("Failed to decode block that passed validation checks, corrupted buffer?");
137-
return false;
150+
printf("Failed to decode block that passed validation checks, corrupted buffer? \n");
151+
return FDecodeResult();
138152
}
139153
else if (DecodeResult == RadADecodeBlock_Done)
140154
{
141-
return true;
155+
break;
142156
}
143-
157+
144158
CompressedData += CompressedDataConsumed;
145159
RemnCompressedDataSize -= CompressedDataConsumed;
160+
161+
int16_t DecodeResultOffset = 0;
162+
163+
if (Decoder->ConsumeFrameCount)
164+
{
165+
int16_t ConsumedThisTime = DecodeResult;
166+
if (Decoder->ConsumeFrameCount < DecodeResult)
167+
{
168+
ConsumedThisTime = (int16_t)Decoder->ConsumeFrameCount;
169+
}
170+
171+
if (ConsumedThisTime)
172+
{
173+
DecodeResultOffset = ConsumedThisTime;
174+
DecodeResult -= ConsumedThisTime;
175+
}
176+
Decoder->ConsumeFrameCount -= ConsumedThisTime;
177+
}
178+
179+
if (DecodeResult == 0)
180+
continue;
181+
182+
int16_t* InterleaveDestination = (int16_t*)OutPCMData;
183+
if (RemnOutputFrames < RadADecodeBlock_MaxOutputFrames)
184+
{
185+
if (OutputReservoir.empty())
186+
OutputReservoir.reserve(RadADecodeBlock_MaxOutputFrames * SampleStride);
187+
188+
InterleaveDestination = (int16_t*)OutputReservoir.data();
189+
}
190+
191+
for (int32_t ChannelIdx = 0; ChannelIdx < NumChannels; ChannelIdx++)
192+
{
193+
const float* InBuffer = DeinterleavedDecodeBuffer.data() + RadADecodeBlock_MaxOutputFrames*ChannelIdx + DecodeResultOffset;
194+
195+
for (int32_t SampleIdx = 0; SampleIdx < DecodeResult; SampleIdx++)
196+
{
197+
float InBufferFloat = InBuffer[SampleIdx] * 32768.0f;
198+
if (InBufferFloat > 32767)
199+
{
200+
InBufferFloat = 32767;
201+
}
202+
else if (InBufferFloat < -32768)
203+
{
204+
InBufferFloat = -32768;
205+
}
206+
207+
InterleaveDestination[ChannelIdx + (SampleIdx * NumChannels)] = (int16_t)InBufferFloat;
208+
}
209+
}
210+
211+
if (InterleaveDestination == (int16_t*)OutputReservoir.data())
212+
{
213+
Decoder->OutputReservoirValidFrames = DecodeResult;
214+
Decoder->OutputReservoirReadFrames = 0;
215+
}
216+
else
217+
{
218+
RemnOutputFrames -= DecodeResult;
219+
OutPCMData += DecodeResult * SampleStride;
220+
}
146221
}
147222

148-
return true;
223+
FDecodeResult Result;
224+
225+
Result.shii = OutputPCMDataSize - RemnOutputFrames;
226+
Result.NumPcmBytesProduced = OutputPCMDataSize - (RemnOutputFrames * SampleStride);
227+
Result.NumAudioFramesProduced = Result.NumPcmBytesProduced / SampleStride;
228+
Result.NumCompressedBytesConsumed = CompressedDataSize - RemnCompressedDataSize;
229+
230+
return Result;
149231
}
150232

151233

RADADecoder/FRadAudioInfo.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
#pragma once
22
#include <cstdint>
33

4+
#include "FDecodeResult.h"
45
#include "FSoundQualityInfo.h"
56
#include "RadAudioDecoderHeader.h"
67

78
class FRadAudioInfo
89
{
910
public:
1011
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 bool Decode(const uint8_t* CompressedData, int32_t CompressedDataSize, uint8_t* OutPCMData, int32_t OutputPCMDataSize, uint32_t
14-
NumChannels, RadAudioDecoderHeader* Decoder);
12+
static bool CreateDecoder(const uint8_t* SrcBufferData, uint32_t SrcBufferDataSize, RadAudioDecoderHeader*& Decoder, uint8_t*& RawMemory, uint32_t
13+
& SrcBufferOffset, RadAContainer*& Container);
14+
static FDecodeResult Decode(uint8_t* CompressedData, int32_t CompressedDataSize, uint8_t* OutPCMData, int32_t OutputPCMDataSize, uint32_t
15+
NumChannels, RadAudioDecoderHeader* Decoder);
16+
17+
static int32_t SeekTableSize(const uint8_t);
1518

1619
private:
1720
template <typename T>

RADADecoder/RADADecoder.cpp

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,21 @@
55

66
#include "FRadAudioInfo.h"
77
#include "FSoundQualityInfo.h"
8+
#include "WaveHeader.h"
89

910
int main()
1011
{
11-
std::string inputFilePath = R"(D:\Programming\RADADecoder\Emote_GasStation_JunoVersion_Loop.rada)";
12+
bool verbose = true;
13+
14+
//std::string inputFilePath = R"(D:\Programming\RadA-Decoder\Emote_GasStation_JunoVersion_Loop.rada)";
15+
//std::ifstream inputFile(inputFilePath, std::ios::binary);
16+
17+
std::string inputFilePath = R"(D:\Leaking Tools\FModel\Output\Exports\FortniteGame\Plugins\GameFeatures\BRCosmetics\Content\Sounds\MusicPacks\BuffCat_Comic\Drop_In_MusicPack_Loop.rada)";
1218
std::ifstream inputFile(inputFilePath, std::ios::binary);
1319

20+
std::string outFilePath = R"(D:\Programming\RadA-Decoder\Output.wav)";
21+
std::ofstream outFile(outFilePath, std::ios::binary);
22+
1423
std::shared_ptr<uint8_t> inputData;
1524

1625
inputFile.seekg(0, std::ios::end);
@@ -48,20 +57,19 @@ int main()
4857

4958
bool inSkip = false;
5059
size_t dstOffset = 0;
51-
52-
for (size_t i = 0; i < inputDataSize; i++)
60+
61+
for (size_t i = srcBufferOffset; i < inputDataSize; i++)
5362
{
5463
if (!inSkip && i + 4 < inputDataSize && std::memcmp(&inputData.get()[i], "SEEK", 4) == 0)
5564
{
5665
inSkip = true;
5766
i += 3;
67+
5868
}
59-
else if (inSkip && i + 2 < inputDataSize && inputData.get()[i] == 0x99 && inputData.get()[i + 1] == 0x99)
69+
else if (inSkip && i + 2 < inputDataSize && inputData.get()[i] == 0x55)
6070
{
6171
inSkip = false;
62-
compressedData.get()[dstOffset++] = 0x99;
63-
compressedData.get()[dstOffset++] = 0x99;
64-
i += 1; // Skip 0x9999
72+
compressedData.get()[dstOffset++] = 0x55;
6573
}
6674
else if (!inSkip)
6775
{
@@ -70,11 +78,37 @@ int main()
7078
}
7179

7280
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-
}
81+
auto result = FRadAudioInfo::Decode(compressedData.get(), dstOffset, OutPCMData, audioInfo.SampleDataSize, audioInfo.NumChannels, decoder);
82+
83+
WaveHeader header = {0};
84+
85+
memcpy(header.riff_tag, "RIFF", 4);
86+
memcpy(header.wave_tag, "WAVE", 4);
87+
memcpy(header.fmt_tag, "fmt ", 4);
88+
memcpy(header.data_tag, "data", 4);
89+
90+
header.sample_rate = audioInfo.SampleRate;
91+
header.num_channels = audioInfo.NumChannels;
92+
header.riff_length = result.shii + sizeof(WaveHeader) - 8;
93+
header.data_length = result.shii;
94+
95+
int bits_per_sample = 16;
96+
97+
header.fmt_length = 16;
98+
header.audio_format = 1;
99+
header.byte_rate = header.num_channels * header.sample_rate * bits_per_sample / 8;
100+
header.block_align = header.num_channels * bits_per_sample / 8;
101+
header.bits_per_sample = bits_per_sample;
102+
103+
outFile.write(reinterpret_cast<char*>(&header), sizeof(header));
104+
outFile.write(reinterpret_cast<char*>(OutPCMData), result.shii);
105+
106+
std::cout << result.NumAudioFramesProduced << '\n';
107+
std::cout << result.NumCompressedBytesConsumed << '\n';
108+
std::cout << result.NumPcmBytesProduced << '\n';
109+
110+
inputFile.close();
111+
outFile.close();
78112

79113
std::cout << "Shit worked" << '\n';
80114
}

RADADecoder/RADADecoder.vcxproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,10 @@
147147
<ClCompile Include="SDK\Src\RadAudio\radaudio_mdct_test.cpp" />
148148
<ClCompile Include="SDK\Src\RadA\rada_decode.cpp" />
149149
<ClCompile Include="SDK\Src\RadA\rada_encode.cpp" />
150+
<ClCompile Include="WaveHeader.cpp" />
150151
</ItemGroup>
151152
<ItemGroup>
153+
<ClInclude Include="FDecodeResult.h" />
152154
<ClInclude Include="FRadAudioInfo.h" />
153155
<ClInclude Include="FSoundQualityInfo.h" />
154156
<ClInclude Include="RadAudioDecoderHeader.h" />
@@ -179,6 +181,7 @@
179181
<ClInclude Include="SDK\Src\RadAudio\radaudio_sse.h" />
180182
<ClInclude Include="SDK\Src\RadAudio\rrbits.h" />
181183
<ClInclude Include="SDK\Src\RadAudio\rrCore.h" />
184+
<ClInclude Include="WaveHeader.h" />
182185
</ItemGroup>
183186
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
184187
<ImportGroup Label="ExtensionTargets">

RADADecoder/WaveHeader.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#include "WaveHeader.h"
2+
3+
#include <cstring>
4+

RADADecoder/WaveHeader.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
3+
struct WaveHeader
4+
{
5+
char riff_tag[4];
6+
int riff_length;
7+
char wave_tag[4];
8+
char fmt_tag[4];
9+
int fmt_length;
10+
short audio_format;
11+
short num_channels;
12+
int sample_rate;
13+
int byte_rate;
14+
short block_align;
15+
short bits_per_sample;
16+
char data_tag[4];
17+
int data_length;
18+
};
19+
20+

0 commit comments

Comments
 (0)