22#include < iostream>
33#include < string>
44#include < memory>
5+ #include < vector>
56
7+ #include " argparse.hpp"
68#include " FRadAudioInfo.h"
79#include " FSoundQualityInfo.h"
810#include " WaveHeader.h"
911
10- int main ()
12+ int main (int argc, char **argv )
1113{
12- bool verbose = true ;
14+ argparse::ArgumentParser program (" RADADecoder" );
15+ program.add_argument (" -i" , " --input-file" ).required ().help (" Input File to Decode" );
16+ program.add_argument (" -o" , " --output-file" ).required ().help (" Path to Output File" );
17+ program.add_argument (" -v" , " --verbose" ).default_value (false ).help (" Verbose Output" );
1318
14- // std::string inputFilePath = R"(D:\Programming\RadA-Decoder\Emote_GasStation_JunoVersion_Loop.rada)";
15- // std::ifstream inputFile(inputFilePath, std::ios::binary);
19+ try
20+ {
21+ program.parse_args (argc, argv);
22+ }
23+ catch (const std::runtime_error &err)
24+ {
25+ std::cout << err.what () << ' \n ' ;
26+ std::cout << program;
27+ exit (0 );
28+ }
1629
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 )" ;
30+ std::string inputFilePath = program. get <std::string>( " -i " ) ;
1831 std::ifstream inputFile (inputFilePath, std::ios::binary);
32+
33+ if (!inputFile)
34+ {
35+ std::cerr << " Failed to open input file: " << inputFilePath << ' \n ' ;
36+ return 1 ;
37+ }
38+
39+ std::string outputFilePath = program.get <std::string>(" -o" );
40+ std::ofstream outFile (outputFilePath, std::ios::binary);
41+
42+ if (!outFile)
43+ {
44+ std::cerr << " Failed to open output file: " << outputFilePath << ' \n ' ;
45+ return 1 ;
46+ }
1947
20- std::string outFilePath = R"( D:\Programming\RadA-Decoder\Output.wav)" ;
21- std::ofstream outFile (outFilePath, std::ios::binary);
48+ bool verbose = program.get <bool >(" -v" );
2249
23- std::shared_ptr<uint8_t > inputData;
50+ if (verbose)
51+ {
52+ std::cout << " Input File: " << inputFilePath << ' \n ' ;
53+ std::cout << " Output File: " << outputFilePath << ' \n ' ;
54+ }
2455
2556 inputFile.seekg (0 , std::ios::end);
2657 size_t inputDataSize = inputFile.tellg ();
@@ -32,55 +63,80 @@ int main()
3263 return 0 ;
3364 }
3465
35- inputData = std::shared_ptr <uint8_t >( new uint8_t [ inputDataSize] );
36- inputFile.read (reinterpret_cast <char *>(inputData.get ()), inputDataSize);
66+ std::vector <uint8_t > inputData ( inputDataSize);
67+ inputFile.read (reinterpret_cast <char *>(inputData.data ()), inputDataSize);
3768
3869 FSoundQualityInfo audioInfo;
39- if (!FRadAudioInfo::ParseHeader (inputData.get (), inputDataSize, &audioInfo))
70+ if (!FRadAudioInfo::ParseHeader (inputData.data (), inputDataSize, &audioInfo))
4071 {
4172 std::cerr << " Failed to parse RADA header." << ' \n ' ;
4273 return 0 ;
4374 }
75+
76+ if (verbose)
77+ {
78+ std::cout << " FSoundQualityInfo->SampleRate: " << audioInfo.SampleRate << ' \n ' ;
79+ std::cout << " FSoundQualityInfo->NumChannels: " << audioInfo.NumChannels << ' \n ' ;
80+ std::cout << " FSoundQualityInfo->SampleDataSize" << audioInfo.SampleDataSize << ' \n ' ;
81+ std::cout << " FSoundQualityInfo->Duration: " << audioInfo.Duration << ' \n ' ;
82+ }
4483
4584 uint8_t * rawMemory = nullptr ;
4685 RadAudioDecoderHeader* decoder = nullptr ;
4786 uint32_t srcBufferOffset = 0 ;
4887 RadAContainer* container = nullptr ;
49-
50- if (!FRadAudioInfo::CreateDecoder (inputData.get (), inputDataSize, decoder, rawMemory, srcBufferOffset, container))
88+
89+ if (!FRadAudioInfo::CreateDecoder (inputData.data (), inputDataSize, decoder, rawMemory, srcBufferOffset, container))
5190 {
5291 std::cerr << " Failed to create decoder." << ' \n ' ;
5392 return 0 ;
5493 }
55-
56- std::unique_ptr<uint8_t > compressedData = std::unique_ptr<uint8_t >(new uint8_t [inputDataSize - srcBufferOffset]);
5794
95+ if (verbose)
96+ {
97+ std::cout << " RadAudioDecoderHeader->SeekTableByteCount" << decoder->SeekTableByteCount << ' \n ' ;
98+ std::cout << " RadAudioDecoderHeader->ConsumeFrameCount" << decoder->ConsumeFrameCount << ' \n ' ;
99+ std::cout << " RadAudioDecoderHeader->OutputReservoirValidFrames" << decoder->OutputReservoirValidFrames << ' \n ' ;
100+ std::cout << " RadAudioDecoderHeader->OutputReservoirReadFrames" << decoder->OutputReservoirReadFrames << ' \n ' ;
101+ }
102+
103+ std::vector<uint8_t > compressedData (inputDataSize - srcBufferOffset);
58104 bool inSkip = false ;
59105 size_t dstOffset = 0 ;
60106
61107 for (size_t i = srcBufferOffset; i < inputDataSize; i++)
62108 {
63- if (!inSkip && i + 4 < inputDataSize && std::memcmp (&inputData. get () [i], " SEEK" , 4 ) == 0 )
109+ if (!inSkip && i + 4 < inputDataSize && std::memcmp (&inputData[i], " SEEK" , 4 ) == 0 )
64110 {
65111 inSkip = true ;
66- i += 3 ;
67-
112+ i += 1 ;
68113 }
69- else if (inSkip && i + 2 < inputDataSize && inputData. get () [i] == 0x55 )
114+ else if (inSkip && i + 2 < inputDataSize && inputData[i] == 0x55 )
70115 {
71116 inSkip = false ;
72- compressedData. get () [dstOffset++] = 0x55 ;
117+ compressedData[dstOffset++] = 0x55 ;
73118 }
74119 else if (!inSkip)
75120 {
76- compressedData. get () [dstOffset++] = inputData. get () [i];
121+ compressedData[dstOffset++] = inputData[i];
77122 }
78123 }
124+
125+ if (verbose)
126+ {
127+ std::cout << " CompressedDataSize" << dstOffset << ' \n ' ;
128+ }
79129
80- uint8_t * OutPCMData = ( uint8_t *) malloc (audioInfo.SampleDataSize );
81- auto result = FRadAudioInfo::Decode (compressedData.get (), dstOffset, OutPCMData, audioInfo.SampleDataSize , audioInfo.NumChannels , decoder);
130+ std::vector< uint8_t > OutPCMData (audioInfo.SampleDataSize );
131+ auto result = FRadAudioInfo::Decode (compressedData.data (), dstOffset, OutPCMData. data () , audioInfo.SampleDataSize , audioInfo.NumChannels , decoder);
82132
83- WaveHeader header = {0 };
133+ if (result.NumPcmBytesProduced == 0 )
134+ {
135+ std::cerr << " Failed to decode." << ' \n ' ;
136+ exit (-1 );
137+ }
138+
139+ WaveHeader header;
84140
85141 memcpy (header.riff_tag , " RIFF" , 4 );
86142 memcpy (header.wave_tag , " WAVE" , 4 );
@@ -89,9 +145,9 @@ int main()
89145
90146 header.sample_rate = audioInfo.SampleRate ;
91147 header.num_channels = audioInfo.NumChannels ;
92- header.riff_length = result.shii + sizeof (WaveHeader) - 8 ;
93- header.data_length = result.shii ;
94-
148+ header.riff_length = result.DataLength + sizeof (WaveHeader) - 8 ;
149+ header.data_length = result.DataLength ;
150+
95151 int bits_per_sample = 16 ;
96152
97153 header.fmt_length = 16 ;
@@ -101,14 +157,16 @@ int main()
101157 header.bits_per_sample = bits_per_sample;
102158
103159 outFile.write (reinterpret_cast <char *>(&header), sizeof (header));
104- outFile.write (reinterpret_cast <char *>(OutPCMData) , result.shii );
160+ outFile.write (reinterpret_cast <char *>(OutPCMData. data ()) , result.DataLength );
105161
106- std::cout << result.NumAudioFramesProduced << ' \n ' ;
107- std::cout << result.NumCompressedBytesConsumed << ' \n ' ;
108- std::cout << result.NumPcmBytesProduced << ' \n ' ;
162+ std::cout << " Audio Frames Produced: " << result.NumAudioFramesProduced << ' \n ' ;
163+ std::cout << " Compressed Bytes Consumed: " << result.NumCompressedBytesConsumed << ' \n ' ;
164+ std::cout << " PCM Bytes Produced: " << result.NumPcmBytesProduced << ' \n ' ;
109165
110166 inputFile.close ();
111167 outFile.close ();
112168
113- std::cout << " Shit worked" << ' \n ' ;
169+ std::cout << " Processing complete." << ' \n ' ;
170+
171+ exit (0 );
114172}
0 commit comments