From 2df23d677e1f5d0bb57523342a6454e58d2314d8 Mon Sep 17 00:00:00 2001 From: morkt Date: Mon, 1 Feb 2016 05:53:25 +0400 Subject: [PATCH] (VafsOpener): implemented audio entries decoding. --- ArcFormats/ArcFormats.csproj | 2 + ArcFormats/Softpal/ArcVAFS.cs | 209 ++++++++++++++++++++++++++++++++-- ArcFormats/Softpal/WaveTable1 | Bin 0 -> 32768 bytes ArcFormats/Softpal/WaveTable2 | Bin 0 -> 512 bytes 4 files changed, 199 insertions(+), 12 deletions(-) create mode 100644 ArcFormats/Softpal/WaveTable1 create mode 100644 ArcFormats/Softpal/WaveTable2 diff --git a/ArcFormats/ArcFormats.csproj b/ArcFormats/ArcFormats.csproj index e0d58d03..e04e7c26 100644 --- a/ArcFormats/ArcFormats.csproj +++ b/ArcFormats/ArcFormats.csproj @@ -418,6 +418,8 @@ WidgetYPF.xaml + + diff --git a/ArcFormats/Softpal/ArcVAFS.cs b/ArcFormats/Softpal/ArcVAFS.cs index b53b1c94..71ec60d7 100644 --- a/ArcFormats/Softpal/ArcVAFS.cs +++ b/ArcFormats/Softpal/ArcVAFS.cs @@ -27,6 +27,8 @@ using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.IO; +using System.Text; +using GameRes.Utility; namespace GameRes.Formats.Softpal { @@ -52,6 +54,9 @@ namespace GameRes.Formats.Softpal return null; uint index_offset = 0x10; uint data_offset = file.View.ReadUInt32 (index_offset); + var base_name = Path.GetFileNameWithoutExtension (file.Name).ToUpperInvariant(); + if (0 == data_offset && "TP" == base_name) + return OpenTpArc (file); if (data_offset < index_offset || data_offset >= file.MaxOffset) return null; int count = (int)(data_offset - index_offset) / 4; @@ -59,9 +64,8 @@ namespace GameRes.Formats.Softpal return null; uint next_offset = data_offset; - var base_name = Path.GetFileNameWithoutExtension (file.Name).ToUpperInvariant(); - bool is_audio = "BGM" == base_name; - bool is_pic = "PIC" == base_name; + bool is_bgm = "BGM" == base_name; + bool is_pic = "PIC" == base_name; var dir = new List (count); for (int i = 0; next_offset != file.MaxOffset && i < count; ++i) { @@ -69,29 +73,28 @@ namespace GameRes.Formats.Softpal var name = string.Format("{0}#{1:D5}", base_name, i); var offset = next_offset; next_offset = index_offset == data_offset ? 0 : file.View.ReadUInt32 (index_offset); - if (uint.MaxValue == next_offset) - break; - else if (0 == next_offset) - next_offset = (uint)file.MaxOffset; - else if (next_offset < offset) + if (uint.MaxValue == next_offset || next_offset < offset) break; uint size = next_offset - offset; if (size < 4) continue; Entry entry; if (is_pic) - entry = new Entry { Name = name, Type = "image", Offset = offset }; - else if (is_audio) - entry = new Entry { Name = name + ".wav", Type = "audio", Offset = offset }; + entry = new Entry { Name = name, Type = "image" }; + else if (is_bgm) + entry = new Entry { Name = name + ".wav", Type = "audio" }; else entry = new AutoEntry (name, () => { uint signature = file.View.ReadUInt32 (offset); uint s16 = signature & 0xFFFF; if (1 == s16 || 3 == s16 || 4 == s16) return s_PicFormat.Value; + if (size > 0x200 && (size >> 9) == (signature >> 9)) + return AudioFormat.Wav; return AutoEntry.DetectFileType (signature); - }) { Offset = offset }; + }); + entry.Offset = offset; entry.Size = size; if (!entry.CheckPlacement (file.MaxOffset)) return null; @@ -101,5 +104,187 @@ namespace GameRes.Formats.Softpal return null; return new ArcFile (file, this, dir); } + + ArcFile OpenTpArc (ArcView file) + { + uint index_offset = 0x20; + uint data_offset; + for (;;) + { + data_offset = file.View.ReadUInt32 (index_offset); + if (0 != data_offset) + break; + index_offset += 0x10; + if (0xA010 == index_offset) + return null; + } + if (data_offset >= file.MaxOffset) + return null; + var dir = new List(); + while (index_offset < data_offset) + { + var offset = file.View.ReadUInt32 (index_offset); + if (0 != offset) + { + var name = string.Format("TP#{0:D5}.wav", index_offset/0x10 - 1); + var entry = new Entry { + Name = name, + Type = "audio", + Offset = offset, + Size = 0x402 * file.View.ReadUInt32 (index_offset+4), + }; + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + } + index_offset += 0x10; + } + return new TpArchive (file, this, dir); + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + if (arc is TpArchive) + return OpenVoiceEntry (arc, entry); + else if ("audio" == entry.Type) + return OpenAudioEntry (arc, entry); + else + return base.OpenEntry (arc, entry); + } + + Stream OpenAudioEntry (ArcFile arc, Entry entry) + { + var offset = entry.Offset; + int size = arc.File.View.ReadInt32 (offset); + offset += 4; + int chunk_count = size >> 9; + int pcm_size = chunk_count * 0x400; + var output = new MemoryStream (0x24 + pcm_size); + using (var wav = new BinaryWriter (output, Encoding.ASCII, true)) + { + WriteWavHeader (wav, 2, 22050, pcm_size); + var buffer = new byte[0x204]; + for (int chunk = 0; chunk < chunk_count; ++chunk) + { + arc.File.View.Read (offset, buffer, 0, 0x204); + offset += 0x204; + int src = 0; + var data_offset = wav.BaseStream.Position; + for (int channel = 0; channel < 2; ++channel) + { + int addend = buffer[src++] << 8; + int pcm = LittleEndian.ToInt16 (buffer, src); + src += 2; + wav.Write ((short)pcm); + wav.BaseStream.Position = data_offset + channel * 2; + for (int i = 0; i < 255; ++i) + { + byte v = buffer[src++]; + int diff = v + addend; + pcm += WaveTable1.Value[diff]; + if (pcm > 32767) + pcm = 32767; + else if (pcm < -32767) + pcm = -32767; + wav.Write ((short)pcm); + wav.BaseStream.Seek (2, SeekOrigin.Current); + addend += WaveTable2.Value[v]; + if (addend < 0) + addend = 0; + else if (addend >= 16384) + addend = 16128; + } + wav.BaseStream.Seek (0, SeekOrigin.End); + } + } + } + output.Position = 0; + return output; + } + + Stream OpenVoiceEntry (ArcFile arc, Entry entry) + { + int remaining = (int)entry.Size; + int chunk_count = remaining / 0x402; + int pcm_size = chunk_count * 0x800; + var output = new MemoryStream (0x24 + pcm_size); + var offset = entry.Offset; + using (var wav = new BinaryWriter (output, Encoding.ASCII, true)) + { + WriteWavHeader (wav, 1, 22050, pcm_size); + var buffer = new byte[0x402]; + while (remaining > 0) + { + arc.File.View.Read (offset, buffer, 0, 0x402); + offset += 0x402; + remaining -= 0x402; + int pcm = LittleEndian.ToInt16 (buffer, 1); + int addend = buffer[0] << 8; + wav.Write ((short)pcm); + for (int src = 3; src < buffer.Length; ++src) + { + byte v = buffer[src]; + int diff = v + addend; + pcm += WaveTable1.Value[diff]; + if (pcm > 32767) + pcm = 32767; + else if (pcm < -32767) + pcm = -32767; + wav.Write ((short)pcm); + addend += WaveTable2.Value[v]; + if (addend < 0) + addend = 0; + else if (addend >= 16384) + addend = 16128; + } + } + } + output.Position = 0; + return output; + } + + void WriteWavHeader (BinaryWriter wav, short channels, int freq, int pcm_size) + { + wav.Write ("RIFF".ToCharArray()); + wav.Write (0x24 + pcm_size); + wav.Write ("WAVE".ToCharArray()); + wav.Write ("fmt ".ToCharArray()); + wav.Write (0x10); + wav.Write ((ushort)1); + wav.Write ((ushort)channels); + wav.Write (freq); + wav.Write (freq*channels*2); + wav.Write ((ushort)(channels*2)); + wav.Write ((ushort)16); + wav.Write ("data".ToCharArray()); + wav.Write (pcm_size); + } + + static readonly Lazy WaveTable1 = new Lazy (() => LoadWaveTable ("WaveTable1")); + static readonly Lazy WaveTable2 = new Lazy (() => LoadWaveTable ("WaveTable2")); + + static short[] LoadWaveTable (string name) + { + + var assembly = typeof(VafsOpener).Assembly; + using (var stream = assembly.GetManifestResourceStream ("GameRes.Formats.Softpal."+name)) + { + if (null == stream) + return null; + var src = new byte[stream.Length]; + stream.Read (src, 0, src.Length); + var array = new short[src.Length/2]; + Buffer.BlockCopy (src, 0, array, 0, src.Length); + return array; + } + } + } + + internal class TpArchive : ArcFile + { + public TpArchive (ArcView arc, ArchiveFormat impl, ICollection dir) + : base (arc, impl, dir) + { + } } } diff --git a/ArcFormats/Softpal/WaveTable1 b/ArcFormats/Softpal/WaveTable1 new file mode 100644 index 0000000000000000000000000000000000000000..d59541cd17a7992d8be09071676de5d073e9f866 GIT binary patch literal 32768 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 literal 0 HcmV?d00001 diff --git a/ArcFormats/Softpal/WaveTable2 b/ArcFormats/Softpal/WaveTable2 new file mode 100644 index 0000000000000000000000000000000000000000..ad4c9ddbcef18b3c860c774977a6521ffe1d1423 GIT binary patch literal 512 zcmd_l?Jj}=7=Ym`MJgqVB9t;}7*=C7*7+YzTWhBEp~v3YIspIN*Ad(%re;2UnOj&| zS%>eCl(KEdue3zQkKM2rvSB~uLOv86grZV7RCW}ORaBigRa1B7T*HM+SDIR`wRPOM cb*HQ6-h)R^p1tTBc=cvz