diff --git a/ANX.Framework/ANX.Framework.csproj b/ANX.Framework/ANX.Framework.csproj index ff27ba43..5db940fb 100644 --- a/ANX.Framework/ANX.Framework.csproj +++ b/ANX.Framework/ANX.Framework.csproj @@ -54,6 +54,10 @@ + + + + diff --git a/ANX.Framework/Audio/AudioCategory.cs b/ANX.Framework/Audio/AudioCategory.cs index 3a2ad8ea..0586bf9c 100644 --- a/ANX.Framework/Audio/AudioCategory.cs +++ b/ANX.Framework/Audio/AudioCategory.cs @@ -1,4 +1,5 @@ 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. @@ -8,45 +9,143 @@ namespace ANX.Framework.Audio { public struct AudioCategory : IEquatable { - #region Public - public string Name + #region Internal helper enums + internal enum InstanceBehaviour { - get - { - throw new NotImplementedException(); - } + // behaviour flags (reside in upper 5 bits of the byte) + FailToPlay = 0x00, + Queue = 0x01, + ReplaceLowestPriority = 0x04, + ReplaceOldest = 0x02, + ReplaceQuietest = 0x03, + } + + internal enum InstanceCrossFading + { + // cross fade type flags (reside in lower 3 bits of byte) + XFadeLinear = 0x00, + XFadeLog = 0x01, + XFadeEqlPow = 0x02, + } + + internal enum Visibility + { + BgMusic = 0x01, + Public = 0x02, + Private = 0x00, } #endregion - #region Pause + #region Public + /// + /// Maximum number of instances (if 0xFF, then there is no limit) + /// + internal byte MaxNumberOfInstances + { + get; + private set; + } + + internal float FadeInSeconds + { + get; + private set; + } + + internal float FadeOutSeconds + { + get; + private set; + } + + internal InstanceBehaviour Behaviour + { + get; + private set; + } + + internal InstanceCrossFading CrossFading + { + get; + private set; + } + + internal byte Volume + { + get; + private set; + } + + internal Visibility CategoryVisibility + { + get; + private set; + } + + public string Name + { + get; + internal set; + } + #endregion + + #region Constructor + internal AudioCategory(BinaryReader reader) + : this() + { + MaxNumberOfInstances = reader.ReadByte(); + + // fixed point (1000 = 1.000) of fade (in seconds) + FadeInSeconds = reader.ReadUInt16() / 1000f; + FadeOutSeconds = reader.ReadUInt16() / 1000f; + + byte behaviourFlags = reader.ReadByte(); + Behaviour = (InstanceBehaviour)(behaviourFlags >> 3); + CrossFading = (InstanceCrossFading)(behaviourFlags & 7); + + // unknown, seems to be 0xFFFF for Default and 0x0000 for everyone else + reader.ReadUInt16(); + + Volume = reader.ReadByte(); + CategoryVisibility = (Visibility)reader.ReadByte(); + } + + internal AudioCategory(string setName) + : this() + { + Name = setName; + } + #endregion + + #region Pause (TODO) public void Pause() { throw new NotImplementedException(); } #endregion - #region Resume + #region Resume (TODO) public void Resume() { throw new NotImplementedException(); } #endregion - #region SetVolume - public void SetVolume(float volume) - { - throw new NotImplementedException(); - } - #endregion - - #region Stop + #region Stop (TODO) public void Stop(AudioStopOptions options) { throw new NotImplementedException(); } #endregion - #region GetHashCode + #region SetVolume (TODO) + public void SetVolume(float volume) + { + throw new NotImplementedException(); + } + #endregion + + #region GetHashCode (TODO) public override int GetHashCode() { throw new NotImplementedException(); @@ -78,7 +177,7 @@ namespace ANX.Framework.Audio } #endregion - #region Equality + #region Equality (TODO) public static bool operator ==(AudioCategory lhs, AudioCategory rhs) { throw new NotImplementedException(); diff --git a/ANX.Framework/Audio/AudioEngine.cs b/ANX.Framework/Audio/AudioEngine.cs index 7a88aa3b..374ffac4 100644 --- a/ANX.Framework/Audio/AudioEngine.cs +++ b/ANX.Framework/Audio/AudioEngine.cs @@ -1,5 +1,9 @@ using System; using System.Collections.ObjectModel; +using System.IO; +using ANX.Framework.Audio.XactParser; +using System.Collections.Generic; +using ANX.Framework.NonXNA; // This file is part of the ANX.Framework created by the // "ANX.Framework developer group" and released under the Ms-PL license. @@ -13,10 +17,14 @@ namespace ANX.Framework.Audio public const int ContentVersion = 0x27; #endregion + #region Private + private XactGeneralSettings generalSettings; + #endregion + #region Events public event EventHandler Disposing; #endregion - + #region Public public bool IsDisposed { @@ -26,22 +34,32 @@ namespace ANX.Framework.Audio public ReadOnlyCollection RendererDetails { - get - { - throw new NotImplementedException(); - } + get; + private set; } #endregion - #region Constructor + #region Constructor (TODO) public AudioEngine(string settingsFile) { - throw new NotImplementedException(); + // TODO: get renderer details + RendererDetails = new ReadOnlyCollection(new List()); + + Stream loadingStream = AddInSystemFactory.DefaultPlatformCreator.OpenReadFilestream(settingsFile); + generalSettings = new XactGeneralSettings(loadingStream); + loadingStream.Dispose(); } public AudioEngine(string settingsFile, TimeSpan lookAheadTime, string rendererId) { - throw new NotImplementedException(); + // TODO: get renderer details + RendererDetails = new ReadOnlyCollection(new List()); + + // TODO: lookAheadTime and rendererId + + Stream loadingStream = AddInSystemFactory.DefaultPlatformCreator.OpenReadFilestream(settingsFile); + generalSettings = new XactGeneralSettings(loadingStream); + loadingStream.Dispose(); } ~AudioEngine() @@ -53,25 +71,35 @@ namespace ANX.Framework.Audio #region GetCategory public AudioCategory GetCategory(string name) { - throw new NotImplementedException(); + for (int index = 0; index < generalSettings.Categories.Length; index++) + if (generalSettings.Categories[index].Name == name) + return generalSettings.Categories[index]; + + return new AudioCategory(name); } #endregion #region GetGlobalVariable public float GetGlobalVariable(string name) { - throw new NotImplementedException(); + foreach (var variable in generalSettings.Variables) + if (variable.Name == name) + return variable.StartingValue; + + return 0f; } #endregion #region SetGlobalVariable public void SetGlobalVariable(string name, float value) { - throw new NotImplementedException(); + foreach (var variable in generalSettings.Variables) + if (variable.Name == name) + variable.StartingValue = MathHelper.Clamp(value, variable.MinValue, variable.MaxValue); } #endregion - #region Update + #region Update (TODO) public void Update() { throw new NotImplementedException(); @@ -83,8 +111,11 @@ namespace ANX.Framework.Audio { if (IsDisposed == false) { + if (Disposing != null) + Disposing(this, EventArgs.Empty); + IsDisposed = true; - throw new NotImplementedException(); + generalSettings = null; } } diff --git a/ANX.Framework/Audio/XactParser/XactGeneralSettings.cs b/ANX.Framework/Audio/XactParser/XactGeneralSettings.cs new file mode 100644 index 00000000..2758ba7c --- /dev/null +++ b/ANX.Framework/Audio/XactParser/XactGeneralSettings.cs @@ -0,0 +1,140 @@ +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 +{ + /// + /// http://code.google.com/p/monoxna/source/browse/wiki/XnaFrameworkAudio.wiki?r=347 + /// + 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 + } +} diff --git a/ANX.Framework/Audio/XactParser/XactGeneralSettingsRpcCurve.cs b/ANX.Framework/Audio/XactParser/XactGeneralSettingsRpcCurve.cs new file mode 100644 index 00000000..00f5073c --- /dev/null +++ b/ANX.Framework/Audio/XactParser/XactGeneralSettingsRpcCurve.cs @@ -0,0 +1,44 @@ +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 +{ + internal class XactGeneralSettingsRpcCurve + { + // what variable this curve involves + public ushort VariableIndex + { + get; + private set; + } + + // which parameter the curve affects refer to the above constants + public short Parameters + { + get; + private set; + } + + public XactGeneralSettingsRpcCurvePoint[] Points + { + get; + private set; + } + + public XactGeneralSettingsRpcCurve(BinaryReader reader) + { + VariableIndex = reader.ReadUInt16(); + byte numberOfCurvePoints = reader.ReadByte(); + Parameters = reader.ReadInt16(); + + Points = new XactGeneralSettingsRpcCurvePoint[numberOfCurvePoints]; + + for (int pointIndex = 0; pointIndex < numberOfCurvePoints; pointIndex++) + Points[pointIndex] = new XactGeneralSettingsRpcCurvePoint(reader); + } + } +} diff --git a/ANX.Framework/Audio/XactParser/XactGeneralSettingsRpcCurvePoint.cs b/ANX.Framework/Audio/XactParser/XactGeneralSettingsRpcCurvePoint.cs new file mode 100644 index 00000000..65a98885 --- /dev/null +++ b/ANX.Framework/Audio/XactParser/XactGeneralSettingsRpcCurvePoint.cs @@ -0,0 +1,45 @@ +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 +{ + internal class XactGeneralSettingsRpcCurvePoint + { + public enum CurveType + { + Linear = 0x00, + Fast = 0x01, + Slow = 0x02, + SinCos = 0x03, + } + + public float X + { + get; + private set; + } + + public float Y + { + get; + private set; + } + + public CurveType Type + { + get; + private set; + } + + public XactGeneralSettingsRpcCurvePoint(BinaryReader reader) + { + X = reader.ReadSingle(); + Y = reader.ReadSingle(); + Type = (XactGeneralSettingsRpcCurvePoint.CurveType)reader.ReadByte(); + } + } +} diff --git a/ANX.Framework/Audio/XactParser/XactGeneralSettingsVariable.cs b/ANX.Framework/Audio/XactParser/XactGeneralSettingsVariable.cs new file mode 100644 index 00000000..3dc12b87 --- /dev/null +++ b/ANX.Framework/Audio/XactParser/XactGeneralSettingsVariable.cs @@ -0,0 +1,54 @@ +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 +{ + internal class XactGeneralSettingsVariable + { + public enum VariableFlags + { + Public = 0x01, + ReadOnly = 0x02, + CueInstance = 0x04, + Reserved = 0x08, + } + + public VariableFlags Flags + { + get; + private set; + } + + public float StartingValue + { + get; + set; + } + + public float MinValue + { + get; + private set; + } + + public float MaxValue + { + get; + private set; + } + + public string Name; + + public XactGeneralSettingsVariable(BinaryReader reader) + { + Flags = (XactGeneralSettingsVariable.VariableFlags)reader.ReadByte(); + StartingValue = reader.ReadSingle(); + MinValue = reader.ReadSingle(); + MaxValue = reader.ReadSingle(); + } + } +} diff --git a/ANX.Framework/NonXNA/PlatformSystem/IPlatformSystemCreator.cs b/ANX.Framework/NonXNA/PlatformSystem/IPlatformSystemCreator.cs index 97425b78..e52b4e57 100644 --- a/ANX.Framework/NonXNA/PlatformSystem/IPlatformSystemCreator.cs +++ b/ANX.Framework/NonXNA/PlatformSystem/IPlatformSystemCreator.cs @@ -1,5 +1,5 @@ -using System; using System.Collections.Generic; +using System.IO; using ANX.Framework.Media; using ANX.Framework.Storage; @@ -12,13 +12,14 @@ namespace ANX.Framework.NonXNA.PlatformSystem public interface IPlatformSystemCreator : ICreator { GameHost CreateGameHost(Game game); - INativeStorageDevice CreateStorageDevice(StorageDevice device, - PlayerIndex player, int sizeInBytes, int directoryCount); + INativeStorageDevice CreateStorageDevice(StorageDevice device, PlayerIndex player, int sizeInBytes, int directoryCount); INativeStorageContainer CreateStorageContainer(StorageContainer container); INativeTitleContainer CreateTitleContainer(); INativeGameTimer CreateGameTimer(); INativeContentManager CreateContentManager(); + Stream OpenReadFilestream(string filepath); + INativeMediaLibrary CreateMediaPlayer(); IList GetAvailableMediaSources(); } diff --git a/ANX.Framework/TitleContainer.cs b/ANX.Framework/TitleContainer.cs index 87e44ce3..999ed6f8 100644 --- a/ANX.Framework/TitleContainer.cs +++ b/ANX.Framework/TitleContainer.cs @@ -14,8 +14,7 @@ namespace ANX.Framework static TitleContainer() { - nativeImplementation = - AddInSystemFactory.DefaultPlatformCreator.CreateTitleContainer(); + nativeImplementation = AddInSystemFactory.DefaultPlatformCreator.CreateTitleContainer(); } public static Stream OpenStream(string name) diff --git a/PlatformSystems/ANX.PlatformSystem.Linux/LinuxPlatformCreator.cs b/PlatformSystems/ANX.PlatformSystem.Linux/LinuxPlatformCreator.cs index d3446096..c54e4a1c 100644 --- a/PlatformSystems/ANX.PlatformSystem.Linux/LinuxPlatformCreator.cs +++ b/PlatformSystems/ANX.PlatformSystem.Linux/LinuxPlatformCreator.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using ANX.Framework; using ANX.Framework.Media; using ANX.Framework.NonXNA; @@ -102,5 +103,12 @@ namespace ANX.PlatformSystem.Linux throw new NotImplementedException(); } #endregion + + #region OpenReadFilestream + public Stream OpenReadFilestream(string filepath) + { + return File.OpenRead(filepath); + } + #endregion } } diff --git a/PlatformSystems/ANX.PlatformSystem.Metro/MetroPlatformCreator.cs b/PlatformSystems/ANX.PlatformSystem.Metro/MetroPlatformCreator.cs index fbdddd50..41fc6d36 100644 --- a/PlatformSystems/ANX.PlatformSystem.Metro/MetroPlatformCreator.cs +++ b/PlatformSystems/ANX.PlatformSystem.Metro/MetroPlatformCreator.cs @@ -3,6 +3,9 @@ using ANX.Framework; using ANX.Framework.NonXNA; using ANX.Framework.NonXNA.PlatformSystem; using ANX.Framework.Storage; +using System.IO; +using ANX.Framework.Media; +using System.Collections.Generic; // This file is part of the ANX.Framework created by the // "ANX.Framework developer group" and released under the Ms-PL license. @@ -97,5 +100,22 @@ namespace ANX.PlatformSystem.Metro return new MetroContentManager(); } #endregion + + #region IPlatformSystemCreator Member + public Stream OpenReadFilestream(string filepath) + { + throw new NotImplementedException(); + } + + public INativeMediaLibrary CreateMediaPlayer() + { + throw new NotImplementedException(); + } + + public IList GetAvailableMediaSources() + { + throw new NotImplementedException(); + } + #endregion } } diff --git a/PlatformSystems/ANX.PlatformSystem.PsVita/PsVitaPlatformCreator.cs b/PlatformSystems/ANX.PlatformSystem.PsVita/PsVitaPlatformCreator.cs index 06678ae8..741f8197 100644 --- a/PlatformSystems/ANX.PlatformSystem.PsVita/PsVitaPlatformCreator.cs +++ b/PlatformSystems/ANX.PlatformSystem.PsVita/PsVitaPlatformCreator.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using ANX.Framework; using ANX.Framework.Media; using ANX.Framework.NonXNA; @@ -105,5 +106,12 @@ namespace ANX.PlatformSystem.PsVita throw new NotImplementedException(); } #endregion + + #region OpenReadFilestream + public Stream OpenReadFilestream(string filepath) + { + return File.OpenRead(filepath); + } + #endregion } } diff --git a/PlatformSystems/ANX.PlatformSystem.Windows/WindowsPlatformCreator.cs b/PlatformSystems/ANX.PlatformSystem.Windows/WindowsPlatformCreator.cs index 31788d3f..dcd0b37f 100644 --- a/PlatformSystems/ANX.PlatformSystem.Windows/WindowsPlatformCreator.cs +++ b/PlatformSystems/ANX.PlatformSystem.Windows/WindowsPlatformCreator.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using ANX.Framework; using ANX.Framework.Media; using ANX.Framework.NonXNA; @@ -102,5 +103,12 @@ namespace ANX.PlatformSystem.Windows throw new NotImplementedException(); } #endregion + + #region OpenReadFilestream + public Stream OpenReadFilestream(string filepath) + { + return File.OpenRead(filepath); + } + #endregion } } diff --git a/SoundSystems/ANX.SoundSystem.OpenAL/ANX.SoundSystem.OpenAL_Linux.csproj b/SoundSystems/ANX.SoundSystem.OpenAL/ANX.SoundSystem.OpenAL_Linux.csproj index c7875f37..41e8ea79 100644 --- a/SoundSystems/ANX.SoundSystem.OpenAL/ANX.SoundSystem.OpenAL_Linux.csproj +++ b/SoundSystems/ANX.SoundSystem.OpenAL/ANX.SoundSystem.OpenAL_Linux.csproj @@ -70,6 +70,12 @@ + + + + + + diff --git a/SoundSystems/ANX.SoundSystem.OpenAL/ANX.SoundSystem.OpenAL_PSVita.csproj b/SoundSystems/ANX.SoundSystem.OpenAL/ANX.SoundSystem.OpenAL_PSVita.csproj index b969bfaf..d55911fe 100644 --- a/SoundSystems/ANX.SoundSystem.OpenAL/ANX.SoundSystem.OpenAL_PSVita.csproj +++ b/SoundSystems/ANX.SoundSystem.OpenAL/ANX.SoundSystem.OpenAL_PSVita.csproj @@ -71,6 +71,12 @@ + + + + + +