141 lines
4.3 KiB
C#
141 lines
4.3 KiB
C#
|
using System;
|
|||
|
using System.IO;
|
|||
|
|
|||
|
// This file is part of the ANX.Framework created by the
|
|||
|
// "ANX.Framework developer group" and released under the Ms-PL license.
|
|||
|
// For details see: http://anxframework.codeplex.com/license
|
|||
|
|
|||
|
namespace ANX.Framework.Audio.XactParser
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// http://code.google.com/p/monoxna/source/browse/wiki/XnaFrameworkAudio.wiki?r=347
|
|||
|
/// </summary>
|
|||
|
internal class XactGeneralSettings
|
|||
|
{
|
|||
|
public class InvalidMagicException : Exception { }
|
|||
|
public class InvalidVersionException : Exception { }
|
|||
|
|
|||
|
#region Public
|
|||
|
public AudioCategory[] Categories
|
|||
|
{
|
|||
|
get;
|
|||
|
private set;
|
|||
|
}
|
|||
|
|
|||
|
public XactGeneralSettingsVariable[] Variables
|
|||
|
{
|
|||
|
get;
|
|||
|
private set;
|
|||
|
}
|
|||
|
|
|||
|
public XactGeneralSettingsRpcCurve[] Curves
|
|||
|
{
|
|||
|
get;
|
|||
|
private set;
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Constructor
|
|||
|
public XactGeneralSettings(Stream stream)
|
|||
|
{
|
|||
|
BinaryReader reader = new BinaryReader(stream);
|
|||
|
ValidateMagic(reader);
|
|||
|
ValidateVersion(reader);
|
|||
|
|
|||
|
// unknown, but seems to be 0x002A across all files
|
|||
|
reader.ReadUInt16();
|
|||
|
// unknown, maybe something to do with the last modified values
|
|||
|
reader.ReadUInt16();
|
|||
|
|
|||
|
DateTime lastModifiedDate = DateTime.FromFileTime(reader.ReadInt64());
|
|||
|
|
|||
|
// unknown, seems to stay 0x03
|
|||
|
reader.ReadByte();
|
|||
|
|
|||
|
Categories = new AudioCategory[reader.ReadUInt16()];
|
|||
|
Variables = new XactGeneralSettingsVariable[reader.ReadUInt16()];
|
|||
|
|
|||
|
// unknown, seems to always be 0x16
|
|||
|
reader.ReadUInt16();
|
|||
|
// unknown, seems to always be 0x16
|
|||
|
reader.ReadUInt16();
|
|||
|
|
|||
|
Curves = new XactGeneralSettingsRpcCurve[reader.ReadUInt16()];
|
|||
|
ushort dspEffectPresetsCount = reader.ReadUInt16();
|
|||
|
ushort dspEffectParametersCount = reader.ReadUInt16();
|
|||
|
|
|||
|
int firstCategorySettingsPosition = reader.ReadInt32();
|
|||
|
int firstVariableSettingsPosition = reader.ReadInt32();
|
|||
|
|
|||
|
// unknown
|
|||
|
stream.Seek(16, SeekOrigin.Current);
|
|||
|
|
|||
|
int positionOfFirstCategoryName = reader.ReadInt32();
|
|||
|
int positionOfFirstVariableName = reader.ReadInt32();
|
|||
|
int positionOfFirstRpcCurve = reader.ReadInt32();
|
|||
|
int positionOfFirstDspEffectPreset = reader.ReadInt32();
|
|||
|
int positionOfFirstDspEffectParameters = reader.ReadInt32();
|
|||
|
|
|||
|
stream.Seek(firstCategorySettingsPosition, SeekOrigin.Begin);
|
|||
|
for (int categoryIndex = 0; categoryIndex < Categories.Length; categoryIndex++)
|
|||
|
Categories[categoryIndex] = new AudioCategory(reader);
|
|||
|
|
|||
|
stream.Seek(firstVariableSettingsPosition, SeekOrigin.Begin);
|
|||
|
for (int variableIndex = 0; variableIndex < Variables.Length; variableIndex++)
|
|||
|
Variables[variableIndex] = new XactGeneralSettingsVariable(reader);
|
|||
|
|
|||
|
if (positionOfFirstRpcCurve > -1)
|
|||
|
{
|
|||
|
stream.Seek(positionOfFirstRpcCurve, SeekOrigin.Begin);
|
|||
|
for (int curveIndex = 0; curveIndex < Curves.Length; curveIndex++)
|
|||
|
Curves[curveIndex] = new XactGeneralSettingsRpcCurve(reader);
|
|||
|
}
|
|||
|
|
|||
|
stream.Seek(positionOfFirstCategoryName, SeekOrigin.Begin);
|
|||
|
string[] names = ParseNames(Categories.Length, reader);
|
|||
|
for (int categoryIndex = 0; categoryIndex < Categories.Length; categoryIndex++)
|
|||
|
Categories[categoryIndex].Name = names[categoryIndex];
|
|||
|
|
|||
|
stream.Seek(positionOfFirstVariableName, SeekOrigin.Begin);
|
|||
|
names = ParseNames(Variables.Length, reader);
|
|||
|
for (int variableIndex = 0; variableIndex < Variables.Length; variableIndex++)
|
|||
|
Variables[variableIndex].Name = names[variableIndex];
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region ValidateMagic
|
|||
|
private static void ValidateMagic(BinaryReader reader)
|
|||
|
{
|
|||
|
char[] magicChars = reader.ReadChars(4);
|
|||
|
if (magicChars[0] != 'X' || magicChars[1] != 'G' || magicChars[2] != 'S' || magicChars[3] != 'F')
|
|||
|
throw new InvalidMagicException();
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region ValidateVersion
|
|||
|
private static void ValidateVersion(BinaryReader reader)
|
|||
|
{
|
|||
|
ushort version = reader.ReadUInt16();
|
|||
|
if (version != 47 && version != 46 && version != 45)
|
|||
|
throw new InvalidVersionException();
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region ParseNames
|
|||
|
private static string[] ParseNames(int count, BinaryReader reader)
|
|||
|
{
|
|||
|
string[] result = new string[count];
|
|||
|
for (int index = 0; index < count; index++)
|
|||
|
{
|
|||
|
result[index] = "";
|
|||
|
char readChar = '\0';
|
|||
|
while ((readChar = (char)reader.ReadByte()) != '\0')
|
|||
|
result[index] += readChar;
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
#endregion
|
|||
|
}
|
|||
|
}
|