diff --git a/Dependencies/vgmstream.dll b/Dependencies/vgmstream.dll index 8602e90..0040d21 100644 Binary files a/Dependencies/vgmstream.dll and b/Dependencies/vgmstream.dll differ diff --git a/Source/AcbEditor/Program.cs b/Source/AcbEditor/Program.cs index 42d8c2a..2fdf14d 100644 --- a/Source/AcbEditor/Program.cs +++ b/Source/AcbEditor/Program.cs @@ -22,7 +22,7 @@ namespace AcbEditor Settings.Default.Reset(); Settings.Default.Save(); } - + if (args.Length < 1) { Console.WriteLine(Resources.Description); @@ -32,283 +32,316 @@ namespace AcbEditor #if !DEBUG try { -#endif - if (args[0].EndsWith(".acb")) +#endif + if (args[0].EndsWith(".acb")) + { + var extractor = new DataExtractor(); + extractor.ProgressChanged += OnProgressChanged; + + extractor.BufferSize = Settings.Default.BufferSize; + extractor.EnableThreading = Settings.Default.EnableThreading; + extractor.MaxThreads = Settings.Default.MaxThreads; + + string baseDirectory = Path.GetDirectoryName(args[0]); + string outputDirectoryPath = Path.ChangeExtension(args[0], null); + string extAfs2ArchivePath = string.Empty; + + Directory.CreateDirectory(outputDirectoryPath); + + using (CriTableReader acbReader = CriTableReader.Create(args[0])) { - var extractor = new DataExtractor(); - extractor.ProgressChanged += OnProgressChanged; - - extractor.BufferSize = Settings.Default.BufferSize; - extractor.EnableThreading = Settings.Default.EnableThreading; - extractor.MaxThreads = Settings.Default.MaxThreads; - - string baseDirectory = Path.GetDirectoryName(args[0]); - string outputDirectoryPath = Path.ChangeExtension(args[0], null); - string extAfs2ArchivePath = string.Empty; - - Directory.CreateDirectory(outputDirectoryPath); - - using (CriTableReader acbReader = CriTableReader.Create(args[0])) - { - acbReader.Read(); - - CriAfs2Archive afs2Archive = new CriAfs2Archive(); - CriAfs2Archive extAfs2Archive = new CriAfs2Archive(); - - CriCpkArchive cpkArchive = new CriCpkArchive(); - CriCpkArchive extCpkArchive = null; - - extAfs2ArchivePath = outputDirectoryPath + ".awb"; - bool found = File.Exists(extAfs2ArchivePath); - - if (!found) - { - extAfs2ArchivePath = outputDirectoryPath + "_streamfiles.awb"; - found = File.Exists(extAfs2ArchivePath); - } - - if (!found) - { - extAfs2ArchivePath = outputDirectoryPath + "_STR.awb"; - found = File.Exists(extAfs2ArchivePath); - } - - bool cpkMode = true; - - long awbPosition = acbReader.GetPosition("AwbFile"); - if (acbReader.GetLength("AwbFile") > 0) - { - using (SubStream afs2Stream = acbReader.GetSubStream("AwbFile")) - { - cpkMode = !CheckIfAfs2(afs2Stream); - - if (cpkMode) - { - cpkArchive.Read(afs2Stream); - } - - else - { - afs2Archive.Read(afs2Stream); - } - } - } - - if (acbReader.GetLength("StreamAwbAfs2Header") > 0) - { - cpkMode = false; - - using (SubStream extAfs2Stream = acbReader.GetSubStream("StreamAwbAfs2Header")) - { - extAfs2Archive.Read(extAfs2Stream); - } - - if (!found) - { - throw new FileNotFoundException("Cannot find the external .AWB file for this .ACB file. Please ensure that the external .AWB file is stored in the directory where the .ACB file is."); - } - } - - using (SubStream waveformTableStream = acbReader.GetSubStream("WaveformTable")) - using (CriTableReader waveformReader = CriTableReader.Create(waveformTableStream)) - { - while (waveformReader.Read()) - { - ushort id = waveformReader.GetUInt16("Id"); - byte encodeType = waveformReader.GetByte("EncodeType"); - bool streaming = waveformReader.GetBoolean("Streaming"); - - string outputName = id.ToString("D5"); - if (streaming) - { - outputName += "_streaming"; - } - - outputName += GetExtension(encodeType); - outputName = Path.Combine(outputDirectoryPath, outputName); - - if (streaming) - { - if (!found) - { - throw new Exception("Cannot find the external .AWB file for this .ACB file. Please ensure that the external .AWB file is stored in the directory where the .ACB file is."); - } - - else if (extCpkArchive == null && cpkMode) - { - extCpkArchive = new CriCpkArchive(); - extCpkArchive.Load(extAfs2ArchivePath, Settings.Default.BufferSize); - } - - EntryBase afs2Entry = null; - - if (cpkMode) - { - afs2Entry = extCpkArchive.GetById(id); - } - - else - { - afs2Entry = extAfs2Archive.GetById(id); - } - - extractor.Add(extAfs2ArchivePath, outputName, afs2Entry.Position, afs2Entry.Length); - } - - else - { - EntryBase afs2Entry = null; - - if (cpkMode) - { - afs2Entry = cpkArchive.GetById(id); - } - - else - { - afs2Entry = afs2Archive.GetById(id); - } - - extractor.Add(args[0], outputName, awbPosition + afs2Entry.Position, afs2Entry.Length); - } - } - } - } - - extractor.Run(); - } - - else if (File.GetAttributes(args[0]).HasFlag(FileAttributes.Directory)) - { - string baseDirectory = Path.GetDirectoryName(args[0]); - string acbPath = args[0] + ".acb"; - - string awbPath = args[0] + "_streamfiles.awb"; - bool found = File.Exists(awbPath); - - if (!found) - { - awbPath = args[0] + "_STR.awb"; - found = File.Exists(awbPath); - } - - if (!found) - { - awbPath = args[0] + ".awb"; - } - - if (!File.Exists(acbPath)) - { - throw new FileNotFoundException("Cannot find the .ACB file for this directory. Please ensure that the .ACB file is stored in the directory where this directory is."); - } - - CriTable acbFile = new CriTable(); - acbFile.Load(acbPath, Settings.Default.BufferSize); + acbReader.Read(); CriAfs2Archive afs2Archive = new CriAfs2Archive(); CriAfs2Archive extAfs2Archive = new CriAfs2Archive(); CriCpkArchive cpkArchive = new CriCpkArchive(); - CriCpkArchive extCpkArchive = new CriCpkArchive(); - cpkArchive.Mode = extCpkArchive.Mode = CriCpkMode.Id; + CriCpkArchive extCpkArchive = null; - afs2Archive.ProgressChanged += OnProgressChanged; - extAfs2Archive.ProgressChanged += OnProgressChanged; - cpkArchive.ProgressChanged += OnProgressChanged; - extCpkArchive.ProgressChanged += OnProgressChanged; + extAfs2ArchivePath = outputDirectoryPath + ".awb"; + bool found = File.Exists(extAfs2ArchivePath); + + if (!found) + { + extAfs2ArchivePath = outputDirectoryPath + "_streamfiles.awb"; + found = File.Exists(extAfs2ArchivePath); + } + + if (!found) + { + extAfs2ArchivePath = outputDirectoryPath + "_STR.awb"; + found = File.Exists(extAfs2ArchivePath); + } bool cpkMode = true; - byte[] awbFile = (byte[])acbFile.Rows[0]["AwbFile"]; - byte[] streamAwbAfs2Header = (byte[])acbFile.Rows[0]["StreamAwbAfs2Header"]; - - cpkMode = !(awbFile != null && awbFile.Length >= 4 && Encoding.ASCII.GetString(awbFile, 0, 4) == "AFS2") && (streamAwbAfs2Header == null || streamAwbAfs2Header.Length == 0); - - using (CriTableReader reader = CriTableReader.Create((byte[])acbFile.Rows[0]["WaveformTable"])) + long awbPosition = acbReader.GetPosition("AwbFile"); + if (acbReader.GetLength("AwbFile") > 0) { - while (reader.Read()) + using (SubStream afs2Stream = acbReader.GetSubStream("AwbFile")) { - ushort id = reader.GetUInt16("Id"); - byte encodeType = reader.GetByte("EncodeType"); - bool streaming = reader.GetBoolean("Streaming"); - - string inputName = id.ToString("D5"); - if (streaming) - { - inputName += "_streaming"; - } - - inputName += GetExtension(encodeType); - inputName = Path.Combine(args[0], inputName); - - if (!File.Exists(inputName)) - { - throw new FileNotFoundException($"Cannot find audio file with id {id} for replacement.\nPath attempt: {inputName}"); - } + cpkMode = !CheckIfAfs2(afs2Stream); if (cpkMode) { - CriCpkEntry entry = new CriCpkEntry(); - entry.FilePath = new FileInfo(inputName); - entry.Id = id; + cpkArchive.Read(afs2Stream); + } - if (streaming) - { - extCpkArchive.Add(entry); - } + else + { + afs2Archive.Read(afs2Stream); + } + } + } - else + if (acbReader.GetLength("StreamAwbAfs2Header") > 0) + { + cpkMode = false; + + using (SubStream extAfs2Stream = acbReader.GetSubStream("StreamAwbAfs2Header")) + { + bool utfMode = DataStream.ReadCString(extAfs2Stream, 4) == "@UTF"; + extAfs2Stream.Seek(0, SeekOrigin.Begin); + + if (utfMode) + { + using (CriTableReader utfAfs2HeaderReader = CriTableReader.Create(extAfs2Stream)) { - cpkArchive.Add(entry); + utfAfs2HeaderReader.Read(); + + using (SubStream extAfs2HeaderStream = utfAfs2HeaderReader.GetSubStream("Header")) + { + extAfs2Archive.Read(extAfs2HeaderStream); + } } } else { - CriAfs2Entry entry = new CriAfs2Entry(); - entry.FilePath = new FileInfo(inputName); - entry.Id = id; + extAfs2Archive.Read(extAfs2Stream); + } + } - if (streaming) + if (!found) + { + throw new FileNotFoundException("Cannot find the external .AWB file for this .ACB file. Please ensure that the external .AWB file is stored in the directory where the .ACB file is."); + } + } + + using (SubStream waveformTableStream = acbReader.GetSubStream("WaveformTable")) + using (CriTableReader waveformReader = CriTableReader.Create(waveformTableStream)) + { + while (waveformReader.Read()) + { + ushort id = waveformReader.GetUInt16("Id"); + byte encodeType = waveformReader.GetByte("EncodeType"); + bool streaming = waveformReader.GetBoolean("Streaming"); + + string outputName = id.ToString("D5"); + if (streaming) + { + outputName += "_streaming"; + } + + outputName += GetExtension(encodeType); + outputName = Path.Combine(outputDirectoryPath, outputName); + + if (streaming) + { + if (!found) { - extAfs2Archive.Add(entry); + throw new Exception("Cannot find the external .AWB file for this .ACB file. Please ensure that the external .AWB file is stored in the directory where the .ACB file is."); + } + + else if (extCpkArchive == null && cpkMode) + { + extCpkArchive = new CriCpkArchive(); + extCpkArchive.Load(extAfs2ArchivePath, Settings.Default.BufferSize); + } + + EntryBase afs2Entry = null; + + if (cpkMode) + { + afs2Entry = extCpkArchive.GetById(id); } else { - afs2Archive.Add(entry); + afs2Entry = extAfs2Archive.GetById(id); } + + extractor.Add(extAfs2ArchivePath, outputName, afs2Entry.Position, afs2Entry.Length); + } + + else + { + EntryBase afs2Entry = null; + + if (cpkMode) + { + afs2Entry = cpkArchive.GetById(id); + } + + else + { + afs2Entry = afs2Archive.GetById(id); + } + + extractor.Add(args[0], outputName, awbPosition + afs2Entry.Position, afs2Entry.Length); } } } + } - acbFile.Rows[0]["AwbFile"] = null; - acbFile.Rows[0]["StreamAwbAfs2Header"] = null; + extractor.Run(); + } - if (afs2Archive.Count > 0 || cpkArchive.Count > 0) + else if (File.GetAttributes(args[0]).HasFlag(FileAttributes.Directory)) + { + string baseDirectory = Path.GetDirectoryName(args[0]); + string acbPath = args[0] + ".acb"; + + string awbPath = args[0] + "_streamfiles.awb"; + bool found = File.Exists(awbPath); + + if (!found) + { + awbPath = args[0] + "_STR.awb"; + found = File.Exists(awbPath); + } + + if (!found) + { + awbPath = args[0] + ".awb"; + } + + if (!File.Exists(acbPath)) + { + throw new FileNotFoundException("Cannot find the .ACB file for this directory. Please ensure that the .ACB file is stored in the directory where this directory is."); + } + + CriTable acbFile = new CriTable(); + acbFile.Load(acbPath, Settings.Default.BufferSize); + + CriAfs2Archive afs2Archive = new CriAfs2Archive(); + CriAfs2Archive extAfs2Archive = new CriAfs2Archive(); + + CriCpkArchive cpkArchive = new CriCpkArchive(); + CriCpkArchive extCpkArchive = new CriCpkArchive(); + cpkArchive.Mode = extCpkArchive.Mode = CriCpkMode.Id; + + afs2Archive.ProgressChanged += OnProgressChanged; + extAfs2Archive.ProgressChanged += OnProgressChanged; + cpkArchive.ProgressChanged += OnProgressChanged; + extCpkArchive.ProgressChanged += OnProgressChanged; + + bool cpkMode = true; + + byte[] awbFile = (byte[])acbFile.Rows[0]["AwbFile"]; + byte[] streamAwbAfs2Header = (byte[])acbFile.Rows[0]["StreamAwbAfs2Header"]; + + cpkMode = !(awbFile != null && awbFile.Length >= 4 && Encoding.ASCII.GetString(awbFile, 0, 4) == "AFS2") && (streamAwbAfs2Header == null || streamAwbAfs2Header.Length == 0); + + using (CriTableReader reader = CriTableReader.Create((byte[])acbFile.Rows[0]["WaveformTable"])) + { + while (reader.Read()) { - Console.WriteLine("Saving internal AWB..."); - acbFile.Rows[0]["AwbFile"] = cpkMode ? cpkArchive.Save() : afs2Archive.Save(); - Console.WriteLine(); - } + ushort id = reader.GetUInt16("Id"); + byte encodeType = reader.GetByte("EncodeType"); + bool streaming = reader.GetBoolean("Streaming"); + + string inputName = id.ToString("D5"); + if (streaming) + { + inputName += "_streaming"; + } + + inputName += GetExtension(encodeType); + inputName = Path.Combine(args[0], inputName); + + if (!File.Exists(inputName)) + { + throw new FileNotFoundException($"Cannot find audio file with id {id} for replacement.\nPath attempt: {inputName}"); + } - if (extAfs2Archive.Count > 0 || extCpkArchive.Count > 0) - { - Console.WriteLine("Saving external AWB..."); if (cpkMode) { - extCpkArchive.Save(awbPath, Settings.Default.BufferSize); + CriCpkEntry entry = new CriCpkEntry(); + entry.FilePath = new FileInfo(inputName); + entry.Id = id; + + if (streaming) + { + extCpkArchive.Add(entry); + } + + else + { + cpkArchive.Add(entry); + } + } + + else + { + CriAfs2Entry entry = new CriAfs2Entry(); + entry.FilePath = new FileInfo(inputName); + entry.Id = id; + + if (streaming) + { + extAfs2Archive.Add(entry); + } + + else + { + afs2Archive.Add(entry); + } + } + } + } + + acbFile.Rows[0]["AwbFile"] = null; + acbFile.Rows[0]["StreamAwbAfs2Header"] = null; + + if (afs2Archive.Count > 0 || cpkArchive.Count > 0) + { + Console.WriteLine("Saving internal AWB..."); + acbFile.Rows[0]["AwbFile"] = cpkMode ? cpkArchive.Save() : afs2Archive.Save(); + Console.WriteLine(); + } + + if (extAfs2Archive.Count > 0 || extCpkArchive.Count > 0) + { + Console.WriteLine("Saving external AWB..."); + if (cpkMode) + { + extCpkArchive.Save(awbPath, Settings.Default.BufferSize); + } + + else + { + extAfs2Archive.Save(awbPath, Settings.Default.BufferSize); + + if (Encoding.UTF8.GetString(streamAwbAfs2Header, 0, 4) == "@UTF") + { + CriTable headerTable = new CriTable(); + headerTable.Load(streamAwbAfs2Header); + + headerTable.Rows[0]["Header"] = extAfs2Archive.Header; + headerTable.WriterSettings = CriTableWriterSettings.Adx2Settings; + acbFile.Rows[0]["StreamAwbAfs2Header"] = headerTable.Save(); } else { - extAfs2Archive.Save(awbPath, Settings.Default.BufferSize); acbFile.Rows[0]["StreamAwbAfs2Header"] = extAfs2Archive.Header; } } + } - acbFile.WriterSettings = CriTableWriterSettings.Adx2Settings; - acbFile.Save(acbPath, Settings.Default.BufferSize); + acbFile.WriterSettings = CriTableWriterSettings.Adx2Settings; + acbFile.Save(acbPath, Settings.Default.BufferSize); } #if !DEBUG } diff --git a/Source/CsbBuilder/Audio/VGMStreamNative.cs b/Source/CsbBuilder/Audio/VGMStreamNative.cs index 44ebd48..4f51adb 100644 --- a/Source/CsbBuilder/Audio/VGMStreamNative.cs +++ b/Source/CsbBuilder/Audio/VGMStreamNative.cs @@ -17,16 +17,6 @@ namespace CsbBuilder.Audio /// public const string DllName = "vgmstream.dll"; - /// - /// Size of VGMSTREAM structure. - /// - public const int SizeOfVgmStream = 152; - - /// - /// Size of VGMSTREAMCHANNEL structure. - /// - public const int SizeOfVgmStreamChannel = 552; - #region VGMStream Exports /// /// Initializes a VGMSTREAM from source file name by doing format detection and returns a usable pointer @@ -165,15 +155,8 @@ namespace CsbBuilder.Audio /// Gets a pointer to the array of supported formats. /// [DllImport(DllName, EntryPoint = "vgmstream_get_formats", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr GetFormatsPtr(); - - /// - /// Gets the length of the format array. - /// - /// - [DllImport(DllName, EntryPoint = "vgmstream_get_formats_length", CallingConvention = CallingConvention.Cdecl)] - public static extern int GetFormatsLength(); - + public static extern IntPtr GetFormatsPtr(out int count); + [DllImport(DllName, EntryPoint = "get_vgmstream_coding_description", CallingConvention = CallingConvention.Cdecl)] public static extern string GetCodingDescription(int codingEnumCode); @@ -189,28 +172,22 @@ namespace CsbBuilder.Audio /// Gets the sample count of a VGMSTREAM. /// /// Pointer to VGMSTREAM. - public static int GetSampleCount(IntPtr vgmstream) - { - return Marshal.ReadInt32(vgmstream); - } + [DllImport(DllName, EntryPoint = "get_vgmstream_sample_count", CallingConvention = CallingConvention.Cdecl)] + public static extern int GetSampleCount(IntPtr vgmstream); /// /// Gets the sample rate of a VGMSTREAM. /// /// Pointer to VGMSTREAM. - public static int GetSampleRate(IntPtr vgmstream) - { - return Marshal.ReadInt32(vgmstream, 4); - } + [DllImport(DllName, EntryPoint = "get_vgmstream_sample_rate", CallingConvention = CallingConvention.Cdecl)] + public static extern int GetSampleRate(IntPtr vgmstream); /// /// Gets the channel count of a VGMSTREAM. /// /// Pointer to VGMSTREAM. - public static int GetChannelCount(IntPtr vgmstream) - { - return Marshal.ReadInt32(vgmstream, 8); - } + [DllImport(DllName, EntryPoint = "get_vgmstream_channels", CallingConvention = CallingConvention.Cdecl)] + public static extern int GetChannelCount(IntPtr vgmstream); /// /// Gets the absolute sample count of a VGMSTREAM. @@ -226,69 +203,50 @@ namespace CsbBuilder.Audio /// Gets the loop flag of a VGMSTREAM. /// /// Pointer to VGMSTREAM. - public static bool GetLoopFlag(IntPtr vgmstream) - { - return Marshal.ReadInt32(vgmstream, 28) != 0; - } + [DllImport(DllName, EntryPoint = "get_vgmstream_loop_flag", CallingConvention = CallingConvention.Cdecl)] + public static extern bool GetLoopFlag(IntPtr vgmstream); /// /// Sets the loop flag of a VGMSTREAM. /// /// Pointer to VGMSTREAM. - public static void SetLoopFlag(IntPtr vgmstream, bool value) - { - if (value && !GetLoopFlag(vgmstream)) - { - Marshal.WriteIntPtr(vgmstream, 48, Marshal.AllocHGlobal(GetChannelCount(vgmstream) * SizeOfVgmStreamChannel)); - } - - Marshal.WriteInt32(vgmstream, 28, value ? 1 : 0); - } + [DllImport(DllName, EntryPoint = "set_vgmstream_loop_flag", CallingConvention = CallingConvention.Cdecl)] + public static extern void SetLoopFlag(IntPtr vgmstream, bool value); /// /// Gets the loop start sample of a VGMSTREAM. /// /// Pointer to VGMSTREAM. - public static int GetLoopStartSample(IntPtr vgmstream) - { - return Marshal.ReadInt32(vgmstream, 32); - } + [DllImport(DllName, EntryPoint = "get_vgmstream_loop_start_sample", CallingConvention = CallingConvention.Cdecl)] + public static extern int GetLoopStartSample(IntPtr vgmstream); /// /// Sets the loop start sample of a VGMSTREAM. /// /// Pointer to VGMSTREAM. - public static void SetLoopStartSample(IntPtr vgmstream, int value) - { - Marshal.WriteInt32(vgmstream, 32, value); - } + [DllImport(DllName, EntryPoint = "set_vgmstream_loop_start_sample", CallingConvention = CallingConvention.Cdecl)] + public static extern void SetLoopStartSample(IntPtr vgmstream, int value); /// /// Gets the loop end sample of a VGMSTREAM. /// /// Pointer to VGMSTREAM. - public static int GetLoopEndSample(IntPtr vgmstream) - { - return Marshal.ReadInt32(vgmstream, 36); - } + [DllImport(DllName, EntryPoint = "get_vgmstream_loop_end_sample", CallingConvention = CallingConvention.Cdecl)] + public static extern int GetLoopEndSample(IntPtr vgmstream); /// /// Sets the loop end sample of a VGMSTREAM. /// /// Pointer to VGMSTREAM. - public static void SetLoopEndSample(IntPtr vgmstream, int value) - { - Marshal.WriteInt32(vgmstream, 36, value); - } + [DllImport(DllName, EntryPoint = "set_vgmstream_loop_end_sample", CallingConvention = CallingConvention.Cdecl)] + public static extern void SetLoopEndSample(IntPtr vgmstream, int value); /// /// Gets the current sample of a VGMSTREAM. /// /// Pointer to VGMSTREAM. - public static int GetCurrentSample(IntPtr vgmstream) - { - return Marshal.ReadInt32(vgmstream, 52); - } + [DllImport(DllName, EntryPoint = "get_vgmstream_current_sample", CallingConvention = CallingConvention.Cdecl)] + public static extern int GetCurrentSample(IntPtr vgmstream); /// /// Gets an array of supported formats. @@ -296,9 +254,9 @@ namespace CsbBuilder.Audio /// Pointer to VGMSTREAM. public static string[] GetFormats() { - string[] formats = new string[GetFormatsLength()]; + IntPtr ptr = GetFormatsPtr(out int count); + string[] formats = new string[count]; - IntPtr ptr = GetFormatsPtr(); for (int i = 0; i < formats.Length; i++) { IntPtr stringPtr = Marshal.ReadIntPtr(ptr, i * IntPtr.Size); diff --git a/Source/CsbBuilder/Program.cs b/Source/CsbBuilder/Program.cs index 897213f..0030d86 100644 --- a/Source/CsbBuilder/Program.cs +++ b/Source/CsbBuilder/Program.cs @@ -47,7 +47,11 @@ namespace CsbBuilder private static void OnException(object sender, ThreadExceptionEventArgs e) { new ExceptionForm(e.Exception).ShowDialog(); - Application.Exit(); + + if (MessageBox.Show("Do you want to continue?", "CSB Builder", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.OK) + { + Application.Exit(); + } } } } diff --git a/Source/SonicAudioCmd/Program.cs b/Source/SonicAudioCmd/Program.cs index ef844f4..324745c 100644 --- a/Source/SonicAudioCmd/Program.cs +++ b/Source/SonicAudioCmd/Program.cs @@ -21,26 +21,6 @@ namespace SonicAudioCmd { static void Main(string[] args) { - using (Stream source = File.OpenRead(args[0])) - { - CriTableReader reader = CriTableReader.Create(source); - reader.MoveToRow(3); - - long pos = reader.GetPosition("utf"); - CriTableReader soundElementReader = reader.GetTableReader("utf"); - - while (soundElementReader.Read()) - { - CriTable table = new CriTable(); - table.Read(soundElementReader.GetSubStream("data")); - - using (Stream output = File.Create(Path.GetFileName(soundElementReader.GetString("name") + "_" + table.Rows[0].GetValue("lpflg") + "_" + ".dsp"))) - { - DataStream.WriteBytes(output, table.Rows[0].GetValue("header")); - DataStream.WriteBytes(output, table.Rows[0].GetValue("data")); - } - } - } } } } diff --git a/Source/SonicAudioLib/CriMw/CriTable.Internal.cs b/Source/SonicAudioLib/CriMw/CriTable.Internal.cs index d68e334..44e4063 100644 --- a/Source/SonicAudioLib/CriMw/CriTable.Internal.cs +++ b/Source/SonicAudioLib/CriMw/CriTable.Internal.cs @@ -1,8 +1,10 @@ using System; using System.IO; +using System.Runtime.InteropServices; namespace SonicAudioLib.CriMw { + [StructLayout(LayoutKind.Sequential)] struct CriTableHeader { public static readonly byte[] SignatureBytes = { 0x40, 0x55, 0x54, 0x46 }; @@ -48,13 +50,14 @@ namespace SonicAudioLib.CriMw TypeMask = 15, }; + [StructLayout(LayoutKind.Sequential)] struct CriTableField { - public uint Offset; public CriFieldFlag Flag; public string Name; public uint Position; public uint Length; + public uint Offset; public object Value; } diff --git a/Source/SonicAudioLib/IO/DataStream.cs b/Source/SonicAudioLib/IO/DataStream.cs index 0639370..f489b7f 100644 --- a/Source/SonicAudioLib/IO/DataStream.cs +++ b/Source/SonicAudioLib/IO/DataStream.cs @@ -517,15 +517,10 @@ namespace SonicAudioLib.IO public static void Pad(Stream destination, long alignment) { - long value = destination.Position; - - while ((value % alignment) != 0) + while (destination.Position % alignment != 0) { - value++; + WriteByte(destination, 0); } - - byte[] buffer = new byte[value - destination.Position]; - destination.Write(buffer, 0, buffer.Length); } } }