diff --git a/ANX.Framework/ANX.Framework.csproj b/ANX.Framework/ANX.Framework.csproj index 4a863414..29384d5b 100644 --- a/ANX.Framework/ANX.Framework.csproj +++ b/ANX.Framework/ANX.Framework.csproj @@ -446,6 +446,7 @@ + diff --git a/ANX.Framework/Audio/AudioEngine.cs b/ANX.Framework/Audio/AudioEngine.cs index 98c4c0bf..dbdd688c 100644 --- a/ANX.Framework/Audio/AudioEngine.cs +++ b/ANX.Framework/Audio/AudioEngine.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; +using System.Linq; using ANX.Framework.Audio.XactParser; using ANX.Framework.NonXNA; using ANX.Framework.NonXNA.Development; @@ -74,32 +75,29 @@ namespace ANX.Framework.Audio #region GetCategory public AudioCategory GetCategory(string name) { - for (int index = 0; index < generalSettings.Categories.Length; index++) - if (generalSettings.Categories[index].Name == name) - return generalSettings.Categories[index]; + foreach (AudioCategory category in generalSettings.Categories.Where(category => category.Name == name)) + return category; - return new AudioCategory(name); + return new AudioCategory(name); } - #endregion + #endregion #region GetGlobalVariable public float GetGlobalVariable(string name) - { - foreach (var variable in generalSettings.Variables) - if (variable.Name == name) - return variable.StartingValue; + { + foreach (var variable in generalSettings.Variables.Where(variable => variable.Name == name)) + return variable.StartingValue; return 0f; } #endregion #region SetGlobalVariable - public void SetGlobalVariable(string name, float value) - { - foreach (var variable in generalSettings.Variables) - if (variable.Name == name) - variable.StartingValue = MathHelper.Clamp(value, variable.MinValue, variable.MaxValue); - } + public void SetGlobalVariable(string name, float value) + { + foreach (var variable in generalSettings.Variables.Where(variable => variable.Name == name)) + variable.StartingValue = MathHelper.Clamp(value, variable.MinValue, variable.MaxValue); + } #endregion #region Update (TODO) @@ -112,14 +110,14 @@ namespace ANX.Framework.Audio #region Dispose protected virtual void Dispose(bool disposing) { - if (IsDisposed == false) - { - if (Disposing != null) - Disposing(this, EventArgs.Empty); + if (IsDisposed) + return; - IsDisposed = true; - generalSettings = null; - } + if (Disposing != null) + Disposing(this, EventArgs.Empty); + + IsDisposed = true; + generalSettings = null; } public void Dispose() diff --git a/ANX.Framework/Audio/SoundEffect.cs b/ANX.Framework/Audio/SoundEffect.cs index f0f131e9..ee3d367d 100644 --- a/ANX.Framework/Audio/SoundEffect.cs +++ b/ANX.Framework/Audio/SoundEffect.cs @@ -17,61 +17,29 @@ namespace ANX.Framework.Audio public sealed class SoundEffect : IDisposable { #region Static - #region DistanceScale - public static float DistanceScale - { - get - { - return GetCreator().DistanceScale; - } - set - { - GetCreator().DistanceScale = value; - } - } - #endregion + public static float DistanceScale + { + get { return GetCreator().DistanceScale; } + set { GetCreator().DistanceScale = value; } + } - #region DopplerScale - public static float DopplerScale - { - get - { - return GetCreator().DopplerScale; - } - set - { - GetCreator().DopplerScale = value; - } - } - #endregion + public static float DopplerScale + { + get { return GetCreator().DopplerScale; } + set { GetCreator().DopplerScale = value; } + } - #region MasterVolume - public static float MasterVolume - { - get - { - return GetCreator().MasterVolume; - } - set - { - GetCreator().MasterVolume = value; - } - } - #endregion + public static float MasterVolume + { + get { return GetCreator().MasterVolume; } + set { GetCreator().MasterVolume = value; } + } - #region SpeedOfSound - public static float SpeedOfSound - { - get - { - return GetCreator().SpeedOfSound; - } - set - { - GetCreator().SpeedOfSound = value; - } - } - #endregion + public static float SpeedOfSound + { + get { return GetCreator().SpeedOfSound; } + set { GetCreator().SpeedOfSound = value; } + } #endregion #region Private @@ -131,11 +99,13 @@ namespace ANX.Framework.Audio { } - public SoundEffect(byte[] buffer, int offset, int count, int sampleRate, AudioChannels channels, int loopStart, int loopLength) + public SoundEffect(byte[] buffer, int offset, int count, int sampleRate, AudioChannels channels, int loopStart, + int loopLength) : this() { var creator = GetCreator(); - NativeSoundEffect = creator.CreateSoundEffect(this, buffer, offset, count, sampleRate, channels, loopStart, loopLength); + NativeSoundEffect = creator.CreateSoundEffect(this, buffer, offset, count, sampleRate, channels, loopStart, + loopLength); } ~SoundEffect() @@ -204,9 +174,7 @@ namespace ANX.Framework.Audio children.Add(new WeakReference(newInstance)); lock (fireAndForgetInstances) - { fireAndForgetInstances.Add(newInstance); - } newInstance.Play(); } @@ -220,8 +188,27 @@ namespace ANX.Framework.Audio } #endregion - #region Dispose - public void Dispose() + #region RecycleStoppedFireAndForgetInstances + internal static void RecycleStoppedFireAndForgetInstances() + { + lock (fireAndForgetInstances) + { + var instancesToDispose = new List(); + foreach (SoundEffectInstance current in fireAndForgetInstances) + if (current.State == SoundState.Stopped) + instancesToDispose.Add(current); + + foreach (SoundEffectInstance current in instancesToDispose) + { + current.Dispose(); + fireAndForgetInstances.Remove(current); + } + } + } + #endregion + + #region Dispose + public void Dispose() { if (IsDisposed) return; diff --git a/ANX.Framework/Audio/SoundEffectInstance.cs b/ANX.Framework/Audio/SoundEffectInstance.cs index 9afce232..656de509 100644 --- a/ANX.Framework/Audio/SoundEffectInstance.cs +++ b/ANX.Framework/Audio/SoundEffectInstance.cs @@ -16,13 +16,8 @@ namespace ANX.Framework.Audio { #region Private private ISoundEffectInstance nativeInstance; - - internal bool IsFireAndForget - { - get; - private set; - } - #endregion + internal bool IsFireAndForget { get; private set; } + #endregion #region Public public bool IsDisposed { get; private set; } diff --git a/ANX.Framework/Audio/XactParser/XactGeneralSettingsRpcCurve.cs b/ANX.Framework/Audio/XactParser/XactGeneralSettingsRpcCurve.cs index 00f5073c..3cdd3865 100644 --- a/ANX.Framework/Audio/XactParser/XactGeneralSettingsRpcCurve.cs +++ b/ANX.Framework/Audio/XactParser/XactGeneralSettingsRpcCurve.cs @@ -10,26 +10,14 @@ namespace ANX.Framework.Audio.XactParser internal class XactGeneralSettingsRpcCurve { // what variable this curve involves - public ushort VariableIndex - { - get; - private set; - } + public ushort VariableIndex { get; private set; } - // which parameter the curve affects refer to the above constants - public short Parameters - { - 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 XactGeneralSettingsRpcCurvePoint[] Points { get; private set; } - public XactGeneralSettingsRpcCurve(BinaryReader reader) + public XactGeneralSettingsRpcCurve(BinaryReader reader) { VariableIndex = reader.ReadUInt16(); byte numberOfCurvePoints = reader.ReadByte(); diff --git a/ANX.Framework/Audio/XactParser/XactGeneralSettingsRpcCurvePoint.cs b/ANX.Framework/Audio/XactParser/XactGeneralSettingsRpcCurvePoint.cs index 65a98885..45f76648 100644 --- a/ANX.Framework/Audio/XactParser/XactGeneralSettingsRpcCurvePoint.cs +++ b/ANX.Framework/Audio/XactParser/XactGeneralSettingsRpcCurvePoint.cs @@ -17,29 +17,15 @@ namespace ANX.Framework.Audio.XactParser SinCos = 0x03, } - public float X - { - get; - private set; - } + public float X { get; private set; } + public float Y { get; private set; } + public CurveType Type { get; private set; } - public float Y - { - get; - private set; - } - - public CurveType Type - { - get; - private set; - } - - public XactGeneralSettingsRpcCurvePoint(BinaryReader reader) + public XactGeneralSettingsRpcCurvePoint(BinaryReader reader) { X = reader.ReadSingle(); Y = reader.ReadSingle(); - Type = (XactGeneralSettingsRpcCurvePoint.CurveType)reader.ReadByte(); + Type = (CurveType)reader.ReadByte(); } } } diff --git a/ANX.Framework/Audio/XactParser/XactGeneralSettingsVariable.cs b/ANX.Framework/Audio/XactParser/XactGeneralSettingsVariable.cs index 3dc12b87..8490e47e 100644 --- a/ANX.Framework/Audio/XactParser/XactGeneralSettingsVariable.cs +++ b/ANX.Framework/Audio/XactParser/XactGeneralSettingsVariable.cs @@ -17,35 +17,15 @@ namespace ANX.Framework.Audio.XactParser 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 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(); + Flags = (VariableFlags)reader.ReadByte(); StartingValue = reader.ReadSingle(); MinValue = reader.ReadSingle(); MaxValue = reader.ReadSingle(); diff --git a/ANX.Framework/FrameworkDispatcher.cs b/ANX.Framework/FrameworkDispatcher.cs index 112b14fb..6295a38c 100644 --- a/ANX.Framework/FrameworkDispatcher.cs +++ b/ANX.Framework/FrameworkDispatcher.cs @@ -1,4 +1,5 @@ using System; +using ANX.Framework.Audio; using ANX.Framework.NonXNA.Development; // This file is part of the ANX.Framework created by the @@ -18,6 +19,8 @@ namespace ANX.Framework { if (OnUpdate != null) OnUpdate(); + + SoundEffect.RecycleStoppedFireAndForgetInstances(); } } } diff --git a/ANX.Framework/Game.cs b/ANX.Framework/Game.cs index 3f3183ce..b15de804 100644 --- a/ANX.Framework/Game.cs +++ b/ANX.Framework/Game.cs @@ -6,6 +6,7 @@ using ANX.Framework.Graphics; using ANX.Framework.NonXNA; using ANX.Framework.NonXNA.Development; using ANX.Framework.NonXNA.PlatformSystem; +using ANX.Framework.NonXNA.SoundSystem; #endregion // Using Statements @@ -78,6 +79,8 @@ namespace ANX.Framework AddSystemCreator(); AddSystemCreator(); + FrameworkDispatcher.Update(); + CreateGameHost(); Logger.Info("creating ContentManager"); @@ -151,6 +154,8 @@ namespace ANX.Framework updateable.Update(gameTime); } } + + FrameworkDispatcher.Update(); } protected virtual void Draw(GameTime gameTime) diff --git a/ANX.Framework/Media/MediaPlayer.cs b/ANX.Framework/Media/MediaPlayer.cs index e83c4baa..e3afdd24 100644 --- a/ANX.Framework/Media/MediaPlayer.cs +++ b/ANX.Framework/Media/MediaPlayer.cs @@ -1,4 +1,5 @@ using System; +using ANX.Framework.NonXNA.Development; // This file is part of the ANX.Framework created by the // "ANX.Framework developer group" and released under the Ms-PL license. @@ -6,189 +7,170 @@ using System; namespace ANX.Framework.Media { - public static class MediaPlayer - { - #region Events - public static event EventHandler ActiveSongChanged; - public static event EventHandler MediaStateChanged; - #endregion + [PercentageComplete(100)] + [TestState(TestStateAttribute.TestState.Untested)] + [Developer("AstrorEnales")] + public static class MediaPlayer + { + #region Events + public static event EventHandler ActiveSongChanged; + public static event EventHandler MediaStateChanged; + #endregion - #region Public - #region IsShuffled (TODO) - public static bool IsShuffled - { - get - { - throw new NotImplementedException(); - } - set - { - throw new NotImplementedException(); - } - } - #endregion + private static bool isRepeating; + private static float volume; + private static MediaState currentState; + internal static float VolumeToUse + { + get { return IsMuted ? 0f : volume; } + } - #region IsRepeating (TODO) - public static bool IsRepeating - { - get - { - throw new NotImplementedException(); - } - set - { - throw new NotImplementedException(); - } - } - #endregion + #region Public + public static bool IsShuffled { get; set; } - #region Volume (TODO) - public static float Volume - { - get - { - throw new NotImplementedException(); - } - set - { - throw new NotImplementedException(); - } - } - #endregion + public static bool IsRepeating + { + get { return isRepeating; } + set { isRepeating = value; } + } - #region IsMuted (TODO) - public static bool IsMuted - { - get - { - throw new NotImplementedException(); - } - set - { - throw new NotImplementedException(); - } - } - #endregion + public static float Volume + { + get { return volume; } + set { volume = MathHelper.Clamp(value, 0f, 1f); } + } - #region IsVisualizationEnabled (TODO) - public static bool IsVisualizationEnabled - { - get - { - throw new NotImplementedException(); - } - set - { - throw new NotImplementedException(); - } - } - #endregion + public static bool IsVisualizationEnabled { get; set; } + public static bool IsMuted { get; set; } + public static MediaQueue Queue { get; private set; } + public static MediaState State + { + get { return currentState; } + private set + { + if (currentState == value) + return; - public static MediaQueue Queue - { - get; - private set; - } + currentState = value; + MediaStateChanged(null, EventArgs.Empty); + } + } - #region State (TODO) - public static MediaState State - { - get - { - throw new NotImplementedException(); - } - } - #endregion + public static TimeSpan PlayPosition + { + get + { + return Queue.ActiveSong == null + ? TimeSpan.Zero : Queue.ActiveSong.NativeSong.PlayPosition; + } + } - #region PlayPosition (TODO) - public static TimeSpan PlayPosition - { - get - { - throw new NotImplementedException(); - } - } - #endregion + public static bool GameHasControl + { + get { return true; } + } + #endregion - #region GameHasControl (TODO) - public static bool GameHasControl - { - get - { - throw new NotImplementedException(); - } - } - #endregion - #endregion + #region Constructor + static MediaPlayer() + { + currentState = MediaState.Stopped; + volume = 1f; + isRepeating = false; + IsMuted = false; + IsVisualizationEnabled = false; + IsShuffled = false; + Queue = new MediaQueue(); + FrameworkDispatcher.OnUpdate += Tick; + } + #endregion - #region Constructor - static MediaPlayer() - { - Queue = new MediaQueue(); - } - #endregion + #region Play + public static void Play(Song song) + { + Queue.Play(song); + } - #region Play - public static void Play(Song song) - { - Queue.Play(song); - } - #endregion + public static void Play(SongCollection songCollection) + { + Queue.Play(songCollection); + } - #region Play - public static void Play(SongCollection songCollection) - { - Queue.Play(songCollection); - } - #endregion + public static void Play(SongCollection songCollection, int index) + { + Queue.Play(songCollection, index); + } + #endregion - #region Play (TODO) - public static void Play(SongCollection songCollection, int index) - { - throw new NotImplementedException(); - } - #endregion + #region Pause + public static void Pause() + { + if (Queue.ActiveSong != null) + Queue.ActiveSong.Pause(); + } + #endregion - #region Pause (TODO) - public static void Pause() - { - throw new NotImplementedException(); - } - #endregion + #region Resume + public static void Resume() + { + if (Queue.ActiveSong != null) + Queue.ActiveSong.Resume(); + } + #endregion - #region Resume (TODO) - public static void Resume() - { - throw new NotImplementedException(); - } - #endregion + #region Stop + public static void Stop() + { + Queue.Stop(); + } + #endregion - #region Stop (TODO) - public static void Stop() - { - throw new NotImplementedException(); - } - #endregion + #region MoveNext + public static void MoveNext() + { + Queue.MoveNext(false); + } + #endregion - #region MoveNext - public static void MoveNext() - { - Queue.MoveNext(); - } - #endregion + #region MovePrevious + public static void MovePrevious() + { + Queue.MovePrevious(); + } + #endregion - #region MovePrevious - public static void MovePrevious() - { - Queue.MovePrevious(); - } - #endregion + #region Tick + private static void Tick() + { + if (Queue.ActiveSong == null) + { + State = MediaState.Stopped; + return; + } - #region GetVisualizationData (TODO) - public static void GetVisualizationData(VisualizationData data) - { - throw new NotImplementedException(); - } - #endregion - } + State = Queue.ActiveSong.State; + if (Queue.ActiveSong.State != MediaState.Stopped) + return; + + if (Queue.MoveNext(isRepeating)) + State = MediaState.Playing; + + ActiveSongChanged(null, EventArgs.Empty); + } + #endregion + + #region GetVisualizationData + public static void GetVisualizationData(VisualizationData visualizationData) + { + if (visualizationData == null) + throw new ArgumentNullException("visualizationData"); + + if (IsVisualizationEnabled == false) + return; + + if(Queue.ActiveSong != null) + Queue.ActiveSong.NativeSong.GetVisualizationData(visualizationData); + } + #endregion + } } diff --git a/ANX.Framework/Media/MediaQueue.cs b/ANX.Framework/Media/MediaQueue.cs index b6f85ef5..b919bbc0 100644 --- a/ANX.Framework/Media/MediaQueue.cs +++ b/ANX.Framework/Media/MediaQueue.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using ANX.Framework.NonXNA.Development; // This file is part of the ANX.Framework created by the // "ANX.Framework developer group" and released under the Ms-PL license. @@ -7,57 +8,53 @@ using System.Collections.Generic; namespace ANX.Framework.Media { + [PercentageComplete(100)] + [TestState(TestStateAttribute.TestState.Untested)] + [Developer("AstrorEnales")] public sealed class MediaQueue { - #region Private - private List queue; - #endregion + private readonly List queue; #region Public - public int Count - { - get - { - return queue.Count; - } - } + public int Count + { + get { return queue.Count; } + } - public int ActiveSongIndex - { - get; - set; - } + public int ActiveSongIndex { get; set; } - public Song ActiveSong - { - get - { - return queue[ActiveSongIndex]; - } - } + public Song ActiveSong + { + get { return queue.Count <= 0 ? null : queue[ActiveSongIndex]; } + } - public Song this[int index] - { - get - { - return queue[index]; - } - } - #endregion + public Song this[int index] + { + get { return queue[index]; } + } + #endregion #region Constructor internal MediaQueue() { queue = new List(); } + + ~MediaQueue() + { + queue.Clear(); + } #endregion - internal void Play(Song song) + #region Play + internal void Play(Song song) { if (song == null) throw new ArgumentNullException("song"); + Clear(); queue.Add(song); + ActiveSong.Play(); } internal void Play(SongCollection songCollection) @@ -65,29 +62,93 @@ namespace ANX.Framework.Media if (songCollection == null) throw new ArgumentNullException("songCollection"); - queue.AddRange(songCollection); + Clear(); + queue.AddRange(songCollection); + // TODO: check if the shuffle is calculated after each finished song or like this! + if (MediaPlayer.IsShuffled) + Shuffle(); + ActiveSong.Play(); } - internal void MoveNext() - { - if (Count > 0) - { - if (ActiveSongIndex < Count - 1) - ActiveSongIndex++; - else - ActiveSongIndex = 0; - } - } + internal void Play(SongCollection songCollection, int index) + { + if (songCollection == null) + throw new ArgumentNullException("songCollection"); - internal void MovePrevious() + Clear(); + ActiveSongIndex = index; + queue.AddRange(songCollection); + // TODO: check if the shuffle is calculated after each finished song or like this! + if (MediaPlayer.IsShuffled) + Shuffle(); + ActiveSong.Play(); + } + #endregion + + private void Clear() + { + Stop(); + ActiveSongIndex = 0; + queue.Clear(); + } + + internal void Stop() + { + if(ActiveSong != null) + ActiveSong.Stop(); + } + + private void Shuffle() + { + var rand = new Random(); + int n = queue.Count; + while (n > 1) + { + int k = rand.Next(n); + n--; + Song value = queue[k]; + queue[k] = queue[n]; + queue[n] = value; + } + } + + #region MoveNext + internal bool MoveNext(bool stopIfEnded) { - if (Count > 0) - { - if (ActiveSongIndex > 0) - ActiveSongIndex--; - else - ActiveSongIndex = Count - 1; - } + if (Count <= 0) + return false; + + ActiveSong.Stop(); + + if (ActiveSongIndex < Count - 1) + ActiveSongIndex++; + else + { + ActiveSongIndex = 0; + if (stopIfEnded) + return false; + } + + ActiveSong.Play(); + return true; } + #endregion + + #region MovePrevious + internal void MovePrevious() + { + if (Count <= 0) + return; + + ActiveSong.Stop(); + + if (ActiveSongIndex > 0) + ActiveSongIndex--; + else + ActiveSongIndex = Count - 1; + + ActiveSong.Play(); + } + #endregion } } diff --git a/ANX.Framework/Media/Song.cs b/ANX.Framework/Media/Song.cs index 907d553d..99ca374c 100644 --- a/ANX.Framework/Media/Song.cs +++ b/ANX.Framework/Media/Song.cs @@ -1,4 +1,7 @@ using System; +using ANX.Framework.NonXNA; +using ANX.Framework.NonXNA.SoundSystem; +using ANX.Framework.NonXNA.Development; // This file is part of the ANX.Framework created by the // "ANX.Framework developer group" and released under the Ms-PL license. @@ -6,29 +9,23 @@ using System; namespace ANX.Framework.Media { + [PercentageComplete(50)] + [Developer("AstrorEnales")] public sealed class Song : IEquatable, IDisposable { - public bool IsDisposed - { - get; - private set; - } + internal ISong NativeSong { get; private set; } + internal MediaState State { get { return NativeSong.State; } } - public string Name - { - get; - private set; - } + #region Public + public bool IsDisposed { get; private set; } + public string Name { get; private set; } - public bool IsRated - { - get - { - return Rating > 0; - } - } + public bool IsRated + { + get { return Rating > 0; } + } - public Artist Artist + public Artist Artist { get { @@ -54,10 +51,7 @@ namespace ANX.Framework.Media public TimeSpan Duration { - get - { - throw new NotImplementedException(); - } + get { return NativeSong.Duration; } } public int Rating @@ -90,11 +84,13 @@ namespace ANX.Framework.Media { throw new NotImplementedException(); } - } + } + #endregion #region Constructor - internal Song(string setName) + internal Song(string setName, Uri uri) { + NativeSong = AddInSystemFactory.Instance.GetDefaultCreator().CreateSong(this, uri); Name = setName; IsDisposed = false; } @@ -105,9 +101,9 @@ namespace ANX.Framework.Media } #endregion - public Song FromUri(string name, Uri uri) + public static Song FromUri(string name, Uri uri) { - throw new NotImplementedException(); + return new Song(name, uri); } public bool Equals(Song other) @@ -125,13 +121,36 @@ namespace ANX.Framework.Media public void Dispose() { - if (IsDisposed == false) - { - IsDisposed = true; - throw new NotImplementedException(); - } + if (IsDisposed) + return; + + IsDisposed = true; + + if(NativeSong != null) + NativeSong.Dispose(); + NativeSong = null; } + internal void Play() + { + NativeSong.Play(); + } + + internal void Stop() + { + NativeSong.Stop(); + } + + internal void Pause() + { + NativeSong.Pause(); + } + + internal void Resume() + { + NativeSong.Resume(); + } + #region ToString public override string ToString() { @@ -149,12 +168,12 @@ namespace ANX.Framework.Media #region Operator overloading public static bool operator ==(Song first, Song second) { - return first.Equals(second); + return first != null && first.Equals(second); } public static bool operator !=(Song first, Song second) { - return first.Equals(second) == false; + return first == null || first.Equals(second) == false; } #endregion } diff --git a/ANX.Framework/Media/VisualizationData.cs b/ANX.Framework/Media/VisualizationData.cs index 975d1793..b6ac2d36 100644 --- a/ANX.Framework/Media/VisualizationData.cs +++ b/ANX.Framework/Media/VisualizationData.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.ObjectModel; // This file is part of the ANX.Framework created by the @@ -7,22 +6,25 @@ using System.Collections.ObjectModel; namespace ANX.Framework.Media { - public class VisualizationData - { - public ReadOnlyCollection Frequencies - { - get - { - throw new NotImplementedException(); - } - } + public class VisualizationData + { + internal readonly float[] FrequencyData; + internal readonly float[] SampleData; - public ReadOnlyCollection Samples - { - get - { - throw new NotImplementedException(); - } - } - } + public ReadOnlyCollection Frequencies + { + get { return new ReadOnlyCollection(FrequencyData); } + } + + public ReadOnlyCollection Samples + { + get { return new ReadOnlyCollection(SampleData); } + } + + public VisualizationData() + { + FrequencyData = new float[256]; + SampleData = new float[256]; + } + } } diff --git a/ANX.Framework/NonXNA/AddInSystemFactory.cs b/ANX.Framework/NonXNA/AddInSystemFactory.cs index 251480dd..9b874fc4 100644 --- a/ANX.Framework/NonXNA/AddInSystemFactory.cs +++ b/ANX.Framework/NonXNA/AddInSystemFactory.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using ANX.Framework.NonXNA.PlatformSystem; using ANX.Framework.NonXNA.Reflection; +using ANX.Framework.NonXNA.SoundSystem; // This file is part of the ANX.Framework created by the // "ANX.Framework developer group" and released under the Ms-PL license. diff --git a/ANX.Framework/NonXNA/SoundSystem/ISong.cs b/ANX.Framework/NonXNA/SoundSystem/ISong.cs new file mode 100644 index 00000000..dbf0e1e5 --- /dev/null +++ b/ANX.Framework/NonXNA/SoundSystem/ISong.cs @@ -0,0 +1,19 @@ +using System; +using ANX.Framework.Media; + +namespace ANX.Framework.NonXNA.SoundSystem +{ + public interface ISong : IDisposable + { + TimeSpan Duration { get; } + TimeSpan PlayPosition { get; } + MediaState State { get; } + + void Play(); + void Stop(); + void Pause(); + void Resume(); + void Update(); + void GetVisualizationData(VisualizationData data); + } +} diff --git a/ANX.Framework/NonXNA/SoundSystem/ISoundSystemCreator.cs b/ANX.Framework/NonXNA/SoundSystem/ISoundSystemCreator.cs index dd1494cc..6d09b291 100644 --- a/ANX.Framework/NonXNA/SoundSystem/ISoundSystemCreator.cs +++ b/ANX.Framework/NonXNA/SoundSystem/ISoundSystemCreator.cs @@ -1,41 +1,23 @@ +using System; using System.IO; using ANX.Framework.Audio; -using ANX.Framework.NonXNA.SoundSystem; using System.Collections.ObjectModel; +using ANX.Framework.Media; // 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.NonXNA +namespace ANX.Framework.NonXNA.SoundSystem { public interface ISoundSystemCreator : ICreator { - float DistanceScale - { - get; - set; - } + float DistanceScale { get; set; } + float DopplerScale { get; set; } + float MasterVolume { get; set; } + float SpeedOfSound { get; set; } - float DopplerScale - { - get; - set; - } - - float MasterVolume - { - get; - set; - } - - float SpeedOfSound - { - get; - set; - } - - IAudioListener CreateAudioListener(); + IAudioListener CreateAudioListener(); IAudioEmitter CreateAudioEmitter(); @@ -52,5 +34,7 @@ namespace ANX.Framework.NonXNA ReadOnlyCollection GetAllMicrophones(); int GetDefaultMicrophone(ReadOnlyCollection allMicrophones); + + ISong CreateSong(Song parentSong, Uri uri); } } diff --git a/ANX.Framework/Properties/AssemblyInfo.cs b/ANX.Framework/Properties/AssemblyInfo.cs index 87ae3161..b073041e 100644 --- a/ANX.Framework/Properties/AssemblyInfo.cs +++ b/ANX.Framework/Properties/AssemblyInfo.cs @@ -39,17 +39,17 @@ using System.Runtime.InteropServices; [assembly: InternalsVisibleTo("ANX.RenderSystem.Windows.Metro")] [assembly: InternalsVisibleTo("ANX.RenderSystem.GL3")] [assembly: InternalsVisibleTo("ANX.RenderSystem.Windows.PsVita")] -[assembly: InternalsVisibleTo("ANX.Framework.Windows.Kinect")] -[assembly: InternalsVisibleTo("ANX.Framework.Windows.XInput")] -[assembly: InternalsVisibleTo("ANX.Framework.Windows.XAudio")] [assembly: InternalsVisibleTo("ANX.InputSystem.Recording")] [assembly: InternalsVisibleTo("ANX.InputDevices.PsVita")] [assembly: InternalsVisibleTo("ANX.InputDevices.Test")] +[assembly: InternalsVisibleTo("ANX.InputDevices.Windows.Kinect")] [assembly: InternalsVisibleTo("ANX.InputDevices.Windows.XInput")] [assembly: InternalsVisibleTo("ANX.InputDevices.Windows.ModernUI")] [assembly: InternalsVisibleTo("ANX.PlatformSystem.Windows")] [assembly: InternalsVisibleTo("ANX.PlatformSystem.Linux")] [assembly: InternalsVisibleTo("ANX.PlatformSystem.Metro")] [assembly: InternalsVisibleTo("ANX.PlatformSystem.PsVita")] +[assembly: InternalsVisibleTo("ANX.SoundSystem.Windows.XAudio")] +[assembly: InternalsVisibleTo("ANX.SoundSystem.Windows.OpenAL")] [assembly: InternalsVisibleTo("ANX.Tools.XNBInspector")] [assembly: InternalsVisibleTo("ANX.Framework.Content.Pipeline")] \ No newline at end of file diff --git a/RenderSystems/ANX.Framework.GL3/GraphicsDeviceWindowsGL3.cs b/RenderSystems/ANX.Framework.GL3/GraphicsDeviceWindowsGL3.cs index 50d46f71..334a850f 100644 --- a/RenderSystems/ANX.Framework.GL3/GraphicsDeviceWindowsGL3.cs +++ b/RenderSystems/ANX.Framework.GL3/GraphicsDeviceWindowsGL3.cs @@ -42,25 +42,17 @@ namespace ANX.RenderSystem.GL3 { get { - return (Current == null || Current.nativeContext == null) ? false : Current.nativeContext.IsCurrent; + return (Current != null && Current.nativeContext != null) && Current.nativeContext.IsCurrent; } } #endregion #region Public - #region VSync - public bool VSync - { - get - { - return nativeContext.VSync; - } - set - { - nativeContext.VSync = value; - } - } - #endregion + public bool VSync + { + get { return nativeContext.VSync; } + set { nativeContext.VSync = value; } + } #endregion #region Constructor diff --git a/Samples/WpfEditor/MainWindow.xaml.cs b/Samples/WpfEditor/MainWindow.xaml.cs index bf4aa73b..e7fd0bbe 100644 --- a/Samples/WpfEditor/MainWindow.xaml.cs +++ b/Samples/WpfEditor/MainWindow.xaml.cs @@ -1,10 +1,10 @@ +using System; +using System.Threading; using System.Windows; +using System.Windows.Threading; using ANX.Framework; using ANX.Framework.Graphics; -using System.Windows.Interop; -using System; -using System.Windows.Threading; -using System.Threading; +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. @@ -12,13 +12,18 @@ using System.Threading; namespace WpfEditor { - public partial class MainWindow : Window + public partial class MainWindow { private GraphicsDevice device; + private readonly ThreadStart emptyThreadStart; public MainWindow() { InitializeComponent(); + emptyThreadStart = delegate { }; + + //AddInSystemFactory.Instance.SetPreferredSystem(AddInType.RenderSystem, "OpenGL3"); + AddInSystemFactory.Instance.SetPreferredSystem(AddInType.RenderSystem, "DirectX10"); } protected override void OnActivated(EventArgs e) @@ -30,10 +35,7 @@ namespace WpfEditor while (IsVisible) { if (Application.Current != null) - { - Application.Current.Dispatcher.Invoke( - DispatcherPriority.Background, new ThreadStart(delegate { })); - } + Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, emptyThreadStart); Tick(); } @@ -41,13 +43,11 @@ namespace WpfEditor public void Initialize() { - device = new GraphicsDevice( - GraphicsAdapter.DefaultAdapter, - GraphicsProfile.HiDef, + device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, GraphicsProfile.HiDef, new PresentationParameters { - BackBufferWidth = (int)GamePanel.Width, - BackBufferHeight = (int)GamePanel.Height, + BackBufferWidth = GamePanel.Width, + BackBufferHeight = GamePanel.Height, BackBufferFormat = SurfaceFormat.Color, DeviceWindowHandle = GamePanel.Handle, PresentationInterval = PresentInterval.Default, diff --git a/Samples/WpfEditor/WpfEditor.csproj b/Samples/WpfEditor/WpfEditor.csproj index 646b1420..2e00831c 100644 --- a/Samples/WpfEditor/WpfEditor.csproj +++ b/Samples/WpfEditor/WpfEditor.csproj @@ -107,6 +107,10 @@ {49066074-3B7B-4A55-B122-6BD33AB73558} ANX.InputSystem.Standard + + {EB8258E0-6741-4DB9-B756-1EBDF67B1ED6} + ANX.RenderSystem.GL3 + {5BE49183-2F6F-4527-AC90-D816911FCF90} ANX.RenderSystem.Windows.DX10 diff --git a/SoundSystems/ANX.SoundSystem.OpenAL/Creator.cs b/SoundSystems/ANX.SoundSystem.OpenAL/Creator.cs index d5c6410a..23acfef4 100644 --- a/SoundSystems/ANX.SoundSystem.OpenAL/Creator.cs +++ b/SoundSystems/ANX.SoundSystem.OpenAL/Creator.cs @@ -2,6 +2,7 @@ using System; using System.Collections.ObjectModel; using System.IO; using ANX.Framework.Audio; +using ANX.Framework.Media; using ANX.Framework.NonXNA; using ANX.Framework.NonXNA.SoundSystem; using OpenTK; @@ -15,24 +16,21 @@ namespace ANX.SoundSystem.OpenAL { public class Creator : ISoundSystemCreator { + private float currentDistanceScale; + private float currentMasterVolume; + #region Public - public string Name - { - get - { - return "OpenAL"; - } - } + public string Name + { + get { return "OpenAL"; } + } - public int Priority - { - get - { - return 100; - } - } + public int Priority + { + get { return 100; } + } - public bool IsSupported + public bool IsSupported { get { @@ -43,80 +41,60 @@ namespace ANX.SoundSystem.OpenAL } } - public float DistanceScale - { - get - { - return 1f; - //throw new NotImplementedException(); - } - set - { - //throw new NotImplementedException(); - } - } + public float DistanceScale + { + get { return currentDistanceScale; } + set + { + currentDistanceScale = value; + // TODO: set actual property + } + } - public float DopplerScale - { - get - { - return AL.Get(ALGetFloat.DopplerFactor); - } - set - { - AL.DopplerFactor(value); - } - } + public float DopplerScale + { + get { return AL.Get(ALGetFloat.DopplerFactor); } + set { AL.DopplerFactor(value); } + } - public float MasterVolume - { - get - { - return 1f; - //throw new NotImplementedException(); - } - set - { - //throw new NotImplementedException(); - } - } + public float MasterVolume + { + get { return currentMasterVolume; } + set + { + currentMasterVolume = value; + // TODO: set actual property + } + } - public float SpeedOfSound - { - get - { - return AL.Get(ALGetFloat.SpeedOfSound); - } - set - { - AL.SpeedOfSound(value); - } - } - #endregion + public float SpeedOfSound + { + get { return AL.Get(ALGetFloat.SpeedOfSound); } + set { AL.SpeedOfSound(value); } + } + #endregion public Creator() { + currentDistanceScale = 1f; + currentMasterVolume = 1f; Init(); } - private void Init() - { - IntPtr deviceHandle; - ContextHandle context = Alc.GetCurrentContext(); - if (context.Handle != IntPtr.Zero) - { - deviceHandle = Alc.GetContextsDevice(context); - } - else - { - deviceHandle = Alc.OpenDevice(Alc.GetString(IntPtr.Zero, AlcGetString.DefaultDeviceSpecifier)); - context = Alc.CreateContext(deviceHandle, new int[0]); - } + private static void Init() + { + ContextHandle context = Alc.GetCurrentContext(); + if (context.Handle == IntPtr.Zero) + { + string deviceName = Alc.GetString(IntPtr.Zero, AlcGetString.DefaultDeviceSpecifier); + IntPtr deviceHandle = Alc.OpenDevice(deviceName); + context = Alc.CreateContext(deviceHandle, new int[0]); + } - bool isNowCurrent = Alc.MakeContextCurrent(context); - } + Alc.MakeContextCurrent(context); + } - #region CreateSoundEffectInstance + #region CreateSoundEffectInstance public ISoundEffectInstance CreateSoundEffectInstance(ISoundEffect nativeSoundEffect) { PreventSystemChange(); @@ -179,9 +157,15 @@ namespace ANX.SoundSystem.OpenAL PreventSystemChange(); throw new NotImplementedException(); } - #endregion + #endregion - private void PreventSystemChange() + public ISong CreateSong(Song parentSong, Uri uri) + { + PreventSystemChange(); + throw new NotImplementedException(); + } + + private static void PreventSystemChange() { AddInSystemFactory.Instance.PreventSystemChange(AddInType.SoundSystem); } diff --git a/SoundSystems/ANX.SoundSystem.OpenAL/OpenALSoundEffectInstance.cs b/SoundSystems/ANX.SoundSystem.OpenAL/OpenALSoundEffectInstance.cs index 980f49a2..1a9da989 100644 --- a/SoundSystems/ANX.SoundSystem.OpenAL/OpenALSoundEffectInstance.cs +++ b/SoundSystems/ANX.SoundSystem.OpenAL/OpenALSoundEffectInstance.cs @@ -12,87 +12,69 @@ namespace ANX.SoundSystem.OpenAL public class OpenALSoundEffectInstance : ISoundEffectInstance { #region Private - private OpenALSoundEffect parent; - + private readonly OpenALSoundEffect parent; + private float currentPan; private int handle; #endregion #region Public - public bool IsLooped - { - get - { - bool result; - AL.GetSource(handle, ALSourceb.Looping, out result); - return result; - } - set - { - AL.Source(handle, ALSourceb.Looping, value); - } - } + public bool IsLooped + { + get + { + bool result; + AL.GetSource(handle, ALSourceb.Looping, out result); + return result; + } + set { AL.Source(handle, ALSourceb.Looping, value); } + } - public float Pan - { - get - { - return 0f; - //throw new NotImplementedException(); - } - set - { - //throw new NotImplementedException(); - } - } + public float Pan + { + get { return currentPan; } + set + { + currentPan = value; + // TODO: set actual parameter + } + } - public float Pitch - { - get - { - float result; - AL.GetSource(handle, ALSourcef.Pitch, out result); - return result; - } - set - { - AL.Source(handle, ALSourcef.Pitch, value); - } - } + public float Pitch + { + get + { + float result; + AL.GetSource(handle, ALSourcef.Pitch, out result); + return result; + } + set { AL.Source(handle, ALSourcef.Pitch, value); } + } - public SoundState State - { - get; - private set; - } + public SoundState State { get; private set; } - public float Volume - { - get - { - float result; - AL.GetSource(handle, ALSourcef.Gain, out result); - return result; - } - set - { - AL.Source(handle, ALSourcef.Gain, value); - } - } - #endregion + public float Volume + { + get + { + float result; + AL.GetSource(handle, ALSourcef.Gain, out result); + return result; + } + set { AL.Source(handle, ALSourcef.Gain, value); } + } + #endregion #region Constructor internal OpenALSoundEffectInstance(OpenALSoundEffect setParent) { parent = setParent; - State = SoundState.Stopped; - handle = AL.GenSource(); AL.Source(handle, ALSourcei.Buffer, parent.bufferHandle); IsLooped = false; Pitch = 1f; Volume = 1f; - // TODO: Pan = 0f; + Pan = 0f; ALError error = AL.GetError(); if (error != ALError.NoError) @@ -103,47 +85,44 @@ namespace ANX.SoundSystem.OpenAL #region Play public void Play() { - if (State != SoundState.Playing) - { - State = SoundState.Playing; - AL.SourcePlay(handle); - } + if (State == SoundState.Playing) + return; + + State = SoundState.Playing; + AL.SourcePlay(handle); } #endregion #region Pause public void Pause() { - if (State != SoundState.Paused) - { - State = SoundState.Paused; - AL.SourcePause(handle); - } + if (State == SoundState.Paused) + return; + + State = SoundState.Paused; + AL.SourcePause(handle); } #endregion #region Stop public void Stop(bool immediate) { - if (State == SoundState.Stopped) + if (State == SoundState.Stopped || immediate == false) return; - if (immediate) - { - State = SoundState.Stopped; - AL.SourceStop(handle); - } + State = SoundState.Stopped; + AL.SourceStop(handle); } #endregion #region Resume public void Resume() { - if (State != SoundState.Playing) - { - State = SoundState.Playing; - AL.SourcePlay(handle); - } + if (State == SoundState.Playing) + return; + + State = SoundState.Playing; + AL.SourcePlay(handle); } #endregion diff --git a/SoundSystems/ANX.SoundSystem.PsVita/Creator.cs b/SoundSystems/ANX.SoundSystem.PsVita/Creator.cs index b0314083..a50ee60a 100644 --- a/SoundSystems/ANX.SoundSystem.PsVita/Creator.cs +++ b/SoundSystems/ANX.SoundSystem.PsVita/Creator.cs @@ -2,6 +2,7 @@ using System; using System.Collections.ObjectModel; using System.IO; using ANX.Framework.Audio; +using ANX.Framework.Media; using ANX.Framework.NonXNA; using ANX.Framework.NonXNA.SoundSystem; @@ -163,6 +164,12 @@ namespace ANX.SoundSystem.PsVita { throw new NotImplementedException(); } - #endregion + #endregion + + public ISong CreateSong(Song parentSong, Uri uri) + { + AddInSystemFactory.Instance.PreventSystemChange(AddInType.SoundSystem); + throw new NotImplementedException(); + } } } diff --git a/SoundSystems/ANX.SoundSystem.Windows.XAudio/Creator.cs b/SoundSystems/ANX.SoundSystem.Windows.XAudio/Creator.cs index 9622562a..dd4a9da6 100644 --- a/SoundSystems/ANX.SoundSystem.Windows.XAudio/Creator.cs +++ b/SoundSystems/ANX.SoundSystem.Windows.XAudio/Creator.cs @@ -2,6 +2,7 @@ using System; using System.Collections.ObjectModel; using System.IO; using ANX.Framework.Audio; +using ANX.Framework.Media; using ANX.Framework.NonXNA; using ANX.Framework.NonXNA.SoundSystem; using SharpDX.XAudio2; @@ -86,7 +87,10 @@ namespace ANX.SoundSystem.Windows.XAudio ~Creator() { if (MasteringVoice != null) + { + MasteringVoice.DestroyVoice(); MasteringVoice.Dispose(); + } if (device != null) device.Dispose(); @@ -149,9 +153,15 @@ namespace ANX.SoundSystem.Windows.XAudio throw new NotImplementedException(); } + public ISong CreateSong(Song parentSong, Uri uri) + { + PreventSystemChange(); + throw new NotImplementedException(); + } + private static void PreventSystemChange() { AddInSystemFactory.Instance.PreventSystemChange(AddInType.SoundSystem); } - } + } } diff --git a/SoundSystems/ANX.SoundSystem.Windows.XAudio/XAudioSoundEffectInstance.cs b/SoundSystems/ANX.SoundSystem.Windows.XAudio/XAudioSoundEffectInstance.cs index ba2ccb0b..b227be95 100644 --- a/SoundSystems/ANX.SoundSystem.Windows.XAudio/XAudioSoundEffectInstance.cs +++ b/SoundSystems/ANX.SoundSystem.Windows.XAudio/XAudioSoundEffectInstance.cs @@ -74,11 +74,17 @@ namespace ANX.SoundSystem.Windows.XAudio currentPan = 0f; currentPitch = 1f; State = SoundState.Stopped; - source = new SourceVoice(device, setParent.WaveFormat); + source = new SourceVoice(device, setParent.WaveFormat, true); source.SubmitSourceBuffer(setParent.AudioBuffer, setParent.DecodedPacketsInfo); + source.StreamEnd += StreamEnd; } #endregion + private void StreamEnd() + { + State = SoundState.Stopped; + } + #region Play public void Play() { @@ -94,6 +100,7 @@ namespace ANX.SoundSystem.Windows.XAudio public void Pause() { State = SoundState.Paused; + throw new NotImplementedException(); } #endregion @@ -115,6 +122,7 @@ namespace ANX.SoundSystem.Windows.XAudio public void Resume() { State = SoundState.Playing; + throw new NotImplementedException(); } #endregion @@ -182,7 +190,11 @@ namespace ANX.SoundSystem.Windows.XAudio public void Dispose() { if (source != null) + { + source.StreamEnd -= StreamEnd; + source.DestroyVoice(); source.Dispose(); + } source = null; } #endregion