mirror of
https://github.com/blueskythlikesclouds/SonicAudioTools.git
synced 2025-02-11 00:12:59 +01:00
170 lines
7.4 KiB
C#
170 lines
7.4 KiB
C#
|
using System;
|
|||
|
using System.Linq;
|
|||
|
using System.IO;
|
|||
|
using System.Windows.Forms;
|
|||
|
|
|||
|
using SonicAudioLib.CriMw;
|
|||
|
using SonicAudioLib.IO;
|
|||
|
using SonicAudioLib.Archive;
|
|||
|
|
|||
|
using System.Globalization;
|
|||
|
|
|||
|
namespace CsbEditor
|
|||
|
{
|
|||
|
class Program
|
|||
|
{
|
|||
|
static void Main(string[] args)
|
|||
|
{
|
|||
|
if (args.Length < 1)
|
|||
|
{
|
|||
|
Console.WriteLine(Properties.Resources.Description);
|
|||
|
Console.ReadLine();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
if (args[0].EndsWith(".csb"))
|
|||
|
{
|
|||
|
string baseDirectory = Path.GetDirectoryName(args[0]);
|
|||
|
string outputDirectoryName = Path.Combine(baseDirectory, Path.GetFileNameWithoutExtension(args[0]));
|
|||
|
|
|||
|
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())
|
|||
|
{
|
|||
|
if (sdlReader.GetByte("stmflg") != 0)
|
|||
|
{
|
|||
|
throw new Exception("The given CSB file contains external audio data. Those kind of CSB files are not supported yet.");
|
|||
|
}
|
|||
|
|
|||
|
if (sdlReader.GetByte("fmt") != 0)
|
|||
|
{
|
|||
|
throw new Exception("The given CSB file contains an audio file which is not an ADX. Only CSB files with ADXs are supported.");
|
|||
|
}
|
|||
|
|
|||
|
string sdlName = sdlReader.GetString("name");
|
|||
|
DirectoryInfo destinationPath = new DirectoryInfo(Path.Combine(outputDirectoryName, sdlName));
|
|||
|
destinationPath.Create();
|
|||
|
|
|||
|
Console.WriteLine("Extracting {0}...", sdlName);
|
|||
|
using (CriTableReader aaxReader = CriTableReader.Create(sdlReader.GetSubstream("data")))
|
|||
|
{
|
|||
|
while (aaxReader.Read())
|
|||
|
{
|
|||
|
string outputName = Path.Combine(destinationPath.FullName, aaxReader.GetBoolean("lpflg") ? "Loop.adx" : "Intro.adx");
|
|||
|
|
|||
|
using (Stream source = aaxReader.GetSubstream("data"))
|
|||
|
using (Stream destination = File.Create(outputName))
|
|||
|
{
|
|||
|
source.CopyTo(destination);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
else if (File.GetAttributes(args[0]).HasFlag(FileAttributes.Directory))
|
|||
|
{
|
|||
|
string baseDirectory = Path.GetDirectoryName(args[0]);
|
|||
|
string csbPath = args[0] + ".csb";
|
|||
|
|
|||
|
if (!File.Exists(csbPath))
|
|||
|
{
|
|||
|
throw new Exception("Cannot find the .CSB file for this directory. Please ensure that the .CSB file is stored in the directory where this directory is.");
|
|||
|
}
|
|||
|
|
|||
|
CriTable csbFile = new CriTable();
|
|||
|
csbFile.Load(csbPath);
|
|||
|
|
|||
|
CriRow soundElementRow = csbFile.Rows.Single(row => (string)row["name"] == "SOUND_ELEMENT");
|
|||
|
|
|||
|
CriTable soundElementTable = new CriTable();
|
|||
|
soundElementTable.Load((byte[])soundElementRow["utf"]);
|
|||
|
|
|||
|
foreach (CriRow sdlRow in soundElementTable.Rows)
|
|||
|
{
|
|||
|
string sdlName = (string)sdlRow["name"];
|
|||
|
|
|||
|
DirectoryInfo sdlDirectory = new DirectoryInfo(Path.Combine(args[0], sdlName));
|
|||
|
|
|||
|
if (!sdlDirectory.Exists)
|
|||
|
{
|
|||
|
throw new Exception($"Cannot find sound element directory for replacement.\nPath attempt: {sdlDirectory.FullName}");
|
|||
|
}
|
|||
|
|
|||
|
uint sampleRate = (uint)sdlRow["sfreq"];
|
|||
|
byte numberChannels = (byte)sdlRow["nch"];
|
|||
|
|
|||
|
Console.WriteLine("Adding {0}...", sdlName);
|
|||
|
|
|||
|
using (MemoryStream memoryStream = new MemoryStream())
|
|||
|
using (CriTableWriter writer = CriTableWriter.Create(memoryStream, CriTableWriterSettings.AdxSettings))
|
|||
|
{
|
|||
|
writer.WriteStartTable("AAX");
|
|||
|
|
|||
|
writer.WriteField("data", typeof(byte[]));
|
|||
|
writer.WriteField("lpflg", typeof(byte));
|
|||
|
|
|||
|
foreach (FileInfo audioFile in sdlDirectory.GetFiles("*.adx"))
|
|||
|
{
|
|||
|
// In Turkish, lowercase I is ı so you get the idea
|
|||
|
if (audioFile.Name.ToLower(CultureInfo.GetCultureInfo("en-US")) == "intro.adx")
|
|||
|
{
|
|||
|
ReadAdx(audioFile, out sampleRate, out numberChannels);
|
|||
|
writer.WriteRow(true, audioFile, (byte)0);
|
|||
|
}
|
|||
|
|
|||
|
else if (audioFile.Name.ToLower() == "loop.adx")
|
|||
|
{
|
|||
|
ReadAdx(audioFile, out sampleRate, out numberChannels);
|
|||
|
writer.WriteRow(true, audioFile, (byte)1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
writer.WriteEndTable();
|
|||
|
sdlRow["data"] = memoryStream.ToArray();
|
|||
|
}
|
|||
|
|
|||
|
sdlRow["sfreq"] = sampleRate;
|
|||
|
sdlRow["nch"] = numberChannels;
|
|||
|
}
|
|||
|
|
|||
|
soundElementTable.WriterSettings = CriTableWriterSettings.AdxSettings;
|
|||
|
soundElementRow["utf"] = soundElementTable.Save();
|
|||
|
|
|||
|
csbFile.WriterSettings = CriTableWriterSettings.AdxSettings;
|
|||
|
csbFile.Save(args[0] + ".csb");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
catch (Exception exception)
|
|||
|
{
|
|||
|
MessageBox.Show($"{exception.Message}", "CSB Editor", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void ReadAdx(FileInfo fileInfo, out uint sampleRate, out byte numberChannels)
|
|||
|
{
|
|||
|
using (Stream source = fileInfo.OpenRead())
|
|||
|
{
|
|||
|
source.Seek(7, SeekOrigin.Begin);
|
|||
|
numberChannels = EndianStream.ReadByte(source);
|
|||
|
sampleRate = EndianStream.ReadUInt32BE(source);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|