SonicAudioTools/Source/SonicAudioCmd/csb_file_replacer.txt
2016-11-12 19:02:48 +03:00

172 lines
7.1 KiB
Plaintext

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Compression;
using System.ComponentModel;
using System.Collections;
using SonicAudioLib;
using SonicAudioLib.Archive;
using SonicAudioLib.Collections;
using SonicAudioLib.IO;
using SonicAudioLib.CriMw;
using System.Xml;
using System.Xml.Serialization;
namespace SonicAudioCmd
{
[Serializable]
public class SoundElement
{
public string Path { get; set; }
public uint SampleRate { get; set; }
public byte NumberChannels { get; set; }
public List<string> Sounds = new List<string>();
}
class Program
{
static void Main(string[] args)
{
if (args.Length < 1)
{
Console.WriteLine(Properties.Resources.HelpText);
Console.ReadLine();
return;
}
if (args[0].EndsWith(".csb"))
{
string directoryName = Path.Combine(Path.GetDirectoryName(args[0]), Path.GetFileNameWithoutExtension(args[0]));
List<SoundElement> soundElements = new List<SoundElement>();
using (CriTableReader reader = CriTableReader.Create(args[0]))
{
while (reader.Read())
{
if (reader.GetString("name") == "SOUND_ELEMENT")
{
using (CriTableReader sdlReader = CriTableReader.Create(reader.GetSubstream("utf")))
{
while (sdlReader.Read())
{
SoundElement soundElement = new SoundElement();
soundElement.Path = sdlReader.GetString("name");
soundElement.SampleRate = sdlReader.GetUInt32("sfreq");
soundElement.NumberChannels = sdlReader.GetByte("nch");
using (CriTableReader aaxReader = CriTableReader.Create(sdlReader.GetSubstream("data")))
{
while (aaxReader.Read())
{
string fileName = Path.Combine(directoryName, soundElement.Path,
$"{soundElement.Path.Replace('/', '_')}_{aaxReader.GetByte("lpflg")}.adx");
soundElement.Sounds.Add(fileName);
FileInfo fileInfo = new FileInfo(fileName);
fileInfo.Directory.Create();
using (Stream inStream = aaxReader.GetSubstream("data"), outStream = fileInfo.Create())
{
inStream.CopyTo(outStream);
}
}
}
soundElements.Add(soundElement);
}
}
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<SoundElement>));
using (XmlWriter xmlWriter = XmlWriter.Create(directoryName + ".xml", new XmlWriterSettings() { Indent = true }))
{
xmlSerializer.Serialize(xmlWriter, soundElements);
}
break;
}
}
}
}
else if (args[0].EndsWith(".xml"))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<SoundElement>));
List<SoundElement> soundElements;
using (XmlReader xmlReader = XmlReader.Create(args[0]))
{
soundElements = (List<SoundElement>)xmlSerializer.Deserialize(xmlReader);
}
CriTable criTable = new CriTable();
string directoryName = Path.Combine(Path.GetDirectoryName(args[0]), Path.GetFileNameWithoutExtension(args[0]));
if (!File.Exists(directoryName + ".csb"))
{
throw new FileNotFoundException("No valid CSB file found for this XML!");
}
criTable.Load(directoryName + ".csb");
Directory.CreateDirectory(directoryName + "-temp");
CriTable soundElementTable = new CriTable();
CriRow soundElementRow = criTable.Rows.Single(row => (string)row["name"] == "SOUND_ELEMENT");
soundElementTable.Load((byte[])soundElementRow["utf"]);
foreach (SoundElement soundElement in soundElements)
{
CriRow elementRow = soundElementTable.Rows.Single(row => (string)row["name"] == soundElement.Path);
elementRow["nch"] = soundElement.NumberChannels;
elementRow["sfreq"] = soundElement.SampleRate;
using (CriTableWriter aaxWriter = CriTableWriter.Create($"{directoryName}-temp/{soundElement.Path.Replace('/', '_')}"))
{
aaxWriter.WriteStartTable("AAX");
aaxWriter.WriteStartFieldCollection();
aaxWriter.WriteField("data", typeof(byte[]));
aaxWriter.WriteField("lpflg", typeof(byte));
aaxWriter.WriteEndFieldCollection();
foreach (string sound in soundElement.Sounds)
{
if (!File.Exists(sound))
{
Directory.Delete(directoryName + "-temp", true);
throw new FileNotFoundException($"Can't find file! {sound}");
}
string baseName = Path.GetFileNameWithoutExtension(sound);
int lastUnderscore = baseName.LastIndexOf('_');
baseName = baseName.Substring(lastUnderscore + 1);
byte loopFlag = byte.Parse(baseName);
aaxWriter.WriteRow(true, new FileInfo(sound), loopFlag);
}
aaxWriter.WriteEndTable();
}
elementRow["data"] = File.ReadAllBytes($"{directoryName}-temp/{soundElement.Path.Replace('/', '_')}");
}
soundElementTable.Save($"{directoryName}-temp/SOUND_ELEMENT");
soundElementRow["utf"] = File.ReadAllBytes($"{directoryName}-temp/SOUND_ELEMENT");
criTable.Save(directoryName + ".csb");
Directory.Delete(directoryName + "-temp", true);
}
else
{
throw new FileNotFoundException("No valid file found!");
}
}
}
}