Improve some stuffs
This commit is contained in:
parent
2379bf30e7
commit
15bb8ac5b4
Binary file not shown.
|
@ -2,5 +2,5 @@
|
|||
<configuration>
|
||||
<startup>
|
||||
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7"/></startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/></startup>
|
||||
</configuration>
|
||||
|
|
|
@ -28,13 +28,12 @@ namespace CXML
|
|||
TYPE_ID_INT
|
||||
};
|
||||
|
||||
class Parser
|
||||
class CXMLParser
|
||||
{
|
||||
private bool DECODE_VAG = true;
|
||||
private bool DECODE_GIM = true;
|
||||
|
||||
private static bool _checkMagicNumber()
|
||||
{
|
||||
|
||||
String Magic = Tools.ReadStringAt(InfoFile, 0x00);
|
||||
|
||||
if (Magic.StartsWith("PSMA"))
|
||||
|
@ -54,6 +53,12 @@ namespace CXML
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static string _lastFileName = "";
|
||||
|
||||
static String MainDir = "";
|
||||
static String FileDir = "";
|
||||
static String XMLFilename = "";
|
||||
|
||||
static FileStream InfoFile;
|
||||
|
||||
|
@ -73,12 +78,13 @@ namespace CXML
|
|||
static BinaryReader bFloatArrayTable;
|
||||
static BinaryReader bIntArrayTable;
|
||||
static BinaryReader bStylesIDTable;
|
||||
static BinaryReader bStringIDTable;
|
||||
|
||||
static XmlWriter XMLFile;
|
||||
|
||||
public static void Init(string Path, bool CheckMagic = true)
|
||||
public static void Init(string path, bool CheckMagic = true)
|
||||
{
|
||||
InfoFile = File.Open(Path, FileMode.Open, FileAccess.Read);
|
||||
InfoFile = File.Open(path, FileMode.Open, FileAccess.Read);
|
||||
if(CheckMagic)
|
||||
{
|
||||
if (!_checkMagicNumber())
|
||||
|
@ -104,6 +110,17 @@ namespace CXML
|
|||
bFloatArrayTable = new BinaryReader(FloatArrayTable);
|
||||
bIntArrayTable = new BinaryReader(IntArrayTable);
|
||||
bStylesIDTable = new BinaryReader(StylesIDTable);
|
||||
bStringIDTable = new BinaryReader(StringIDTable);
|
||||
|
||||
MainDir = Path.GetFileNameWithoutExtension(path);
|
||||
FileDir = Path.Combine(MainDir, "files");
|
||||
XMLFilename = Path.GetFileNameWithoutExtension(path) + ".xml";
|
||||
|
||||
if (Directory.Exists(MainDir))
|
||||
Directory.Delete(MainDir, true);
|
||||
|
||||
if (!Directory.Exists(FileDir))
|
||||
Directory.CreateDirectory(FileDir);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -310,17 +327,19 @@ namespace CXML
|
|||
|
||||
public static void DecompileCXML(String CXMLFile, bool force = false)
|
||||
{
|
||||
if(Directory.Exists("files"))
|
||||
Directory.Delete("files", true);
|
||||
|
||||
Directory.CreateDirectory(MainDir);
|
||||
|
||||
Term();
|
||||
Init(CXMLFile,force);
|
||||
|
||||
XmlWriterSettings XMLSettings = new XmlWriterSettings();
|
||||
XMLSettings.Indent = true;
|
||||
|
||||
XMLFile = XmlWriter.Create(Path.GetFileNameWithoutExtension(CXMLFile)+".xml", XMLSettings);
|
||||
XMLFile = XmlWriter.Create(Path.Combine(MainDir, XMLFilename), XMLSettings);
|
||||
XMLFile.WriteStartDocument();
|
||||
|
||||
ReadElement();
|
||||
ReadElements();
|
||||
|
||||
XMLFile.WriteEndDocument();
|
||||
XMLFile.Flush();
|
||||
|
@ -331,25 +350,25 @@ namespace CXML
|
|||
public static void ProcessFile(String FileName)
|
||||
{
|
||||
String Extension = Path.GetExtension(FileName);
|
||||
|
||||
|
||||
if (Extension == ".vag") //Remove this IF statment if you dont want VAG Conversion.
|
||||
{
|
||||
Console.WriteLine("Decoding: " + Path.GetFileName(FileName));
|
||||
byte[] WaveData = VAG.VAGAudio.Vag2Wav(FileName);
|
||||
String WaveName = Path.GetFileNameWithoutExtension(FileName) + "-" + VAG.VAGAudio.GetFilename(FileName) + ".wav";
|
||||
|
||||
if (!Directory.Exists("files/converted/VAGtoWAV"))
|
||||
Directory.CreateDirectory("files/converted/VAGtoWAV");
|
||||
if (!Directory.Exists(FileDir+"/converted/VAGtoWAV"))
|
||||
Directory.CreateDirectory(FileDir + "/converted/VAGtoWAV");
|
||||
|
||||
File.WriteAllBytes("files/converted/VAGtoWAV/" + WaveName, WaveData);
|
||||
File.WriteAllBytes(FileDir + "/converted/VAGtoWAV/" + WaveName, WaveData);
|
||||
Console.WriteLine("Decoded file written to: " + WaveName);
|
||||
}
|
||||
if (Extension == ".gim") //Remove this IF statement if you dont want GIM Conversion.
|
||||
{
|
||||
if (File.Exists("GimConv/GimConv.exe"))
|
||||
{
|
||||
if (!Directory.Exists("files/converted"))
|
||||
Directory.CreateDirectory("files/converted/GIMtoPNG");
|
||||
if (!Directory.Exists(FileDir + "/converted/GIMtoPNG"))
|
||||
Directory.CreateDirectory(FileDir + "/converted/GIMtoPNG");
|
||||
|
||||
Console.WriteLine("Decoding GIM.");
|
||||
|
||||
|
@ -359,7 +378,7 @@ namespace CXML
|
|||
Proc.StartInfo.RedirectStandardOutput = true;
|
||||
Proc.StartInfo.RedirectStandardError = true;
|
||||
Proc.StartInfo.UseShellExecute = false;
|
||||
Proc.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory() + "/files/decompressed";
|
||||
Proc.StartInfo.WorkingDirectory = Path.GetDirectoryName(FileName);
|
||||
Proc.Start();
|
||||
Proc.WaitForExit();
|
||||
Console.WriteLine(Proc.StandardOutput.ReadToEnd());
|
||||
|
@ -368,7 +387,24 @@ namespace CXML
|
|||
}
|
||||
|
||||
}
|
||||
if (Extension == ".zlib")
|
||||
{
|
||||
Console.WriteLine("Decompressing " + FileName);
|
||||
Byte[] FileData = File.ReadAllBytes(FileName);
|
||||
Byte[] DecompressedData = ZlibStream.UncompressBuffer(FileData);
|
||||
Extension = Tools.GetFileExtension(DecompressedData);
|
||||
|
||||
if (!Directory.Exists(FileDir + "/decompressed"))
|
||||
Directory.CreateDirectory(FileDir + "/decompressed");
|
||||
|
||||
String DecompressedFilename = FileDir + "/decompressed /" + Path.GetFileNameWithoutExtension(FileName) + Extension;
|
||||
Console.WriteLine("Decompressed file written to: " + DecompressedFilename);
|
||||
File.WriteAllBytes(DecompressedFilename, DecompressedData);
|
||||
|
||||
ProcessFile(DecompressedFilename);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void ReadAttribute(String ElementName = "")
|
||||
{
|
||||
|
@ -377,6 +413,7 @@ namespace CXML
|
|||
|
||||
String AttributeName = Tools.ReadStringAt(StringTable, AttributePtr);
|
||||
object AttributeValue = "";
|
||||
|
||||
Console.WriteLine("AttributeType: " + Type.ToString() + " - "+ TreeTable.Position.ToString());
|
||||
switch (Type)
|
||||
{
|
||||
|
@ -463,9 +500,6 @@ namespace CXML
|
|||
FileTable.Seek(FilePtr, SeekOrigin.Begin);
|
||||
FileTable.Read(FileData, 0, FileSz);
|
||||
|
||||
if (!Directory.Exists("files"))
|
||||
Directory.CreateDirectory("files");
|
||||
|
||||
int count = 0;
|
||||
string CounterStr = count.ToString();
|
||||
do
|
||||
|
@ -474,25 +508,15 @@ namespace CXML
|
|||
CounterStr = count.ToString();
|
||||
if (count == 0)
|
||||
CounterStr = "";
|
||||
FileName = "files/" + ElementName + "-" + AttributeName + CounterStr + Extension;
|
||||
FileName = Path.Combine(FileDir , ElementName , AttributeName + CounterStr + Extension);
|
||||
count++;
|
||||
}
|
||||
while (File.Exists(FileName));
|
||||
|
||||
Console.WriteLine("Writing: " + FileName);
|
||||
if(Path.GetExtension(FileName) == ".zlib")
|
||||
{
|
||||
Console.WriteLine("Decompressing " + FileName);
|
||||
Byte[] DecompressedData = ZlibStream.UncompressBuffer(FileData);
|
||||
String Extension = Tools.GetFileExtension(DecompressedData);
|
||||
if (!Directory.Exists("files/decompressed"))
|
||||
Directory.CreateDirectory("files/decompressed");
|
||||
String DecompressedFilename = "files/decompressed/" + ElementName + "-" + AttributeName + CounterStr + Extension;
|
||||
Console.WriteLine("Decompressed file written to: " + DecompressedFilename);
|
||||
|
||||
File.WriteAllBytes(DecompressedFilename, DecompressedData);
|
||||
ProcessFile(DecompressedFilename);
|
||||
}
|
||||
if (!Directory.Exists(Path.GetDirectoryName(FileName)))
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(FileName));
|
||||
|
||||
File.WriteAllBytes(FileName, FileData);
|
||||
ProcessFile(FileName);
|
||||
|
@ -501,7 +525,16 @@ namespace CXML
|
|||
break;
|
||||
case AttributeType.TYPE_ID_STRING_LOOPBACK:
|
||||
int StringIdTableOffset = bTreeTable.ReadInt32();
|
||||
AttributeValue = Tools.ReadStringAt(StringIDTable, StringIdTableOffset + 0x4);
|
||||
StringIDTable.Seek(StringIdTableOffset, SeekOrigin.Begin);
|
||||
|
||||
int LoopbackPtr = bStringIDTable.ReadInt32();
|
||||
int StringPtr = Tools.ReadIntAt(TreeTable, LoopbackPtr);
|
||||
string LoopbackAttribute = Tools.ReadStringAt(StringTable, StringPtr);
|
||||
|
||||
Console.WriteLine("Loopback: " + LoopbackAttribute);
|
||||
|
||||
AttributeValue = Tools.ReadString(StringIDTable);
|
||||
|
||||
TreeTable.Seek(4, SeekOrigin.Current);
|
||||
break;
|
||||
case AttributeType.TYPE_ID_STRING:
|
||||
|
@ -511,14 +544,18 @@ namespace CXML
|
|||
case AttributeType.TYPE_ID_INT_LOOPBACK:
|
||||
int IntIdTableOffset = bTreeTable.ReadInt32();
|
||||
IntIDTable.Seek(IntIdTableOffset, SeekOrigin.Begin);
|
||||
int Loopback = bIntIDTable.ReadInt32();
|
||||
|
||||
LoopbackPtr = bIntIDTable.ReadInt32();
|
||||
StringPtr = Tools.ReadIntAt(TreeTable, LoopbackPtr);
|
||||
|
||||
int IDValue = bIntIDTable.ReadInt32();
|
||||
|
||||
int StringPtr = Tools.ReadIntAt(TreeTable, Loopback);
|
||||
String LoopbackAttribute = Tools.ReadStringAt(StringTable, StringPtr);
|
||||
|
||||
LoopbackAttribute = Tools.ReadStringAt(StringTable, StringPtr);
|
||||
Console.WriteLine("Loopback: " + LoopbackAttribute);
|
||||
|
||||
AttributeValue = IDValue.ToString("X8");
|
||||
|
||||
TreeTable.Seek(4, SeekOrigin.Current);
|
||||
break;
|
||||
case AttributeType.TYPE_ID_INT:
|
||||
|
@ -540,7 +577,7 @@ namespace CXML
|
|||
XMLFile.Flush();
|
||||
}
|
||||
|
||||
public static void ReadElement()
|
||||
public static void ReadElements()
|
||||
{
|
||||
|
||||
int ElementPtr = bTreeTable.ReadInt32();
|
||||
|
@ -577,7 +614,7 @@ namespace CXML
|
|||
if (FirstChild != -1)
|
||||
{
|
||||
TreeTable.Seek(FirstChild, SeekOrigin.Begin);
|
||||
ReadElement();
|
||||
ReadElements();
|
||||
}
|
||||
|
||||
|
||||
|
@ -587,7 +624,7 @@ namespace CXML
|
|||
if (NextSibling != -1)
|
||||
{
|
||||
TreeTable.Seek(NextSibling, SeekOrigin.Begin);
|
||||
ReadElement();
|
||||
ReadElements();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>CXMLDecompiler</RootNamespace>
|
||||
<AssemblyName>CXMLDecompiler</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
|
|
|
@ -9,6 +9,8 @@ namespace CXMLCli
|
|||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
//args = "src20.vag -iv".Split(' ');
|
||||
|
||||
bool Check = true;
|
||||
|
||||
if (args.Length == 0)
|
||||
|
@ -49,7 +51,7 @@ namespace CXMLCli
|
|||
return;
|
||||
}
|
||||
|
||||
CXML.Parser.Init(path, Check);
|
||||
CXML.CXMLParser.Init(path, Check);
|
||||
|
||||
|
||||
if (ArgsFull.Contains("-f") || ArgsFull.Contains("--force"))
|
||||
|
@ -65,66 +67,66 @@ namespace CXMLCli
|
|||
if (ArgsFull.Contains("-tt") || ArgsFull.Contains("--dump-tree"))
|
||||
{
|
||||
Console.WriteLine("Dumping tree table.");
|
||||
File.WriteAllBytes("tree-table.bin", CXML.Parser.GetTreeTable());
|
||||
File.WriteAllBytes("tree-table.bin", CXML.CXMLParser.GetTreeTable());
|
||||
|
||||
}
|
||||
|
||||
if (ArgsFull.Contains("-ist") || ArgsFull.Contains("--dump-string-id"))
|
||||
{
|
||||
Console.WriteLine("Dumping string ID table.");
|
||||
File.WriteAllBytes("string-id-table.bin", CXML.Parser.GetStringIDTable());
|
||||
File.WriteAllBytes("string-id-table.bin", CXML.CXMLParser.GetStringIDTable());
|
||||
|
||||
}
|
||||
|
||||
if (ArgsFull.Contains("-iit") || ArgsFull.Contains("--dump-int-id"))
|
||||
{
|
||||
Console.WriteLine("Dumping int ID table.");
|
||||
File.WriteAllBytes("int-id-table.bin", CXML.Parser.GetIntIDTable());
|
||||
File.WriteAllBytes("int-id-table.bin", CXML.CXMLParser.GetIntIDTable());
|
||||
}
|
||||
|
||||
if (ArgsFull.Contains("-st") || ArgsFull.Contains("--dump-string"))
|
||||
{
|
||||
Console.WriteLine("Dumping string table.");
|
||||
File.WriteAllBytes("string-table.bin",CXML.Parser.GetStringTable());
|
||||
File.WriteAllBytes("string-table.bin",CXML.CXMLParser.GetStringTable());
|
||||
|
||||
}
|
||||
|
||||
if (ArgsFull.Contains("-ct") || ArgsFull.Contains("--dump-char"))
|
||||
{
|
||||
Console.WriteLine("Dumping char table.");
|
||||
File.WriteAllBytes("char-table.bin", CXML.Parser.GetCharTable());
|
||||
File.WriteAllBytes("char-table.bin", CXML.CXMLParser.GetCharTable());
|
||||
}
|
||||
|
||||
if (ArgsFull.Contains("-sit") || ArgsFull.Contains("--dump-style-id"))
|
||||
{
|
||||
Console.WriteLine("Dumping style ID table.");
|
||||
File.WriteAllBytes("style-id-table.bin", CXML.Parser.GetStyleIDTable());
|
||||
File.WriteAllBytes("style-id-table.bin", CXML.CXMLParser.GetStyleIDTable());
|
||||
}
|
||||
|
||||
|
||||
if (ArgsFull.Contains("-iat") || ArgsFull.Contains("--dump-int-array"))
|
||||
{
|
||||
Console.WriteLine("Dumping int array table.");
|
||||
File.WriteAllBytes("int-array-table.bin", CXML.Parser.GetIntArrayTable());
|
||||
File.WriteAllBytes("int-array-table.bin", CXML.CXMLParser.GetIntArrayTable());
|
||||
}
|
||||
|
||||
if (ArgsFull.Contains("-fat") || ArgsFull.Contains("--dump-float-array"))
|
||||
{
|
||||
Console.WriteLine("Dumping float array table.");
|
||||
File.WriteAllBytes("float-array-table.bin", CXML.Parser.GetFloatArrayTable());
|
||||
File.WriteAllBytes("float-array-table.bin", CXML.CXMLParser.GetFloatArrayTable());
|
||||
}
|
||||
|
||||
|
||||
if (ArgsFull.Contains("-ft") || ArgsFull.Contains("--dump-tree"))
|
||||
{
|
||||
Console.WriteLine("Dumping file table.");
|
||||
File.WriteAllBytes("file-table.bin", CXML.Parser.GetTreeTable());
|
||||
File.WriteAllBytes("file-table.bin", CXML.CXMLParser.GetTreeTable());
|
||||
}
|
||||
|
||||
if (ArgsFull.Contains("-d") || ArgsFull.Contains("--decompile") || args.Length == 1)
|
||||
{
|
||||
Console.WriteLine("Decompiling.");
|
||||
CXML.Parser.DecompileCXML(path, Check);
|
||||
CXML.CXMLParser.DecompileCXML(path, Check);
|
||||
Console.WriteLine("\n\nDECOMPILATION COMPLETE!");
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
|
|
@ -54,10 +54,6 @@ namespace General
|
|||
{
|
||||
return ".zlib";
|
||||
}
|
||||
else if (IsGim(Bytes))
|
||||
{
|
||||
return ".gim";
|
||||
}
|
||||
else if (IsRcf(Bytes))
|
||||
{
|
||||
return ".rcs";
|
||||
|
@ -70,6 +66,10 @@ namespace General
|
|||
{
|
||||
return ".vag";
|
||||
}
|
||||
else if (IsGim(Bytes))
|
||||
{
|
||||
return ".gim";
|
||||
}
|
||||
else
|
||||
{
|
||||
return ".bin";
|
||||
|
@ -196,18 +196,38 @@ namespace General
|
|||
return i;
|
||||
}
|
||||
|
||||
public static int ReadBigEndainIntAt(Stream ms, int location)
|
||||
{
|
||||
long ogPos = ms.Position;
|
||||
ms.Seek(location, SeekOrigin.Begin);
|
||||
int i = ReadBigEndainInt(ms);
|
||||
ms.Seek(ogPos, SeekOrigin.Begin);
|
||||
return i;
|
||||
}
|
||||
|
||||
public static int ReadBigEndainInt(Stream ms)
|
||||
{
|
||||
byte[] IntBytes = new byte[4];
|
||||
ms.Read(IntBytes, 0x00, 4);
|
||||
IntBytes = IntBytes.Reverse().ToArray();
|
||||
int i = BitConverter.ToInt32(IntBytes, 0x00);
|
||||
return i;
|
||||
}
|
||||
|
||||
public static String ReadString(Stream ms, int limit = -1)
|
||||
{
|
||||
int i = 0xFF;
|
||||
int counter = 0;
|
||||
|
||||
MemoryStream StringStream = new MemoryStream();
|
||||
|
||||
do
|
||||
{
|
||||
i = ms.ReadByte();
|
||||
if (i == 0 && i != limit)
|
||||
if (i == 0 || counter == limit)
|
||||
break;
|
||||
StringStream.WriteByte((byte)i);
|
||||
counter += 1;
|
||||
}
|
||||
while (true);
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace VAG
|
|||
{
|
||||
class VAGAudio
|
||||
{
|
||||
static int[,] HEVAGCoeffTable = new int[,]
|
||||
private static int[,] HEVAGCoeffTable = new int[,]
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 7680, 0, 0, 0 },
|
||||
|
@ -144,7 +144,6 @@ namespace VAG
|
|||
{ 13064, -4075, -2824, 1877 },
|
||||
{ 5333, 2999, 775, -1132 },
|
||||
};
|
||||
|
||||
private static byte[] WriteWaveHeader(byte[] PCMData, int channels, int samplerate)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
|
@ -161,8 +160,8 @@ namespace VAG
|
|||
bw.Write((short)1);
|
||||
bw.Write((short)channels);
|
||||
bw.Write(samplerate);
|
||||
bw.Write(samplerate * channels * 2);
|
||||
bw.Write((short)(channels * 2));
|
||||
bw.Write((samplerate * 16 * channels)/8);
|
||||
bw.Write((short)(16 * channels));
|
||||
bw.Write((short)16);
|
||||
|
||||
Tools.WriteStringToStream(ms, "data");
|
||||
|
@ -172,72 +171,76 @@ namespace VAG
|
|||
ms.Seek(0x00, SeekOrigin.Begin);
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
|
||||
public static FileStream VagStream;
|
||||
|
||||
public static void Init(string VagFile)
|
||||
{
|
||||
VagStream = new FileStream(VagFile, FileMode.Open, FileAccess.Read);
|
||||
if (Tools.ReadStringAt(VagStream, 0x00) != "VAGp")
|
||||
throw new Exception("Not a VAG file.");
|
||||
}
|
||||
|
||||
|
||||
public static byte[] Vag2Wav(string VagFile)
|
||||
{
|
||||
byte[] FileData = File.ReadAllBytes(VagFile);
|
||||
if(Tools.IsVAG(FileData))
|
||||
{
|
||||
byte[] PCMData = DecodePCM(FileData);
|
||||
byte[] WAVData = WriteWaveHeader(PCMData, GetChannels(VagFile), GetSampleRate(VagFile));
|
||||
return WAVData;
|
||||
}
|
||||
throw new Exception("Not a VAG file.");
|
||||
Init(VagFile);
|
||||
|
||||
byte[] PCMData = DecodePCM();
|
||||
byte[] WAVData = WriteWaveHeader(PCMData, 1, GetSampleRate());
|
||||
return WAVData;
|
||||
}
|
||||
|
||||
public static int GetChannels(string VagFile)
|
||||
public static int GetChannels()
|
||||
{
|
||||
FileStream VagStream = new FileStream(VagFile, FileMode.Open, FileAccess.Read);
|
||||
VagStream.Seek(0x1E, SeekOrigin.Begin);
|
||||
int ChannelCount = VagStream.ReadByte();
|
||||
if (ChannelCount == 0)
|
||||
ChannelCount = 1; //Its most likely mono...
|
||||
VagStream.Close();
|
||||
|
||||
if (ChannelCount >= 2)
|
||||
ChannelCount = 2;
|
||||
else
|
||||
ChannelCount = 1;
|
||||
|
||||
return ChannelCount;
|
||||
}
|
||||
|
||||
public static string GetFilename(string VagFile)
|
||||
{
|
||||
FileStream VagStream = new FileStream(VagFile, FileMode.Open, FileAccess.Read);
|
||||
String FileName = Tools.ReadStringAt(VagStream, 0x20);
|
||||
VagStream.Close();
|
||||
return FileName;
|
||||
return Tools.ReadStringAt(VagStream, 0x20);
|
||||
}
|
||||
|
||||
public static int GetSampleRate(String VagFile)
|
||||
public static int GetSampleRate()
|
||||
{
|
||||
FileStream VagStream = new FileStream(VagFile, FileMode.Open, FileAccess.Read);
|
||||
VagStream.Seek(0x12, SeekOrigin.Begin);
|
||||
return Tools.ReadBigEndainIntAt(VagStream, 0x10);
|
||||
}
|
||||
|
||||
//IDK Either, ask sony why they didnt just use an int16
|
||||
int SampleRate = VagStream.ReadByte() * 256 + VagStream.ReadByte();
|
||||
VagStream.Close();
|
||||
|
||||
return SampleRate;
|
||||
public static int GetWaveformDataSize()
|
||||
{
|
||||
return Tools.ReadBigEndainIntAt(VagStream, 0x0C);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] DecodePCM(byte[] VagFile)
|
||||
|
||||
public static byte[] DecodePCM()
|
||||
{
|
||||
int Hist = 0;
|
||||
int Hist2 = 0;
|
||||
int Hist3 = 0;
|
||||
int Hist4 = 0;
|
||||
|
||||
MemoryStream VagStream = Tools.ByteToStream(VagFile);
|
||||
int FileSize = GetWaveformDataSize() - 0x40;
|
||||
int Channels = GetChannels();
|
||||
bool IsStereo = (Channels > 1);
|
||||
|
||||
BinaryReader VagReader = new BinaryReader(VagStream);
|
||||
|
||||
MemoryStream PCMStream = new MemoryStream();
|
||||
BinaryWriter PCMWriter = new BinaryWriter(PCMStream);
|
||||
|
||||
|
||||
VagStream.Seek(0x40, SeekOrigin.Begin);
|
||||
|
||||
while (VagStream.Position < VagStream.Length)
|
||||
{
|
||||
|
||||
while (VagStream.Position < FileSize)
|
||||
{
|
||||
byte DecodingCoefficent = VagReader.ReadByte();
|
||||
int ShiftBy = DecodingCoefficent & 0xf;
|
||||
int PredictNr = DecodingCoefficent >> 0x4;
|
||||
|
@ -254,97 +257,59 @@ namespace VAG
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
for (int i = 0; i < 14; i++)
|
||||
{
|
||||
//First Byte:
|
||||
|
||||
byte ADPCMData = VagReader.ReadByte();
|
||||
int SampleFlags = ADPCMData & 0xF;
|
||||
int Coefficent;
|
||||
int Sample;
|
||||
|
||||
if (SampleFlags > 7)
|
||||
short Sample;
|
||||
|
||||
for(int ii = 0; ii <= 1; ii++)
|
||||
{
|
||||
SampleFlags -= 16;
|
||||
if (SampleFlags > 7)
|
||||
{
|
||||
SampleFlags -= 16;
|
||||
}
|
||||
|
||||
if (PredictNr < 128)
|
||||
{
|
||||
Coefficent = Hist * HEVAGCoeffTable[PredictNr, 0] + Hist2 * HEVAGCoeffTable[PredictNr, 1] + Hist3 * HEVAGCoeffTable[PredictNr, 2] + Hist4 * HEVAGCoeffTable[PredictNr, 3];
|
||||
}
|
||||
else
|
||||
{
|
||||
Coefficent = 0;
|
||||
}
|
||||
|
||||
Sample = (short)(Coefficent / 32 + (SampleFlags << 20 - ShiftBy) + 128 >> 8);
|
||||
|
||||
PCMWriter.Write(Sample);
|
||||
|
||||
|
||||
Hist4 = Hist3;
|
||||
Hist3 = Hist2;
|
||||
Hist2 = Hist;
|
||||
Hist = Sample;
|
||||
|
||||
SampleFlags = ADPCMData >> 4;
|
||||
}
|
||||
|
||||
if (PredictNr < 128)
|
||||
{
|
||||
Coefficent = Hist * HEVAGCoeffTable[PredictNr, 0] + Hist2 * HEVAGCoeffTable[PredictNr, 1] + Hist3 * HEVAGCoeffTable[PredictNr, 2] + Hist4 * HEVAGCoeffTable[PredictNr, 3];
|
||||
}
|
||||
else
|
||||
{
|
||||
Coefficent = 0;
|
||||
}
|
||||
|
||||
Sample = Coefficent / 32 + (SampleFlags << 20 - ShiftBy) + 128 >> 8;
|
||||
|
||||
//Apparently unchecked(short) isnt good enough?
|
||||
//I guess it cant be modulo?
|
||||
//IDK im just doing what i saw in the decompiled code.
|
||||
|
||||
if (Sample > 32767)
|
||||
{
|
||||
Sample = 32767;
|
||||
}
|
||||
else if (Sample < -32768)
|
||||
{
|
||||
Sample = -32768;
|
||||
}
|
||||
|
||||
PCMWriter.Write((short)Sample);
|
||||
|
||||
//Second Byte:
|
||||
|
||||
Hist4 = Hist3;
|
||||
Hist3 = Hist2;
|
||||
Hist2 = Hist;
|
||||
Hist = Sample;
|
||||
|
||||
SampleFlags = ADPCMData >> 4;
|
||||
|
||||
if (SampleFlags > 7)
|
||||
{
|
||||
SampleFlags -= 16;
|
||||
}
|
||||
|
||||
if (PredictNr < 128)
|
||||
{
|
||||
Coefficent = Hist * HEVAGCoeffTable[PredictNr, 0] + Hist2 * HEVAGCoeffTable[PredictNr, 1] + Hist3 * HEVAGCoeffTable[PredictNr, 2] + Hist4 * HEVAGCoeffTable[PredictNr, 3];
|
||||
}
|
||||
else
|
||||
{
|
||||
Coefficent = 0;
|
||||
}
|
||||
|
||||
Sample = Coefficent / 32 + (SampleFlags << 20 - ShiftBy) + 128 >> 8;
|
||||
|
||||
if (Sample > 32767)
|
||||
{
|
||||
Sample = 32767;
|
||||
}
|
||||
else if (Sample < -32768)
|
||||
{
|
||||
Sample = -32768;
|
||||
}
|
||||
|
||||
PCMWriter.Write((short)Sample);
|
||||
|
||||
Hist4 = Hist3;
|
||||
Hist3 = Hist2;
|
||||
Hist2 = Hist;
|
||||
Hist = Sample;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Arg im mad because i know how to get left/right channels
|
||||
* But i have no idea how to combine them
|
||||
* So lets just get one and call it a day.
|
||||
*/
|
||||
|
||||
if (IsStereo)
|
||||
VagStream.Seek(16, SeekOrigin.Current);
|
||||
}
|
||||
|
||||
|
||||
PCMStream.Seek(0x00, SeekOrigin.Begin);
|
||||
byte[] PCMData = PCMStream.ToArray();
|
||||
|
||||
VagReader.Close();
|
||||
VagStream.Close();
|
||||
|
||||
PCMWriter.Close();
|
||||
PCMStream.Close();
|
||||
|
||||
|
|
Loading…
Reference in New Issue