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