Skip to content

Commit

Permalink
Merge pull request #50 from hozuki/master
Browse files Browse the repository at this point in the history
Bug fixes
  • Loading branch information
hozuki committed Feb 21, 2019
2 parents 883e7c6 + a2ffc45 commit 0845d99
Show file tree
Hide file tree
Showing 18 changed files with 513 additions and 322 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2E1C8FF3-0E5E-4963-8DC4-F711F09B9419}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>DereTore.Apps.BatchDecodeFromAcb</RootNamespace>
<RootNamespace>DereTore.Apps.Acb2Wavs</RootNamespace>
<AssemblyName>acb2wavs</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
Expand Down
5 changes: 1 addition & 4 deletions Apps/Acb2Wavs/Options.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
using CommandLine;
using DereTore.Common.StarlightStage;

namespace DereTore.Apps.BatchDecodeFromAcb {
namespace DereTore.Apps.Acb2Wavs {
public sealed class Options {

[Value(0, HelpText = "Input file name", Required = true)]
public string InputFileName { get; set; } = string.Empty;

[Option('o', "out", HelpText = "Output file name", Required = false)]
public string OutputFileName { get; set; } = string.Empty;

[Option('a', "key1", HelpText = "Key 1 (8 hex digits)", Required = false, Default = "f27e3b22")]
public string Key1 { get; set; } = CgssCipher.Key1.ToString("x8");

Expand Down
9 changes: 7 additions & 2 deletions Apps/Acb2Wavs/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using DereTore.Exchange.Archive.ACB;
using DereTore.Exchange.Audio.HCA;

namespace DereTore.Apps.BatchDecodeFromAcb {
namespace DereTore.Apps.Acb2Wavs {
internal static class Program {

private static int Main(string[] args) {
Expand Down Expand Up @@ -162,7 +162,12 @@ internal static class Program {
File.Delete(extractFilePath);
}

Console.WriteLine(ex.Message);
Console.WriteLine(ex.ToString());

if (ex.InnerException != null) {
Console.WriteLine("Details:");
Console.WriteLine(ex.InnerException.ToString());
}
}
} else {
Console.WriteLine("skipped (not HCA)");
Expand Down
2 changes: 1 addition & 1 deletion DereTore.sln
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "external", "external", "{F8
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpAL", "external\SharpAL\SharpAL\SharpAL.csproj", "{7E5E07E6-4300-438E-BD37-C9F6E5E14A41}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DereTore.Apps.BatchDecodeFromAcb", "Apps\Acb2Wavs\DereTore.Apps.BatchDecodeFromAcb.csproj", "{2E1C8FF3-0E5E-4963-8DC4-F711F09B9419}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DereTore.Apps.Acb2Wavs", "Apps\Acb2Wavs\DereTore.Apps.Acb2Wavs.csproj", "{2E1C8FF3-0E5E-4963-8DC4-F711F09B9419}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DereTore.Interop.D3DX9", "Interop\DereTore.Interop.D3DX9\DereTore.Interop.D3DX9.csproj", "{F81398AD-9CF5-43A4-9CD3-DABB50F6BA3B}"
EndProject
Expand Down
7 changes: 5 additions & 2 deletions Exchange/DereTore.Exchange.Audio.HCA/Ath.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using DereTore.Common;
using DereTore.Common;

namespace DereTore.Exchange.Audio.HCA {
internal sealed class Ath {

static Ath() {
}

public bool Initialize(uint type, uint key) {
switch (type) {
case 0:
Expand Down Expand Up @@ -38,7 +41,7 @@ internal sealed class Ath {

private readonly byte[] _table = new byte[0x80];

private static readonly byte[] AthInitList = new byte[] {
private static readonly byte[] AthInitList = {
0x78, 0x5f, 0x56, 0x51, 0x4e, 0x4c, 0x4b, 0x49, 0x48, 0x48, 0x47, 0x46, 0x46, 0x45, 0x45, 0x45,
0x44, 0x44, 0x44, 0x44, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x40, 0x40, 0x40, 0x40,
Expand Down
288 changes: 14 additions & 274 deletions Exchange/DereTore.Exchange.Audio.HCA/Channel.cs
Original file line number Diff line number Diff line change
@@ -1,294 +1,34 @@
using System;
using System;
using System.Runtime.InteropServices;
using DereTore.Common;

namespace DereTore.Exchange.Audio.HCA {
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct Channel {

[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8, SizeConst = 0x80)]
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = 0x80)]
public float[] Block;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8, SizeConst = 0x80)]
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = 0x80)]
public float[] Base;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 0x80)]
public byte[] Value;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 0x80)]
public byte[] Scale;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 8)]
public byte[] Value2;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 0x80)]
public sbyte[] Value;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 0x80)]
public sbyte[] Scale;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 8)]
public sbyte[] Value2;
[MarshalAs(UnmanagedType.I4)]
public int Type;
// Original type: public char *
public IntPtr Value3;
[MarshalAs(UnmanagedType.U4)]
public uint Value3;
public uint Count;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8, SizeConst = 0x80)]
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = 0x80)]
public float[] Wav1;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8, SizeConst = 0x80)]
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = 0x80)]
public float[] Wav2;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8, SizeConst = 0x80)]
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = 0x80)]
public float[] Wav3;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8, SizeConst = 8 * 0x80)]
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = 8 * 0x80)]
public float[] Wave;

public static Channel CreateDefault() {
var v = default(Channel);
v.Block = new float[0x80];
v.Base = new float[0x80];
v.Value = new byte[0x80];
v.Scale = new byte[0x80];
v.Value2 = new byte[8];
v.Type = 0;
v.Value3 = 0;
v.Count = 0;
v.Wav1 = new float[0x80];
v.Wav2 = new float[0x80];
v.Wav3 = new float[0x80];
v.Wave = new float[8 * 0x80];
return v;
}

public void Decode1(DataBits data, uint a, int b, byte[] ath) {
int v = data.GetBit(3);
if (v >= 6) {
for (uint i = 0; i < Count; ++i) {
Value[i] = (byte)data.GetBit(6);
}
} else if (v != 0) {
int v1 = data.GetBit(6);
int v2 = (1 << v) - 1;
int v3 = v2 >> 1;
Value[0] = (byte)v1;
for (uint i = 1; i < Count; ++i) {
int v4 = data.GetBit(v);
if (v4 != v2) {
v1 += v4 - v3;
} else {
v1 = data.GetBit(6);
}
Value[i] = (byte)v1;
}
} else {
Value.ZeroMem();
}
if (Type == 2) {
v = data.CheckBit(4);
Value2[0] = (byte)v;
if (v < 15) {
for (var i = 0; i < 8; ++i) {
Value2[i] = (byte)data.GetBit(4);
}
}
} else {
for (uint i = 0; i < a; ++i) {
//Value3[i] = (byte)data.GetBit(6);
SetValue3(i, (byte)data.GetBit(6));
}
}
for (uint i = 0; i < Count; ++i) {
v = Value[i];
if (v != 0) {
v = (int)(ath[i] + ((b + i) >> 8) - ((v * 5) >> 1) + 1);
if (v < 0) {
v = 15;
} else if (v >= 0x39) {
v = 1;
} else {
v = ChannelTables.Decode1ScaleList[v];
}
}
Scale[i] = (byte)v;
}
for (var i = Count; i < Scale.Length; ++i) {
Scale[i] = 0;
}
for (uint i = 0; i < Count; ++i) {
Base[i] = ChannelTables.Decode1ValueSingle[Value[i]] * ChannelTables.Decode1ScaleSingle[Scale[i]];
}
}

public void Decode2(DataBits data) {
for (uint i = 0; i < Count; ++i) {
float f;
int s = Scale[i];
int bitSize = ChannelTables.Decode2List1[s];
int v = data.GetBit(bitSize);
if (s < 8) {
v += s << 4;
data.AddBit(ChannelTables.Decode2List2[v] - bitSize);
f = ChannelTables.Decode2List3[v];
} else {
v = (1 - ((v & 1) << 1)) * (v >> 1);
if (v == 0) {
data.AddBit(-1);
}
f = v;
}
Block[i] = Base[i] * f;
}
for (var i = Count; i < Block.Length; ++i) {
Block[i] = 0;
}
}

public void Decode3(uint a, uint b, uint c, uint d) {
if (Type != 2 && b != 0) {
float[] listFloat = ChannelTables.Decode3ListSingle;
int offset = ChannelTables.Decode3ListOffset;
for (uint i = 0, k = c, l = c - 1; i < a; ++i) {
for (uint j = 0; j < b && k < d; ++j, --l) {
Block[k++] = listFloat[GetValue3(i) - Value[l] + offset] * Block[l];
}
}
Block[0x80 - 1] = 0;
}
}

public static void Decode4(ref Channel @this, ref Channel next, int index, uint a, uint b, uint c) {
if (@this.Type == 1 && c != 0) {
var f1 = ChannelTables.Decode4ListSingle[next.Value2[index]];
var f2 = f1 - 2f;
float[] s = @this.Block;
float[] d = next.Block;
int sIndex, dIndex;
sIndex = (int)b;
dIndex = (int)b;
for (uint i = 0; i < a; ++i) {
// Don't know why, but it just happened.
// See se_live_flic_perfect.hca
// original:
/*
* (no 'break')
* d[dIndex++] = s[sIndex] * f2;
* s[sIndex++] = s[sIndex] * f1;
*/
if (sIndex >= s.Length || dIndex >= d.Length) {
break;
}
d[dIndex] = s[sIndex] * f2;
dIndex++;
s[sIndex] = s[sIndex] * f1;
sIndex++;
}
}
}

public void Decode5(int index) {
float[] s;
float[] d;
s = Block;
d = Wav1;
int sIndex = 0, dIndex = 0;
int s1Index, s2Index;
for (int i = 0, count1 = 1, count2 = 0x40; i < 7; ++i, count1 <<= 1, count2 >>= 1) {
int dIndex1 = dIndex, dIndex2 = dIndex + count2;
for (int j = 0; j < count1; ++j) {
for (int k = 0; k < count2; ++k) {
float a = s[sIndex++];
float b = s[sIndex++];
d[dIndex1++] = b + a;
d[dIndex2++] = a - b;
}
dIndex1 += count2;
dIndex2 += count2;
}
sIndex -= 0x80;
HcaHelper.Exchange(ref sIndex, ref dIndex);
HcaHelper.Exchange(ref s, ref d);
}
s = Wav1;
d = Block;
sIndex = dIndex = 0;
for (int i = 0, count1 = 0x40, count2 = 1; i < 7; ++i, count1 >>= 1, count2 <<= 1) {
// The original array is a 2-rank array, [7][0x40].
int list1FloatIndex = i * 0x40;
// The original array is a 2-rank array, [7][0x40].
int list2FloatIndex = i * 0x40;
s1Index = sIndex;
s2Index = sIndex + count2;
int dIndex1 = dIndex;
int dIndex2 = dIndex + count2 * 2 - 1;
for (int j = 0; j < count1; ++j) {
for (int k = 0; k < count2; ++k) {
float fa = s[s1Index++];
float fb = s[s2Index++];
float fc = ChannelTables.Decode5List1Single[list1FloatIndex++];
float fd = ChannelTables.Decode5List2Single[list2FloatIndex++];
d[dIndex1++] = fa * fc - fb * fd;
d[dIndex2--] = fa * fd + fb * fc;
}
s1Index += count2;
s2Index += count2;
dIndex1 += count2;
dIndex2 += count2 * 3;
}
HcaHelper.Exchange(ref sIndex, ref dIndex);
HcaHelper.Exchange(ref s, ref d);
}
d = Wav2;
for (int i = 0; i < 0x80; ++i) {
d[i] = s[i];
}
s = ChannelTables.Decode5List3Single;
sIndex = 0;
d = Wave;
// The original array is [8][0x80].
dIndex = index * 0x80;
float[] s1 = Wav2;
s1Index = 0x40;
float[] s2 = Wav3;
s2Index = 0;
for (int i = 0; i < 0x40; ++i) {
d[dIndex++] = s1[s1Index++] * s[sIndex++] + s2[s2Index++];
}
for (int i = 0; i < 0x40; ++i) {
d[dIndex++] = s[sIndex++] * s1[--s1Index] - s2[s2Index++];
}
s1 = Wav2;
s2 = Wav3;
s1Index = 0x40 - 1;
s2Index = 0;
for (int i = 0; i < 0x40; ++i) {
s2[s2Index++] = s1[s1Index--] * s[--sIndex];
}
for (int i = 0; i < 0x40; ++i) {
s2[s2Index++] = s[--sIndex] * s1[++s1Index];
}
}

private byte GetValue3(int refIndex) {
int index = (int)(refIndex + Value3);
if (0 <= index && index < 0x80) {
return Value[index];
} else if (0x80 <= index && index < 0x80 + 0x80) {
return Scale[index - 0x80];
} else {
throw new ArgumentOutOfRangeException(nameof(refIndex));
}
}

private byte GetValue3(uint refIndex) {
var index = refIndex + Value3;
if (index < 0x80) {
return Value[index];
} else if (index < 0x80 + 0x80) {
return Scale[index - 0x80];
} else {
throw new ArgumentOutOfRangeException(nameof(refIndex));
}
}

private void SetValue3(int refIndex, byte value) {
Value[refIndex + Value3] = value;
}

private void SetValue3(uint refIndex, byte value) {
Value[refIndex + Value3] = value;
}

private void SetValue3(byte value) {
Value[Value3] = value;
}

}
}
Loading

0 comments on commit 0845d99

Please sign in to comment.