mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-23 13:45:34 +08:00
(Legacy): FL2 archives and WV1 audio.
This commit is contained in:
parent
85c0358ca0
commit
eb72b78b45
78
Legacy/Aaru/ArcFL2.cs
Normal file
78
Legacy/Aaru/ArcFL2.cs
Normal file
@ -0,0 +1,78 @@
|
||||
//! \file ArcFL2.cs
|
||||
//! \date 2018 Dec 13
|
||||
//! \brief Aaru resource archive
|
||||
//
|
||||
// Copyright (C) 2018 by morkt
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
|
||||
// [000428][Aaru] Koutei Heika ni Narou!
|
||||
|
||||
namespace GameRes.Formats.Aaru
|
||||
{
|
||||
[Export(typeof(ArchiveFormat))]
|
||||
public class Fl2Opener : Fl4Opener
|
||||
{
|
||||
public override string Tag { get { return "FL2/AARU"; } }
|
||||
public override string Description { get { return "Aaru resource archive"; } }
|
||||
public override uint Signature { get { return 0x2E324C46; } } // 'FL2.0'
|
||||
public override bool IsHierarchic { get { return false; } }
|
||||
public override bool CanWrite { get { return false; } }
|
||||
|
||||
public override ArcFile TryOpen (ArcView file)
|
||||
{
|
||||
if (file.View.ReadByte (4) != '0')
|
||||
return null;
|
||||
uint data_offset = file.View.ReadUInt16 (6);
|
||||
int count = file.View.ReadInt16 (8);
|
||||
uint index_size = file.View.ReadUInt32 (0xC);
|
||||
long index_offset = file.View.ReadUInt32 (0x10);
|
||||
if (index_offset + index_size > file.MaxOffset || !IsSaneCount (count))
|
||||
return null;
|
||||
using (var index = file.CreateStream (index_offset, index_size))
|
||||
{
|
||||
var dir = new List<Entry> (count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
uint size = index.ReadUInt32();
|
||||
if (uint.MaxValue == size)
|
||||
break;
|
||||
int name_length = index.ReadUInt8();
|
||||
var name = index.ReadCString (name_length);
|
||||
var entry = Create<PackedEntry> (name);
|
||||
entry.Offset = data_offset;
|
||||
entry.Size = size;
|
||||
if (!entry.CheckPlacement (file.MaxOffset))
|
||||
return null;
|
||||
data_offset += size;
|
||||
dir.Add (entry);
|
||||
}
|
||||
if (0 == dir.Count)
|
||||
return null;
|
||||
return new ArcFile (file, this, dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
160
Legacy/Aaru/AudioWV1.cs
Normal file
160
Legacy/Aaru/AudioWV1.cs
Normal file
@ -0,0 +1,160 @@
|
||||
//! \file AudioWV1.cs
|
||||
//! \date 2018 Dec 13
|
||||
//! \brief Aaru compressed audio format.
|
||||
//
|
||||
// Copyright (C) 2018 by morkt
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace GameRes.Formats.Aaru
|
||||
{
|
||||
[Export(typeof(AudioFormat))]
|
||||
public class Wv1Audio : AudioFormat
|
||||
{
|
||||
public override string Tag { get { return "WV1"; } }
|
||||
public override string Description { get { return "Aaru compressed audio"; } }
|
||||
public override uint Signature { get { return 0x2E315657; } } // 'WV1.0'
|
||||
public override bool CanWrite { get { return false; } }
|
||||
|
||||
public Wv1Audio ()
|
||||
{
|
||||
Extensions = new string[] { "wv1", "wav" };
|
||||
}
|
||||
|
||||
public override SoundInput TryOpen (IBinaryStream file)
|
||||
{
|
||||
var header = file.ReadHeader (0x30);
|
||||
if (!header.AsciiEqual (0, "WV1.0\0"))
|
||||
return null;
|
||||
var format = new WaveFormat {
|
||||
FormatTag = 1,
|
||||
Channels = header.ToUInt16 (0xA),
|
||||
SamplesPerSecond = header.ToUInt32 (0xE),
|
||||
BitsPerSample = 16,
|
||||
};
|
||||
format.BlockAlign = (ushort)(format.Channels * format.BitsPerSample / 8);
|
||||
format.SetBPS();
|
||||
int sample_count = header.ToInt32 (0x26);
|
||||
var pcm = new MemoryStream (2 * sample_count);
|
||||
using (var output = new BinaryWriter (pcm, Encoding.ASCII, true))
|
||||
{
|
||||
var l_decoder = new Wv1Decoder();
|
||||
var r_decoder = l_decoder;
|
||||
if (format.Channels > 1)
|
||||
r_decoder = new Wv1Decoder();
|
||||
int input_sample = 0;
|
||||
for (int i = 0; i < sample_count; ++i)
|
||||
{
|
||||
bool odd_sample = (i & 1) != 0;
|
||||
short sample;
|
||||
if (odd_sample)
|
||||
{
|
||||
sample = r_decoder.DecodeSample (input_sample >> 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
input_sample = file.ReadByte();
|
||||
if (-1 == input_sample)
|
||||
break;
|
||||
sample = l_decoder.DecodeSample (input_sample & 0xF);
|
||||
}
|
||||
output.Write (sample);
|
||||
}
|
||||
}
|
||||
file.Dispose();
|
||||
pcm.Position = 0;
|
||||
return new RawPcmInput (pcm, format);
|
||||
}
|
||||
}
|
||||
|
||||
internal class Wv1Decoder
|
||||
{
|
||||
short last_sample = 0;
|
||||
int last_index = 0;
|
||||
int[] shift_table = new int[8];
|
||||
|
||||
public short DecodeSample (int input)
|
||||
{
|
||||
int s0 = SampleTable[last_index];
|
||||
shift_table[0] = s0 >> 3;
|
||||
shift_table[1] = shift_table[0] + (s0 >> 2);
|
||||
shift_table[2] = shift_table[0] + (s0 >> 1);
|
||||
shift_table[3] = shift_table[1] + (s0 >> 1);
|
||||
shift_table[4] = shift_table[0] + s0;
|
||||
shift_table[5] = shift_table[1] + s0;
|
||||
shift_table[6] = shift_table[2] + s0;
|
||||
shift_table[7] = shift_table[3] + s0;
|
||||
int shift_index = input & 7;
|
||||
if ((input & 8) != 0)
|
||||
last_sample -= (short)shift_table[shift_index];
|
||||
else
|
||||
last_sample += (short)shift_table[shift_index];
|
||||
switch (shift_index)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
if (last_index > 0)
|
||||
--last_index;
|
||||
break;
|
||||
case 4:
|
||||
last_index = Math.Min (last_index + 2, 0x7F);
|
||||
break;
|
||||
case 5:
|
||||
last_index = Math.Min (last_index + 4, 0x7F);
|
||||
break;
|
||||
case 6:
|
||||
last_index = Math.Min (last_index + 6, 0x7F);
|
||||
break;
|
||||
case 7:
|
||||
last_index = Math.Min (last_index + 8, 0x7F);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (short)(2 * last_sample);
|
||||
}
|
||||
|
||||
static readonly short[] SampleTable = {
|
||||
0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000E, 0x000F,
|
||||
0x0010, 0x0012, 0x0014, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D,
|
||||
0x0020, 0x0022, 0x0025, 0x0028, 0x002B, 0x002E, 0x0031, 0x0035,
|
||||
0x0038, 0x003C, 0x0041, 0x0045, 0x004A, 0x004F, 0x0055, 0x005A,
|
||||
0x0061, 0x0067, 0x006E, 0x0075, 0x007D, 0x0085, 0x008E, 0x0098,
|
||||
0x00A2, 0x00AC, 0x00B7, 0x00C3, 0x00D0, 0x00DE, 0x00EC, 0x00FB,
|
||||
0x010B, 0x011C, 0x012F, 0x0142, 0x0157, 0x016D, 0x0184, 0x019C,
|
||||
0x01B7, 0x01D3, 0x01F0, 0x0210, 0x0231, 0x0254, 0x027A, 0x02A2,
|
||||
0x02CD, 0x02FA, 0x032A, 0x035D, 0x0393, 0x03CD, 0x040A, 0x044B,
|
||||
0x0490, 0x04D9, 0x0527, 0x057A, 0x05D2, 0x062F, 0x0693, 0x06FC,
|
||||
0x076C, 0x07E3, 0x0862, 0x08E8, 0x0977, 0x0A0E, 0x0AAF, 0x0B5A,
|
||||
0x0C10, 0x0CD1, 0x0D9E, 0x0E78, 0x0F60, 0x1056, 0x115B, 0x1270,
|
||||
0x1397, 0x14D1, 0x161D, 0x177F, 0x18F7, 0x1A86, 0x1C2E, 0x1DF0,
|
||||
0x1FCF, 0x21CB, 0x23E7, 0x2625, 0x2886, 0x2B0E, 0x2DBE, 0x3098,
|
||||
0x33A1, 0x36D9, 0x3A46, 0x3DE9, 0x41C5, 0x45E0, 0x4A3C, 0x4EDE,
|
||||
0x53CA, 0x5904, 0x5E92, 0x6478, 0x6ABC, 0x7165, 0x7878, 0x7FFF,
|
||||
};
|
||||
}
|
||||
}
|
@ -62,8 +62,10 @@
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Aaru\ArcFL2.cs" />
|
||||
<Compile Include="Aaru\ArcFL3.cs" />
|
||||
<Compile Include="Aaru\ArcFL4.cs" />
|
||||
<Compile Include="Aaru\AudioWV1.cs" />
|
||||
<Compile Include="Aaru\ImageBM2.cs" />
|
||||
<Compile Include="Acme\ImageARD.cs" />
|
||||
<Compile Include="Acme\ImagePMG.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user