Implemented the Framework side of DynamicSoundEffectInstance (still needs native implementation)

This commit is contained in:
SND\AstrorEnales_cp 2012-09-30 08:28:17 +00:00 committed by Konstantin Koch
parent 3bf2261cd0
commit d4cce42aa8
12 changed files with 162 additions and 165 deletions

View File

@ -445,6 +445,7 @@
<Compile Include="NonXNA\RenderSystem\INativeConstantBuffer.cs" /> <Compile Include="NonXNA\RenderSystem\INativeConstantBuffer.cs" />
<Compile Include="NonXNA\RenderSystem\IOcclusionQuery.cs" /> <Compile Include="NonXNA\RenderSystem\IOcclusionQuery.cs" />
<Compile Include="NonXNA\RenderSystem\VertexTypeHelper.cs" /> <Compile Include="NonXNA\RenderSystem\VertexTypeHelper.cs" />
<Compile Include="NonXNA\SoundSystem\IDynamicSoundEffectInstance.cs" />
<Compile Include="NonXNA\SoundSystem\IMicrophone.cs" /> <Compile Include="NonXNA\SoundSystem\IMicrophone.cs" />
<Compile Include="NonXNA\SoundSystem\ISong.cs" /> <Compile Include="NonXNA\SoundSystem\ISong.cs" />
<Compile Include="NonXNA\ThreadHelper.cs" /> <Compile Include="NonXNA\ThreadHelper.cs" />

View File

@ -4,7 +4,6 @@ using System.Collections.ObjectModel;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using ANX.Framework.Audio.XactParser; using ANX.Framework.Audio.XactParser;
using ANX.Framework.NonXNA;
using ANX.Framework.NonXNA.Development; using ANX.Framework.NonXNA.Development;
using ANX.Framework.NonXNA.PlatformSystem; using ANX.Framework.NonXNA.PlatformSystem;
@ -44,17 +43,12 @@ namespace ANX.Framework.Audio
#endregion #endregion
#region Constructor (TODO) #region Constructor (TODO)
public AudioEngine(string settingsFile) public AudioEngine(string settingsFile)
{ : this(settingsFile, TimeSpan.FromMilliseconds(250.0), String.Empty)
// TODO: get renderer details {
RendererDetails = new ReadOnlyCollection<RendererDetail>(new List<RendererDetail>()); }
Stream loadingStream = PlatformSystem.Instance.OpenReadFilestream(settingsFile); public AudioEngine(string settingsFile, TimeSpan lookAheadTime, string rendererId)
generalSettings = new XactGeneralSettings(loadingStream);
loadingStream.Dispose();
}
public AudioEngine(string settingsFile, TimeSpan lookAheadTime, string rendererId)
{ {
// TODO: get renderer details // TODO: get renderer details
RendererDetails = new ReadOnlyCollection<RendererDetail>(new List<RendererDetail>()); RendererDetails = new ReadOnlyCollection<RendererDetail>(new List<RendererDetail>());

View File

@ -1,5 +1,7 @@
using System; using System;
using ANX.Framework.NonXNA;
using ANX.Framework.NonXNA.Development; using ANX.Framework.NonXNA.Development;
using ANX.Framework.NonXNA.SoundSystem;
// 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.
@ -7,82 +9,75 @@ using ANX.Framework.NonXNA.Development;
namespace ANX.Framework.Audio namespace ANX.Framework.Audio
{ {
[PercentageComplete(0)] [PercentageComplete(100)]
public sealed class DynamicSoundEffectInstance : SoundEffectInstance [TestState(TestStateAttribute.TestState.Untested)]
{ [Developer("AstrorEnales")]
#region Events public sealed class DynamicSoundEffectInstance : SoundEffectInstance
public event EventHandler<EventArgs> BufferNeeded; {
#endregion private IDynamicSoundEffectInstance nativeDynamicInstance;
private readonly AudioChannels channels;
private readonly int sampleRate;
#region Public public event EventHandler<EventArgs> BufferNeeded;
public override bool IsLooped
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public int PendingBufferCount #region Public
{ public int PendingBufferCount
get {
{ get { return nativeDynamicInstance.PendingBufferCount; }
throw new NotImplementedException(); }
} #endregion
}
#endregion
#region Constructor #region Constructor
public DynamicSoundEffectInstance(int sampleRate, AudioChannels channels) public DynamicSoundEffectInstance(int sampleRate, AudioChannels channels)
{ {
throw new NotImplementedException(); this.sampleRate = sampleRate;
} this.channels = channels;
#endregion var creator = AddInSystemFactory.Instance.GetDefaultCreator<ISoundSystemCreator>();
nativeDynamicInstance = creator.CreateDynamicSoundEffectInstance();
nativeDynamicInstance.BufferNeeded += OnBufferNeeded;
SetNativeInstance(nativeDynamicInstance);
}
#endregion
#region GetSampleDuration private void OnBufferNeeded(object sender, EventArgs args)
public TimeSpan GetSampleDuration(int sizeInBytes) {
{ BufferNeeded.Invoke(this, EventArgs.Empty);
throw new NotImplementedException(); }
}
#endregion
#region GetSampleSizeInBytes #region GetSampleDuration
public int GetSampleSizeInBytes(TimeSpan duration) public TimeSpan GetSampleDuration(int sizeInBytes)
{ {
throw new NotImplementedException(); float sizeMulBlockAlign = (float)sizeInBytes / ((int)channels * 2);
} return TimeSpan.FromMilliseconds(sizeMulBlockAlign * 1000f / sampleRate);
#endregion }
#endregion
#region Play #region GetSampleSizeInBytes
public override void Play() public int GetSampleSizeInBytes(TimeSpan duration)
{ {
throw new NotImplementedException(); int timeMulSamples = (int)(duration.TotalMilliseconds * (sampleRate / 1000f));
} return (timeMulSamples + timeMulSamples % (int)channels) * ((int)channels * 2);
#endregion }
#endregion
public void SubmitBuffer(byte[] buffer)
{
nativeDynamicInstance.SubmitBuffer(buffer);
}
#region SubmitBuffer public void SubmitBuffer(byte[] buffer, int offset, int count)
public void SubmitBuffer(byte[] buffer) {
{ nativeDynamicInstance.SubmitBuffer(buffer, offset, count);
throw new NotImplementedException(); }
}
#endregion
#region SubmitBuffer protected override void Dispose(bool disposing)
public void SubmitBuffer(byte[] buffer, int offset, int count) {
{ if (nativeDynamicInstance != null)
throw new NotImplementedException(); {
} nativeDynamicInstance.BufferNeeded -= OnBufferNeeded;
#endregion }
nativeDynamicInstance = null;
#region Dispose base.Dispose(true);
protected override void Dispose(bool disposing) }
{ }
throw new NotImplementedException();
}
#endregion
}
} }

View File

@ -16,22 +16,16 @@ namespace ANX.Framework.Audio
#endregion #endregion
#region Public #region Public
public string FriendlyName public string FriendlyName
{ {
get get { return friendlyName; }
{ }
return friendlyName;
}
}
public string RendererId public string RendererId
{ {
get get { return rendererId; }
{ }
return rendererId; #endregion
}
}
#endregion
#region Constructor #region Constructor
internal RendererDetail(string setFriendlyName, string setRendererId) internal RendererDetail(string setFriendlyName, string setRendererId)
@ -66,10 +60,8 @@ namespace ANX.Framework.Audio
#region Equality #region Equality
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
if (obj != null && obj is RendererDetail) if (obj is RendererDetail)
{
return this == (RendererDetail)obj; return this == (RendererDetail)obj;
}
return false; return false;
} }

View File

@ -15,7 +15,7 @@ namespace ANX.Framework.Audio
public class SoundEffectInstance : IDisposable public class SoundEffectInstance : IDisposable
{ {
#region Private #region Private
private ISoundEffectInstance nativeInstance; internal ISoundEffectInstance NativeInstance { get; private set; }
internal bool IsFireAndForget { get; private set; } internal bool IsFireAndForget { get; private set; }
#endregion #endregion
@ -24,31 +24,31 @@ namespace ANX.Framework.Audio
public virtual bool IsLooped public virtual bool IsLooped
{ {
get { return nativeInstance.IsLooped; } get { return NativeInstance.IsLooped; }
set { nativeInstance.IsLooped = value; } set { NativeInstance.IsLooped = value; }
} }
public float Pan public float Pan
{ {
get { return nativeInstance.Pan; } get { return NativeInstance.Pan; }
set { nativeInstance.Pan = value; } set { NativeInstance.Pan = value; }
} }
public float Pitch public float Pitch
{ {
get { return nativeInstance.Pitch; } get { return NativeInstance.Pitch; }
set { nativeInstance.Pitch = value; } set { NativeInstance.Pitch = value; }
} }
public SoundState State public SoundState State
{ {
get { return nativeInstance.State; } get { return NativeInstance.State; }
} }
public float Volume public float Volume
{ {
get { return nativeInstance.Volume; } get { return NativeInstance.Volume; }
set { nativeInstance.Volume = value; } set { NativeInstance.Volume = value; }
} }
#endregion #endregion
@ -60,7 +60,7 @@ namespace ANX.Framework.Audio
internal SoundEffectInstance(SoundEffect setParent, bool setIsFireAndForget) internal SoundEffectInstance(SoundEffect setParent, bool setIsFireAndForget)
{ {
IsFireAndForget = setIsFireAndForget; IsFireAndForget = setIsFireAndForget;
nativeInstance = GetCreator().CreateSoundEffectInstance(setParent.NativeSoundEffect); NativeInstance = GetCreator().CreateSoundEffectInstance(setParent.NativeSoundEffect);
} }
~SoundEffectInstance() ~SoundEffectInstance()
@ -69,6 +69,11 @@ namespace ANX.Framework.Audio
} }
#endregion #endregion
internal void SetNativeInstance(IDynamicSoundEffectInstance dynamicInstance)
{
NativeInstance = dynamicInstance;
}
#region GetCreator #region GetCreator
private static ISoundSystemCreator GetCreator() private static ISoundSystemCreator GetCreator()
{ {
@ -84,28 +89,28 @@ namespace ANX.Framework.Audio
public void Apply3D(AudioListener[] listeners, AudioEmitter emitter) public void Apply3D(AudioListener[] listeners, AudioEmitter emitter)
{ {
nativeInstance.Apply3D(listeners, emitter); NativeInstance.Apply3D(listeners, emitter);
} }
#endregion #endregion
#region Pause #region Pause
public void Pause() public void Pause()
{ {
nativeInstance.Pause(); NativeInstance.Pause();
} }
#endregion #endregion
#region Play #region Play
public virtual void Play() public virtual void Play()
{ {
nativeInstance.Play(); NativeInstance.Play();
} }
#endregion #endregion
#region Resume #region Resume
public void Resume() public void Resume()
{ {
nativeInstance.Resume(); NativeInstance.Resume();
} }
#endregion #endregion
@ -117,7 +122,7 @@ namespace ANX.Framework.Audio
public void Stop(bool immediate) public void Stop(bool immediate)
{ {
nativeInstance.Stop(immediate); NativeInstance.Stop(immediate);
} }
#endregion #endregion
@ -129,10 +134,10 @@ namespace ANX.Framework.Audio
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {
if (nativeInstance != null) if (NativeInstance != null)
{ {
nativeInstance.Dispose(); NativeInstance.Dispose();
nativeInstance = null; NativeInstance = null;
} }
IsDisposed = true; IsDisposed = true;

View File

@ -1,13 +1,13 @@
using System; using System;
using ANX.Framework.Audio;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using ANX.Framework.Audio;
namespace ANX.Framework.Content namespace ANX.Framework.Content
{ {
internal class SoundEffectReader : ContentTypeReader<SoundEffect> internal class SoundEffectReader : ContentTypeReader<SoundEffect>
{ {
private struct WAVEFORMATEX private struct WaveFormatEx
{ {
public ushort wFormatTag; public ushort wFormatTag;
public ushort nChannels; public ushort nChannels;
@ -23,11 +23,11 @@ namespace ANX.Framework.Content
int formatCount = input.ReadInt32(); int formatCount = input.ReadInt32();
byte[] header = input.ReadBytes(formatCount); byte[] header = input.ReadBytes(formatCount);
WAVEFORMATEX headerStruct; WaveFormatEx headerStruct;
unsafe unsafe
{ {
fixed(byte* ptr = &header[0]) fixed(byte* ptr = &header[0])
headerStruct = (WAVEFORMATEX)Marshal.PtrToStructure((IntPtr)ptr, typeof(WAVEFORMATEX)); headerStruct = (WaveFormatEx)Marshal.PtrToStructure((IntPtr)ptr, typeof(WaveFormatEx));
} }
int dataCount = input.ReadInt32(); int dataCount = input.ReadInt32();
@ -38,10 +38,10 @@ namespace ANX.Framework.Content
int duration = input.ReadInt32(); int duration = input.ReadInt32();
byte[] soundData = null; byte[] soundData;
using (MemoryStream mStream = new MemoryStream(20 + header.Length + 8 + data.Length)) using (var mStream = new MemoryStream(20 + header.Length + 8 + data.Length))
{ {
BinaryWriter writer = new BinaryWriter(mStream); var writer = new BinaryWriter(mStream);
writer.Write("RIFF".ToCharArray()); writer.Write("RIFF".ToCharArray());
writer.Write(20 + header.Length + data.Length); writer.Write(20 + header.Length + data.Length);
writer.Write("WAVE".ToCharArray()); writer.Write("WAVE".ToCharArray());

View File

@ -0,0 +1,17 @@
using System;
// 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.SoundSystem
{
public interface IDynamicSoundEffectInstance : ISoundEffectInstance
{
event EventHandler<EventArgs> BufferNeeded;
int PendingBufferCount { get; }
void SubmitBuffer(byte[] buffer);
void SubmitBuffer(byte[] buffer, int offset, int count);
}
}

View File

@ -7,45 +7,18 @@ using ANX.Framework.Audio;
namespace ANX.Framework.NonXNA.SoundSystem namespace ANX.Framework.NonXNA.SoundSystem
{ {
public interface ISoundEffectInstance : IDisposable public interface ISoundEffectInstance : IDisposable
{ {
bool IsLooped bool IsLooped { get; set; }
{ float Pan { get; set; }
get; float Pitch { get; set; }
set; SoundState State { get; }
} float Volume { get; set; }
float Pan void Play();
{ void Pause();
get; void Stop(bool immediate);
set; void Resume();
} void Apply3D(AudioListener[] listeners, AudioEmitter emitter);
}
float Pitch
{
get;
set;
}
SoundState State
{
get;
}
float Volume
{
get;
set;
}
void Play();
void Pause();
void Stop(bool immediate);
void Resume();
void Apply3D(AudioListener[] listeners, AudioEmitter emitter);
}
} }

View File

@ -36,5 +36,7 @@ namespace ANX.Framework.NonXNA.SoundSystem
int GetDefaultMicrophone(ReadOnlyCollection<Microphone> allMicrophones); int GetDefaultMicrophone(ReadOnlyCollection<Microphone> allMicrophones);
ISong CreateSong(Song parentSong, Uri uri); ISong CreateSong(Song parentSong, Uri uri);
IDynamicSoundEffectInstance CreateDynamicSoundEffectInstance();
} }
} }

View File

@ -160,6 +160,12 @@ namespace ANX.SoundSystem.OpenAL
#endregion #endregion
public ISong CreateSong(Song parentSong, Uri uri) public ISong CreateSong(Song parentSong, Uri uri)
{
PreventSystemChange();
throw new NotImplementedException();
}
public IDynamicSoundEffectInstance CreateDynamicSoundEffectInstance()
{ {
PreventSystemChange(); PreventSystemChange();
throw new NotImplementedException(); throw new NotImplementedException();

View File

@ -171,5 +171,11 @@ namespace ANX.SoundSystem.PsVita
AddInSystemFactory.Instance.PreventSystemChange(AddInType.SoundSystem); AddInSystemFactory.Instance.PreventSystemChange(AddInType.SoundSystem);
throw new NotImplementedException(); throw new NotImplementedException();
} }
public IDynamicSoundEffectInstance CreateDynamicSoundEffectInstance()
{
AddInSystemFactory.Instance.PreventSystemChange(AddInType.SoundSystem);
throw new NotImplementedException();
}
} }
} }

View File

@ -154,6 +154,12 @@ namespace ANX.SoundSystem.Windows.XAudio
} }
public ISong CreateSong(Song parentSong, Uri uri) public ISong CreateSong(Song parentSong, Uri uri)
{
PreventSystemChange();
throw new NotImplementedException();
}
public IDynamicSoundEffectInstance CreateDynamicSoundEffectInstance()
{ {
PreventSystemChange(); PreventSystemChange();
throw new NotImplementedException(); throw new NotImplementedException();