Fixed issue #994 in XAudio and working on XAudio properties
This commit is contained in:
parent
a07d5c69b6
commit
c5145397bf
@ -75,9 +75,9 @@ namespace ANX.Framework.Audio
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private
|
#region Private
|
||||||
private static List<SoundEffectInstance> fireAndForgetInstances;
|
private static readonly List<SoundEffectInstance> fireAndForgetInstances;
|
||||||
private List<WeakReference> children;
|
private readonly List<WeakReference> children;
|
||||||
internal ISoundEffect nativeSoundEffect;
|
internal ISoundEffect NativeSoundEffect;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public
|
#region Public
|
||||||
@ -85,7 +85,7 @@ namespace ANX.Framework.Audio
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return nativeSoundEffect.Duration;
|
return NativeSoundEffect.Duration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ namespace ANX.Framework.Audio
|
|||||||
: this()
|
: this()
|
||||||
{
|
{
|
||||||
var creator = GetCreator();
|
var creator = GetCreator();
|
||||||
nativeSoundEffect = creator.CreateSoundEffect(this, stream);
|
NativeSoundEffect = creator.CreateSoundEffect(this, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SoundEffect(byte[] buffer, int sampleRate, AudioChannels channels)
|
public SoundEffect(byte[] buffer, int sampleRate, AudioChannels channels)
|
||||||
@ -135,7 +135,7 @@ namespace ANX.Framework.Audio
|
|||||||
: this()
|
: this()
|
||||||
{
|
{
|
||||||
var creator = GetCreator();
|
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()
|
~SoundEffect()
|
||||||
@ -168,16 +168,15 @@ namespace ANX.Framework.Audio
|
|||||||
#region GetSampleDuration
|
#region GetSampleDuration
|
||||||
public static TimeSpan GetSampleDuration(int sizeInBytes, int sampleRate, AudioChannels channels)
|
public static TimeSpan GetSampleDuration(int sizeInBytes, int sampleRate, AudioChannels channels)
|
||||||
{
|
{
|
||||||
float sizeMulBlockAlign = sizeInBytes / ((int)channels * 2);
|
float sizeMulBlockAlign = (float)sizeInBytes / ((int)channels * 2);
|
||||||
return TimeSpan.FromMilliseconds((double)(sizeMulBlockAlign * 1000f / (float)sampleRate));
|
return TimeSpan.FromMilliseconds(sizeMulBlockAlign * 1000f / sampleRate);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GetSampleSizeInBytes
|
#region GetSampleSizeInBytes
|
||||||
public static int GetSampleSizeInBytes(TimeSpan duration, int sampleRate,
|
public static int GetSampleSizeInBytes(TimeSpan duration, int sampleRate, AudioChannels channels)
|
||||||
AudioChannels channels)
|
|
||||||
{
|
{
|
||||||
int timeMulSamples = (int)(duration.TotalMilliseconds * (double)((float)sampleRate / 1000f));
|
int timeMulSamples = (int)(duration.TotalMilliseconds * (sampleRate / 1000f));
|
||||||
return (timeMulSamples + timeMulSamples % (int)channels) * ((int)channels * 2);
|
return (timeMulSamples + timeMulSamples % (int)channels) * ((int)channels * 2);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -195,12 +194,12 @@ namespace ANX.Framework.Audio
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SoundEffectInstance newInstance = new SoundEffectInstance(this, true)
|
var newInstance = new SoundEffectInstance(this, true)
|
||||||
{
|
{
|
||||||
Volume = volume,
|
Volume = volume,
|
||||||
Pitch = pitch,
|
Pitch = pitch,
|
||||||
Pan = pan,
|
Pan = pan,
|
||||||
};
|
};
|
||||||
|
|
||||||
children.Add(new WeakReference(newInstance));
|
children.Add(new WeakReference(newInstance));
|
||||||
|
|
||||||
@ -228,26 +227,22 @@ namespace ANX.Framework.Audio
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
nativeSoundEffect.Dispose();
|
NativeSoundEffect.Dispose();
|
||||||
nativeSoundEffect = null;
|
NativeSoundEffect = null;
|
||||||
|
|
||||||
List<WeakReference> weakRefs = new List<WeakReference>(children);
|
var weakRefs = new List<WeakReference>(children);
|
||||||
|
|
||||||
lock (fireAndForgetInstances)
|
lock (fireAndForgetInstances)
|
||||||
{
|
{
|
||||||
foreach (WeakReference current in weakRefs)
|
foreach (WeakReference current in weakRefs)
|
||||||
{
|
{
|
||||||
SoundEffectInstance soundInstance =
|
var soundInstance = current.Target as SoundEffectInstance;
|
||||||
current.Target as SoundEffectInstance;
|
if (soundInstance == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (soundInstance != null)
|
if (soundInstance.IsFireAndForget)
|
||||||
{
|
fireAndForgetInstances.Remove(soundInstance);
|
||||||
if (soundInstance.IsFireAndForget)
|
soundInstance.Dispose();
|
||||||
{
|
|
||||||
fireAndForgetInstances.Remove(soundInstance);
|
|
||||||
}
|
|
||||||
soundInstance.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,6 @@ namespace ANX.Framework.Audio
|
|||||||
public class SoundEffectInstance : IDisposable
|
public class SoundEffectInstance : IDisposable
|
||||||
{
|
{
|
||||||
#region Private
|
#region Private
|
||||||
private SoundEffect parent;
|
|
||||||
|
|
||||||
private ISoundEffectInstance nativeInstance;
|
private ISoundEffectInstance nativeInstance;
|
||||||
|
|
||||||
internal bool IsFireAndForget
|
internal bool IsFireAndForget
|
||||||
@ -27,93 +25,47 @@ namespace ANX.Framework.Audio
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public
|
#region Public
|
||||||
#region IsDisposed
|
public bool IsDisposed { get; private set; }
|
||||||
public bool IsDisposed
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IsLooped
|
public virtual bool IsLooped
|
||||||
public virtual bool IsLooped
|
{
|
||||||
{
|
get { return nativeInstance.IsLooped; }
|
||||||
get
|
set { nativeInstance.IsLooped = value; }
|
||||||
{
|
}
|
||||||
return nativeInstance.IsLooped;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
nativeInstance.IsLooped = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Pan
|
public float Pan
|
||||||
public float Pan
|
{
|
||||||
{
|
get { return nativeInstance.Pan; }
|
||||||
get
|
set { nativeInstance.Pan = value; }
|
||||||
{
|
}
|
||||||
return nativeInstance.Pan;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
nativeInstance.Pan = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Pitch
|
public float Pitch
|
||||||
public float Pitch
|
{
|
||||||
{
|
get { return nativeInstance.Pitch; }
|
||||||
get
|
set { nativeInstance.Pitch = value; }
|
||||||
{
|
}
|
||||||
return nativeInstance.Pitch;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
nativeInstance.Pitch = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region State
|
public SoundState State
|
||||||
public SoundState State
|
{
|
||||||
{
|
get { return nativeInstance.State; }
|
||||||
get
|
}
|
||||||
{
|
|
||||||
return nativeInstance.State;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Volume
|
public float Volume
|
||||||
public float Volume
|
{
|
||||||
{
|
get { return nativeInstance.Volume; }
|
||||||
get
|
set { nativeInstance.Volume = value; }
|
||||||
{
|
}
|
||||||
return nativeInstance.Volume;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
nativeInstance.Volume = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructor
|
#region Constructor
|
||||||
protected SoundEffectInstance()
|
protected SoundEffectInstance()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
internal SoundEffectInstance(SoundEffect setParent, bool setIsFireAndForget)
|
internal SoundEffectInstance(SoundEffect setParent, bool setIsFireAndForget)
|
||||||
{
|
{
|
||||||
parent = setParent;
|
|
||||||
IsFireAndForget = setIsFireAndForget;
|
IsFireAndForget = setIsFireAndForget;
|
||||||
|
nativeInstance = GetCreator().CreateSoundEffectInstance(setParent.NativeSoundEffect);
|
||||||
nativeInstance = GetCreator().CreateSoundEffectInstance(
|
|
||||||
setParent.nativeSoundEffect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~SoundEffectInstance()
|
~SoundEffectInstance()
|
||||||
@ -132,7 +84,7 @@ namespace ANX.Framework.Audio
|
|||||||
#region Apply3D
|
#region Apply3D
|
||||||
public void Apply3D(AudioListener listener, AudioEmitter emitter)
|
public void Apply3D(AudioListener listener, AudioEmitter emitter)
|
||||||
{
|
{
|
||||||
Apply3D(new AudioListener[] { listener }, emitter);
|
Apply3D(new[] { listener }, emitter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Apply3D(AudioListener[] listeners, AudioEmitter emitter)
|
public void Apply3D(AudioListener[] listeners, AudioEmitter emitter)
|
||||||
|
@ -91,6 +91,10 @@
|
|||||||
<Project>{068EB2E9-963C-4E1B-8831-E25011F11FFE}</Project>
|
<Project>{068EB2E9-963C-4E1B-8831-E25011F11FFE}</Project>
|
||||||
<Name>ANX.PlatformSystem.Windows</Name>
|
<Name>ANX.PlatformSystem.Windows</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\..\RenderSystems\ANX.RenderSystem.Windows.DX10\ANX.RenderSystem.Windows.DX10.csproj">
|
||||||
|
<Project>{5BE49183-2F6F-4527-AC90-D816911FCF90}</Project>
|
||||||
|
<Name>ANX.RenderSystem.Windows.DX10</Name>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\..\SoundSystems\ANX.SoundSystem.OpenAL\ANX.SoundSystem.OpenAL.csproj">
|
<ProjectReference Include="..\..\SoundSystems\ANX.SoundSystem.OpenAL\ANX.SoundSystem.OpenAL.csproj">
|
||||||
<Project>{14EF49AB-6D3F-458D-9D5C-D120B86EDD7A}</Project>
|
<Project>{14EF49AB-6D3F-458D-9D5C-D120B86EDD7A}</Project>
|
||||||
<Name>ANX.SoundSystem.OpenAL</Name>
|
<Name>ANX.SoundSystem.OpenAL</Name>
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using ANX.Framework;
|
using ANX.Framework;
|
||||||
using ANX.Framework.Audio;
|
using ANX.Framework.Audio;
|
||||||
|
|
||||||
@ -8,51 +7,45 @@ using ANX.Framework.Audio;
|
|||||||
|
|
||||||
namespace AudioSample
|
namespace AudioSample
|
||||||
{
|
{
|
||||||
public class Game1 : Game
|
public class Game1 : Game
|
||||||
{
|
{
|
||||||
GraphicsDeviceManager graphics;
|
private GraphicsDeviceManager graphics;
|
||||||
SoundEffect sound;
|
private SoundEffect sound;
|
||||||
|
private float timer;
|
||||||
|
private float duration;
|
||||||
|
|
||||||
float timer;
|
public Game1()
|
||||||
float duration;
|
{
|
||||||
|
graphics = new GraphicsDeviceManager(this);
|
||||||
|
Content.RootDirectory = "SampleContent";
|
||||||
|
}
|
||||||
|
|
||||||
public Game1()
|
protected override void LoadContent()
|
||||||
{
|
{
|
||||||
graphics = new GraphicsDeviceManager(this);
|
sound = Content.Load<SoundEffect>("Sounds\\testsound");
|
||||||
Content.RootDirectory = "SampleContent";
|
timer = duration = (float)sound.Duration.TotalSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Initialize()
|
protected override void UnloadContent()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoadContent()
|
protected override void Update(GameTime gameTime)
|
||||||
{
|
{
|
||||||
sound = Content.Load<SoundEffect>("Sounds\\testsound");
|
timer += (float)gameTime.ElapsedGameTime.TotalSeconds;
|
||||||
timer = duration = (float)sound.Duration.TotalSeconds;
|
if (timer >= duration)
|
||||||
}
|
{
|
||||||
|
timer -= duration;
|
||||||
|
sound.Play(1f, 1f, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void UnloadContent()
|
base.Update(gameTime);
|
||||||
{
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update(GameTime gameTime)
|
protected override void Draw(GameTime gameTime)
|
||||||
{
|
{
|
||||||
timer += (float)gameTime.ElapsedGameTime.TotalSeconds;
|
GraphicsDevice.Clear(Color.CornflowerBlue);
|
||||||
if (timer >= duration)
|
base.Draw(gameTime);
|
||||||
{
|
}
|
||||||
timer -= duration;
|
}
|
||||||
sound.Play();
|
|
||||||
}
|
|
||||||
|
|
||||||
base.Update(gameTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Draw(GameTime gameTime)
|
|
||||||
{
|
|
||||||
GraphicsDevice.Clear(Color.CornflowerBlue);
|
|
||||||
base.Draw(gameTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ namespace AudioSample
|
|||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
AddInSystemFactory.Instance.SetPreferredSystem(AddInType.SoundSystem, "OpenAL");
|
//AddInSystemFactory.Instance.SetPreferredSystem(AddInType.SoundSystem, "OpenAL");
|
||||||
//AddInSystemFactory.Instance.SetPreferredSystem(AddInType.SoundSystem, "XAudio");
|
AddInSystemFactory.Instance.SetPreferredSystem(AddInType.SoundSystem, "XAudio");
|
||||||
|
|
||||||
using (Game1 game = new Game1())
|
using (Game1 game = new Game1())
|
||||||
{
|
{
|
||||||
|
@ -13,120 +13,98 @@ using SharpDX.XAudio2;
|
|||||||
namespace ANX.SoundSystem.Windows.XAudio
|
namespace ANX.SoundSystem.Windows.XAudio
|
||||||
{
|
{
|
||||||
public class Creator : ISoundSystemCreator
|
public class Creator : ISoundSystemCreator
|
||||||
{
|
{
|
||||||
private XAudio2 device;
|
private XAudio2 device;
|
||||||
private MasteringVoice masteringVoice;
|
private float distanceScale;
|
||||||
|
private float dopplerScale;
|
||||||
|
private float speedOfSound;
|
||||||
|
internal static MasteringVoice MasteringVoice { get; private set; }
|
||||||
|
|
||||||
#region Public
|
#region Public
|
||||||
#region Name
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get { return "XAudio"; }
|
get { return "XAudio"; }
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Priority
|
|
||||||
public int Priority
|
public int Priority
|
||||||
{
|
{
|
||||||
get { return 10; }
|
get { return 10; }
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IsSupported
|
public bool IsSupported
|
||||||
public bool IsSupported
|
{
|
||||||
{
|
get { return OSInformation.IsWindows; }
|
||||||
get
|
}
|
||||||
{
|
|
||||||
//TODO: this is just a very basic version of test for support
|
|
||||||
return OSInformation.IsWindows;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public float DistanceScale
|
public float DistanceScale
|
||||||
{
|
{
|
||||||
get
|
get { return distanceScale; }
|
||||||
{
|
set
|
||||||
return 1f;
|
{
|
||||||
//throw new NotImplementedException();
|
distanceScale = value;
|
||||||
}
|
// TODO: actually set the parameter to XAudio
|
||||||
set
|
}
|
||||||
{
|
|
||||||
//throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float DopplerScale
|
public float DopplerScale
|
||||||
{
|
{
|
||||||
get
|
get { return dopplerScale; }
|
||||||
{
|
set
|
||||||
return 1f;
|
{
|
||||||
//throw new NotImplementedException();
|
dopplerScale = value;
|
||||||
}
|
// TODO: actually set the parameter to XAudio
|
||||||
set
|
}
|
||||||
{
|
|
||||||
//throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float MasterVolume
|
public float MasterVolume
|
||||||
{
|
{
|
||||||
get
|
get { return MasteringVoice.Volume; }
|
||||||
{
|
set { MasteringVoice.SetVolume(value, 0); }
|
||||||
return masteringVoice.Volume;
|
}
|
||||||
//throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
masteringVoice.SetVolume(value, 0);
|
|
||||||
//throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float SpeedOfSound
|
public float SpeedOfSound
|
||||||
{
|
{
|
||||||
get
|
get { return speedOfSound; }
|
||||||
{
|
set
|
||||||
return 1f;
|
{
|
||||||
//throw new NotImplementedException();
|
speedOfSound = value;
|
||||||
}
|
// TODO: actually set the parameter to XAudio
|
||||||
set
|
}
|
||||||
{
|
|
||||||
//throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructor
|
#region Constructor
|
||||||
public Creator()
|
public Creator()
|
||||||
{
|
{
|
||||||
|
distanceScale = 1f;
|
||||||
|
dopplerScale = 1f;
|
||||||
|
speedOfSound = 343.5f;
|
||||||
device = new XAudio2();
|
device = new XAudio2();
|
||||||
masteringVoice = new MasteringVoice(device);
|
MasteringVoice = new MasteringVoice(device, XAudio2.DefaultChannels, XAudio2.DefaultSampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
~Creator()
|
~Creator()
|
||||||
{
|
{
|
||||||
if (masteringVoice != null)
|
if (MasteringVoice != null)
|
||||||
{
|
MasteringVoice.Dispose();
|
||||||
masteringVoice.Dispose();
|
|
||||||
masteringVoice = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device != null)
|
if (device != null)
|
||||||
{
|
device.Dispose();
|
||||||
device.Dispose();
|
|
||||||
device = null;
|
MasteringVoice = null;
|
||||||
}
|
device = null;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public IAudioListener CreateAudioListener()
|
public IAudioListener CreateAudioListener()
|
||||||
{
|
{
|
||||||
|
PreventSystemChange();
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IAudioEmitter CreateAudioEmitter()
|
public IAudioEmitter CreateAudioEmitter()
|
||||||
{
|
{
|
||||||
|
PreventSystemChange();
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,21 +132,24 @@ namespace ANX.SoundSystem.Windows.XAudio
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public IMicrophone CreateMicrophone(Microphone managedMicrophone)
|
public IMicrophone CreateMicrophone(Microphone managedMicrophone)
|
||||||
{
|
{
|
||||||
|
PreventSystemChange();
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyCollection<Microphone> GetAllMicrophones()
|
public ReadOnlyCollection<Microphone> GetAllMicrophones()
|
||||||
{
|
{
|
||||||
|
PreventSystemChange();
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetDefaultMicrophone(ReadOnlyCollection<Microphone> allMicrophones)
|
public int GetDefaultMicrophone(ReadOnlyCollection<Microphone> allMicrophones)
|
||||||
{
|
{
|
||||||
|
PreventSystemChange();
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PreventSystemChange()
|
private static void PreventSystemChange()
|
||||||
{
|
{
|
||||||
AddInSystemFactory.Instance.PreventSystemChange(AddInType.SoundSystem);
|
AddInSystemFactory.Instance.PreventSystemChange(AddInType.SoundSystem);
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using ANX.Framework.Audio;
|
using ANX.Framework.Audio;
|
||||||
using ANX.Framework.NonXNA.SoundSystem;
|
using ANX.Framework.NonXNA.SoundSystem;
|
||||||
using SharpDX.XAudio2;
|
|
||||||
using SharpDX.Multimedia;
|
using SharpDX.Multimedia;
|
||||||
|
using SharpDX.XAudio2;
|
||||||
|
|
||||||
// This file is part of the ANX.Framework created by the
|
// This file is part of the ANX.Framework created by the
|
||||||
// "ANX.Framework developer group" and released under the Ms-PL license.
|
// "ANX.Framework developer group" and released under the Ms-PL license.
|
||||||
@ -14,38 +14,35 @@ namespace ANX.SoundSystem.Windows.XAudio
|
|||||||
public class XAudioSoundEffect : ISoundEffect
|
public class XAudioSoundEffect : ISoundEffect
|
||||||
{
|
{
|
||||||
#region Private
|
#region Private
|
||||||
internal SoundEffect parent;
|
internal SoundEffect Parent;
|
||||||
private TimeSpan duration;
|
private TimeSpan duration;
|
||||||
internal WaveFormat waveFormat;
|
internal WaveFormat WaveFormat;
|
||||||
internal AudioBuffer audioBuffer;
|
internal AudioBuffer AudioBuffer;
|
||||||
internal uint[] DecodedPacketsInfo;
|
internal uint[] DecodedPacketsInfo;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public
|
#region Public
|
||||||
public TimeSpan Duration
|
public TimeSpan Duration
|
||||||
{
|
{
|
||||||
get
|
get { return duration; }
|
||||||
{
|
}
|
||||||
return duration;
|
#endregion
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructor
|
#region Constructor
|
||||||
internal XAudioSoundEffect(SoundEffect setParent, Stream stream)
|
internal XAudioSoundEffect(SoundEffect setParent, Stream stream)
|
||||||
{
|
{
|
||||||
parent = setParent;
|
Parent = setParent;
|
||||||
CreateFromStream(stream);
|
CreateFromStream(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal XAudioSoundEffect(SoundEffect setParent, byte[] buffer, int offset, int count, int sampleRate,
|
internal XAudioSoundEffect(SoundEffect setParent, byte[] buffer, int offset, int count, int sampleRate,
|
||||||
AudioChannels channels, int loopStart, int loopLength)
|
AudioChannels channels, int loopStart, int loopLength)
|
||||||
{
|
{
|
||||||
parent = setParent;
|
Parent = setParent;
|
||||||
|
|
||||||
using (MemoryStream stream = new MemoryStream())
|
using (var stream = new MemoryStream())
|
||||||
{
|
{
|
||||||
BinaryWriter writer = new BinaryWriter(stream);
|
var writer = new BinaryWriter(stream);
|
||||||
writer.Write(buffer, offset, count);
|
writer.Write(buffer, offset, count);
|
||||||
stream.Position = 0;
|
stream.Position = 0;
|
||||||
CreateFromStream(stream);
|
CreateFromStream(stream);
|
||||||
@ -62,16 +59,16 @@ namespace ANX.SoundSystem.Windows.XAudio
|
|||||||
private void CreateFromStream(Stream stream)
|
private void CreateFromStream(Stream stream)
|
||||||
{
|
{
|
||||||
var soundStream = new SoundStream(stream);
|
var soundStream = new SoundStream(stream);
|
||||||
waveFormat = soundStream.Format;
|
WaveFormat = soundStream.Format;
|
||||||
audioBuffer = new AudioBuffer
|
AudioBuffer = new AudioBuffer
|
||||||
{
|
{
|
||||||
Stream = soundStream.ToDataStream(),
|
Stream = soundStream.ToDataStream(),
|
||||||
AudioBytes = (int)stream.Length,
|
AudioBytes = (int)stream.Length,
|
||||||
Flags = BufferFlags.EndOfStream
|
Flags = BufferFlags.EndOfStream
|
||||||
};
|
};
|
||||||
|
|
||||||
float sizeMulBlockAlign = soundStream.Length / (waveFormat.Channels * 2);
|
float sizeMulBlockAlign = (float)soundStream.Length / (WaveFormat.Channels * 2);
|
||||||
duration = TimeSpan.FromMilliseconds((double)(sizeMulBlockAlign * 1000f / (float)waveFormat.SampleRate));
|
duration = TimeSpan.FromMilliseconds(sizeMulBlockAlign * 1000f / WaveFormat.SampleRate);
|
||||||
|
|
||||||
DecodedPacketsInfo = soundStream.DecodedPacketsInfo;
|
DecodedPacketsInfo = soundStream.DecodedPacketsInfo;
|
||||||
|
|
||||||
@ -82,8 +79,8 @@ namespace ANX.SoundSystem.Windows.XAudio
|
|||||||
#region Dispose
|
#region Dispose
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
waveFormat = null;
|
WaveFormat = null;
|
||||||
audioBuffer = null;
|
AudioBuffer = null;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using ANX.Framework;
|
||||||
using ANX.Framework.Audio;
|
using ANX.Framework.Audio;
|
||||||
using ANX.Framework.NonXNA.SoundSystem;
|
using ANX.Framework.NonXNA.SoundSystem;
|
||||||
using SharpDX.XAudio2;
|
using SharpDX.XAudio2;
|
||||||
@ -9,147 +10,181 @@ using SharpDX.XAudio2;
|
|||||||
|
|
||||||
namespace ANX.SoundSystem.Windows.XAudio
|
namespace ANX.SoundSystem.Windows.XAudio
|
||||||
{
|
{
|
||||||
public class XAudioSoundEffectInstance : ISoundEffectInstance
|
public class XAudioSoundEffectInstance : ISoundEffectInstance
|
||||||
{
|
{
|
||||||
#region Private
|
#region Private
|
||||||
private XAudioSoundEffect parent;
|
private SourceVoice source;
|
||||||
|
private float currentPitch;
|
||||||
|
private float currentPan;
|
||||||
|
private bool currentIsLooped;
|
||||||
|
private readonly XAudioSoundEffect parent;
|
||||||
|
private float[] panMatrix;
|
||||||
|
#endregion
|
||||||
|
|
||||||
private SourceVoice source;
|
#region Public
|
||||||
#endregion
|
public bool IsLooped
|
||||||
|
{
|
||||||
|
get { return currentIsLooped; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
currentIsLooped = value;
|
||||||
|
// TODO: set real parameter
|
||||||
|
if(value)
|
||||||
|
throw new NotImplementedException("IsLooped is currently not implemented for XAudio!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region Public
|
public float Pan
|
||||||
public bool IsLooped
|
{
|
||||||
{
|
get { return currentPan; }
|
||||||
get
|
set
|
||||||
{
|
{
|
||||||
return false;
|
currentPan = MathHelper.Clamp(value, -1f, 1f);
|
||||||
//throw new NotImplementedException();
|
UpdateSourcePan();
|
||||||
}
|
}
|
||||||
set
|
}
|
||||||
{
|
|
||||||
//throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float Pan
|
public float Pitch
|
||||||
{
|
{
|
||||||
get
|
get { return currentPitch; }
|
||||||
{
|
set
|
||||||
return 0f;
|
{
|
||||||
//throw new NotImplementedException();
|
currentPitch = value;
|
||||||
}
|
source.SetFrequencyRatio(value);
|
||||||
set
|
// TODO: pitch <= 1 is working, but greater isn't
|
||||||
{
|
if (value > 1f)
|
||||||
//throw new NotImplementedException();
|
throw new NotImplementedException("Pitch greater than 1f is currently not implemented for XAudio!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float Pitch
|
public SoundState State { get; private set; }
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return 1f;
|
|
||||||
//throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
//throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SoundState State
|
public float Volume
|
||||||
{
|
{
|
||||||
get;
|
get { return source.Volume; }
|
||||||
private set;
|
set { source.SetVolume(value, 0); }
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
public float Volume
|
#region Constructor
|
||||||
{
|
internal XAudioSoundEffectInstance(XAudio2 device, XAudioSoundEffect setParent)
|
||||||
get
|
{
|
||||||
{
|
parent = setParent;
|
||||||
return source.Volume;
|
currentIsLooped = false;
|
||||||
}
|
currentPan = 0f;
|
||||||
set
|
currentPitch = 1f;
|
||||||
{
|
State = SoundState.Stopped;
|
||||||
source.SetVolume(value, 0);
|
source = new SourceVoice(device, setParent.WaveFormat);
|
||||||
}
|
source.SubmitSourceBuffer(setParent.AudioBuffer, setParent.DecodedPacketsInfo);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructor
|
#region Play
|
||||||
internal XAudioSoundEffectInstance(XAudio2 device, XAudioSoundEffect setParent)
|
public void Play()
|
||||||
{
|
{
|
||||||
parent = setParent;
|
if (State == SoundState.Playing)
|
||||||
|
return;
|
||||||
|
|
||||||
State = SoundState.Stopped;
|
State = SoundState.Playing;
|
||||||
|
source.Start();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
var sourceVoice = new SourceVoice(device, setParent.waveFormat);
|
#region Pause
|
||||||
sourceVoice.SubmitSourceBuffer(setParent.audioBuffer, setParent.DecodedPacketsInfo);
|
public void Pause()
|
||||||
sourceVoice.Start();
|
{
|
||||||
}
|
State = SoundState.Paused;
|
||||||
#endregion
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Play
|
#region Stop
|
||||||
public void Play()
|
public void Stop(bool immediate)
|
||||||
{
|
{
|
||||||
if (State != SoundState.Playing)
|
if (State == SoundState.Stopped)
|
||||||
{
|
return;
|
||||||
State = SoundState.Playing;
|
|
||||||
source.Start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Pause
|
if (immediate == false)
|
||||||
public void Pause()
|
return;
|
||||||
{
|
|
||||||
if (State != SoundState.Paused)
|
|
||||||
{
|
|
||||||
State = SoundState.Paused;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Stop
|
State = SoundState.Stopped;
|
||||||
public void Stop(bool immediate)
|
source.Stop();
|
||||||
{
|
}
|
||||||
if (State == SoundState.Stopped)
|
#endregion
|
||||||
return;
|
|
||||||
|
|
||||||
if (immediate)
|
#region Resume
|
||||||
{
|
public void Resume()
|
||||||
State = SoundState.Stopped;
|
{
|
||||||
source.Stop();
|
State = SoundState.Playing;
|
||||||
}
|
}
|
||||||
}
|
#endregion
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Resume
|
#region UpdateSourcePan (TODO)
|
||||||
public void Resume()
|
private void UpdateSourcePan()
|
||||||
{
|
{
|
||||||
if (State != SoundState.Playing)
|
var sourceChannelCount = parent.WaveFormat.Channels;
|
||||||
{
|
var destinationChannelCount = Creator.MasteringVoice.VoiceDetails.InputChannelCount;
|
||||||
State = SoundState.Playing;
|
InitializePanMatrix(destinationChannelCount);
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Apply3D (TODO)
|
var leftPanValue = 1f - currentPan;
|
||||||
public void Apply3D(AudioListener[] listeners, AudioEmitter emitter)
|
var rightPanValue = 1f + currentPan;
|
||||||
{
|
panMatrix[0] = leftPanValue;
|
||||||
throw new NotImplementedException();
|
panMatrix[1] = rightPanValue;
|
||||||
}
|
|
||||||
#endregion
|
// TODO: get the channel mask which is strangely only available on Windows8
|
||||||
|
//switch (Creator.MasteringVoice.ChannelMask)
|
||||||
|
//{
|
||||||
|
// case (int)Speakers.Quad:
|
||||||
|
// panMatrix[2] = leftPanValue;
|
||||||
|
// panMatrix[3] = rightPanValue;
|
||||||
|
// break;
|
||||||
|
|
||||||
#region Dispose
|
// case (int)Speakers.FourPointOne:
|
||||||
public void Dispose()
|
// panMatrix[3] = leftPanValue;
|
||||||
{
|
// panMatrix[4] = rightPanValue;
|
||||||
if (source != null)
|
// break;
|
||||||
{
|
|
||||||
source.Dispose();
|
// case (int)Speakers.FivePointOne:
|
||||||
source = null;
|
// case (int)Speakers.SevenPointOne:
|
||||||
}
|
// case (int)Speakers.FivePointOneSurround:
|
||||||
}
|
// panMatrix[4] = leftPanValue;
|
||||||
#endregion
|
// panMatrix[5] = rightPanValue;
|
||||||
}
|
// break;
|
||||||
|
|
||||||
|
// case (int)Speakers.SevenPointOneSurround:
|
||||||
|
// panMatrix[4] = panMatrix[6] = leftPanValue;
|
||||||
|
// panMatrix[5] = panMatrix[7] = rightPanValue;
|
||||||
|
// break;
|
||||||
|
//}
|
||||||
|
|
||||||
|
source.SetOutputMatrix(sourceChannelCount, destinationChannelCount, panMatrix);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region InitializePanMatrix
|
||||||
|
private void InitializePanMatrix(int size)
|
||||||
|
{
|
||||||
|
if (panMatrix == null || panMatrix.Length < size)
|
||||||
|
panMatrix = new float[Math.Max(size, 8)];
|
||||||
|
|
||||||
|
for (var index = 0; index < panMatrix.Length; index++)
|
||||||
|
panMatrix[index] = 1f;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Apply3D (TODO)
|
||||||
|
public void Apply3D(AudioListener[] listeners, AudioEmitter emitter)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Dispose
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (source != null)
|
||||||
|
source.Dispose();
|
||||||
|
source = null;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user